Skip to content

Commit dc98dc6

Browse files
Merge pull request #34 from ogavb/dynamicOptionsAlignment4
Dynamic options alignment4
2 parents 40becbf + 59ae268 commit dc98dc6

File tree

4 files changed

+342
-1
lines changed

4 files changed

+342
-1
lines changed

app.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var forceSSL = require('express-force-ssl');
66
var webSocket = require('websocket').w3cwebsocket;
77
var fs = require('fs');
88
var pug = require('pug');
9+
var jpointer = require('json-pointer');
910
const compression = require('compression');
1011

1112
// System config loading
@@ -19,6 +20,10 @@ var maxAge = properties.max_age;
1920
// Services configuration file
2021
var servicesConfig = require('./config/services.json');
2122

23+
// This function validates the JSON schemas
24+
var Ajv = require('ajv');
25+
validateJsonSchemas();
26+
2227
var pckg = require('./package.json');
2328

2429
var app = express();
@@ -146,3 +151,63 @@ function getExcecutorURL(data) {
146151
}
147152
}
148153
}
154+
155+
function validateJsonSchemas() {
156+
// Validate JSON file with the relative scheme
157+
var servicesValidation = validateSchema('./config/services.json', './config/services-schema.json');
158+
var appConfigValidation = validateSchema('./config/app-config.json', './config/app-config-schema.json');
159+
160+
if(servicesValidation.criticalError || appConfigValidation.criticalError) {
161+
console.log('Fatal error: configuration files are not setted up properly!');
162+
process.exit(1);
163+
}
164+
}
165+
166+
function validateSchema(jsonPath, schemaPath) {
167+
// Loading files
168+
var json = require(jsonPath);
169+
var schema = require(schemaPath);
170+
171+
// Config
172+
var ajv = new Ajv({
173+
allErrors: true,
174+
jsonPointers: true
175+
});
176+
177+
// Compiling the schema
178+
var compiledSchema = ajv.compile(schema);
179+
var validated = false;
180+
var printError = true;
181+
var response = { };
182+
183+
while(!validated) {
184+
// Validating
185+
var validatedJson = compiledSchema(json);
186+
// If some there is some error, the nearest parent object in the file, containing this error, is deleted
187+
if (!validatedJson) {
188+
// Prints the errors only the first time
189+
if(printError) {
190+
console.log(compiledSchema.errors);
191+
printError = false;
192+
}
193+
194+
for(var index in compiledSchema.errors) {
195+
var path = compiledSchema.errors[index].dataPath;
196+
if(path === '') {
197+
// 'This' case happen when there is a problem in to the root of the json file (eg. when the file is empty)
198+
console.log('Fatal error: ' + jsonPath + ' is not setted up properly!');
199+
response.criticalError = true;
200+
validated = true;
201+
} else {
202+
jpointer.remove(json, path);
203+
}
204+
}
205+
}
206+
else {
207+
console.log('Validated: ' + jsonPath);
208+
validated = true;
209+
}
210+
}
211+
212+
return response;
213+
}

config/app-config-schema.json

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "app-config-schema.json",
4+
"self": {
5+
"vendor": "unical",
6+
"name": "app-config",
7+
"format": "jsonschema",
8+
"version": "1-0-0"
9+
},
10+
"type": "object",
11+
"properties": {
12+
"max_age": {
13+
"title": "HSTS max age",
14+
"description": "This property specifies HTTP Strict Transport Security max age.",
15+
"type": "number",
16+
"minimum": 0
17+
},
18+
"port": {
19+
"title": "Ports configuration object",
20+
"description": "This object contains information about ports to be used for the various supported protocols.",
21+
"type": "object",
22+
"properties": {
23+
"http": {
24+
"title": "HTTP port",
25+
"description": "This property specifies the port to use for HTTP connections.",
26+
"type": "number",
27+
"minimum": 0,
28+
"maximum": 65535
29+
},
30+
"https": {
31+
"title": "HTTPS port",
32+
"description": "This property specifies the port to use for HTTPS connections.",
33+
"type": "number",
34+
"minimum": 0,
35+
"maximum": 65535
36+
}
37+
},
38+
"required": [
39+
"http"
40+
],
41+
"additionalProperties": false
42+
},
43+
"path": {
44+
"title": "Paths configuration object",
45+
"description": "This object contains information about paths to be used for the various configurations.",
46+
"type": "object",
47+
"properties": {
48+
"key": {
49+
"title": "HTTPS key",
50+
"description": "This property specifies the path for the HTTPS key.",
51+
"type": "string"
52+
},
53+
"cert": {
54+
"title": "HTTPS certificate",
55+
"description": "This property specifies the path for the HTTPS certificate.",
56+
"type": "string"
57+
}
58+
},
59+
"required": [
60+
"key",
61+
"cert"
62+
],
63+
"additionalProperties": false
64+
}
65+
},
66+
"required": [
67+
"port",
68+
"max_age"
69+
],
70+
"additionalProperties": false
71+
}

config/services-schema.json

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "services-schema.json",
4+
"self": {
5+
"vendor": "unical",
6+
"name": "services",
7+
"format": "jsonschema",
8+
"version": "1-0-0"
9+
},
10+
"properties": {
11+
"languages": {
12+
"title": "Supported languages.",
13+
"description": "This property indicates all the supported languages by the services avalable on the LoIDE Web Application.",
14+
"type": "array",
15+
"minItems": 1,
16+
"items": {
17+
"$ref": "#/definitions/language"
18+
}
19+
}
20+
},
21+
"required": [
22+
"languages"
23+
],
24+
"additionalProperties": false,
25+
"definitions": {
26+
"language": {
27+
"type": "object",
28+
"properties": {
29+
"name": {
30+
"title": "Language name.",
31+
"description": "This property indicates the language name.",
32+
"type": "string"
33+
},
34+
"value": {
35+
"title": "Language value.",
36+
"description": "This property indicates the language value used in communication with other services.",
37+
"type": "string"
38+
},
39+
"syntax-highlighter": {
40+
"title": "Syntax-Highlighter path.",
41+
"description": "This property indicates the syntax highlighter path corresponding to this language.",
42+
"type": "object",
43+
"properties": {
44+
"name": {
45+
"title": "Syntax-Highlighter name.",
46+
"description": "This property indicates the syntax-highlighter name.",
47+
"type": "string"
48+
},
49+
"description": {
50+
"title": "Syntax-Highlighter description.",
51+
"description": "This property indicates the syntax-highlighter description.",
52+
"type": "string"
53+
},
54+
"path": {
55+
"title": "Syntax-Highlighter path.",
56+
"description": "This property indicates the syntax-highlighter file path.",
57+
"type": "string"
58+
}
59+
},
60+
"required": [
61+
"name",
62+
"path"
63+
],
64+
"additionalProperties": false
65+
},
66+
"solvers": {
67+
"title": "Supporting solvers.",
68+
"description": "This property indicates all supporting solvers for this language.",
69+
"type": "array",
70+
"minItems": 1,
71+
"items": {
72+
"$ref": "#/definitions/solver"
73+
}
74+
}
75+
},
76+
"required": [
77+
"name",
78+
"value",
79+
"solvers"
80+
],
81+
"additionalProperties": false
82+
},
83+
"solver": {
84+
"type": "object",
85+
"properties": {
86+
"name": {
87+
"title": "Solver name.",
88+
"description": "This property indicates the solver name.",
89+
"type": "string"
90+
},
91+
"value": {
92+
"title": "Solver value.",
93+
"description": "This property indicates the solver value used in communication with other services.",
94+
"type": "string"
95+
},
96+
"executors": {
97+
"title": "Supporting executors.",
98+
"description": "This property indicates all supporting executors for this solver.",
99+
"type": "array",
100+
"minItems": 1,
101+
"items": {
102+
"$ref": "#/definitions/executor"
103+
}
104+
},
105+
"options": {
106+
"title": "Solver option",
107+
"description": "This property indicates the options supported by the solver.",
108+
"type": "array",
109+
"minItems": 1,
110+
"items": {
111+
"type": "object",
112+
"properties": {
113+
"name": {
114+
"title": "Option name.",
115+
"description": "This property indicates the option name.",
116+
"type": "string"
117+
},
118+
"value": {
119+
"title": "Option value.",
120+
"description": "This property indicates the command line argument passed to the solver.",
121+
"type": "string"
122+
},
123+
"word_argument": {
124+
"title": "Word argument.",
125+
"description": "This property indicates if this type of argument requires the second argument or it's just a word argument (this is just a flag).",
126+
"type": "boolean"
127+
},
128+
"description": {
129+
"title": "Option description.",
130+
"description": "This property contains the description of the option.",
131+
"type": "string"
132+
}
133+
},
134+
"required": [
135+
"name",
136+
"value",
137+
"word_argument",
138+
"description"
139+
],
140+
"additionalProperties": false
141+
}
142+
}
143+
},
144+
"required": [
145+
"name",
146+
"value",
147+
"executors",
148+
"options"
149+
],
150+
"additionalProperties": false
151+
},
152+
"executor": {
153+
"type": "object",
154+
"properties": {
155+
"protocol": {
156+
"title": "Protocol name.",
157+
"description": "This property indicates the protocol name to use for a connection with this Executor.",
158+
"enum": [ "ws", "http" ]
159+
},
160+
"url": {
161+
"title": "Executor URL.",
162+
"description": "This property indicates the executor URL to connect with it.",
163+
"type": "string",
164+
"oneOf": [
165+
{ "format": "hostname" },
166+
{ "format": "ipv4" },
167+
{ "format": "ipv6" }
168+
]
169+
},
170+
"name": {
171+
"title": "Executor name.",
172+
"description": "This property indicates the executor name.",
173+
"type": "string"
174+
},
175+
"value": {
176+
"title": "Executor value.",
177+
"description": "This property indicates the option value.",
178+
"type": "string"
179+
},
180+
"path": {
181+
"title": "Executor path.",
182+
"description": "This property indicates the executor path relative to its URL.",
183+
"type": "string",
184+
"_comment": "Add the pattern to match with the 'path'."
185+
},
186+
"port": {
187+
"title": "Connection port number.",
188+
"description": "This property indicates the port number open on this executor for the incoming connections.",
189+
"type": "number",
190+
"minimum": 0,
191+
"maximum": 65535
192+
}
193+
},
194+
"required": [
195+
"protocol",
196+
"url",
197+
"path",
198+
"port"
199+
],
200+
"additionalProperties": false
201+
}
202+
}
203+
}

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "LoIDE",
3-
"version": "2.6.1",
3+
"version": "2.7.0",
44
"description": "Web-based IDE for Logic Programming",
55
"main": "app.js",
66
"scripts": {
@@ -38,9 +38,11 @@
3838
"url": "https://github.com/DeMaCS-UNICAL/LoIDE/issues"
3939
},
4040
"dependencies": {
41+
"ajv": "^6.12.2",
4142
"express": "^4.17.1",
4243
"express-force-ssl": "^0.3.2",
4344
"helmet": "^3.21.1",
45+
"json-pointer": "^0.6.0",
4446
"pug": "^2.0.4",
4547
"socket.io": "^2.3.0",
4648
"websocket": "^1.0.30"

0 commit comments

Comments
 (0)