5daf53d2d8ecd73bd44b1e3b8bca4dacf1b99db21882b10d042c0b2f066b8ac3b5e1e79175c71ff7f4a610b3c044eefdcc3788d5158e8f8093625f8d536520 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # merge-options [![Build Status](https://travis-ci.org/schnittstabil/merge-options.svg?branch=master)](https://travis-ci.org/schnittstabil/merge-options) [![Coverage Status](https://coveralls.io/repos/schnittstabil/merge-options/badge.svg?branch=master&service=github)](https://coveralls.io/github/schnittstabil/merge-options?branch=master) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
  2. > Merge Option Objects
  3. `merge-options` considers [plain objects](https://github.com/sindresorhus/is-plain-obj) as *Option Objects*, everything else as *Option Values*.
  4. ## Install
  5. ```
  6. $ npm install --save merge-options
  7. ```
  8. ## Usage
  9. ```js
  10. const mergeOptions = require('merge-options');
  11. mergeOptions({foo: 0}, {bar: 1}, {baz: 2}, {bar: 3})
  12. //=> {foo: 0, bar: 3, baz: 2}
  13. mergeOptions({nested: {unicorns: 'none'}}, {nested: {unicorns: 'many'}})
  14. //=> {nested: {unicorns: 'many'}}
  15. mergeOptions({[Symbol.for('key')]: 0}, {[Symbol.for('key')]: 42})
  16. //=> {Symbol(key): 42}
  17. ```
  18. ## API
  19. ### mergeOptions(option1, ...options)<br/>mergeOptions.call(config, option1, ...options)<br/>mergeOptions.apply(config, [option1, ...options])
  20. `mergeOptions` recursively merges one or more *Option Objects* into a new one and returns that. The `options` are merged in order, thus *Option Values* of additional `options` take precedence over previous ones.
  21. The merging does not alter the passed `option` arguments, taking roughly the following steps:
  22. * recursively cloning<sup><a href="#note1">[1]</a></sup> *Option Objects* and [arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) until reaching *Option Values*
  23. * copying<sup><a href="#note1">[1]</a></sup> references to *Option Values* to the result object
  24. ```js
  25. const defaultOpts = {
  26. fn: () => false, // functions are Option Values
  27. promise: Promise.reject(new Error()), // all non-plain objects are Option Values
  28. array: ['foo'], // arrays are Option Values
  29. nested: {unicorns: 'none'} // {…} is plain, therefore an Option Object
  30. };
  31. const opts = {
  32. fn: () => true, // [1]
  33. promise: Promise.resolve('bar'), // [2]
  34. array: ['baz'], // [3]
  35. nested: {unicorns: 'many'} // [4]
  36. };
  37. mergeOptions(defaultOpts, opts)
  38. //=>
  39. {
  40. fn: [Function], // === [1]
  41. promise: Promise { 'bar' }, // === [2]
  42. array: ['baz'], // !== [3] (arrays are cloned)
  43. nested: {unicorns: 'many'} // !== [4] (Option Objects are cloned)
  44. }
  45. ```
  46. #### config
  47. Type: `object`
  48. ##### config.concatArrays
  49. Type: `boolean`<br/>Default: `false`
  50. Concatenate arrays:
  51. ```js
  52. mergeOptions({src: ['src/**']}, {src: ['test/**']})
  53. //=> {src: ['test/**']}
  54. // Via call
  55. mergeOptions.call({concatArrays: true}, {src: ['src/**']}, {src: ['test/**']})
  56. //=> {src: ['src/**', 'test/**']}
  57. // Via apply
  58. mergeOptions.apply({concatArrays: true}, [{src: ['src/**']}, {src: ['test/**']}])
  59. //=> {src: ['src/**', 'test/**']}
  60. ```
  61. ## Related
  62. * See [object-assign](https://github.com/sindresorhus/object-assign) if you need a ES2015 Object.assign() ponyfill
  63. * See [deep-assign](https://github.com/sindresorhus/deep-assign) if you need to do Object.assign() recursively
  64. ## Notes
  65. <ol>
  66. <li id="note1">copying and cloning take only enumerable own properties into account</li>
  67. </ol>
  68. ## License
  69. MIT © [Michael Mayer](http://schnittstabil.de)