<commit_before>import validator from 'validator';
import ValidationError from './errors';

const defaultConfig = {
    validator,
    validateOnSave: false,
};

function doValidation (validator, fnName, value, options) {
    // The argument can be a boolean for argumentless validation, or an
    // array of options passed to the validator
    return typeof options === 'boolean' ?
        validator[fnName](value) === options
        : validator[fnName](value, options);
}

export default function validationPlugin (bookshelf, config = defaultConfig) {
    var Plugin = {
        validationErrors () {
            const output = {};

            function addError (propName, errorName) {
                const propertyErrors = output[propName] || [];

                propertyErrors.push(errorName);
                output[propName] = propertyErrors;
            }

            // Validate each property with the given rule arguments
            for (const propName in this.validations) {
                if (!this.validations.hasOwnProperty(propName)) {
                    return null;
                }

                const propValue = this.get(propName);
                const validations = this.validations[propName];

                for (const validation of validations) {
                    const {
                        method: fnName,
                        options = true,
                        error,
                    } = validation;

                    const isValid = doValidation(
                        validator,
                        fnName,
                        propValue,
                        options
                    );

                    if (!isValid) {
                        const errorMsg = error ? error : method;

                        addError(propName, errorMsg);
                    }
                }
            }

            // Return null if every property is valid
            return Object.keys(output).length > 0 ? output : null;
        },
    };

    if (config.validateOnSave) {
        Plugin.initialize = function initialize () {
            if (typeof this.validateOnSave === 'function') {
                this.on('saving', this.validateOnSave);
            }<commit_msg>Cover multiple argument types in the validator function.<commit_after>import validator from 'validator';
import ValidationError from './errors';

const defaultConfig = {
    validator,
    validateOnSave: false,
};

function doValidation (validator, fnName, value, args) {
    // The argument can be a boolean for argumentless validation,
    // a single argument or object, or an array of argument values
    if (typeof args === 'boolean') {
        return validator[fnName](value) === args;
    }

    if (!Array.isArray(args)) {
        return validator[fnName](value, args);
    }

    return validator[fnName](value, ...args);
}

export default function validationPlugin (bookshelf, config = defaultConfig) {
    var Plugin = {
        validationErrors () {
            const output = {};

            function addError (propName, errorName) {
                const propertyErrors = output[propName] || [];

                propertyErrors.push(errorName);
                output[propName] = propertyErrors;
            }

            // Validate each property with the given rule arguments
            for (const propName in this.validations) {
                if (!this.validations.hasOwnProperty(propName)) {
                    return null;
                }

                const propValue = this.get(propName);
                const validations = this.validations[propName];

                for (const validation of validations) {
                    const {
                        method: fnName,
                        args = true,
                        error,
                    } = validation;

                    const isValid = doValidation(
                        validator,
                        fnName,
                        propValue,
                        args
                    );

                    if (!isValid) {
                        const errorMsg = error ? error : method;

                        addError(propName, errorMsg);
                    }
                }
            }

            // Return null if every property is valid
            return Object.keys(output).length > 0 ? output : null;
        },
    };

    if (config.validateOnSave) {
        Plugin.initialize = function initialize () {
            if (typeof this.validateOnSave === 'function') {
                this.on('saving', this.validateOnSave);
            }
{'fraction_non_alphanumeric': 0.08500539374325781, 'fraction_numerical': 0.0004314994606256742, 'mean_word_length': 1.407061266874351, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3161145', 'n_tokens_mistral': 1090, 'n_tokens_neox': 1012, 'n_words': 298}