util/freeze.js

'use strict';

/**
 * @author schukai GmbH
 */

import {Monster} from '../namespace.js';
import {validateObject} from '../types/validate.js';

/**
 * deep freeze a object
 *
 * you can call the method via the monster namespace `Monster.Util.deepFreeze()`.
 *
 * ```
 * <script type="module">
 * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.5.0/dist/modules/util/freeze.js';
 * console.log(Monster.Util.deepFreeze({})) 
 * </script>
 * ```
 *
 * Alternatively, you can also integrate this function individually.
 *
 * ```
 * <script type="module">
 * import {deepFreeze} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.5.0/dist/modules/util/freeze.js';
 * console.log(deepFreeze({}))  
 * </script>
 * ```
 *
 * @param {object} obj object to be freeze
 * @since 1.0.0
 * @returns {object}
 * @memberOf Monster/Util
 * @copyright schukai GmbH
 * @throws {TypeError} value is not a object
 */
function deepFreeze(object) {
    
    validateObject(object)

    // Retrieve the defined property names of the object
    var propNames = Object.getOwnPropertyNames(object);

    // Freeze properties before freezing yourself
    for (let name of propNames) {
        let value = object[name];

        object[name] = value && typeof value === "object" ?
            deepFreeze(value) : value;
    }

    return Object.freeze(object);
}

Monster.assignToNamespace('Monster.Util', deepFreeze);
export {Monster, deepFreeze}