.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / object-copy / index.js
1 'use strict';
2
3 var typeOf = require('kind-of');
4 var copyDescriptor = require('copy-descriptor');
5 var define = require('define-property');
6
7 /**
8  * Copy static properties, prototype properties, and descriptors from one object to another.
9  *
10  * ```js
11  * function App() {}
12  * var proto = App.prototype;
13  * App.prototype.set = function() {};
14  * App.prototype.get = function() {};
15  *
16  * var obj = {};
17  * copy(obj, proto);
18  * ```
19  * @param {Object} `receiver`
20  * @param {Object} `provider`
21  * @param {String|Array} `omit` One or more properties to omit
22  * @return {Object}
23  * @api public
24  */
25
26 function copy(receiver, provider, omit) {
27   if (!isObject(receiver)) {
28     throw new TypeError('expected receiving object to be an object.');
29   }
30   if (!isObject(provider)) {
31     throw new TypeError('expected providing object to be an object.');
32   }
33
34   var props = nativeKeys(provider);
35   var keys = Object.keys(provider);
36   var len = props.length;
37   omit = arrayify(omit);
38
39   while (len--) {
40     var key = props[len];
41
42     if (has(keys, key)) {
43       define(receiver, key, provider[key]);
44     } else if (!(key in receiver) && !has(omit, key)) {
45       copyDescriptor(receiver, provider, key);
46     }
47   }
48 };
49
50 /**
51  * Return true if the given value is an object or function
52  */
53
54 function isObject(val) {
55   return typeOf(val) === 'object' || typeof val === 'function';
56 }
57
58 /**
59  * Returns true if an array has any of the given elements, or an
60  * object has any of the give keys.
61  *
62  * ```js
63  * has(['a', 'b', 'c'], 'c');
64  * //=> true
65  *
66  * has(['a', 'b', 'c'], ['c', 'z']);
67  * //=> true
68  *
69  * has({a: 'b', c: 'd'}, ['c', 'z']);
70  * //=> true
71  * ```
72  * @param {Object} `obj`
73  * @param {String|Array} `val`
74  * @return {Boolean}
75  */
76
77 function has(obj, val) {
78   val = arrayify(val);
79   var len = val.length;
80
81   if (isObject(obj)) {
82     for (var key in obj) {
83       if (val.indexOf(key) > -1) {
84         return true;
85       }
86     }
87
88     var keys = nativeKeys(obj);
89     return has(keys, val);
90   }
91
92   if (Array.isArray(obj)) {
93     var arr = obj;
94     while (len--) {
95       if (arr.indexOf(val[len]) > -1) {
96         return true;
97       }
98     }
99     return false;
100   }
101
102   throw new TypeError('expected an array or object.');
103 }
104
105 /**
106  * Cast the given value to an array.
107  *
108  * ```js
109  * arrayify('foo');
110  * //=> ['foo']
111  *
112  * arrayify(['foo']);
113  * //=> ['foo']
114  * ```
115  *
116  * @param {String|Array} `val`
117  * @return {Array}
118  */
119
120 function arrayify(val) {
121   return val ? (Array.isArray(val) ? val : [val]) : [];
122 }
123
124 /**
125  * Returns true if a value has a `contructor`
126  *
127  * ```js
128  * hasConstructor({});
129  * //=> true
130  *
131  * hasConstructor(Object.create(null));
132  * //=> false
133  * ```
134  * @param  {Object} `value`
135  * @return {Boolean}
136  */
137
138 function hasConstructor(val) {
139   return isObject(val) && typeof val.constructor !== 'undefined';
140 }
141
142 /**
143  * Get the native `ownPropertyNames` from the constructor of the
144  * given `object`. An empty array is returned if the object does
145  * not have a constructor.
146  *
147  * ```js
148  * nativeKeys({a: 'b', b: 'c', c: 'd'})
149  * //=> ['a', 'b', 'c']
150  *
151  * nativeKeys(function(){})
152  * //=> ['length', 'caller']
153  * ```
154  *
155  * @param  {Object} `obj` Object that has a `constructor`.
156  * @return {Array} Array of keys.
157  */
158
159 function nativeKeys(val) {
160   if (!hasConstructor(val)) return [];
161   return Object.getOwnPropertyNames(val);
162 }
163
164 /**
165  * Expose `copy`
166  */
167
168 module.exports = copy;
169
170 /**
171  * Expose `copy.has` for tests
172  */
173
174 module.exports.has = has;