aboutsummaryrefslogtreecommitdiff
path: root/node_modules/merge-options
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/merge-options')
-rw-r--r--node_modules/merge-options/index.js163
-rw-r--r--node_modules/merge-options/license21
-rw-r--r--node_modules/merge-options/package.json42
-rw-r--r--node_modules/merge-options/readme.md102
4 files changed, 328 insertions, 0 deletions
diff --git a/node_modules/merge-options/index.js b/node_modules/merge-options/index.js
new file mode 100644
index 00000000..8eb954de
--- /dev/null
+++ b/node_modules/merge-options/index.js
@@ -0,0 +1,163 @@
+'use strict';
+const isOptionObject = require('is-plain-obj');
+
+const hasOwnProperty = Object.prototype.hasOwnProperty;
+const propIsEnumerable = Object.propertyIsEnumerable;
+const defineProperty = (obj, name, value) => Object.defineProperty(obj, name, {
+ value,
+ writable: true,
+ enumerable: true,
+ configurable: true
+});
+
+const globalThis = this;
+const defaultMergeOpts = {
+ concatArrays: false
+};
+
+const getEnumerableOwnPropertyKeys = value => {
+ const keys = [];
+
+ for (const key in value) {
+ if (hasOwnProperty.call(value, key)) {
+ keys.push(key);
+ }
+ }
+
+ /* istanbul ignore else */
+ if (Object.getOwnPropertySymbols) {
+ const symbols = Object.getOwnPropertySymbols(value);
+
+ for (let i = 0; i < symbols.length; i++) {
+ if (propIsEnumerable.call(value, symbols[i])) {
+ keys.push(symbols[i]);
+ }
+ }
+ }
+
+ return keys;
+};
+
+function clone(value) {
+ if (Array.isArray(value)) {
+ return cloneArray(value);
+ }
+
+ if (isOptionObject(value)) {
+ return cloneOptionObject(value);
+ }
+
+ return value;
+}
+
+function cloneArray(array) {
+ const result = array.slice(0, 0);
+
+ getEnumerableOwnPropertyKeys(array).forEach(key => {
+ defineProperty(result, key, clone(array[key]));
+ });
+
+ return result;
+}
+
+function cloneOptionObject(obj) {
+ const result = Object.getPrototypeOf(obj) === null ? Object.create(null) : {};
+
+ getEnumerableOwnPropertyKeys(obj).forEach(key => {
+ defineProperty(result, key, clone(obj[key]));
+ });
+
+ return result;
+}
+
+/**
+ * @param merged {already cloned}
+ * @return {cloned Object}
+ */
+const mergeKeys = (merged, source, keys, mergeOpts) => {
+ keys.forEach(key => {
+ // Do not recurse into prototype chain of merged
+ if (key in merged && merged[key] !== Object.getPrototypeOf(merged)) {
+ defineProperty(merged, key, merge(merged[key], source[key], mergeOpts));
+ } else {
+ defineProperty(merged, key, clone(source[key]));
+ }
+ });
+
+ return merged;
+};
+
+/**
+ * @param merged {already cloned}
+ * @return {cloned Object}
+ *
+ * see [Array.prototype.concat ( ...arguments )](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat)
+ */
+const concatArrays = (merged, source, mergeOpts) => {
+ let result = merged.slice(0, 0);
+ let resultIndex = 0;
+
+ [merged, source].forEach(array => {
+ const indices = [];
+
+ // `result.concat(array)` with cloning
+ for (let k = 0; k < array.length; k++) {
+ if (!hasOwnProperty.call(array, k)) {
+ continue;
+ }
+
+ indices.push(String(k));
+
+ if (array === merged) {
+ // Already cloned
+ defineProperty(result, resultIndex++, array[k]);
+ } else {
+ defineProperty(result, resultIndex++, clone(array[k]));
+ }
+ }
+
+ // Merge non-index keys
+ result = mergeKeys(result, array, getEnumerableOwnPropertyKeys(array).filter(key => {
+ return indices.indexOf(key) === -1;
+ }), mergeOpts);
+ });
+
+ return result;
+};
+
+/**
+ * @param merged {already cloned}
+ * @return {cloned Object}
+ */
+function merge(merged, source, mergeOpts) {
+ if (mergeOpts.concatArrays && Array.isArray(merged) && Array.isArray(source)) {
+ return concatArrays(merged, source, mergeOpts);
+ }
+
+ if (!isOptionObject(source) || !isOptionObject(merged)) {
+ return clone(source);
+ }
+
+ return mergeKeys(merged, source, getEnumerableOwnPropertyKeys(source), mergeOpts);
+}
+
+module.exports = function () {
+ const mergeOpts = merge(clone(defaultMergeOpts), (this !== globalThis && this) || {}, defaultMergeOpts);
+ let merged = {foobar: {}};
+
+ for (let i = 0; i < arguments.length; i++) {
+ const option = arguments[i];
+
+ if (option === undefined) {
+ continue;
+ }
+
+ if (!isOptionObject(option)) {
+ throw new TypeError('`' + option + '` is not an Option Object');
+ }
+
+ merged = merge(merged, {foobar: option}, mergeOpts);
+ }
+
+ return merged.foobar;
+};
diff --git a/node_modules/merge-options/license b/node_modules/merge-options/license
new file mode 100644
index 00000000..527cbd86
--- /dev/null
+++ b/node_modules/merge-options/license
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016-2018 Michael Mayer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/merge-options/package.json b/node_modules/merge-options/package.json
new file mode 100644
index 00000000..85a57174
--- /dev/null
+++ b/node_modules/merge-options/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "merge-options",
+ "version": "1.0.1",
+ "description": "Merge Option Objects",
+ "license": "MIT",
+ "repository": "schnittstabil/merge-options",
+ "author": {
+ "name": "Michael Mayer",
+ "email": "michael@schnittstabil.de",
+ "url": "schnittstabil.de"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "scripts": {
+ "test": "xo && nyc ava",
+ "clean": "rimraf .nyc_output/ coverage/",
+ "coverage-html": "nyc ava && nyc report --reporter=html"
+ },
+ "files": [
+ "index.js"
+ ],
+ "keywords": [
+ "merge",
+ "options",
+ "deep",
+ "plain",
+ "object",
+ "extend",
+ "clone"
+ ],
+ "devDependencies": {
+ "ava": "^0.25",
+ "coveralls": "^3.0",
+ "nyc": "^11.7",
+ "rimraf": "^2.5",
+ "xo": "^0.20"
+ },
+ "dependencies": {
+ "is-plain-obj": "^1.1"
+ }
+}
diff --git a/node_modules/merge-options/readme.md b/node_modules/merge-options/readme.md
new file mode 100644
index 00000000..c9c07c87
--- /dev/null
+++ b/node_modules/merge-options/readme.md
@@ -0,0 +1,102 @@
+# 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)
+
+
+> Merge Option Objects
+
+`merge-options` considers [plain objects](https://github.com/sindresorhus/is-plain-obj) as *Option Objects*, everything else as *Option Values*.
+
+## Install
+
+```
+$ npm install --save merge-options
+```
+
+## Usage
+
+```js
+const mergeOptions = require('merge-options');
+
+mergeOptions({foo: 0}, {bar: 1}, {baz: 2}, {bar: 3})
+//=> {foo: 0, bar: 3, baz: 2}
+
+mergeOptions({nested: {unicorns: 'none'}}, {nested: {unicorns: 'many'}})
+//=> {nested: {unicorns: 'many'}}
+
+mergeOptions({[Symbol.for('key')]: 0}, {[Symbol.for('key')]: 42})
+//=> {Symbol(key): 42}
+```
+
+## API
+
+### mergeOptions(option1, ...options)<br/>mergeOptions.call(config, option1, ...options)<br/>mergeOptions.apply(config, [option1, ...options])
+
+`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.
+
+The merging does not alter the passed `option` arguments, taking roughly the following steps:
+* 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*
+* copying<sup><a href="#note1">[1]</a></sup> references to *Option Values* to the result object
+
+
+```js
+const defaultOpts = {
+ fn: () => false, // functions are Option Values
+ promise: Promise.reject(new Error()), // all non-plain objects are Option Values
+ array: ['foo'], // arrays are Option Values
+ nested: {unicorns: 'none'} // {…} is plain, therefore an Option Object
+};
+
+const opts = {
+ fn: () => true, // [1]
+ promise: Promise.resolve('bar'), // [2]
+ array: ['baz'], // [3]
+ nested: {unicorns: 'many'} // [4]
+};
+
+mergeOptions(defaultOpts, opts)
+//=>
+{
+ fn: [Function], // === [1]
+ promise: Promise { 'bar' }, // === [2]
+ array: ['baz'], // !== [3] (arrays are cloned)
+ nested: {unicorns: 'many'} // !== [4] (Option Objects are cloned)
+}
+```
+
+#### config
+
+Type: `object`
+
+##### config.concatArrays
+
+Type: `boolean`<br/>Default: `false`
+
+Concatenate arrays:
+
+```js
+mergeOptions({src: ['src/**']}, {src: ['test/**']})
+//=> {src: ['test/**']}
+
+// Via call
+mergeOptions.call({concatArrays: true}, {src: ['src/**']}, {src: ['test/**']})
+//=> {src: ['src/**', 'test/**']}
+
+// Via apply
+mergeOptions.apply({concatArrays: true}, [{src: ['src/**']}, {src: ['test/**']}])
+//=> {src: ['src/**', 'test/**']}
+```
+
+
+## Related
+
+* See [object-assign](https://github.com/sindresorhus/object-assign) if you need a ES2015 Object.assign() ponyfill
+* See [deep-assign](https://github.com/sindresorhus/deep-assign) if you need to do Object.assign() recursively
+
+## Notes
+
+<ol>
+ <li id="note1">copying and cloning take only enumerable own properties into account</li>
+</ol>
+
+## License
+
+MIT © [Michael Mayer](http://schnittstabil.de)