Skip to content

Instantly share code, notes, and snippets.

@jdthorpe
Created June 9, 2017 19:26
Show Gist options
  • Save jdthorpe/c528006143006c4eb54014fd96fd0c80 to your computer and use it in GitHub Desktop.
Save jdthorpe/c528006143006c4eb54014fd96fd0c80 to your computer and use it in GitHub Desktop.
Validation of columnar data via AJV
var Ajv = require('ajv');
var ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}
var ajv = new Ajv({"v5":true}); //https://github.com/epoberezkin/ajv/issues/297
ajv.addKeyword('columns', {
type: 'object',
macro: function (schema) {
console.log("IN Schema:\n", JSON.stringify(schema,null,2) ,"\n");
if(!schema.hasOwnProperty("properties"))
throw new Error("schema is missing required property 'properties'")
var props = [];
for(var prop in schema.properties){
if(schema.properties.hasOwnProperty(prop)){
props.push(prop)
}
}
if(!props.length)
throw new Error("schema.properties must have at least one property")
var ref_prop = props[1];
out = {
type:"object",
properties:{},
}
props.map(function(prop){
out.properties[prop] = {
"type":"array",
"items":schema.properties[prop],
"maxItems":{"$data":"1/"+ref_prop+"/length"},
"minItems":{"$data":"1/"+ref_prop+"/length"}
};
})
if(schema.patternProperties){
out.patternProperties = {};
for(prop in schema.patternProperties){
if(!schema.patternProperties.hasOwnProperty(prop))
continue;
out.patternProperties[prop] = {
"type":"array",
"items":schema.patternProperties[prop],
"maxItems":{"$data":"1/"+ref_prop+"/length"},
"minItems":{"$data":"1/"+ref_prop+"/length"}
};
}
}
if(schema.required)
out.required = schema.required
if(schema.propertyNames)
out.required = schema.propertyNames
console.log("OUT Schema:\n", JSON.stringify(out,null,2) ,"\n");
return out;
}
})
valiate = ajv.compile({
//https://github.com/epoberezkin/ajv/issues/297
"$schema": "https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#",
columns: {
properties:{
"foo":{type:'number'},
"bar":{type:'string'},
"bat":{type:'string',format:'email'},
},
required:[
"foo",
"bar",
],
patternProperties:{
"^@[a-z]+$":{
type:"object",
properties:{
name:{type:"string"},
time:{
type:"string",
format:"date",
}
},
}
}
}
})
good1 = {
"foo":[1],
"bar":["Hello"],
"bat":["[email protected]"],
}
good2 = {
"foo":[1,2],
"bar":["Hello","mickey"],
"bat":["[email protected]","[email protected]"],
}
good3 = {
"foo":[],
"bar":[],
"bat":[],
}
good4 = {
"foo":[],
"bar":[],
"bat":[],
}
good5 = {
"foo":[],
"bar":[],
}
good6 = {
"foo":[1],
"bar":['hi'],
"@foo":[{name:"foo",time:"2016-01-01"}],
}
valiate(good1) // true
valiate(good2) // true
valiate(good3) // true
valiate(good4) // true
valiate(good5) // true
valiate(good6) // true
bad1 = {
"foo":[1,2],
"bar":["Hello"],
"bat":["[email protected]"],
}
bad2 = {
"foo":[1,2],
"bar":["Hello","Oscar"],
"bat":["world","madison"],
}
bad3 = {
"foo":[1],
"bar":[],
"bat":[],
}
bad4 = {
"foo":[],
"bat":[],
}
valiate(bad1) // false
valiate(bad2) // false
valiate(bad3) // false
valiate(bad4) // false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment