Skip to content

Commit

Permalink
fix(core): fix schema id dereferencing
Browse files Browse the repository at this point in the history
Fixes #6, #9

Signed-off-by: Johny Jose <[email protected]>
  • Loading branch information
Johny Jose committed Jan 31, 2015
1 parent 704d37a commit cb0be79
Showing 1 changed file with 82 additions and 27 deletions.
109 changes: 82 additions & 27 deletions src/themis.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,24 +89,29 @@ var Utils = {

dereferencePath: function (path, schema_id, schemas) {
var hash_index, index, ref, parts;
hash_index = path.indexOf('#');
if (hash_index === 0) {
if (path === "#") { return schemas[schema_id]; }
ref = schemas[schema_id];
parts = path.slice(2).split("/").map(function (part) { return Utils.decodeJSONPointer(part); });
for (index = 0; index < parts.length; index++) {
ref = ref[parts[index]];
}
return ref;
} else if (hash_index > 0) {
ref = schemas[path.slice(0, hash_index)];
parts = path.slice(hash_index + 2).split("/").map(function (part) { return Utils.decodeJSONPointer(part); });
for (index = 0; index < parts.length; index++) {
ref = ref[parts[index]];
if (schemas[path]) {
return schemas[path];
} else {
hash_index = path.indexOf("#");
if (hash_index === 0) {
if (path === "#") { return schemas[schema_id]; }
ref = schemas[schema_id];
parts = path.slice(2).split("/").map(function (part) { return Utils.decodeJSONPointer(part); });
for (index = 0; index < parts.length; index++) {
ref = ref[parts[index]];
}
return ref;
} else if (hash_index > 0) {
ref = schemas[path.slice(0, hash_index)];
parts = path.slice(hash_index + 2).split("/").map(function (part) { return Utils.decodeJSONPointer(part); });
for (index = 0; index < parts.length; index++) {
ref = ref[parts[index]];
}
return ref;
} else {
throw Error("invalid ref: " + path + ' in ' + schema_id);
}
return ref;
}
return schemas[path];
},

defaults: function (obj) {
Expand Down Expand Up @@ -155,8 +160,8 @@ var Utils = {

decodeJSONPointer: function (str) {
// http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07#section-3
if (str === '#') {
return '';
if (str === "#") {
return "";
} else {
return decodeURIComponent(str).replace(/~[0-1]/g, function (x) {
return x === "~1" ? "/" : "~";
Expand All @@ -177,6 +182,7 @@ var Utils = {
case "object":
value = ["{"];
for (index in data) {
if (!data.hasOwnProperty(index)) continue;
if (!flag) {
flag = true;
value.push(" \"" + index + "\": " + _stringify(data[index]));
Expand All @@ -193,6 +199,7 @@ var Utils = {
case "array":
value = ["["];
for (index in data) {
if (!data.hasOwnProperty(index)) continue;
if (!flag) {
flag = true;
value.push(" " + _stringify(data[index]));
Expand Down Expand Up @@ -1764,7 +1771,7 @@ var generateSchema = function (schema, schema_path, schema_id, cache, options) {
}

if (Utils.typeOf(schema.$ref) === "string") {
if (schema.$ref[0] === "#") {
if (schema.$ref === "#" || schema.$ref.indexOf("#/") === 0) {
if (code.length === 10) {
code = [
"validators['"+ validator_path +"'] = function (data, _schema, parent, root, path, Utils) {",
Expand Down Expand Up @@ -1846,6 +1853,13 @@ var generateSchema = function (schema, schema_path, schema_id, cache, options) {
];
}

// Add id references
if (Utils.typeOf(schema.id) === "string") {
code.push(
"validators['" + schema.id + "'] = validators['"+ validator_path +"']"
);
}

// Generate validators for arrays
if (Array.isArray(schema.items)) {
for (index = 0; index < schema.items.length; index++) {
Expand Down Expand Up @@ -1993,19 +2007,60 @@ var buildValidator = function (schemas, options) {

var buildSchemas = function (schema_data, options) {
var schema, schemas, schema_id, key, _key, index, _schemas = {}, buffer = [];

// Create a deep clone of schemas
eval("schemas = "+ Utils.stringify(schema_data) +";");
index = schemas.length;

// Index all schemas
for (;index--;) {
schema_id = (schemas[index].id !== undefined) ? schemas[index].id: index;
_schemas[schema_id] = schemas[index];
buffer[index] = [schemas[index], schema_id];
for (index = 0; index < schemas.length; index++) {
schema = schemas[index];
if (schema.id !== undefined) {
schema_id = schema.id;
_schemas[schema_id] = schema;
buffer[index] = [schema, schema_id];
} else {
schema_id = index;
_schemas[schema_id] = schema;
if (index < schema_data.length) {
buffer[index] = [schema, schema_id];
}
}
for (key in schema) {
switch (key) {
case "not":
case "additionalItems":
case "additionalProperties":
if (Utils.typeOf(schema[key].$ref) !== "string") {
schemas.push(schema[key]);
}
break;
case "items":
case "oneOf":
case "allOf":
case "anyOf":
if (Utils.typeOf(schema[key]) === "array") {
for (_key in schema[key]) {
if (Utils.typeOf(schema[key][_key].$ref) !== "string") {
schemas.push(schema[key][_key]);
}
}
} else if (Utils.typeOf(schema[key]) === "object") {
if (Utils.typeOf(schema[key].$ref) !== "string") {
schemas.push(schema[key]);
}
}
break;
case "definitions":
case "properties":
case "patternProperties":
for (_key in schema[key]) {
if (Utils.typeOf(schema[key][_key].$ref) !== "string") {
schemas.push(schema[key][_key]);
}
}
break;
}
}
}


// Build refs
index = buffer.length;
while (buffer.length > 0) {
Expand Down

0 comments on commit cb0be79

Please sign in to comment.