Home Reference Source Test Repository

src/util/validator.js

/**
 * A utility class which performs validations by checking of required object properties exist.
 */
export default class Validator {
    /**
     * Validates collection doc format
     *
     * @param {Object} collectionDoc
     * @throws {TypeError} if collection doc is invalid
     */
    static validateCollectionDoc(collectionDoc) {
        const requiredNames = [
            'version', 'href', 'attributes', 'items', 'links', 'errors',
        ];

        Validator._validate(collectionDoc, requiredNames);
    }

    /**
     * Validates an access token model (obtained from the `POST /authorization/v2/token` endpoint)
     *
     * @param {Object} accessTokenModel
     * @throws {TypeError} if access token model is invalid
     */
    static validateAccessToken(accessTokenModel) {
        const requiredNames = [
            'access_token', 'token_type', 'expires_in',
        ];

        Validator._validate(accessTokenModel, requiredNames);
    }

    /**
     * Validates a device code model (obtained from the `POST /authorization/v2/device` endpoint)
     *
     * @param {Object} deviceCodeModel
     * @throws {TypeError} if device code model is invalid
     */
    static validateDeviceCode(deviceCodeModel) {
        const requiredNames = [
            'user_code', 'verification_uri', 'expires_in', 'interval',
        ];

        Validator._validate(deviceCodeModel, requiredNames);
    }

    /**
     * Base validator function.
     *
     * @param {Object} object
     * @param {Array<string>} requiredNames
     * @throws {TypeError} if object is invalid
     * @private
     */
    static _validate(object, requiredNames) {
        const messages = [];

        for (const name of requiredNames) {
            if (!Validator._has(object, name)) {
                messages.push(`'${name}' is missing and is required.`);
            }
        }

        if (messages.length > 0) {
            throw new TypeError(`${messages.join(', ')} :${JSON.stringify(object)}`);
        }
    }

    /**
     * A typesafe check to make sure the property exists within the object.
     *
     * @param {Object} object
     * @param {string} key
     * @returns {boolean}
     * @private
     */
    static _has(object, key) {
        /* istanbul ignore next: defensive coding, not going to worry too much about this */
        return object ? {}.hasOwnProperty.call(object, key) : false;
    }
}