Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Add type validator #80

Closed
Jokero opened this issue Oct 16, 2015 · 12 comments
Closed

Add type validator #80

Jokero opened this issue Oct 16, 2015 · 12 comments
Milestone

Comments

@Jokero
Copy link
Contributor

Jokero commented Oct 16, 2015

Basic types:

  • object (plain object)
  • array
  • integer
  • number
  • string
  • boolean
  • null

Example:

validate.single([1, 2, 3], { type: 'array' }); // undefined
validate.single('123', { type: 'array' }); // ['is not an array']

User should be able to add own or modify existing types:

validate.validators.type.options = { notIntegerArray: 'is not an array of integers' };

// validate.validators.type.checks contains all types validation rules
validate.validators.type.checks.integerArray = function(value) {
    if (!Array.isArray(value)) {
        return false;
    }

    for (var i in value) {
        if (!Number.isInteger(value[i])) {
            return false;
        }
    }

    return true;
};

// ...

validate.single([1, 2, 3], { type: 'integerArray' }); // undefined
validate.single(['1', '2', '3'], { type: 'integerArray' }); // ['is not an array of integers']
@ansman
Copy link
Owner

ansman commented Oct 18, 2015

I'm guessing this would be a mostly server side validator since the end user cannot really do anything to fix the error if it's used in a browser.

The number/integer version already exists with the numericality validator.
And what would the purpose of the null check be?

I'm weighing between this being a separate validators or one that does it all.

@fnky
Copy link

fnky commented Oct 21, 2015

+1 This would be helpful both client- and server-side. Also could allow for custom type comparators for custom types, or perhaps use actual objects/prototypes for comparison:

var constraints = {
  name: { type: String },
  age: { type: Number },
  multiple: { type: [String, Boolean, Number] },
  custom: { type: User }
}

var data = {
  age: 17,
  name: 'John',
  multiple: true, // can also be String and Number
  custom: new User()
}

v(data, constraints)

I had made a partial working validator for this already, but not a comprehensive one.

@Jokero
Copy link
Contributor Author

Jokero commented Oct 21, 2015

@ansman Yes, it's mostly for the backend. I think it should be one validator. We can use numericality only to compare numbers.
null can be useful when we want to remove any object in PATCH request for example (how does github https://developer.github.com/v3/gists/#edit-a-gist)

@Screeze
Copy link

Screeze commented Dec 31, 2015

I also was looking for this, so I added it as custom validator. Might be useful for somebody else, or maybe somebody wants to integrate it into the library?

validate.validators.type = function(value, options, key, attributes) {
   // allow empty values by default (needs to be checked by "presence" check)
   if(value === null || typeof value === 'undefined') {
      return null;
   }

   // allow defining object of any type using their constructor. --> options = {clazz: ClassName}
   if(typeof options  === 'object' && options.clazz) {
      return value instanceof options.clazz ? null : ' is not of type "' + options.clazz.name + '"';
   }

   if(!validate.validators.type.checks[options]) {
      throw new Error("Could not find validator for type " + options);
   }
   return validate.validators.type.checks[options](value) ? null : ' is not of type "' + options + '"' ;
};
validate.validators.type.checks = {
   Object: function(value) {
      return validate.isObject(value) && !validate.isArray(value);
   },
   Array: validate.isArray,
   Integer: validate.isInteger,
   Number: validate.isNumber,
   String: validate.isString,
   Date: validate.isDate,
   Boolean: function(value) {
      return typeof value === 'boolean';
   }
};

It also supports something like this:

{
    test: {
        type: {clazz: TestClass}
    },
}

(Sadly options cannot be the object itself like type: TestClass, because if options is a Function, it gets evaluated by validate.js to allow dynamic options based on the value. Thats why I used this object with clazz property)

@jordanh
Copy link

jordanh commented Jan 21, 2016

+1 to this (and thank you @Screeze). I'm using validator to validate function parameters. Type checking is very useful.

@ghost
Copy link

ghost commented Sep 30, 2016

I'd like to give my vote for this.

I'm really surprised there wasn't type checking to begin with.

Thank you @Screeze for the validator. I'll be using that for now.

@nicodewet
Copy link

nicodewet commented Oct 31, 2017

+1, handy for server-side validation. Going to roll with the @Screeze option in the meantime.

In any case, I just went with the following as per earlier suggestions but trimmed it down.

/**
 * CUSTOM validate.js validator
 * https://validatejs.org/#custom-validator
 */
validate.validators.must_be_type_string = function(value, options, key, attributes) {

  info(`must_be_type_string ${value} ${options} ${key} ${JSON.stringify(attributes)}`);

  if (options === true) {
    if (validate.isString(value)) {
      return null;
    } else {
      return key + " has value " + value + " which is not a String";
    }
  } else {
    return null;
  }
};

Use as follows (and I'm ok with the superfluous true):

const FOO_CONSTRAINTS = {
  foo: { presence: { allowEmpty: false }, must_be_type_string: true }
};

@magic-madrigal
Copy link

+1

@ansman ansman closed this as completed in c54cd8e Nov 22, 2017
@ansman ansman modified the milestones: Future, Next Nov 22, 2017
@ansman
Copy link
Owner

ansman commented Nov 22, 2017

This has been implemented and will be released in the next version.

@emckay
Copy link

emckay commented Jan 20, 2018

Awesome! When will the next version be published? Anything blocking the next release that a new contributor could help with?

@hhff
Copy link

hhff commented Sep 9, 2018

Hi - echo'ing @emckay - anything we can do to get this out?

@AndreasGassmann
Copy link

I just tested the master branch and it seems to work. Anything that still needs to be done to get it into the next release?

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

No branches or pull requests

10 participants