<commit_before>var validator = require("validator"),
    FilterPrototype = validator.Filter.prototype,
    object = require("object-additions").object;

function Filter(fieldname) {
  var stack = [];

  this.extend = function(func) {
    stack.push(func);
    return this;
  };

  this.run = function(formData) {
    stack.forEach(function(filter) {
      formData[fieldname] = filter(formData[fieldname]);
    });
  };
}

var externalFilter = new validator.Filter();

Object.keys(FilterPrototype).forEach(function(name) {
  if (name.match(/^ifNull$/))
    return;
  
  Filter.prototype[name] = function() {
    var args = Array.prototype.slice.call(arguments);
    return this.extend(function(value) {
      return FilterPrototype[name].apply(externalFilter.sanitize(value), args);
    });
  };
});

Filter.prototype.ifNull = function(replacement) {
  return this.extend(function(value) {
    if (object.isUndefined(value) || value === null || value === '') {
      return replacement;
    }
    return value;
  });
};

Filter.prototype.toUpper = function() {
  return this.extend(function(value) {
    return value.toUpperCase();
  });
};

Filter.prototype.truncate = function(length) {
  return this.extend(function(value) {
    if (value.length > length) {
      return value.substr(0,length);
    }
    return value;
  });
};

Filter.prototype.custom = function(func) {
  return this.extend(func);
};

module.exports = Filter;
<commit_msg>Fix truncate filter. Alias toUpper filter to toUpperCase. Add toLower and toLowerCase filters. Added comments.<commit_after>var validator = require("validator"),
    FilterPrototype = validator.Filter.prototype,
    object = require("object-additions").object;

function Filter(fieldname) {
  var stack = [];

  this.extend = function(func) {
    stack.push(func);
    return this;
  };

  this.run = function(formData) {
    stack.forEach(function(filter) {
      formData[fieldname] = filter(formData[fieldname]);
    });
  };
}

var externalFilter = new validator.Filter();

Object.keys(FilterPrototype).forEach(function(name) {
  if (name.match(/^ifNull$/)) // Skip built-in ifNull implementation.
    return;
  
  Filter.prototype[name] = function() {
    var args = Array.prototype.slice.call(arguments);
    return this.extend(function(value) {
      return FilterPrototype[name].apply(externalFilter.sanitize(value), args);
    });
  };
});

Filter.prototype.ifNull = function(replacement) {
  return this.extend(function(value) {
    if (object.isUndefined(value) || value === null || value === '') {
      return replacement;
    }
    return value;
  });
};

Filter.prototype.toUpper = Filter.prototype.toUpperCase = function() {
  return this.extend(function(value) {
    return value.toUpperCase();
  });
};

Filter.prototype.toLower = Filter.prototype.toLowerCase = function() {
  return this.extend(function(value) {
    return value.toLowerCase();
  });
};

Filter.prototype.truncate = function(length) {
  return this.extend(function(value) {
    if (value.length <= length) {
      return value;
    }

    if (length <= 3) return "...";

    if (value.length > length - 3) {
      return value.substr(0,length - 3) + "...";
    }

    return value;
  });
};

Filter.prototype.custom = function(func) {
  return this.extend(func);
};

module.exports = Filter;

{'fraction_non_alphanumeric': 0.15291992775436483, 'fraction_numerical': 0.0015051173991571343, 'mean_word_length': 3.65406162464986, 'pattern_counts': {'":': 0, '<': 5, '<?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': '3772778', 'n_tokens_mistral': 1024, 'n_tokens_neox': 1023, 'n_words': 187}