<commit_before>/**
 * The building blocks of Types and Forms, Fields help to validate and authorize
 * changes to docuemnt values.
 *
 * @module
 */


/**
 * Module dependencies
 */

var permissions = require('kanso/permissions'),
    validators = require('kanso/validators'),
    widgets = require('kanso/widgets'),
    utils = require('kanso/utils'),
    _ = require('underscore')._;


/**
 * Field objects are used when constructing content types and forms.
 *
 * #### Options ####
 *
 * * **omit_empty**  *Boolean* - whether to omit the field from a document when
 *                               the field is empty
 * * **permissions** *Object*  - a permissions check function or an object
 *                               containing separate functions to run on create,
 *                               edit and update operations.
 * * **validators**  *Array*   - an array of validation functions (default: [])
 * * **required**    *Boolean* - whether the field is required (default: true)
 *
 * @constructor
 * @name Field
 * @param {Object} options
 * @api public
 */

var Field = exports.Field = function Field(options) {
    _.extend(this, _.defaults(options || {}, {
        widget: widgets.text(),
        omit_empty: false,
        permissions: {},
        validators: [],
        required: true
    }));
    return this;
};


/**
 * Parses a raw value returning the correct JavaScript type for this field.
 * This will usually be overridden by other field types.
 *
 * @name Field.parse(raw)
 * @param raw
 * @api public
 */

Field.prototype.parse = function (raw) {
    return raw;
};


/**
 * Test values to see if field is considered empty.
 *
 * This function accepts the raw value even though by default it only
 * checks the parsed value, so that other field types overridding this method
 * have the raw data available.
 *
 * @name Field.isEmpty(value, raw)
 * @param value - the parsed value for the field
 * @param raw - the raw value for this field
 * @returns {Boolean}
 * @api public
 */

Field.prototype.isEmpty = function (value, raw) {
    if (raw === undefined) {
        if (typeof value === 'number' && isNaN(value)) {
            return true;
        }
        raw = value;
    }
    return (raw === '' || raw === null || raw === undefined);
};

/**
 * Run the field's validation functions against a value. Returns an
 * array of validation errors, or an empty array if valid.
 *
 * @name Field.validate(doc, value, raw)
 * @param {Object} doc
 * @param value
 * @param raw
 * @returns {Array}
 * @api public
 */

Field.prototype.validate = function (doc, value, raw) {
    // don't validate empty fields, but check if required
    if (this.isEmpty(value, raw)) {
        if (this.required) {
            return [ new Error('Required field') ];
        }
        return [];
    }
    return _.reduce(this.validators, function (errs, v) {
        try {
            // check that v is actually a function, since IE likes to
            // insert nulls here for some reason
            if (v) {
                errs = errs.concat(v(doc, value, raw) || []);
            }
        }
        catch (e) {
            errs.push(e);
        }<commit_msg>allow a function for the required property of a field and evaluate it to find if the field is required or not<commit_after>/**
 * The building blocks of Types and Forms, Fields help to validate and authorize
 * changes to docuemnt values.
 *
 * @module
 */


/**
 * Module dependencies
 */

var permissions = require('kanso/permissions'),
    validators = require('kanso/validators'),
    widgets = require('kanso/widgets'),
    utils = require('kanso/utils'),
    _ = require('underscore')._;


/**
 * Field objects are used when constructing content types and forms.
 *
 * #### Options ####
 *
 * * **omit_empty**  *Boolean* - whether to omit the field from a document when
 *                               the field is empty
 * * **permissions** *Object*  - a permissions check function or an object
 *                               containing separate functions to run on create,
 *                               edit and update operations.
 * * **validators**  *Array*   - an array of validation functions (default: [])
 * * **required**    *Boolean* - whether the field is required (default: true)
 *
 * @constructor
 * @name Field
 * @param {Object} options
 * @api public
 */

var Field = exports.Field = function Field(options) {
    _.extend(this, _.defaults(options || {}, {
        widget: widgets.text(),
        omit_empty: false,
        permissions: {},
        validators: [],
        required: true
    }));
    return this;
};


/**
 * Parses a raw value returning the correct JavaScript type for this field.
 * This will usually be overridden by other field types.
 *
 * @name Field.parse(raw)
 * @param raw
 * @api public
 */

Field.prototype.parse = function (raw) {
    return raw;
};


/**
 * Test values to see if field is considered empty.
 *
 * This function accepts the raw value even though by default it only
 * checks the parsed value, so that other field types overridding this method
 * have the raw data available.
 *
 * @name Field.isEmpty(value, raw)
 * @param value - the parsed value for the field
 * @param raw - the raw value for this field
 * @returns {Boolean}
 * @api public
 */

Field.prototype.isEmpty = function (value, raw) {
    if (raw === undefined) {
        if (typeof value === 'number' && isNaN(value)) {
            return true;
        }
        raw = value;
    }
    return (raw === '' || raw === null || raw === undefined);
};

/**
 * Run the field's validation functions against a value. Returns an
 * array of validation errors, or an empty array if valid.
 *
 * @name Field.validate(doc, value, raw)
 * @param {Object} doc
 * @param value
 * @param raw
 * @returns {Array}
 * @api public
 */

Field.prototype.validate = function (doc, value, raw) {
    // don't validate empty fields, but check if required
    if (this.isEmpty(value, raw)) {
        if (this.required) {
            if(_.isFunction(this.required)) {
                if(this.required(doc, value, raw)) {
                    return [ new Error('Required field') ];
                }
            } else {
                return [ new Error('Required field') ];
            }
        }
        return [];
    }
    return _.reduce(this.validators, function (errs, v) {
        try {
            // check that v is actually a function, since IE likes to
            // insert nulls here for some reason
            if (v) {
                errs = errs.concat(v(doc, value, raw) || []);
            }
        }
        catch (e) {
            errs.push(e);
        }
{'fraction_non_alphanumeric': 0.1214757048590282, 'fraction_numerical': 0.0, 'mean_word_length': 2.2659157688540645, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4900695', 'n_tokens_mistral': 1840, 'n_tokens_neox': 1804, 'n_words': 678}