jsen icon indicating copy to clipboard operation
jsen copied to clipboard

Add asynchronous validation support

Open pashoo2 opened this issue 10 years ago • 18 comments

Please look at my fork https://github.com/pashoo2/jsen and add my code into the yours, if you'll like it. I've not understood how to create a pull request

pashoo2 avatar May 28 '15 09:05 pashoo2

@pashoo2 Nice work adding async support in your fork. However, as the primary goal of JSEN is performance, async validation is not in the scope of the project. Further, I believe that true async execution in a JSON validation library is achieved only if validation can be performed on a separate thread.

Also, looking at the code, you've implemented async support only for custom formats. The rest of the validation code will not run asynchronously. In this case, async execution seems more of a convenience feature for dealing with asynchronous format validation that may involve async I/O.

bugventure avatar Jun 04 '15 10:06 bugventure

Yes, but even this implementation of the asynchronous validation may help to many peoples like me, and it have another features

pashoo2 avatar Jun 04 '15 17:06 pashoo2

I've compared the performance of my fork and your code. It seems to be on a par

pashoo2 avatar Jun 04 '15 17:06 pashoo2

And the async validation may be the main benefit of this library against the library is-my-json-valid

pashoo2 avatar Jun 04 '15 17:06 pashoo2

We need more use cases for that and additional research on the optimal approach for asynchronous execution. I'm adding this as a planned feature for v0.4.0, but want to hear more voices here.

bugventure avatar Jun 05 '15 11:06 bugventure

You have the bug with a custom patterns and the predefined formats:

var jsen = require("jsen");

var obj1 = { date : 2 };

var schema = { type : "object", additionalProperties : false, required : ["date"], properties : { date : { format : "email" } } };

var validator = jsen(schema); var res = validator(obj1); console.log(res);

pashoo2 avatar Jun 06 '15 18:06 pashoo2

I've fixed this error with the 0.4.2 release

pashoo2 avatar Jun 06 '15 19:06 pashoo2

Another bug with a custom formats, it's may be not only a strings

pashoo2 avatar Jun 06 '15 19:06 pashoo2

Also fixed

pashoo2 avatar Jun 06 '15 20:06 pashoo2

Can you, please, provide more details for these two bugs? In the first case, I can't see anything wrong with the validation. obj1 is valid, because you don't specify a type for the date field. According to the JSON schema spec, keywords that do not apply to a particular type are ignored and validation succeeds. In this case, the format keyword is ignored as it only applies to strings.

bugventure avatar Jun 08 '15 07:06 bugventure

I don't know these details about the first error, after your explanation i think it's not an error. The second error, as i remember, is that if a value has a non-string type, then it will be ignored for the custom validation function, that was defined by a custom format

pashoo2 avatar Jun 08 '15 11:06 pashoo2

Ok, if it is a standard behaviour, that a schema without a specified type ignores the format keyword, then there is no errors

pashoo2 avatar Jun 08 '15 12:06 pashoo2

Custom formats are different. They are run for all types (I have a test that covers this scenario). Note, however, that custom format validators are run after all built-in keyword validators pass successfully. This means if validation fails on any of the built-in keywords, custom format validators won't run.

bugventure avatar Jun 08 '15 12:06 bugventure

Yes, it is. But in my test, custom formats have been applied only for string properties. I've done this to resolve the problem:

function getGenerators(schema) {
    var keys = Object.keys(schema),
        start = [],
        perType = {},
        gen, i;

    for (i = 0; i < keys.length; i++) {
        gen = keywords[keys[i]];

        if (!gen) {
            continue;
        }

        //pashoo--
        if ( keys[i] === "format"  && formats[schema.format] === undefined ) { //if it is a custom format
            continue;
        } //--pashoo

        if (gen.type) {
            if (!perType[gen.type]) {
                perType[gen.type] = [];
            }

            perType[gen.type].push(gen);
        }
        else {
            start.push(gen);
        }
    }

    return start.concat(Object.keys(perType).reduce(function (arr, key) {
        return arr.concat(perType[key]);
    }, []));
}

pashoo2 avatar Jun 08 '15 17:06 pashoo2

Another issue:

var obj = {
    _fl1 : true,
    _m : [
        {
            t: "22",
            k: "22",
            b : 2
        },
        {
            t: "23",
            k "22",
            b : {a:1, b:2}
        }
    ]
};
var schema = {
            type: "object",
            additionalProperties : false,
        required : ["_fl1", "_m"],
            properties: {
                _fl1: {"enum": [true]},
                _messages: {
                    type: "array",
                    additionalItems : false,
                    items:{
                            type: "object",
                            additionalProperties : false,
                            required : ["t","k","b"],
                            properties: {
                                t: {type: "string", minLength : 1, maxLength: 50},
                                k: {type: "string", minLength : 1, maxLength: 50},
                                b: {
                                    oneOf:[
                                        {type:"object", maxProperties: 50, minProperties: 1},
                                        {type:"number"}
                                    ]
                                }
                            }
                        }
                }
            }
        };
var validator = jsen(schema);
var res = validator(obj);

pashoo2 avatar Jun 10 '15 17:06 pashoo2

You use _messages in the schema, but _m in the validated object.

bugventure avatar Jun 10 '15 19:06 bugventure

oh, sorry, you need to change messages to m into the schema, and the result will be wrong. I've added async validation for the oneOf keyword. This means that it is possible and easy for all other keywords

pashoo2 avatar Jun 10 '15 23:06 pashoo2

+1 for async validation

seeden avatar Jul 04 '15 10:07 seeden