Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

core-functions

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

core-functions - npm Package Compare versions

Comparing version 2.0.5 to 2.0.6

79

objects.js

@@ -13,3 +13,4 @@ 'use strict';

valueOf: valueOf,
merge: merge
merge: merge,
copy: copy
};

@@ -37,24 +38,66 @@

function merge(from, to, replace, deep) {
const fromNames = Object.getOwnPropertyNames(from);
const toNames = Object.getOwnPropertyNames(to);
for (let i = 0; i < fromNames.length; ++i) {
const name = fromNames[i];
const history = new WeakMap();
const fromProp = from[name];
const fromPropIsObject = fromProp && typeof fromProp === 'object';
function mergeWithHistory(src, dest) {
if (history.has(src)) {
return history.get(src);
}
// Remember this merge in case the same source appears again within its own graph
history.set(src, dest);
const existsOnTo = toNames.indexOf(name) !== -1;
const srcNames = Object.getOwnPropertyNames(src);
const destNames = Object.getOwnPropertyNames(dest);
for (let i = 0; i < srcNames.length; ++i) {
const name = srcNames[i];
if (existsOnTo) {
const toProp = to[name];
if (deep && fromPropIsObject && toProp && typeof toProp === 'object') {
merge(fromProp, toProp, replace, deep);
} else if (replace) {
to[name] = fromPropIsObject ? merge(fromProp, {}) : fromProp;
const srcPropertyValue = src[name];
const srcPropertyIsObject = srcPropertyValue && typeof srcPropertyValue === 'object';
const existsOnDest = destNames.indexOf(name) !== -1;
console.log(`############ src ${name} = ${srcPropertyValue}${existsOnDest ? ', exists on dest' : ''}, is object? ${srcPropertyIsObject}`);
if (existsOnDest) {
const destPropertyValue = dest[name];
if (deep && srcPropertyIsObject && destPropertyValue && typeof destPropertyValue === 'object') {
mergeWithHistory(srcPropertyValue, destPropertyValue, replace, deep);
} else if (replace) {
dest[name] = srcPropertyIsObject ? copy(srcPropertyValue, true) : srcPropertyValue;
}
} else {
dest[name] = srcPropertyIsObject ? copy(srcPropertyValue, true) : srcPropertyValue;
}
} else {
to[name] = fromPropIsObject ? merge(fromProp, {}) : fromProp;
}
return dest;
}
return to;
}
return mergeWithHistory(from, to);
}
/**
* Copies the enumerable properties of the given object into a new object. Executes a deep copy if the given deep flag
* is true, otherwise only does a shallow copy. Returns the new copy of the original object.
* @param {Object} object - the object from which to copy enumerable properties into a new object
* @param {boolean|undefined} [deep] - Executes a deep copy if the given deep flag is true, otherwise only does a shallow copy
*/
function copy(object, deep) {
const history = new WeakMap();
function copyWithHistory(src, dest) {
if (history.has(src)) {
return history.get(src);
}
// Remember this copy in case the same source appears again within its own graph
history.set(src, dest);
const names = Object.getOwnPropertyNames(src);
for (let i = 0; i < names.length; ++i) {
const name = names[i];
const property = src[name];
const propertyIsObject = property && typeof property === 'object';
dest[name] = deep && propertyIsObject ? copyWithHistory(property, {}) : property;
}
return dest;
}
return copyWithHistory(object, {});
}
{
"name": "core-functions",
"version": "2.0.5",
"version": "2.0.6",
"description": "Core functions, utilities and classes for working with Node/JavaScript primitives and built-in objects, including strings, booleans, Promises, base 64, Arrays, Objects, standard AppErrors, etc.",

@@ -5,0 +5,0 @@ "author": "Byron du Preez",

@@ -1,2 +0,2 @@

# core-functions v2.0.5
# core-functions v2.0.6

@@ -106,2 +106,7 @@ Core functions, utilities and classes for working with Node/JavaScript primitives and built-in objects, including

### 2.0.6
- Change to `objects.js`:
- Improved `merge` function to handle circular, non-Directed Acyclic Graphs of objects
- Added a `copy` function also able to handle non-DAGs
### 2.0.5

@@ -108,0 +113,0 @@ - Change to `objects.js`:

@@ -100,3 +100,111 @@ 'use strict';

// check that functions get merged in too
function a1() {}
function a2() {}
function b() {}
function c() {}
const from5 = {a: a2, b: b, c: c, z: 'Z2'};
const to5 = {a: a1, z: 'Z1'};
const expected5 = {a: a1, b: b, c: c, z: 'Z1'};
t.deepEqual(Objects.merge(from5, to5, false, false), expected5, 'deep merge without replace must have all functions of to5 and only extra functions of from5');
t.equal(to5.a, a1, 'to5.a must be function a1');
t.equal(to5.b, b, 'to5.b must be function b');
t.equal(to5.c, c, 'to5.c must be function c');
t.equal(to5.z, 'Z1', 'to5.z must be Z1');
function x() {}
const to6 = {a: a1, x: x, y: 'y1', z: 'Z1'};
const expected6 = {a: a2, b: b, c: c, x: x, y: 'y1', z: 'Z2'};
t.deepEqual(Objects.merge(from5, to6, true, false), expected6, 'deep merge with replace must have all functions of from5 and only extra functions of to6');
t.equal(to6.a, a2, 'to6.a must be function a2');
t.equal(to6.x, x, 'to6.x must be function x');
t.equal(to6.z, 'Z2', 'to5.z must be Z2');
const from7 = {a: a2, b: b, c: c, z: 'Z2'};
const to7 = {a: a1, x: x, y: 'y1', z: 'Z1'};
const expected7 = {a: a2, b: b, c: c, x: x, y: 'y1', z: 'Z2'};
t.deepEqual(Objects.merge(from7, to7, true, true), expected7, 'deep merge with replace must have all functions of from7 and only extra functions of to7');
function d() {}
const from8 = {o: {a: a2, b: b}, c: c, z: 'Z2'};
const to8 = {o: {a: a1, x: x, y: 'y1'}, d: d, z: 'Z1'};
const expected8 = {o: {a: a1, b: b, x: x, y: 'y1'}, c: c, d: d, z: 'Z1'};
t.deepEqual(Objects.merge(from8, to8, false, true), expected8, 'deep merge without replace must have all functions of to8 and only extra functions of from8');
const from9 = {o: {a: a2, b: b}, c: c, z: 'Z2'};
const to9 = {o: {a: a1, x: x, y: 'y1'}, d: d, z: 'Z1'};
const expected9 = {o: {a: a2, b: b, x: x, y: 'y1'}, c: c, d: d, z: 'Z2'};
t.deepEqual(Objects.merge(from9, to9, true, true), expected9, 'deep merge with replace must have all functions of from9 and only extra functions of to9');
const from10 = {o: {a: a2, b: b}, c: c, z: 'Z2'};
const to10 = {o: {a: a1, x: x, y: 'y1'}, d: d, z: 'Z1'};
const expected10 = {o: {a: a2, b: b}, c: c, d: d, z: 'Z2'};
t.deepEqual(Objects.merge(from10, to10, true, false), expected10, 'shallow merge with replace must have all of from10 and only extra top-level properties of to10');
const from11 = {o: {a: a2, b: b}, c: c, z: 'Z2'};
const to11 = {o: {a: a1, x: x, y: 'y1'}, d: d, z: 'Z1'};
const expected11 = {o: {a: a1, x: x, y: 'y1'}, c: c, d: d, z: 'Z1'};
t.deepEqual(Objects.merge(from11, to11, false, false), expected11, 'shallow merge with replace must have all of to11 and only extra top-level properties of from11');
// Create infinite loops (non-DAGs)
const o3 = {o: {a: a1, x: 'X', p: {b: b, y: 'Y'}}, c: c, z: 'Z'};
o3.o.o3Again = o3;
o3.o.p.o3Again = o3;
const c3 = {o: {a: a2, x: 'X2', p: {b: b, y: 'Y2'}}, c: c, z: 'Z2'};
c3.o.o3Again = c3;
c3.o.p.o3Again = c3;
Objects.merge(o3, c3, false, true);
//EEK t.deepEqual fails with "Maximum call stack size exceeded"
//t.deepEqual(c3, o3, 'deep copy must be deep equal to o3');
t.deepEqual(Object.getOwnPropertyNames(c3).sort(), Object.getOwnPropertyNames(o3).sort(), 'deep merge circular - c3 must have same names as o3');
t.deepEqual(Object.getOwnPropertyNames(c3.o).sort(), Object.getOwnPropertyNames(o3.o).sort(), 'deep merge circular - c3.o must have same names as o3.o');
t.deepEqual(Object.getOwnPropertyNames(c3.o.p).sort(), Object.getOwnPropertyNames(o3.o.p).sort(), 'deep merge circular - c3.o.p must have same names as o3.o.p');
t.notEqual(c3, o3, 'deep merge circular - c3 must not be o3');
t.notEqual(c3.o, o3.o, 'deep merge circular - c3.o must not be o3.o');
t.notEqual(c3.o.p, o3.o.p, 'deep merge circular - c3.o.p must not be o3.o.p');
t.equal(c3, c3.o.o3Again, 'deep merge circular - c3 must be c3.o.o3Again');
t.equal(c3, c3.o.p.o3Again, 'deep merge circular - c3 must be c3.o.p.o3Again');
t.end();
});
test('copy', t => {
function a() {}
function b() {}
function c() {}
//function d() {}
const o1 = {o: {a: a, x: 'X', p: {b: b, y: 'Y'}}, c: c, z: 'Z'};
const c1 = Objects.copy(o1, false);
t.deepEqual(c1, o1, 'shallow copy circular - c1 must be deep equal to o1');
t.notEqual(c1, o1, 'shallow copy circular - c1 must not be o1');
t.equal(c1.o, o1.o, 'shallow copy circular - c1.o must be o1.o');
t.equal(c1.o.p, o1.o.p, 'shallow copy circular - c1.o.p must be o1.o.p');
const o2 = {o: {a: a, x: 'X', p: {b: b, y: 'Y'}}, c: c, z: 'Z'};
const c2 = Objects.copy(o2, true);
t.deepEqual(c2, o2, 'deep copy circular - c2 must be deep equal to o2');
t.notEqual(c2, o2, 'deep copy circular - c2 must not be o2');
t.notEqual(c2.o, o2.o, 'deep copy circular - c2.o must not be o2.o');
t.notEqual(c2.o.p, o2.o.p, 'deep copy circular - c2.o.p must not be o2.o.p');
// Create infinite loops (non-DAGs)
const o3 = {o: {a: a, x: 'X', p: {b: b, y: 'Y'}}, c: c, z: 'Z'};
o3.o.o3Again = o3;
o3.o.p.o3Again = o3;
const c3 = Objects.copy(o3, true);
//EEK t.deepEqual fails with "Maximum call stack size exceeded"
//t.deepEqual(c3, o3, 'deep copy must be deep equal to o3');
t.deepEqual(Object.getOwnPropertyNames(c3), Object.getOwnPropertyNames(o3), 'deep copy circular - c3 must have same names as o3');
t.deepEqual(Object.getOwnPropertyNames(c3.o), Object.getOwnPropertyNames(o3.o), 'deep copy circular - c3.o must have same names as o3.o');
t.deepEqual(Object.getOwnPropertyNames(c3.o.p), Object.getOwnPropertyNames(o3.o.p), 'deep copy circular - c3.o.p must have same names as o3.o.p');
t.notEqual(c3, o3, 'deep copy circular - c3 must not be o3');
t.notEqual(c3.o, o3.o, 'deep copy circular - c3.o must not be o3.o');
t.notEqual(c3.o.p, o3.o.p, 'deep copy circular - c3.o.p must not be o3.o.p');
t.equal(c3, c3.o.o3Again, 'deep copy circular - c3 must be c3.o.o3Again');
t.equal(c3, c3.o.p.o3Again, 'deep copy circular - c3 must be c3.o.p.o3Again');
t.end();
});
{
"name": "core-functions-tests",
"version": "2.0.5",
"version": "2.0.6",
"author": "Byron du Preez",

@@ -13,5 +13,5 @@ "license": "Apache-2.0",

"devDependencies": {
"tape": "^4.6.2"
"tape": "^4.6.3"
},
"repository": "https://github.com/byron-dupreez/core-functions"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc