factory-girl
Advanced tools
Comparing version 4.0.0-beta to 4.0.0-beta.1
@@ -0,1 +1,9 @@ | ||
## v4.0.0 | ||
Total rewrite. Should preserve backwards compatibility except as noted below. | ||
- `assocBuild` is now `assocAttr` | ||
- `assocBuildMany` | ||
- `FactoryGirl.setAdapter` now takes an array of `factoryNames` for convenience | ||
## v3.0.0 | ||
@@ -2,0 +10,0 @@ |
@@ -5,4 +5,17 @@ { | ||
"main": "./index", | ||
"author": "Simon Wade", | ||
"version": "4.0.0-beta", | ||
"author": [ | ||
"@aexmachina", | ||
"@chetanism" | ||
], | ||
"babel": { | ||
"presets": [ | ||
"es2015", | ||
"stage-0" | ||
], | ||
"plugins": [ | ||
"transform-runtime", | ||
"transform-class-properties" | ||
] | ||
}, | ||
"version": "4.0.0-beta.1", | ||
"keywords": [ | ||
@@ -30,18 +43,44 @@ "factory", | ||
"dependencies": { | ||
"lodash.merge": "^3.3.2" | ||
"babel-runtime": "^6.6.1", | ||
"chance": "^1.0.3" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.8.0", | ||
"babel-core": "^6.8.0", | ||
"babel-eslint": "^6.0.4", | ||
"babel-plugin-transform-runtime": "^6.8.0", | ||
"babel-preset-es2015": "^6.6.0", | ||
"babel-preset-es2015-rollup": "^1.1.1", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"babel-register": "^6.9.0", | ||
"bluebird": "^2.9.25", | ||
"bookshelf": "^0.10.0", | ||
"chai": "^3.5.0", | ||
"mocha": "^2.2.5", | ||
"should": "^6.0.3" | ||
"chai-as-promised": "^5.3.0", | ||
"del": "^2.2.0", | ||
"eslint": "^2.11.1", | ||
"eslint-config-airbnb": "^9.0.1", | ||
"eslint-plugin-import": "^1.8.1", | ||
"eslint-plugin-jsx-a11y": "^1.3.0", | ||
"eslint-plugin-mocha": "^3.0.0", | ||
"eslint-plugin-react": "^5.1.1", | ||
"istanbul": "^1.0.0-alpha.2", | ||
"knex": "^0.11.7", | ||
"mocha": "^2.5.3", | ||
"mocha-eslint": "^2.1.1", | ||
"mongoose": "^4.5.4", | ||
"rollup": "^0.27.0", | ||
"rollup-plugin-babel": "^2.5.0", | ||
"should": "^6.0.3", | ||
"sinon": "^2.0.0-pre", | ||
"sinon-chai": "https://github.com/sjmulder/sinon-chai.git#pr/sinon-2.0.0-pre", | ||
"sqlite3": "^3.1.4" | ||
}, | ||
"scripts": { | ||
"test": "mocha" | ||
}, | ||
"files": [ | ||
"lib", | ||
"test", | ||
"index.js" | ||
] | ||
"lint": "eslint src test tools", | ||
"test": "NODE_ENV=test mocha", | ||
"test:cover": "NODE_ENV=test babel-node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha", | ||
"build": "node tools/build", | ||
"prepublish": "npm run test && npm run build" | ||
} | ||
} |
399
README.md
@@ -15,6 +15,12 @@ # factory-girl | ||
To use `factory-girl` in the browser or other JavaScript environments, just include `index.js` and access `window.Factory`. | ||
To use `factory-girl` in the browser or other JavaScript environments, there are | ||
builds for numerous module systems in the `dist/` directory. | ||
## Usage | ||
Refer to [the tutorial](docs/tutorial.md) for a gentle introduction of building a simple | ||
user factory. | ||
Here's the crash course: | ||
```javascript | ||
@@ -29,5 +35,4 @@ var factory = require('factory-girl'); | ||
factory.build('user', function(err, user) { | ||
console.log(user.attributes); | ||
// => {username: 'Bob', score: 50} | ||
factory.build('user').then(user => { | ||
console.log(user); // => User {username: 'Bob', score: 50} | ||
}); | ||
@@ -38,50 +43,46 @@ ``` | ||
Define factories using the `factory.define()` method. | ||
For example: | ||
```javascript | ||
var factory = require('factory-girl'); | ||
var User = require('../models/user'); | ||
// Using objects as initializer | ||
factory.define('product', Product, { | ||
// use sequences to generate values sequentially | ||
id: factory.sequence('Product.id', (n) => `product_${n}`), | ||
// use functions to compute some complex value | ||
launchDate: () => new Date(), | ||
// return a promise to populate data asynchronously | ||
asyncData: () => fetch('some/resource'), | ||
}); | ||
factory.define('user', User, { | ||
// seq is an alias for sequence | ||
email: factory.seq('User.email', (n) => `user${n}@ymail.com`), | ||
factory.define('user', User, { | ||
email: factory.sequence(function(n) { | ||
return 'user' + n + '@demo.com'; | ||
}), | ||
// async functions can be used by accepting a callback as an argument | ||
async: function(callback) { | ||
somethingAsync(callback); | ||
}, | ||
// you can refer to other attributes using `this` | ||
username: function() { | ||
return this.email; | ||
} | ||
// use the chance(http://chancejs.com/) library to generate real-life like data | ||
about: factory.chance('sentence'), | ||
// use assoc to associate with other models | ||
profileImage: factory.assoc('profile_image', '_id'), | ||
// or assocMany to associate multiple models | ||
addresses: factory.assocMany('address', 2, '_id'), | ||
// use assocAttrs to embed models that are not persisted | ||
creditCardNumber: factory.assocAttrs('credit_card', 'number', {type: 'masterCard'}), | ||
// use assocAttrs or assocAttrsMany to embed plain json objects | ||
twitterDetails: factory.assocAttrs('twitter_details'), | ||
}); | ||
factory.build('user', function(err, user) { | ||
console.log(user.attributes); | ||
// => {state: 'active', email: 'user1@demo.com', async: 'foo', username: 'user1@demo.com'} | ||
}); | ||
``` | ||
### Initializer function | ||
You can provide a function instead of an object to initialize models. | ||
You can pass the `buildOptions` object to the `factory.attrs`, `factory.build`, `factory.create` and the same object will be passed on to the initializer function. | ||
```javascript | ||
var factory = require('factory-girl'); | ||
var User = require('../models/user'); | ||
factory.define('user', User, function (buildOptions) { | ||
// Using functions as initializer | ||
factory.define('account', Account, buildOptions => { | ||
var attrs = { | ||
email: factory.sequence(function(n) { | ||
return 'user' + n + '@demo.com'; | ||
}), | ||
// async functions can be used by accepting a callback as an argument | ||
async: function(callback) { | ||
somethingAsync(callback); | ||
}, | ||
// you can refer to other attributes using `this` | ||
username: function() { | ||
return this.email; | ||
}, | ||
confirmed: false, | ||
confirmedAt: null | ||
}; | ||
// use build options to modify the returned object | ||
if (buildOptions.confirmedUser) { | ||
@@ -91,7 +92,7 @@ attrs.confirmed = true; | ||
} | ||
return attrs; | ||
}); | ||
factory.build('user', function(err, user) { | ||
console.log(user.attributes); | ||
// => {state: 'active', email: 'user1@demo.com', async: 'foo', username: 'user1@demo.com'} | ||
}); | ||
// buildOptions can be passed while requesting an object | ||
factory.build('account', {}, {confirmed: true}); | ||
``` | ||
@@ -101,3 +102,3 @@ | ||
Options can be provided when you define a model: | ||
Options can be provided when you define a factory: | ||
@@ -108,6 +109,6 @@ ```javascript | ||
Alternatively you can create a new factory that specifies options for all of its models: | ||
Alternatively you can set options for the factory that will get applied for all model-factories: | ||
```javascript | ||
var builder = factory.withOptions(options); | ||
factory.withOptions(options); | ||
``` | ||
@@ -117,23 +118,28 @@ | ||
#### `afterBuild: function(instance, attrs, callback)` | ||
#### `afterBuild: function(model, attrs, buildOptions)` | ||
Provides a function that is called after the model is built. | ||
The function should return the instance or throw an error. For asynchronous functions, it should return a promise that either resolves with the instance or rejects with the error. | ||
#### `afterCreate: function(instance, attrs, callback)` | ||
#### `afterCreate: function(model, attrs, buildOptions)` | ||
Provides a function that is called after a new model instance is saved. | ||
Provides a function that is called after a new model instance is saved. The function | ||
should return the instance or throw an error. For asynchronous functions, it should return | ||
a promise that resolves with the instance or rejects with the error. | ||
```javascript | ||
factory.define('user', User, { | ||
foo: 'bar' | ||
}, { | ||
afterCreate: function(instance, attrs, callback) { | ||
generateBazBasedOnID(instance.id, function(error, generatedBaz) { | ||
if(error) { | ||
callback(error, null); | ||
} else { | ||
instance.baz = generatedBaz; | ||
callback(null, instance); | ||
} | ||
factory.define('user', User, {foo: 'bar'}, { | ||
afterBuild: (model, attrs, buildOptions) => { | ||
return doSomethingAsync(model).then(() => { | ||
doWhateverElse(model); | ||
return model; | ||
}); | ||
}, | ||
afterCreate: (model, attrs, buildOptions) => { | ||
modify(model); | ||
if ('something' === 'wrong') { | ||
throw new Error; | ||
} | ||
maybeLog('something'); | ||
return model; | ||
} | ||
@@ -143,97 +149,63 @@ }); | ||
Other builder options can be accessed, inside hooks, using `this.options`. | ||
## Using Factories | ||
## Defining Associations | ||
### Factory#attrs | ||
Generates and returns model attributes as an object hash instead of the model instance. | ||
This may be useful where you need a JSON representation of the model e.g. mocking an API | ||
response. | ||
```javascript | ||
factory.define('post', Post, { | ||
// create associations using factory.assoc(model, key) or factory.assoc('user') to return the user object itself. | ||
user_id: factory.assoc('user', 'id'), | ||
// create array of associations using factory.assocMany(model, key, num) | ||
comments: factory.assocMany('comment', 'text', 2) | ||
factory.attrs('post').then(postAttrs => { | ||
// postAttrs is a json representation of the Post model | ||
}); | ||
factory.create('post', function(err, post) { | ||
console.log(post.attributes); | ||
// => { id: 1, user_id: 1, comments: [{ text: 'hello' }, { text: 'hello' }] } | ||
factory.attrs('post', {title: 'Foo', content: 'Bar'}).then(postAttrs => { | ||
// builds post json object and overrides title and content | ||
}); | ||
``` | ||
Be aware that `assoc()` will always create associated records, even when `factory.build()` is called. | ||
You can use `assocBuild()`, which will always build associated records. | ||
## Defining Sequences | ||
```javascript | ||
factory.define('post', Post, { | ||
// Creates a new sequence that returns the next number in the sequence for | ||
// each created instance, starting with 1. | ||
num: factory.sequence(), | ||
// factory.sequence can be abbreviated as factory.seq | ||
email: factory.seq(function(n) { | ||
return 'email' + n + '@test.com'; | ||
}), | ||
// Can also be async | ||
asyncProp: factory.seq(function(n, callback) { | ||
somethingAsync(n, callback); | ||
}) | ||
factory.attrs('post', {title: 'Foo'}, {hasComments: true}).then(postAttrs => { | ||
// builds post json object | ||
// overrides title | ||
// invokes the initializer function with buildOptions of {hasComments: true} | ||
}); | ||
``` | ||
## Using Factories | ||
You can use `Factory#attrsMany` to generate a set of model attributes | ||
### Factory#attrs | ||
Generates and returns attrs. | ||
```javascript | ||
factory.attrs('post', function(err, postAttrs) { | ||
// postAttrs is a post attributes | ||
console.log(postAttrs); | ||
// => {title: 'Hello', authorEmail: 'user1@demo.com'} | ||
factory.attrsMany('post', 5, [{title: 'foo1'}, {title: 'foo2'}]).then(postAttrsArray => { | ||
// postAttrsArray is an array of 5 post json objects | ||
debug(postAttrsArray); | ||
}); | ||
factory.attrs('post', {title: 'Foo', content: 'Bar'}, function(err, postAttrs) { | ||
// build post attrs and override title and content | ||
}); | ||
``` | ||
In case you have defined your factory with an [initializer function](#initializer-function), you can pass on `buildOptions` to be passed to the initializer function. | ||
Refer [API docs](docs/api.md) for complete API documentation. | ||
```javascript | ||
factory.attrs('user', {}, { confirmedUser: true }, function (err, userAttrs) { | ||
// userAttrs is a user attributes | ||
console.log(userAttrs); | ||
} | ||
``` | ||
Note that in case you want to pass buildOptions, you have to pass attributes parameter as well. Otherwise, the buildOptions will be treated as attribute parameters. | ||
### Factory#build | ||
Creates a new (unsaved) instance. | ||
Builds a new model instance that is not persisted. | ||
```javascript | ||
factory.build('post', function(err, post) { | ||
// post is a Post instance that is not saved | ||
factory.build('post').then(post => { | ||
// post is a Post instance that is not persisted | ||
}); | ||
factory.build('post', {title: 'Foo', content: 'Bar'}, function(err, post) { | ||
// build a post and override title and content | ||
}); | ||
``` | ||
In case you have defined your factory with an [initializer function](#initializer-function), you can pass on `buildOptions` to be passed to the initializer function. | ||
The `buildMany` version builds an array of model instances. | ||
```javascript | ||
factory.build('user', {}, { confirmedUser: true }, function (err, userAttrs) { | ||
// userAttrs is a user attributes | ||
console.log(userAttrs); | ||
} | ||
factory.buildMany('post', 5).then(postsArray => { | ||
// postsArray is an array of 5 Post instances | ||
}); | ||
``` | ||
Note that in case you want to pass buildOptions, you have to pass attributes parameter as well. Otherwise, the buildOptions will be treated as attribute parameters. | ||
### Factory#create | ||
Similar to `Factory#attrs`, you can pass attributes to override or buildOptions. | ||
Builds and saves a new instance. | ||
### Factory#create(name, attrs, buildOptions) | ||
``` | ||
factory.create('post', function(err, post) { | ||
Builds a new model instance that is persisted. | ||
```js | ||
factory.create('post').then(post => { | ||
// post is a saved Post instance | ||
@@ -243,140 +215,34 @@ }); | ||
In case you have defined your factory with an [initializer function](#initializer-function), you can pass on `buildOptions` to be passed to the initializer function. | ||
The createMany version creates an array of model instances. | ||
```javascript | ||
factory.create('user', {}, { confirmedUser: true }, function (err, userAttrs) { | ||
// userAttrs is a user attributes | ||
console.log(userAttrs); | ||
} | ||
``` | ||
Note that in case you want to pass buildOptions, you have to pass attributes parameter as well. Otherwise, the buildOptions will be treated as attribute parameters. | ||
### Factory#assoc(model, key = null, attrs = null, buildOptions = null) | ||
Defines an attribute of a model that creates an associated instance of another model. | ||
Use the `key` argument to return an attribute of the associated instance. | ||
You can optionally provide attributes to the associated factory by passing an object as third | ||
argument. | ||
Be aware that `assoc()` will always _create_ associated records, even when `factory.build()` is | ||
called. You can use `assocBuild()`, which will always build associated records. | ||
### Factory#assocBuild(model, key = null, attrs = null, buildOptions = null) | ||
Same as `#assoc`, but builds the associated models rather than creating them. | ||
### Factory#assocMany(model, key, num, attrs = null, buildOptions = null) | ||
Creates multiple entries. | ||
### Factory#assocManyBuild | ||
Same as `#assocMany`, but builds the associated models rather than creating them. | ||
### Factory#buildMany | ||
Allow you to create a number of models at once. | ||
```javascript | ||
factory.buildMany('post', 10, function(err, posts) { | ||
// build 10 posts | ||
factory.createMany('post', 5).then(postsArray => { | ||
// postsArray is an array of 5 Post saved instances | ||
}); | ||
factory.buildMany('post', 10, [{withImage: true}, {veryLong: true}], function(err, posts) { | ||
// build 10 posts, using build options for first two | ||
}); | ||
factory.buildMany('post', 10, {withImage: true}, function(err, posts) { | ||
// build 10 posts, using same build options for all of them | ||
}); | ||
factory.buildMany('post', [{title: 'Foo'}, {title: 'Bar'}], function(err, posts) { | ||
// build 2 posts using the specified attributes | ||
}); | ||
factory.buildMany('post', [{title: 'Foo'}, {title: 'Bar'}], [{withImage: true}], function(err, posts) { | ||
// build 2 posts using the specified attributes | ||
// build first post using the build option | ||
}); | ||
factory.buildMany('post', [{title: 'Foo'}, {title: 'Bar'}], {withImage: true}, function(err, posts) { | ||
// build first 2 posts using the specified attributes using same build options for all of them | ||
}); | ||
factory.buildMany('post', [{title: 'Foo'}, {title: 'Bar'}], 10, function(err, posts) { | ||
// build 10 posts using the specified attributes for the first and second | ||
}); | ||
factory.buildMany('post', [{title: 'Foo'}, {title: 'Bar'}], 10, [{withImage: true}, {veryLong: true}], function(err, posts) { | ||
// build 10 posts using the specified attributes and build options for the first and second | ||
}); | ||
factory.buildMany('post', [{title: 'Foo'}, {title: 'Bar'}], 10, {withImage: true}, function(err, posts) { | ||
// build 10 posts using the specified attributes for the first and second | ||
// uses same build options for all of them | ||
}); | ||
factory.buildMany('post', {title: 'Foo'}, 10, function(err, posts) { | ||
// build 10 posts using the specified attributes for all of them | ||
}); | ||
factory.buildMany('post', {title: 'Foo'}, 10, [{withImage: true}, {veryLong: true}], function(err, posts) { | ||
// build 10 posts using the specified attributes for all of them but using build options only for first two | ||
}); | ||
factory.buildMany('post', {title: 'Foo'}, 10, {withImage: true}, function(err, posts) { | ||
// build 10 posts using the specified attributes and build options for all of them | ||
}); | ||
``` | ||
### Factory#createMany | ||
Similar to `Factory#attrs` and `Factory#build`, you can pass `attrs` to override and | ||
`buildOptions`. | ||
`factory.createMany` takes the same arguments as `buildMany`, but returns saved models. | ||
### Factory#buildSync | ||
When you have factories that don't use async property functions, you can use `buildSync()`. | ||
Be aware that `assoc()` is an async function, so it can't be used with `buildSync()`. | ||
```javascript | ||
var doc = factory.buildSync('post', {title: 'Foo'}); | ||
``` | ||
### Factory#cleanup | ||
Destroys all of the created models. This is done using the adapter's `destroy` method. | ||
It might be useful to clear all created models before each test or testSuite. | ||
## Adapters | ||
Adapters provide [support for different databases and ORMs](https://www.npmjs.org/browse/keyword/factory-girl). | ||
Adapters can be registered for specific models, or as the 'default adapter', which is used for any models for which an adapter has not been specified. | ||
See the adapter docs for usage, but typical usage is: | ||
Adapters provide support for different databases and ORMs. Adapters can be registered for | ||
specific models, or as the 'default adapter', which is used for any models for which an | ||
adapter has not been specified. See the adapter docs for usage, but typical usage is: | ||
```javascript | ||
// use the bookshelf adapter as the default adapter | ||
require('factory-girl-bookshelf')(); | ||
``` | ||
const adapter = new factory.MongooseAdapter(); | ||
### `ObjectAdapter` | ||
// use the mongoose adapter as the default adapter | ||
factory.setAdapter(adapter); | ||
You can use the included ObjectAdapter to work without model classes. This adapter simply returns | ||
the provided attribute objects. | ||
// Or use it only for one model-factory | ||
factory.setAdapter(adapter, 'factory-name'); | ||
``` | ||
factory.setAdapter(new factory.ObjectAdapter()); | ||
``` | ||
### Using Different Adapters Per-model | ||
``` | ||
// use an ObjectAdapter for the `post` model only | ||
factory.setAdapter(new factory.ObjectAdapter(), 'post'); | ||
``` | ||
## Creating new Factories | ||
@@ -387,23 +253,26 @@ | ||
```javascript | ||
var anotherFactory = new factory.Factory(); | ||
var BookshelfAdapter = require('factory-girl-bookshelf').BookshelfAdapter; | ||
anotherFactory.setAdapter(new BookshelfAdapter()); // use the Bookshelf adapter | ||
var anotherFactory = new factory.FactoryGirl(); | ||
anotherFactory.setAdapter(new MongooseAdapter()); // use the Mongoose adapter | ||
``` | ||
## Like Promises? | ||
## History | ||
Me too! Bluebird and q are both supported: | ||
This module started out as a fork of | ||
[factory-lady](https://github.com/petejkim/factory-lady), but the fork deviated quite a | ||
bit. This module uses an adapter to talk to your models so it can support different ORMs | ||
such as [Bookshelf](https://github.com/aexmachina/factory-girl-bookshelf), | ||
[Sequelize](https://github.com/aexmachina/factory-girl-sequelize), | ||
[JugglingDB](https://github.com/rehanift/factory-girl-jugglingdb), and | ||
[Mongoose](https://github.com/jesseclark/factory-girl-mongoose) (and doesn't use `throw` | ||
for errors that might occur during save). | ||
```javascript | ||
var bluebird = require('bluebird'); | ||
var factory = require('factory-girl').promisify(bluebird); | ||
``` | ||
Version 4.0 is a complete rewrite with thanks to @chetanism. | ||
## History | ||
## License | ||
It started out as a fork of [factory-lady](https://github.com/petejkim/factory-lady), but the fork deviated quite a bit. This module uses an adapter to talk to your models so it can support different ORMs such as [Bookshelf](https://github.com/aexmachina/factory-girl-bookshelf), [Sequelize](https://github.com/aexmachina/factory-girl-sequelize), [JugglingDB](https://github.com/rehanift/factory-girl-jugglingdb), and [Mongoose](https://github.com/jesseclark/factory-girl-mongoose) (and doesn't use `throw` for errors that might occur during save). | ||
Copyright (c) 2016 Chetan Verma. | ||
Copyright (c) 2014 Simon Wade. | ||
Copyright (c) 2011 Peter Jihoon Kim. | ||
## License | ||
Copyright (c) 2014 Simon Wade. This software is licensed under the [MIT License](http://github.com/petejkim/factory-lady/raw/master/LICENSE). | ||
Copyright (c) 2011 Peter Jihoon Kim. This software is licensed under the [MIT License](http://github.com/petejkim/factory-lady/raw/master/LICENSE). | ||
This software is licensed under the [MIT | ||
License](http://github.com/aexmachina/factory-girl/raw/master/LICENSE.txt). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
325080
67
5753
2
30
2
269
1
1
+ Addedbabel-runtime@^6.6.1
+ Addedchance@^1.0.3
+ Addedbabel-runtime@6.26.0(transitive)
+ Addedchance@1.1.12(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addedregenerator-runtime@0.11.1(transitive)
- Removedlodash.merge@^3.3.2
- Removedlodash._arraycopy@3.0.0(transitive)
- Removedlodash._arrayeach@3.0.0(transitive)
- Removedlodash._basecopy@3.0.1(transitive)
- Removedlodash._basefor@3.0.3(transitive)
- Removedlodash._bindcallback@3.0.1(transitive)
- Removedlodash._createassigner@3.1.1(transitive)
- Removedlodash._getnative@3.9.1(transitive)
- Removedlodash._isiterateecall@3.0.9(transitive)
- Removedlodash.isarguments@3.1.0(transitive)
- Removedlodash.isarray@3.0.4(transitive)
- Removedlodash.isplainobject@3.2.0(transitive)
- Removedlodash.istypedarray@3.0.6(transitive)
- Removedlodash.keys@3.1.2(transitive)
- Removedlodash.keysin@3.0.8(transitive)
- Removedlodash.merge@3.3.2(transitive)
- Removedlodash.restparam@3.6.1(transitive)
- Removedlodash.toplainobject@3.0.0(transitive)