Code Monkey home page Code Monkey logo

checkit's People

Contributors

akawry avatar bendrucker avatar djmadcat avatar dwillie avatar federicobond avatar fredericheem avatar gfarrell avatar goowikns avatar jeduan avatar johanneslumpe avatar korbin avatar limianwang avatar luggage66 avatar majorbreakfast avatar mploki avatar muddydixon avatar ninjabanjo avatar rhys-vdw avatar scottjutsu avatar stith avatar tgriesser avatar tommoor avatar whoaa512 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

checkit's Issues

null and '' get a pass?

The section below seems a bit odd to me as. If I have optional email field for users validated with 'email' rule, they can submit null and '' as values and it passes. However if they provide ' ' (single space) it fails as an invalid email. This seems like a bit of a hole for all rules (except 'accepted', 'exists', and 'required'). If I don't want to require an email, but want it validated if present, I would NOT expect '' or null to pass validation. Null and '' ARE values to be validated against. Thoughts?

// If the rule isn't an existence / required check, return
// true if the value doesn't exist.
if (rule !== 'accepted' && rule !== 'exists' && rule !== 'required') {
if (value === '' || value == null) return;
}

Message for Custom Rule

Hey Guys,

I am trying to add custom error messages for custom rules that I add into the CheckIt object. For instance, this works fine:

var rules = {
  title: [{
    rule: 'required',
    message: 'Required'
  }]
};

That returns the expected Required message. However, if I want to add a unique function and change it's message, it returns null:

var rules = {
  title: [{
        rule: function(val) {
          return new Promise(function(resolve, reject) {
            User.where('email', '=', val).count('id').then(function(res) {
              if (res > 0) return reject(true);

              resolve(true);
            });
          });
        },
        message: 'Exists'
      }]
};

The function runs properly, but the message is null. Any thoughts on customizing the message for custom rules?

target in custom validators

Might be worth documenting that in adding custom validators to the Checkit.Validator object's prototype you have to use this._target to access the target object (as opposed to this.target as used in the custom rule example).

Happy to do a PR if desired.

Why clone the `this.target` object?

https://github.com/tgriesser/checkit/blame/master/core.js#L121

That line is causing issues for a project I'm working on, because we need this.target to retain its properties that it inherits through prototype, but they're being lost by that one line.

Is there a reason why you're cloning it?

Here's some pics of the problem:

Here I'm highlighting the object we want as this.target in the validation:

screen shot 2016-07-07 at 16 43 42

But then over here, because of the clone that __proto__ information gets lost and this.target is no longer the same object.

screen shot 2016-07-07 at 16 43 45

Is there a reason why you decided to do that clone there?

How to validate unique using two fields

I have the following unique validation

Checkit.Validators.unique = Checkit.Validators.unique || function(value, table, column) {   
    return knex(table).where(column, '=', value).then(function(resp) {
        if (resp.length > 0)
            throw new ValError([model , column].join('.') + ' must be unique!');
    });
};

i'm using like this

var rules = {
name: ['required', 'unique:my_table:name']
};

works fine but i need validate using two columns (name and parent_id), How i can achieve this?

Better documentation

Could you better document this?

For example, there is no explanation nor is there a test case showing how to do a custom Regex validation.

When the words 'value must be a valid Regex' is used, where is the RegEx defined to pass to CheckIt?

It is very unclear what the arguments are and what the expected usage of the API is.

Cannot find module 'pg-native'

I see this message If i used checkit with Bookshelf and pg. Without checkit all works normal.

P.S pg-native is not installed (not build on windows), but i am not "require()" this package in my code.

Manual invalidation

Is it possible to do something like:

// schema is a `checkit` object.
schema.invalidate('path', 'error message');

I'm working on a new project where manual invalidation could be very helpful. In my head this (potential) API would work regardless if the schema has already been run() or not.

Needed regexp example

how can I use the regular expression in checkit
as I have to escape single quote using regular expression and have to check.
Expression is (/'/g, "'");

No longer subclassing Error

I noticed that the newest version of Checkit no longer subclasses Error, nor does it use create-error to name the error. This means there is no way to catch it with Bluebird (previously I was comparing the name property).

Any chance you could at least restore the name property if not the inheritance?

Not catching errors at all.

Stack - React 16.2.0 with webpack 3
npm install checkit

usage -

import Checkit from 'checkit'; import { CheckitRules } from '../../_helpers/checkit/campaign';

Campaign Rules below as defined in '../../_helpers/checkit/campaign';

var CheckitRules = new Checkit({ name: 'required', type: 'required', audience_list_id: 'required' }, { labels: { name: 'name', type: 'type', audience_list_id: 'audience_list_id' } });

var payload = { name: campaign_name || 'test', type: campaign_type || 'regular', audience_list_id: audience_list_id }

CheckitRules.run(payload).then(function(validated) { console.log(validated); }).catch(Checkit.Error, function(err) { console.log(err.toJSON()); });

As soon as I any empty value on payload it doesn't catch error. The success function is working fine if I make sure to populate every value.

This is surprising !

Nested Validations

I may have missed it in the documentation, but is there a way to check an object with nested objects contained within it, or is this not possible? For example, if I have an object like:

{
  "key1": "example",
  "key2": {
    "key3: "example",
    "key4": "example"
  }
}

Would I be able to write a CheckIt validator to validate the entire object at once, even the keys under key2? The only alternative seems to be to validate the contained objects individually, which would make my code less general than I had hoped.

If this is not possible, perhaps it would be a useful enhancement.

synchronous, non-promise api

@tgriesser ,

I am trying to use checkit for both doing function parameter validation as well as with bookshelf. I really like checkit's error type system but I also like http://validatejs.org/ because it offers a non-promise based api when you know that all your validators are synchronous.

Do you use checkit for standard function parameter validation?

Having it return a checkit.Error when validation fails instead of a promise that is rejected will make it possible to use checkit in synchronous functions that just return values as opposed to promises.

Heres a somewhat contrived example of the usage pattern I'm looking for:

function getFullName( user ) {
  var err = checkit( { firstName : [ 'required' ], lastName : [ 'required' ] } ).runSync( user );

  if( err ) {
    // err is an instance of checkit.Error
    throw err;
  }

  return user.firstName + ' " + user.lastName;

}

Do you think this is something that makes sense to implement in checkit?

Thanks!

email validation on android

It seems that the email validation is not working on my android device (Samsung S5) but is fine for other browser.

No validation defined for "max:value" and "min:value"

With version 0.7.0:

checkit.check('myField', -1 , ['min:0'])
    .catch(console.log.bind(console))

Returns an error with message: 'No validation defined for min'

The min/max validations did not throw in version 0.6.0, but they actually did not work as expected because they used the _.min and _.max methods of lodash that return the smallest/largest value of a collection. This does not seem to be the expected behavior as described in Checkit's documentation.

I think the best course of action would simply be to remove these validators from the documentation as they can already be accomplished with 'greaterThanEqualTo:value' and 'lessThanEqualTo:value'.

async version (0.7.0) doesn't run

I like checkit pretty much, but I can't get it working using the async call in version 0.7.0 working (Node.js 6.2.2).

This is my test code:

'use strict';
console.log(global.Promise);
const Checkit = require('checkit');
const createCheckit = new Checkit({
  name: 'required'
});

createCheckit.run({}).then(validated => {
  console.log('async: ', validated);
}).catch(Checkit.Error, err => {
  console.log('async errors: ', err.errors);
});

const [err, validated] = createCheckit.validateSync({});

console.log('sync errors: ', err.errors);

This is the console output:

[Function: Promise]
sync errors: { name: 
   { Error
       at module.exports (/home/alexzeitler/src/hellocheckit/node_modules/checkit/core.js:448:24)
       at Object.<anonymous> (/home/alexzeitler/src/hellocheckit/node_modules/checkit/index.js:2:35)
       at Module._compile (module.js:541:32)
       at Object.Module._extensions..js (module.js:550:10)
       at Module.load (module.js:458:32)
       at tryModuleLoad (module.js:417:12)
       at Function.Module._load (module.js:409:3)
       at Module.require (module.js:468:17)
       at require (internal/module.js:20:19)
       at Object.<anonymous> (/home/alexzeitler/src/hellocheckit/index.js:3:17)
     message: 'The name is required',
     errors: [ [Object] ],
     key: 'name' } } null

As you can see, there is a global Promise and the sync version works as expected but the async version doesn't throw.

If I pass in a valid object, validated is passed in and the console looks like async: { name: 'alex' }

Front page text truncated

The front page/readme file has the following:

It supports both sync

It looks like something got chopped off there on accident, and maybe the full sentence should be something like:

It supports both synchronous and asynchronous operation.

Unique Name Validation using multiple columns

I'm using bookshelf.js instead of knex and I want to check for unique using name and id attribute of the table.

How can I pass req.params in my custom function that checks for unique name in table?

Below is my code:

function assertEditRoleName(val, params, context) {
        return Role
            .forge()
            .where('id', '<>', 2)
            .where('name', '=', val)
            .where('is_deleted', '=', 0)
            .fetchAll()
            .then(function (existing) {
                if (existing.models.length > 0) {
                    throw new Error('Duplicated role name');
                }
            }).catch(function (err) {
                console.log(err);
            });
    }

In above code, i'm getting only name in val and I want to pass id also from my request body.

I have checked #26
Thanks

`finite` does not seem to exist?

The documentation speaks of a finite validator, but it doesn't seem that there's actually any code in checkit that implements this validator. Am I just missing something, or does this validator not exist at all?

(Version: 0.7.0)

EDIT: The same seems to apply to min and max?

Unexpected validated object

If you're validating properties of an object inside of the object being validated, they don't come through to the final validation object even though they're being validated:

const checkit = new Checkit({
  title: 'required',
  'name.first': 'required',
  'name.last': 'required',
  age: ['required', 'numeric']
});

checkit.runSync({
  title: 'Janitor',
  name: {first: 'John'},
  age: 32
});
// [ { Error message: '1 invalid values', errors: { 'name.last': [Object] } }, null ]

checkit.runSync({
  title: 'Janitor',
  name: {first: 'John', last: 'Doe'},
  age: 32
});
// [ null, { title: 'Janitor', age: 32 } ]

Given that the name property is being validated, I would expect that it would be part of the output too.

Unique constraint

Maybe this is a silly question since it requires performing a query to validate it, but is there any way of implementing a unique validator? Or perhaps some standard workaround that I'm not aware of?

I'm also having a problem finding out where I could catch whatever error the mysql driver is returning when the insert fails the db level enforced unique constraint.

This is what I'm seeing when I attempt to insert something that fails the db level unique validator (username in this case; I reformatted the JSON for readability):

{
    "message": "{\"sql\":\"insert into `users` (`email`, `password`, `username`) 
     values (?, ?, ?)\",\"bindings\":
     [\"[email protected]\",\"$2a$10$NlzLA6AV0rsH0xcbhkcc4utr5lcs.h2rTahBXOhBheFcWpQlLJG1q\",\"j\"]}"
}

custom validation value not being split by :

Is there a way to perform the following inline, without appending a custom function to CheckIt.Validations? I'd like to provide a custom function within the validation array, but have it parse the value by colon, as is performed when a custom function is added to CheckIt.Validations.

validations = 
  to_user: 'user:matt123:1'

body = 
  to_user: "#{post.to_user}:1"

yield CheckIt(validations).run(body)

In the example above, the custom function would have access to val, username, organization_id.

For clarification, the following works just fine, I'm just looking to replicate this behavior with an inline custom function in the validations array.

CheckIt.Validators.user = (val, username, organization_id) ->
  # console.log 'val', val
  # console.log 'username', username
  # console.log 'organization_id', organization_id
  return Bookshelf.db.knex('user').where(username: username, organization_id: organization_id).then (result) ->
    throw new Error("That user doesn't exist!") unless result.length > 0

Thanks!

"date" validation problem

When updating to latest version (0.7.0), I can't get "date" validations to run properly. See:

vagrant@spitdev:/opt/app$ node
> var checkit = require('checkit');
undefined
> var c = new checkit({a:'date'});
undefined
> var body = {a:new Date()};
undefined
> c.run(body).catch(err => console.log(err));
Promise { <pending> }
> { [Error: 1 invalid values]
  message: '1 invalid values',
  errors:
   { a:
      { [Error: No validation defined for date]
        message: 'No validation defined for date',
        errors: [Object],
        key: 'a' } } }

I presume the problem is caused by commit 3307c84, which did not bring in the isDate method?

email regexp should have a source comment explaining the rationale

Currently in line 417 of core.js.

First, big thumbs up ๐Ÿ‘ that it looks like this module won't claim email addresses with a "+" in the name as invalid.

That said, since the current regexp is very permissive, and more accurate (probably slower) regexps have been invented and discussed, the source should carry a comment with a link explaining this project's stance on what to expect from an email regexp.

How to get a value of some other field in the same form ?

For example : -

'title':[{
           rule:'required',
           message:'Required'
       },{
           rule:(val,params,context) => {
               console.log(this.a)
               if (val.indexOf('/') !== (-1)){
                   throw new Error('Title cannot contain slashes')
               }
           },
           message:'Title cannot contain slashes'
       }],
       'description':[{
           rule:'required',
           message:'Required'
       },{
           rule:'minLength',
           params:'20',
           message:'Description should be atleast 20 characters'
       }],
       'categories':[{
           rule:'minLength',
           params:'1',
           message:'Required'
       }],

In the title field validation rule ,
how to get the value of categories ?

Transform the property after validate

Hi, I'm using Checkit in my web project to validation the request's parameters like this:

var [err, params] = new Checkit({
      id: ['required', 'naturalNonZero']
    }).validateSync(req.params);

But the type of params.id is still string. I want it to be integer actually.
or another case:

var [err, params] = new Checkit({
      tags: ['parseableNumericArray'],
    }).validateSync(req.params);

with parseableNumericArray is a customized validation. I think if params.tags can be array of number instead of string after validation, it would be great.

Can we do that with Checkit currently? Or can I make a pull request? Is this project being maintained? I see it's a while since the last update...
Thanks for your attention.

Custom messages

I spent about an hour going through the source looking for one of these many ways to set custom messages (:P), but only noticed that you removed setLabels. I'm assuming there's a way to override default messages within the rules object when you instantiate a validator, but wasn't able to find where this is happening or what key it's looking for.

Error message for URL

With url validation, if the input is not a valid URL you get the generic error:

Validation for endpoint did not pass

I can make a PR for the english and spanish error messages but I don't know the other languages ๐Ÿ˜ž

Using context correctly

Hi, I checked the example in #19 to use context (for transacting) and I replicated the same idea in code and can't get the context var to work keep the information.

const createRules = {
  status: 
    [ 'required'
    , function (val) {
        if (! _.includes(statusArray, val)) {
          throw new Error('400:status:Invalid status')
        }
      } 
    ],

  commission: 
    [ 'required'
    , 'between:0:1'
    ],

  activity_request_id: { 
      rule: function (val, params, context) {
        console.log("params: ", params)
        console.log("context: ", context, context && context.transacting)
        return ActivityRequest.where({id: val}).fetch()
          .then((actReq) => {
            if (actReq === null) {
              // no ActivityRequest
              throw new Error('404:The order has to be related to an existent activity request')
            } else if (actReq.attributes.status !== 'approved') {
              // ActivityRequest not approved
              throw new Error('400:Activity request must be approved to create order')
            }
          })
      }
    }
  }
};

var Order = bookshelf.Model.extend({
  tableName: 'orders',
  hasTimestamps: true,

  activityRequest: function() {
    return this.belongsTo('ActivityRequest');
  },
  bill: function() {
    return this.belongsTo('Bill');
  },
  wireTransactionResponses: function() {
    return this.hasMany('WireTransactionResponses');
  },
  paymentGatewayResponses: function() {
    return this.hasMany('PaymentGatewayResponses');
  },

  initialize : function(){    
    this.on("creating", function(model, attrs, options){
      // generate uuid (Universally Unique IDentifier)
      model.attributes.reference_code = uuid.v4();    

      // if no status was given, set pending
      model.attributes.status = model.attributes.status || 'pending';

      model._validateCreate(model, attrs, options)
    })
  },

  _validateCreate : function(model, attrs, options) {
    console.log('attrs:', attrs)
    console.log('options:', options)
    return checkit(createRules, {context: options})
      .run(this.attributes)
      .catch(checkit.Error, (err) => {
        console.log(err);
        throw errors.toBoom(err); 
      }); 
  }

});

The console.log('options:', options) does print a {transacting: ... }, but console.log("context: ", context, context && context.transacting) prints {} undefined.

Better validator documentation

I took the liberty of writing a clearer quick reference for the possible validators in checkit - it can currently be found here. I've organized them by 'category', and ordered them roughly in the order that people are most likely to need them, or whichever other order makes sense for that particular category.

It's missing some items from the current README and, conversely, contains some items that the current README doesn't; this is because it seems that the current README is outdated, and doesn't match the implementation (see also #84).

I'd be happy to see this merged into checkit, replacing the validator reference that's currently there... however, it seems like there are currently some unreleased changes in master, and a documentation update like this would require a patch release to make it visible on NPM, even if the library code itself hasn't changed.

I'm not sure what branch to make a PR against, hence filing this as an issue instead :) I can create a pull request if needed though, just let me know.

string validator?

I see the alpha stuff but nothing seems to also take into account numbers and special chars.

Do I need to use my own?

function string(val) {
    if (typeof(val) !== "string") {
        throw new Error('Value must be a string.');
    }
}

Catching all errors in validators is dangerous

The following seems like a reasonable way to check for uniqueness of email for a given collection:

// 'unique:users:email'
Checkit.Validators.unique = function(val, collection, field) {
  collection = require('./collections/' + collection);
  var query  = {};
  query[field] = val;

  collection.fetch(query).then(function(resp) {
    if (resp.length > 0) {
      throw new Error('error message');
    }
  });
};

However, since Checkit considers any error type to be a failed validation, by the time I'm handling the validation failures for a model save, there's no way to differentiate between errors thrown by programmer error, database connection issues, or anything other than the "expected" failed validation.

In the example above, simply mis-typing the collection name ('unique:uers:email') might result in something like this...

model.save().then(function(model) {
  res.json(model);
}).caught(Checkit.Error, function(err) {
  res.statusCode = 422;
  res.json(err.toJSON());
});

...returning errors like { "email": ["Cannot find module './collection/uers'"] }. Worse if one accidentally does something like this...

process.env.MY_SECRET_SOMETHING.slce(1); // I meant to type "slice"!

...which might return { "email": ["Object my-secret-something-value has no method 'slce'"] }.

Unless I'm missing something, there's currently not a way around this. In light of this, I think it makes sense for Checkit to throw errors that are of anything other than a specific type (maybe Checkit.ValidationError) separately.

Complete README documentation

The README has sections for [e.g.] language and labels but there is no usage documentation for those options. Can you please update the documentation so that it includes a more up-to-date picture of what your project can do?

These are some README issues I noticed:

  • update dependency list (package.json shows underscore-contrib and when )
  • remove section about Bluebird as you don't seem to be using it
  • update description/examples for ALL options given, and update code example below options (unless including an example for each option). the example doesn't reflect usage of ANY of the options.
  • add descriptions/examples for Checkit.Validators, Checkit.language, Checkit.i18n
  • add description/example for fieldError.errors and Checkit.labelTransform(fn). It appears that you started a sentence for each but never either of them. =]

I understand that sometimes projects are in progress, but if there are features which don't work, they shouldn't be documented or users will try to use them. Even worse is to document them even if the feature is not yet complete. The least you could do is put one of those "build failing" images at the top to let users know that the project is not quite ready. It is equally as frustrating to not document working features. I simply don't have the time to comb through your source code. It's just a big tease!

Great idea, though! I hope you get some time to work more on it and flesh it out a bit. My team is trying to use your project for an API server we're standing up, but we may have to scrap it if you don't have time for regular maintenance/documentation.

_.clone(...) modifies target and context

These lines (core.js lines 118-119) modify the target and context parameters:

this.target         = _.clone(target || {})
this.context        = _.clone(context || {})

This breaks for example passing a bookshelf model instance as context. After the model instance went through _.clone, it doesn't have a get method anymore. Is there a specific reason for using _.clone here? I think these statements should be replaced by target || {} and context || {} - the user can still decide to use _.clone.

Email validation doesn't cover apostrophes

Turns out (who knew?) that apostrophes are allowed in email addresses. Rather embarrassingly one of our customers was unable to login, I discovered that checkit invalidates an email address with an apostrophe in it ๐Ÿ˜ข .

bcrypt password hash validation

Any interest in a PR for a bcrypt password hash validation? It would be a simple regex matcher of
/^\$2[aby]?\$[\d]+\$[./A-Za-z0-9]{53}$/ (Ref https://pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html#format-algorithm)

A more general version of this would be password hashes in "modular crypt" format.
/\$[a-z0-9-]+\$[0-9A-Za-z./+=,$-]+$/ (Ref: https://pythonhosted.org/passlib/modular_crypt_format.html)

(Unfortunately lots of other password hash formats are all over the map with various combinations fixed length Base64 strings, prefixes, and field separators, so a general passwordHash validator would probably be watered down to accept almost anything.)

Checkit and languages

As you know from bookshelf/bookshelf#224 I'm currently using bookshelf and checkit together. And I'm using it with express to build my API. First: I really like that you make an effort to support errors in multiple languages.
But here's my problem: I'm using Checkit in the model and there I don't really know which language the user speaks because that depends solely on the request. The ideal solution would be if I could use Checkit client side to localize the validation errors I get from my API.
I'm just thinking aloud here. Maybe all this is out of scope for this project. However it would be cool if all this would work out in an elegant way.

Contains - can I specify multiple values?

We're using an enum in the db to restrict a varchar field to a set of values (required or optional - which of course is confusing in itself! :-p)

Is this kind of validation possible?

necessity: [ 'required', { rule: 'contains', params: ['required', 'optional'] } ]

This only allows the first value... is this a bug or is this intentional? Is it possible to allow multiple valid values to be enumerated?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.