Commit 3022748d authored by Boris Kocherov's avatar Boris Kocherov

add ability display schema resolving reference error and reimport current state slapos schemas

parent 088946da
...@@ -2,11 +2,6 @@ ...@@ -2,11 +2,6 @@
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"description": "Parameters to instantiate ERP5", "description": "Parameters to instantiate ERP5",
"additionalProperties": false, "additionalProperties": false,
"definitions": {
"tcpv4port": {
"type": "integer"
}
},
"properties": { "properties": {
"sla-dict": { "sla-dict": {
"description": "Where to request instances. Each key is a query string for criterions (e.g. \"computer_guid=foo\"), and each value is a list of partition references (note: Zope partitions reference must be prefixed with \"zope-\").", "description": "Where to request instances. Each key is a query string for criterions (e.g. \"computer_guid=foo\"), and each value is a list of partition references (note: Zope partitions reference must be prefixed with \"zope-\").",
......
...@@ -16,13 +16,14 @@ ...@@ -16,13 +16,14 @@
return _str.replace(/~/g, '~0').replace(/\//g, '~1'); return _str.replace(/~/g, '~0').replace(/\//g, '~1');
} }
function getBaseUrl(g, path) { function convertToRealWorldSchemaPath(g, path) {
var base_url, var base_url,
key, key,
hash,
map = g.props.schema_map, map = g.props.schema_map,
max_len = 0; max_len = 0;
if (!path) { if (!path) {
return; return "";
} }
for (key in map) { for (key in map) {
if (map.hasOwnProperty(key) && if (map.hasOwnProperty(key) &&
...@@ -32,9 +33,30 @@ ...@@ -32,9 +33,30 @@
max_len = key.length; max_len = key.length;
} }
} }
if (base_url === undefined) {
base_url = "";
max_len = 1;
}
hash = path.substr(max_len - 1);
if (hash) {
// XXX urlencode for hash
if (base_url.indexOf("#") >= 0) {
base_url = base_url + hash;
} else {
base_url = base_url + "#" + path.substr(max_len - 1);
}
}
return base_url; return base_url;
} }
function getBaseUrl(g, path) {
var ret = convertToRealWorldSchemaPath(g, path);
if (ret.indexOf("#") === 0) {
return;
}
return ret;
}
function downloadJSON(url) { function downloadJSON(url) {
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
...@@ -57,6 +79,9 @@ ...@@ -57,6 +79,9 @@
return schema; return schema;
} }
for (i = 0; i < parts.length; i += 1) { for (i = 0; i < parts.length; i += 1) {
if (schema === undefined) {
throw new Error("local ref `" + ref + "` does not exist in:");
}
schema = schema[decodeJsonPointer(parts[i])]; schema = schema[decodeJsonPointer(parts[i])];
} }
return schema; return schema;
...@@ -824,6 +849,10 @@ ...@@ -824,6 +849,10 @@
if (json_field.pattern) { if (json_field.pattern) {
input.pattern = json_field.pattern; input.pattern = json_field.pattern;
} }
if (json_field.format === 'uri') {
input.type = "url";
input.spellcheck = false;
}
} }
} }
} }
...@@ -1404,6 +1433,7 @@ ...@@ -1404,6 +1433,7 @@
if (!g.props.toplevel) { if (!g.props.toplevel) {
return g.checkValidityParent(json_document); return g.checkValidityParent(json_document);
} }
// return RSVP.Queue();
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
if (json_document === undefined) { if (json_document === undefined) {
...@@ -1420,6 +1450,8 @@ ...@@ -1420,6 +1450,8 @@
error, error,
span, span,
tasks = [], tasks = [],
errors = [],
schema_resolve_errors = g.props.schema_resolve_errors,
errors_block = g.element.querySelector("div.error-block"); errors_block = g.element.querySelector("div.error-block");
if (errors_block) { if (errors_block) {
...@@ -1434,7 +1466,17 @@ ...@@ -1434,7 +1466,17 @@
g.element.querySelectorAll("div.error-input").forEach(function (div) { g.element.querySelectorAll("div.error-input").forEach(function (div) {
div.setAttribute("class", ""); div.setAttribute("class", "");
}); });
if (validation.valid) {
for (i in schema_resolve_errors) {
if (schema_resolve_errors.hasOwnProperty(i)) {
errors.push(schema_resolve_errors[i]);
}
}
errors = errors.concat(validation.errors);
errors = errors.concat(validation.missing);
if (errors.length === 0) {
return g.notifyValid() return g.notifyValid()
.push(function () { .push(function () {
return false; return false;
...@@ -1451,6 +1493,7 @@ ...@@ -1451,6 +1493,7 @@
return function (element) { return function (element) {
var id = element.id, var id = element.id,
error_message, error_message,
createTextNode = document.createTextNode.bind(document),
a = document.createElement("a"); a = document.createElement("a");
a.setAttribute("href", "#" + errorUid); a.setAttribute("href", "#" + errorUid);
a.text = errorId; a.text = errorId;
...@@ -1458,18 +1501,27 @@ ...@@ -1458,18 +1501,27 @@
error_message = element.querySelector("#" + id.replace("/", "\\/") + " > .error"); error_message = element.querySelector("#" + id.replace("/", "\\/") + " > .error");
error_message.appendChild(a); error_message.appendChild(a);
error_message.setAttribute("id", errorUid); error_message.setAttribute("id", errorUid);
error_message.appendChild(document.createTextNode(error.message)); if (error.message instanceof Array) {
error.message.forEach(function (x) {
error_message.appendChild(x);
});
} else {
error_message.appendChild(createTextNode(error.message));
}
error_message.hidden = false; error_message.hidden = false;
a = document.createElement("a"); a = document.createElement("a");
a.text = errorId; a.text = errorId;
a.setAttribute("data-error-link", "#" + errorUid); a.setAttribute("data-error-link", "#" + errorUid);
a.setAttribute("class", "error-link"); a.setAttribute("class", "error-link");
if (errorId !== "1") {
errors_block.appendChild(createTextNode(","));
}
errors_block.appendChild(a); errors_block.appendChild(a);
}; };
} }
for (i = 0; i < validation.errors.length; i += 1) { for (i = 0; i < errors.length; i += 1) {
error = validation.errors[i]; error = errors[i];
error_id = (i + 1).toString(); error_id = (i + 1).toString();
tasks.push( tasks.push(
g.getElementByPath(error.dataPath || "/") g.getElementByPath(error.dataPath || "/")
...@@ -1477,14 +1529,6 @@ ...@@ -1477,14 +1529,6 @@
); );
} }
for (i = 0; i < validation.missing.length; i += 1) {
error = validation.missing[i];
error_id = (i + 1).toString();
tasks.push(
g.getElementByPath(error.dataPath || "/")
.push(print_error(error, "missing" + error_id, error_id))
);
}
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
return RSVP.all(tasks); return RSVP.all(tasks);
...@@ -1603,11 +1647,41 @@ ...@@ -1603,11 +1647,41 @@
}); });
}) })
.push(function (json) { .push(function (json) {
g.props.schema_map[path] = url;
return resolveLocalReference(json, hash); return resolveLocalReference(json, hash);
}) })
.push(undefined, function (err) {
// XXX it will be great to have ability convert json_pointers(hash)
// in line numbers for pointed to line in rich editors.
var url_from_pointed = convertToRealWorldSchemaPath(g, path),
schema_a = document.createElement("a"),
pointed_a = document.createElement("a");
schema_a.setAttribute("href", download_url);
schema_a.text = (new URL(download_url)).pathname;
pointed_a.setAttribute("href", url_from_pointed);
pointed_a.text = (new URL(url_from_pointed)).pathname;
g.props.schema_resolve_errors[url_from_pointed] = {
schemaPath: path,
message: [
document.createTextNode("schema error: "),
document.createTextNode(err.message),
schema_a,
document.createTextNode(" pointed from schema: "),
pointed_a
]
};
return null; // schema part can't be null
})
.push(function (schema_part) { .push(function (schema_part) {
// console.log(path); // console.log(path);
if (schema_part === null) {
// if resolving schema part contain errors
// use {} as failback
schema_part = {};
} else {
// save map url only for correctly resolved schema
// otherwise we have issue in convertToRealWorldSchemaPath
g.props.schema_map[path] = url;
}
schemaPushSchemaPart(g.props.schema, path, schema_part); schemaPushSchemaPart(g.props.schema, path, schema_part);
// console.log(g.props.schema[""]); // console.log(g.props.schema[""]);
return schema_part; return schema_part;
...@@ -1626,6 +1700,11 @@ ...@@ -1626,6 +1700,11 @@
g.props.schema = {}; g.props.schema = {};
g.props.schema_map = {}; g.props.schema_map = {};
g.props.schema_cache = {}; g.props.schema_cache = {};
// schema_resolve_errors[schema_url] = {
// schemaPath: local_schema_path,
// message: error_message can be array containing dom elements
// }
g.props.schema_resolve_errors = {};
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
if (options.schema) { if (options.schema) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment