Commit 53b7a3ec authored by Boris Kocherov's avatar Boris Kocherov

format

parent 3022748d
[ [
"docs/1_clean_document.json", "docs/1_clean_document.json",
"docs/bad_circular_A_schema.json",
"docs/bad_circular_B_schema.json",
"docs/bad_circular_C_schema.json",
"docs/circular_A_schema.json",
"docs/circular_B_schema.json",
"docs/circular_C_schema.json",
"docs/demo.json", "docs/demo.json",
"docs/xmla_settings_schema.json" "docs/xmla_settings_schema.json"
] ]
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Settings for XMLA connection",
"properties": {
"url": {
"uniqueItems": true,
"items": {
"$ref": "bad_circular_B_schema.json"
},
"minItems": 1,
"type": "array"
},
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
}
\ No newline at end of file
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Settings for XMLA connection",
"properties": {
"url": {
"uniqueItems": true,
"items": {
"$ref": "bad_circular_C_schema.json"
},
"minItems": 1,
"type": "array"
},
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
}
\ No newline at end of file
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Settings for XMLA connection",
"properties": {
"url": {
"uniqueItems": true,
"items": {
"$ref": "bad_circular_A_schema.json"
},
"minItems": 1,
"type": "array"
},
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
}
\ No newline at end of file
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Settings for XMLA connection",
"properties": {
"url": {
"uniqueItems": true,
"items": {
"$ref": "circular_B_schema.json"
},
"minItems": 1,
"type": "array"
},
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
}
\ No newline at end of file
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Settings for XMLA connection",
"properties": {
"url": {
"uniqueItems": true,
"items": {
"$ref": "circular_C_schema.json"
},
"minItems": 0,
"type": "array"
},
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
}
\ No newline at end of file
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Settings for XMLA connection",
"properties": {
"url": {
"uniqueItems": true,
"items": {
"$ref": "circular_A_schema.json"
},
"minItems": 1,
"type": "array"
},
"username": {
"type": "string"
},
"password": {
"type": "string"
}
},
"required": [
"url"
],
"additionalProperties": false
}
\ No newline at end of file
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
"slapos/software/cloudooo/instance-cloudooo-input-schema.json", "slapos/software/cloudooo/instance-cloudooo-input-schema.json",
"slapos/software/cloudooo/software.cfg.json", "slapos/software/cloudooo/software.cfg.json",
"slapos/software/cloudooo/instance-cloudooo-output-schema.json", "slapos/software/cloudooo/instance-cloudooo-output-schema.json",
"slapos/software/proftpd/instance-output-schema.json",
"slapos/software/proftpd/software.cfg.json",
"slapos/software/proftpd/instance-input-schema.json",
"slapos/software/re6stnet/software.cfg.json", "slapos/software/re6stnet/software.cfg.json",
"slapos/software/re6stnet/instance-re6stnet-output-schema.json", "slapos/software/re6stnet/instance-re6stnet-output-schema.json",
"slapos/software/re6stnet/instance-re6stnet-slave-input-schema.json", "slapos/software/re6stnet/instance-re6stnet-slave-input-schema.json",
......
...@@ -16,45 +16,75 @@ ...@@ -16,45 +16,75 @@
return _str.replace(/~/g, '~0').replace(/\//g, '~1'); return _str.replace(/~/g, '~0').replace(/\//g, '~1');
} }
function convertToRealWorldSchemaPath(g, path) { function getMaxPathInDict(dict, path) {
var base_url, var target,
key, key,
hash,
map = g.props.schema_map,
max_len = 0; max_len = 0;
if (!path) { if (!path) {
return ""; return "";
} }
for (key in map) { for (key in dict) {
if (map.hasOwnProperty(key) && if (dict.hasOwnProperty(key) &&
path.startsWith(key) && path.startsWith(key) &&
key.length > max_len) { key.length > max_len) {
base_url = map[key]; target = key;
max_len = key.length; max_len = key.length;
} }
} }
if (base_url === undefined) { return target;
base_url = ""; }
function checkCircular(g, path, url) {
var required_stack,
prev_field_path = getMaxPathInDict(g.props.schema_required_urls, path);
required_stack = g.props.schema_required_urls[prev_field_path] || [];
if (required_stack.indexOf(url) >= 0) {
throw new Error("Circular reference detected");
}
g.props.schema_required_urls[path] = [url].concat(required_stack);
}
function convertToRealWorldSchemaPath(g, path) {
var url,
hash,
map = g.props.schema_map,
prev_downl_path,
max_len = 0;
if (!path) {
return "";
}
// previous downloaded path
prev_downl_path = getMaxPathInDict(map, path);
if (prev_downl_path === undefined) {
url = "";
max_len = 1; max_len = 1;
} else {
url = map[prev_downl_path];
max_len = prev_downl_path.length;
} }
hash = path.substr(max_len - 1); hash = path.substr(max_len - 1);
if (hash) { if (hash) {
// XXX urlencode for hash // XXX urlencode for hash
if (base_url.indexOf("#") >= 0) { if (url.indexOf("#") >= 0) {
base_url = base_url + hash; url = url + hash;
} else { } else {
base_url = base_url + "#" + path.substr(max_len - 1); url = url + "#" + path.substr(max_len - 1);
} }
} }
return base_url; return url;
} }
function getBaseUrl(g, path) { function convertUrlToAbsolute(g, path, url, base_url_failback) {
var ret = convertToRealWorldSchemaPath(g, path); var // previous downloaded path
if (ret.indexOf("#") === 0) { base_url = convertToRealWorldSchemaPath(g, path),
return; absolute_url;
if (base_url === "" || base_url.indexOf("#") === 0) {
absolute_url = new URL(url, base_url_failback);
} else {
absolute_url = new URL(url, base_url);
} }
return ret; checkCircular(g, path, absolute_url.href);
return absolute_url;
} }
function downloadJSON(url) { function downloadJSON(url) {
...@@ -372,7 +402,14 @@ ...@@ -372,7 +402,14 @@
}); });
}; };
function expandProperties(g, properties, schema_path) { function expandSchemaForField(g, schema, schema_path, for_required) {
return g.markSchemaFieldAsRequired(schema_path, for_required)
.push(function () {
return expandSchema(g, schema, schema_path);
});
}
function expandProperties(g, properties, schema_path, required) {
var ret_obj = {}; var ret_obj = {};
return RSVP.Queue() return RSVP.Queue()
.push(function () { .push(function () {
...@@ -386,8 +423,11 @@ ...@@ -386,8 +423,11 @@
for (property_name in properties) { for (property_name in properties) {
if (properties.hasOwnProperty(property_name)) { if (properties.hasOwnProperty(property_name)) {
arr.push( arr.push(
expandSchema(g, properties[property_name], expandSchemaForField(g,
schema_path + encodeJsonPointer(property_name)) properties[property_name],
schema_path + encodeJsonPointer(property_name),
required.indexOf(property_name) >= 0
)
.push(addPropertyName(property_name)) .push(addPropertyName(property_name))
); );
} }
...@@ -665,7 +705,8 @@ ...@@ -665,7 +705,8 @@
function render_array(gadget, schema, json_document, root, path, schema_path) { function render_array(gadget, schema, json_document, root, path, schema_path) {
var div, var div,
div_input, div_input,
input; input,
minItems = schema.minItems || 0;
div = document.createElement("div"); div = document.createElement("div");
div.setAttribute("class", "subfield"); div.setAttribute("class", "subfield");
div.title = schema.description; div.title = schema.description;
...@@ -687,11 +728,10 @@ ...@@ -687,11 +728,10 @@
// XXX add failback rendering if json_document not array // XXX add failback rendering if json_document not array
// input = render_textarea(schema, default_value, "array"); // input = render_textarea(schema, default_value, "array");
return expandSchema(gadget, schema.items, schema_path + '/items') return expandSchemaForField(gadget, schema.items, schema_path + '/items', minItems !== 0)
.push(function (schema_arr) { .push(function (schema_arr) {
var queue = RSVP.Queue(), var queue = RSVP.Queue(),
i, i,
minItems = schema.minItems || 0,
len = 0; len = 0;
// XXX rewrite loading document for anyOf schema // XXX rewrite loading document for anyOf schema
if (json_document) { if (json_document) {
...@@ -932,7 +972,7 @@ ...@@ -932,7 +972,7 @@
input.placeholder = "name of " + title; input.placeholder = "name of " + title;
div_input.appendChild(input); div_input.appendChild(input);
return expandSchema(g, schema, schema_path) return expandSchemaForField(g, schema, schema_path)
.push(function (schema_arr) { .push(function (schema_arr) {
var queue = RSVP.Queue(), var queue = RSVP.Queue(),
property_name; property_name;
...@@ -998,7 +1038,7 @@ ...@@ -998,7 +1038,7 @@
default_dict = {}; default_dict = {};
} }
return expandProperties(g, json_field.properties, schema_path + '/properties/') return expandProperties(g, json_field.properties, schema_path + '/properties/', required)
.push(function (ret) { .push(function (ret) {
var schema_arr, var schema_arr,
q = RSVP.Queue(), q = RSVP.Queue(),
...@@ -1600,22 +1640,16 @@ ...@@ -1600,22 +1640,16 @@
var g = this, var g = this,
protocol, protocol,
download_url, download_url,
base_url,
hash, hash,
schema_url_map; schema_url_map;
if (!g.props.toplevel) { if (!g.props.toplevel) {
return g.loadJSONSchemaParent(url, path); return g.loadJSONSchemaParent(url, path);
} }
// XXX need use $id // XXX need use $id
base_url = getBaseUrl(g, path);
if (!base_url) {
// allow relative link
base_url = window.location;
}
if (!path) { if (!path) {
path = "/"; path = "/";
} }
url = new URL(url, base_url); url = convertUrlToAbsolute(g, path, url, window.location);
download_url = url.origin + url.pathname; download_url = url.origin + url.pathname;
schema_url_map = { schema_url_map = {
"http://json-schema.org/draft-04/schema": "json-schema/schema4.json", "http://json-schema.org/draft-04/schema": "json-schema/schema4.json",
...@@ -1691,6 +1725,26 @@ ...@@ -1691,6 +1725,26 @@
.allowPublicAcquisition("loadJSONSchemaTop", function (arr) { .allowPublicAcquisition("loadJSONSchemaTop", function (arr) {
return this.loadJSONSchema(arr[0], arr[1]); return this.loadJSONSchema(arr[0], arr[1]);
}) })
.declareMethod("markSchemaFieldAsRequired", function (schema_path, for_required) {
var g = this,
required_stack,
prev_field_path;
if (!g.props.toplevel) {
return g.markSchemaFieldAsRequiredParent(schema_path, for_required);
}
// previous downloaded path
if (for_required) {
prev_field_path = getMaxPathInDict(g.props.schema_required_urls, schema_path);
required_stack = g.props.schema_required_urls[prev_field_path];
} else {
required_stack = [];
}
g.props.schema_required_urls[schema_path] = required_stack;
})
.declareAcquiredMethod("markSchemaFieldAsRequiredParent", "markSchemaFieldAsRequiredTop")
.allowPublicAcquisition("markSchemaFieldAsRequiredTop", function (arr) {
return this.markSchemaFieldAsRequired(arr[0], arr[1]);
})
.declareMethod('render', function (options) { .declareMethod('render', function (options) {
var g = this; var g = this;
g.props.toplevel = true; g.props.toplevel = true;
...@@ -1700,6 +1754,12 @@ ...@@ -1700,6 +1754,12 @@
g.props.schema = {}; g.props.schema = {};
g.props.schema_map = {}; g.props.schema_map = {};
g.props.schema_cache = {}; g.props.schema_cache = {};
// schema_required_urls[path] = [
// stack required urls, on every unrequired field stack begining from []
// "url1",
// "url2"
// ]
g.props.schema_required_urls = {};
// schema_resolve_errors[schema_url] = { // schema_resolve_errors[schema_url] = {
// schemaPath: local_schema_path, // schemaPath: local_schema_path,
// message: error_message can be array containing dom elements // message: error_message can be array containing dom elements
......
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