blob: 7bd7ddaed16ae1a8cc8433d5e99ef98440e9ba9f [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001'use strict';
2
3var GetIntrinsic = require('get-intrinsic');
4
5var $TypeError = GetIntrinsic('%TypeError%');
6
7var callBound = require('call-bind/callBound');
8var forEach = require('../helpers/forEach');
9var every = require('../helpers/every');
10var OwnPropertyKeys = require('../helpers/OwnPropertyKeys');
11
12var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
13
14var CreateDataPropertyOrThrow = require('./CreateDataPropertyOrThrow');
15var Get = require('./Get');
16var IsArray = require('./IsArray');
17var IsInteger = require('./IsInteger');
18var IsPropertyKey = require('./IsPropertyKey');
19var SameValue = require('./SameValue');
20var ToNumber = require('./ToNumber');
21var ToObject = require('./ToObject');
22var Type = require('./Type');
23
24// https://262.ecma-international.org/11.0/#sec-copydataproperties
25
26module.exports = function CopyDataProperties(target, source, excludedItems) {
27 if (Type(target) !== 'Object') {
28 throw new $TypeError('Assertion failed: "target" must be an Object');
29 }
30
31 if (!IsArray(excludedItems) || !every(excludedItems, IsPropertyKey)) {
32 throw new $TypeError('Assertion failed: "excludedItems" must be a List of Property Keys');
33 }
34
35 if (typeof source === 'undefined' || source === null) {
36 return target;
37 }
38
39 var from = ToObject(source);
40
41 var sourceKeys = OwnPropertyKeys(from);
42 forEach(sourceKeys, function (nextKey) {
43 var excluded = false;
44
45 forEach(excludedItems, function (e) {
46 if (SameValue(e, nextKey) === true) {
47 excluded = true;
48 }
49 });
50
51 var enumerable = $isEnumerable(from, nextKey) || (
52 // this is to handle string keys being non-enumerable in older engines
53 typeof source === 'string'
54 && nextKey >= 0
55 && IsInteger(ToNumber(nextKey))
56 );
57 if (excluded === false && enumerable) {
58 var propValue = Get(from, nextKey);
59 CreateDataPropertyOrThrow(target, nextKey, propValue);
60 }
61 });
62
63 return target;
64};