keys/required.js

/**
 * Checking structs have the right keys
 * @module
 * @since 0.1.0
 */

/**
 * check we have a valid object
 * @param {anything} value
 * @returns {boolean}
 */
const isValidObject = (value) => typeof value === 'object'
            && !Array.isArray(value)
            && value !== null;

/**
 * check we have a key in the struct
 * @param {struct} skv_to_check
 * @returns {boolean}
 */
const isKeyPresent = (skv_to_check, str_key) => {
    // key may have | to denote that either key is valid
    const arr_keys = str_key.split('|');
    const cnt_keys = arr_keys.length;

    for (let i = 0; i < cnt_keys; i += 1) {
        const str_key_to_check = arr_keys[i];

        if (Object.prototype.hasOwnProperty.call(skv_to_check, str_key_to_check)) {
            return true;
        }
    }

    return false;
};

/**
 * If a key isn't present in the struct then return is with a success false
 * @param {struct} skv_to_check
 * @param {array} arr_required_keys Array of strings to check
 * @returns {struct} In json api format any missing keys
 */
const requiredKeys = (skv_to_check, arr_required_keys) => {
    const required_keys = arr_required_keys;
    const cnt_keys = required_keys.length;

    const skv_return = {
        success: false,
        msg: 'Missing required keys',
        data: [],
    };

    if (!isValidObject(skv_to_check)) {
        skv_return.msg = 'Invalid object passed in to check keys against';
        return skv_return;
    }

    for (let i = 0; i < cnt_keys; i += 1) {
        const str_key = required_keys[i];

        // check whether key is present including optional keys
        if (!isKeyPresent(skv_to_check, str_key)) {
            skv_return.data.push(str_key);
        }
    }

    if (skv_return.data.length === 0) {
        skv_return.success = true;
        skv_return.msg = 'All required keys present';
    }

    return skv_return;
};

export {
    requiredKeys,
    isKeyPresent,
};