Skip to content

Instantly share code, notes, and snippets.

@nitely
Last active August 29, 2015 14:16
Show Gist options
  • Save nitely/36df1db7d94dbc5eeafc to your computer and use it in GitHub Desktop.
Save nitely/36df1db7d94dbc5eeafc to your computer and use it in GitHub Desktop.
First steps: JSON Schema validator
/*
Author: Esteban Castro Borsani
Licence: MIT
*/
/*
This is a schema validator... errrgh.... this is the first step to create a json validator.
It does not do any validation, but it iterates over nested objects and arrays defined in your schema, recording the full path for error outputs.
REQUIRES: lodash
*/
var schema = {
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
required: true,
"description": "The unique identifier for a product",
"type": "integer"
},
"name": {
"description": "Name of the product",
"type": "string"
},
"tags": {
required: true,
"type": "array",
"items": {
"type": "string"
}
},
"more": {
"type": "object",
"properties": {
"id2222": {
"description": "The unique2222",
"type": "integer"
},
"name222": {
"description": "Name of the product 2222",
"type": "string"
}
}
},
"even_more": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id333": {
"description": "The unique2222",
"type": "integer"
},
"name333": {
"description": "Name of the product 2222",
"type": "string"
}
}
}
},
"some_more": {
"type": "array",
"items": {
"type": "string"
}
}
}
};
var data = {
bad: "nooooooooooooooo",
id: "sup?",
name: "wtf?",
more: {
id2222: "dang"
},
even_more: [
{
id333: 1111,
name333: "zzzzzzzzzz"
},
{
id333: 2222,
name333: "yyyyyyyyyy"
}
],
some_more: ["aaa", "bbbb", "cccc"]
};
var nodePath = [];
function test(sch, data, opt) {
console.log("------");
opt = opt || {};
if (opt.nodeName)
nodePath.push(opt.nodeName);
_.forOwn(sch, function(node, name) {
if (typeof data[name] === 'undefined') {
console.info("MISSING: " + nodePath.join(".") + "." + name);
return;
}
console.log(nodePath.join(".") + "." + name);
if (node.type == "object") {
test(node.properties, data[name], {nodeName: name});
}
if (node.type == "array") {
data[name].forEach(function(item, index) {
var nodeObj = {};
var itemObj = {};
nodeObj[index] = node.items;
itemObj[index] = item;
test(nodeObj, itemObj, {nodeName: name});
});
}
});
if (opt.nodeName)
nodePath.pop();
}
test({root: schema}, {root: data});
/*
OUTPUT
"------"
".root"
"------"
"root.name"
"MISSING: root.tags" test.js:122
"root.more"
"------"
"root.even_more"
"------"
"root.even_more.0"
"------"
"root.even_more.0.id333"
"root.even_more.0.name333"
"------"
"root.even_more.1"
"------"
"root.even_more.1.id333"
"root.even_more.1.name333"
"root.some_more"
"------"
"root.some_more.0"
"------"
"root.some_more.1"
"------"
"root.some_more.2"
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment