Skip to content
This repository was archived by the owner on Mar 7, 2024. It is now read-only.

Commit e9be986

Browse files
author
Morten Christensen
committed
Initial commit
1 parent 60e1062 commit e9be986

17 files changed

+1593
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ build/Release
2929
# Dependency directories
3030
node_modules
3131
jspm_packages
32+
dist
3233

3334
# Optional npm cache directory
3435
.npm

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2016 Morten Christensen
3+
Copyright (c) 2016 Morten M. Christensen (mmc41)
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,204 @@
11
# json-schema-js-gui-model
22
Handy gui model and associated translator that can be used to construct javascript UI forms from json-schemas
3+
4+
WARNING: Work in progress.
5+
6+
Schemas can be translated using the exported GuiModelMapper class or by using the command line
7+
client linked by npm: ```mapToGuiModel sourceSchema destFile```
8+
9+
**Example input schema:**
10+
```
11+
{
12+
"$schema": "http://json-schema.org/draft-04/schema#",
13+
"type": "object",
14+
"properties": {
15+
"authentication": {
16+
"type": "object",
17+
"title": "Authentication",
18+
"description": "an authentication description here",
19+
"properties": {
20+
"user": {
21+
"type": "string",
22+
"minLength": 1,
23+
"default": "",
24+
"title" : "User",
25+
"description": "a username"
26+
},
27+
"password": {
28+
"type": "string",
29+
"minLength": 1,
30+
"default": "",
31+
"title" : "Password",
32+
"description": "a password"
33+
},
34+
"scheme": {
35+
"type": "string",
36+
"default": "basic"
37+
},
38+
"preemptive": {
39+
"type": "boolean",
40+
"default": true
41+
}
42+
},
43+
"required": [
44+
"user",
45+
"password"
46+
]
47+
},
48+
"server": {
49+
"type": "object",
50+
"title": "Server",
51+
"properties": {
52+
"host": {
53+
"type": "string",
54+
"default": ""
55+
},
56+
"port": {
57+
"type": "integer",
58+
"multipleOf": 1,
59+
"maximum": 65535,
60+
"minimum": 0,
61+
"exclusiveMaximum": false,
62+
"exclusiveMinimum": false,
63+
"default": 80
64+
},
65+
"protocol": {
66+
"type": "string",
67+
"default": "http",
68+
"enum" : ["http", "ftp"]
69+
}
70+
}
71+
}
72+
}
73+
}
74+
```
75+
76+
**Example gui model output:**
77+
```
78+
{
79+
"kind": "group",
80+
"name": "",
81+
"controlType": "group",
82+
"settingsObjectPath": "",
83+
"label": "",
84+
"tooltip": "",
85+
"isRoot": true,
86+
"required": true,
87+
"elements": [
88+
{
89+
"kind": "group",
90+
"name": "authentication",
91+
"controlType": "group",
92+
"settingsObjectPath": "authentication",
93+
"label": "Authentication",
94+
"tooltip": "an authentication description here",
95+
"isRoot": false,
96+
"required": false,
97+
"elements": [
98+
{
99+
"kind": "field",
100+
"name": "user",
101+
"controlType": "input",
102+
"label": "User",
103+
"tooltip": "a username",
104+
"settingsObjectPath": "authentication.user",
105+
"defaultValue": "",
106+
"required": true,
107+
"type": "string",
108+
"subType": "none"
109+
},
110+
{
111+
"kind": "field",
112+
"name": "password",
113+
"controlType": "input",
114+
"label": "Password",
115+
"tooltip": "a password",
116+
"settingsObjectPath": "authentication.password",
117+
"defaultValue": "",
118+
"required": true,
119+
"type": "string",
120+
"subType": "none"
121+
},
122+
{
123+
"kind": "field",
124+
"name": "scheme",
125+
"controlType": "input",
126+
"label": "scheme",
127+
"tooltip": "",
128+
"settingsObjectPath": "authentication.scheme",
129+
"defaultValue": "basic",
130+
"required": false,
131+
"type": "string",
132+
"subType": "none"
133+
},
134+
{
135+
"kind": "field",
136+
"name": "preemptive",
137+
"controlType": "yesno",
138+
"label": "preemptive",
139+
"tooltip": "",
140+
"settingsObjectPath": "authentication.preemptive",
141+
"defaultValue": true,
142+
"required": false,
143+
"type": "boolean",
144+
"subType": "none"
145+
}
146+
]
147+
},
148+
{
149+
"kind": "group",
150+
"name": "server",
151+
"controlType": "group",
152+
"settingsObjectPath": "server",
153+
"label": "Server",
154+
"tooltip": "",
155+
"isRoot": false,
156+
"required": false,
157+
"elements": [
158+
{
159+
"kind": "field",
160+
"name": "host",
161+
"controlType": "input",
162+
"label": "host",
163+
"tooltip": "",
164+
"settingsObjectPath": "server.host",
165+
"defaultValue": "",
166+
"required": false,
167+
"type": "string",
168+
"subType": "none"
169+
},
170+
{
171+
"kind": "field",
172+
"name": "port",
173+
"controlType": "input",
174+
"label": "port",
175+
"tooltip": "",
176+
"settingsObjectPath": "server.port",
177+
"defaultValue": 80,
178+
"required": false,
179+
"type": "integer",
180+
"subType": "none"
181+
},
182+
{
183+
"kind": "field",
184+
"name": "protocol",
185+
"controlType": "dropdown",
186+
"label": "protocol",
187+
"tooltip": "",
188+
"settingsObjectPath": "server.protocol",
189+
"defaultValue": "http",
190+
"values": [
191+
"http",
192+
"ftp"
193+
],
194+
"required": false,
195+
"type": "string",
196+
"subType": "none"
197+
}
198+
]
199+
}
200+
],
201+
"errors": []
202+
}
203+
```
204+

package.json

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"name": "json-schema-js-gui-model",
3+
"version": "0.1.0",
4+
"description": "Handy gui model and associated translator that can be used to construct javascript UI forms from json-schemas",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"scripts": {
8+
"watch": "tsc && npm-run-all --continue-on-error --parallel build:watch test:watch",
9+
"test": "tsc && mocha dist/test/index.js",
10+
"test:watch": "mocha --watch dist/test/index.js",
11+
"build": "tsc",
12+
"build:watch": "tsc -w",
13+
"clean": "rimraf dist",
14+
"lint": "tslint src/**/*.ts"
15+
},
16+
"bin": {
17+
"mapToGuiModel": "/dist/cli/index.js"
18+
},
19+
"files": [
20+
"dist",
21+
"LICENSE",
22+
"README.md"
23+
],
24+
"repository": {
25+
"type": "git",
26+
"url": "git+https://github.com/mmc41/json-schema-js-gui-model.git"
27+
},
28+
"keywords": [
29+
"json-schema",
30+
"javascript",
31+
"typescript",
32+
"gui",
33+
"model"
34+
],
35+
"author": "Morten M. Christensen (mmc41)",
36+
"license": "MIT",
37+
"bugs": {
38+
"url": "https://github.com/mmc41/json-schema-js-gui-model/issues"
39+
},
40+
"homepage": "https://github.com/mmc41/json-schema-js-gui-model#readme",
41+
"devDependencies": {
42+
"@types/chai": "3.4.34",
43+
"@types/mocha": "2.2.32",
44+
"@types/node": "^6.0.46",
45+
"chai": "3.5.0",
46+
"mocha": "3.1.2",
47+
"nodemon": "1.11.0",
48+
"npm-run-all": "3.1.1",
49+
"rimraf": "2.5.4",
50+
"ts-npm-lint": "^0.1.0",
51+
"tslint": "3.15.1",
52+
"typescript": "2.0.7"
53+
},
54+
"engines": {
55+
"node": ">=6.0.0",
56+
"npm": "~3.0.0"
57+
}
58+
}

src/cli/index.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#! /usr/bin/env node
2+
3+
import { argv, stdin, stdout, exit } from 'process';
4+
import { readFileSync, writeFileSync, existsSync } from 'fs';
5+
6+
import { JsonSchema } from '../dependencies/json-schema';
7+
import { GuiModelMapper } from '../lib/gui-model.mapper';
8+
import { GuiModel } from '../lib/gui-model';
9+
10+
/**
11+
* Name of bin executable specified in package.json:
12+
*/
13+
const npmCmd = 'mapToGuiModel';
14+
15+
/**
16+
* Description of to use the npm executable cli command:
17+
*/
18+
const usageString = 'Usage: ' + npmCmd + ' sourcePath destPath';
19+
20+
/**
21+
* Help that abouts with error output
22+
*/
23+
function failure(msg) {
24+
console.error(msg);
25+
exit(-1);
26+
}
27+
28+
// Validate cmd arguments:
29+
let userArgs = argv.slice(2);
30+
if (userArgs.length !== 2) {
31+
failure(usageString);
32+
}
33+
34+
let sourcePath = userArgs[0];
35+
let destPath = userArgs[1];
36+
37+
// Read input:
38+
let source: string;
39+
40+
if (!existsSync(sourcePath)) {
41+
failure('Error. Could not locate source file \"' + sourcePath + '\".');
42+
}
43+
44+
try {
45+
source = readFileSync(sourcePath, {
46+
encoding: 'utf8',
47+
flag: 'r'
48+
});
49+
} catch (e) {
50+
failure('Error reading file \"' + sourcePath + '\"');
51+
}
52+
53+
// Convert input:
54+
let sourceJson: any;
55+
try {
56+
sourceJson = JSON.parse(source);
57+
} catch (e) {
58+
failure('Error. File \"' + sourcePath + '\" is not a valid json file');
59+
}
60+
61+
// Generate output:
62+
let mapper: GuiModelMapper = new GuiModelMapper();
63+
64+
let result;
65+
try {
66+
let resultObj = mapper.mapToGuiModel(sourceJson as JsonSchema);
67+
result = JSON.stringify(resultObj, null, 2);
68+
} catch (e) {
69+
failure('Error. Unexpected internal error while mapping \"' + sourcePath + '\".');
70+
}
71+
72+
// Check if file exists already?:
73+
if (existsSync(destPath)) {
74+
failure('Error. Output file \"' + destPath + '\" already exists.');
75+
}
76+
77+
// Write output:
78+
try {
79+
writeFileSync(destPath, result, {
80+
encoding: 'utf8',
81+
mode: 0o666,
82+
flag: 'wx' // Don't allow overwriting files for safety.
83+
});
84+
} catch (e) {
85+
failure('Error. Could not write new file \"' + destPath + '\".');
86+
}
87+
88+
// Success msg:
89+
console.log('Successfully mapped json schema in \"' + sourcePath + '\" to gui model and stored result in \"' + destPath + '\"');
90+
exit(0);
91+

0 commit comments

Comments
 (0)