feat(support): Add a helper to deep freeze objects
MODIFY
packages/support/lib/node.js
packages/support/lib/node.js
@@ -166,4 +166,33 @@ function getObjectId (object) {
return OBJECTS_MAPPING.get(object);
}
-export { requirePackage, getObjectSize, getObjectId };
+/**
+ * Perform deep freeze of the given object (e. g.
+ * all nested objects also become immutable).
+ * If the passed object is of a plain type
+ * then no change is done and the same object
+ * is returned.
+ * ! This function changes the given object,
+ * so it becomes immutable.
+ *
+ * @param {*} object Any valid ECMA object
+ * @returns {*} The same object that was passed to the
+ * function after it was made immutable.
+ */
+function deepFreeze (object) {
+ let propNames;
+ try {
+ propNames = Object.getOwnPropertyNames(object);
+ } catch (ign) {
+ return object;
+ }
+ for (const name of propNames) {
+ const value = object[name];
+ if (value && typeof value === 'object') {
+ deepFreeze(value);
+ }
+ }
+ return Object.freeze(object);
+}
+
+export { requirePackage, getObjectSize, getObjectId, deepFreeze };

MODIFY
packages/support/test/unit/node.spec.js
packages/support/test/unit/node.spec.js
+import { should } from 'chai';
import { node } from '../../lib';
describe('node utilities', function () {
@@ -30,4 +31,17 @@ describe('node utilities', function () {
node.getObjectId(obj2).should.eql(node.getObjectId(obj2));
});
});
+
+ describe('deepFreeze', function () {
+ it('should be able to deep freeze objects', function () {
+ const obj1 = {};
+ node.deepFreeze(obj1).should.eql(obj1);
+ const obj2 = node.deepFreeze({a: {b: 'c'}});
+ should().throw(() => obj2.a.b = 'd');
+ node.deepFreeze(1).should.eql(1);
+ should().equal(node.deepFreeze(null), null);
+ const obj3 = [1, {}, 3];
+ should().equal(node.deepFreeze(obj3), obj3);
+ });
+ });
});

feat(support): Add a helper to deep freeze objects (#16849)