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

Commit c86543d

Browse files
author
Morten Christensen
committed
Removed isRoot, es5 support + improved docs
1 parent 17c781a commit c86543d

File tree

9 files changed

+39
-31
lines changed

9 files changed

+39
-31
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
v1.0.0 Initial stable release
2+
v2.0.0 ES5 retargeting.
3+
Removed isRoot.

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# json-schema-js-gui-model
2-
Handy framework-agnostic gui model and associated translator that can be used as a basis when constructing
2+
3+
Use this library when you need to construct many different custom UI forms that shares common
4+
characteristics, want to be in charge of how exactly your UI form should present itself, want to
5+
pick your own web framework for the UI, and want to use a json schema to drive the UI forms
6+
but finds json schema complex to process and lacking of UI information.
7+
8+
This library contains a handy framework-agnostic gui model and associated translator that can be used as a basis when constructing
39
dynamic javascript UI forms (in any web framework) from json-schemas. For details, refer to the declared gui
410
model [here](src/lib/gui-model.ts) and the translator declared at the bottom of this [file](src/lib/gui-model.mapper.ts).
511

@@ -8,7 +14,7 @@ dynamically using the gui model provided by this library. Such UI code will be
814
different depending on the exact web framework used and this out of scope of this more
915
fundamental and general project.
1016

11-
This library is on purpose keept small with no runtime-dependencies. It can be used from both nodejs v6+
17+
This library is on purpose keept small with few runtime-dependencies. It can be used from both nodejs v6+
1218
and with a modern es6 capable browser.
1319

1420
## Getting started
@@ -121,7 +127,6 @@ in realtime at each keypress if necessary.
121127
"dataObjectPath": "",
122128
"label": "",
123129
"tooltip": "",
124-
"isRoot": true,
125130
"required": true,
126131
"elements": [
127132
{
@@ -131,7 +136,6 @@ in realtime at each keypress if necessary.
131136
"dataObjectPath": "authentication",
132137
"label": "Authentication",
133138
"tooltip": "an authentication description here",
134-
"isRoot": false,
135139
"required": false,
136140
"elements": [
137141
{
@@ -191,7 +195,6 @@ in realtime at each keypress if necessary.
191195
"dataObjectPath": "server",
192196
"label": "Server",
193197
"tooltip": "",
194-
"isRoot": false,
195198
"required": false,
196199
"elements": [
197200
{
@@ -248,7 +251,8 @@ in realtime at each keypress if necessary.
248251

249252
## Status and future plans
250253

251-
The current version appears to work fine in my own project but has not been tested beyond that.
254+
The current version appears to work fine in my own project but has not been tested beyond that. Some advanced
255+
schema constructs like links are not yet supported.
252256

253257
I am considering to support some kind of json schema ui extensions in order to construct a even more detailed gui model.
254258

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-schema-js-gui-model",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"description": "Handy gui model and associated translator that is useful when constructing javascript UI forms from json-schemas",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -20,6 +20,7 @@
2020
"files": [
2121
"dist",
2222
"LICENSE",
23+
"CHANGELOG.md",
2324
"README.md"
2425
],
2526
"repository": {
@@ -41,6 +42,7 @@
4142
"homepage": "https://github.com/mmc41/json-schema-js-gui-model#readme",
4243
"devDependencies": {
4344
"@types/chai": "3.4.34",
45+
"@types/core-js": "0.9.34",
4446
"@types/mocha": "2.2.32",
4547
"@types/node": "6.0.46",
4648
"chai": "3.5.0",
@@ -61,5 +63,8 @@
6163
"ghooks": {
6264
"pre-commit": "npm run test"
6365
}
66+
},
67+
"dependencies": {
68+
"core-js": "2.4.1"
6469
}
6570
}

src/lib/constants.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export let EMPTY_GUI_MODEL: GuiModel = Object.freeze<GuiModel>({
1010
label: '',
1111
tooltip: '',
1212
dataObjectPath: '',
13-
isRoot: true,
1413
required: true,
1514
elements: [],
1615
errors: []
@@ -23,7 +22,6 @@ export let EMPTY_GUI_MODEL_GROUP: Group = Object.freeze<Group>({
2322
label: '',
2423
tooltip: '',
2524
dataObjectPath: '',
26-
isRoot: false,
2725
required: true,
2826
elements: []
2927
});

src/lib/gui-model.mapper.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
"use strict";
2+
3+
import 'core-js/library';
14
import { JsonSchema } from '../dependencies/json-schema';
25
import { isString, isNumber, isBoolean, isIntegerNumber, isArray, isObject } from './type-utils';
36

@@ -225,7 +228,6 @@ function createGroupProperty(key: string, objectPath: string, label: string, too
225228
dataObjectPath: objectPath,
226229
label: label,
227230
tooltip: tooltip,
228-
isRoot: false,
229231
required: required,
230232
elements: Object.freeze(elements)
231233
});
@@ -282,7 +284,7 @@ export class GuiModelMapper {
282284
* Converts a json schema into an immutable gui model. In case of errors, the associated error array will be non-empty and the
283285
* resulting gui model may be invalid.
284286
*/
285-
mapToGuiModel(schema: JsonSchema): GuiModel {
287+
public mapToGuiModel(schema: JsonSchema): GuiModel {
286288
// Setup mutable error reporting array that will have values added during procesing in case of errors.
287289
let errors: TranslationError[] = [];
288290

@@ -304,7 +306,6 @@ export class GuiModelMapper {
304306
dataObjectPath: '',
305307
label: '',
306308
tooltip: '',
307-
isRoot: true,
308309
required: true,
309310
elements: Object.freeze(result),
310311
errors: Object.freeze(errors)

src/lib/gui-model.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ export interface TypedField<T> extends FieldBase {
8383
export interface Group extends GuiElementBase {
8484
readonly kind: 'group';
8585
readonly elements: GuiElement[];
86-
readonly isRoot: boolean;
8786
}
8887

8988
export interface TranslationError {

src/test/gui-models.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ export const simple_gui_model1: GuiModel = Object.freeze<GuiModel>(
1515
{ kind: 'field', name: 'username', controlType: 'input', label: 'username', tooltip: '', dataObjectPath: 'username', defaultValue: '', required: true, type: 'string', subType: 'none' },
1616
{ kind: 'field', name: 'password', controlType: 'input', label: 'password', tooltip: '', dataObjectPath: 'password', defaultValue: '', required: true, type: 'string', subType: 'none' }
1717
],
18-
errors: [],
19-
isRoot: true
18+
errors: []
2019
});
2120

2221
export const simple_gui_model2: GuiModel = Object.freeze<GuiModel>({
@@ -31,8 +30,7 @@ export const simple_gui_model2: GuiModel = Object.freeze<GuiModel>({
3130
{ kind: 'field', name: 'username', controlType: 'input', label: 'user name', tooltip: 'a username description here', dataObjectPath: 'username', defaultValue: 'username default', required: true, type: 'string', subType: 'none' },
3231
{ kind: 'field', name: 'password', controlType: 'input', label: 'password', tooltip: 'a password description here', dataObjectPath: 'password', defaultValue: 'password default', required: true, type: 'string', subType: 'none' }
3332
],
34-
errors: [],
35-
isRoot: true
33+
errors: []
3634
});
3735

3836
export const test_different_elements_gui_model1: GuiModel = Object.freeze<GuiModel>({
@@ -53,8 +51,7 @@ export const test_different_elements_gui_model1: GuiModel = Object.freeze<GuiMod
5351
{ kind: 'field', name: 'rank', controlType: 'dropdown', label: 'Rank', tooltip: 'a rank description here', dataObjectPath: 'rank', defaultValue: 3.14, values: [ 3.14, 0.33, 9.99], required: false, type: 'number', subType: 'none'},
5452
{ kind: 'field', name: 'registered', controlType: 'yesno', label: 'Registered', tooltip: 'a registered description here', dataObjectPath: 'registered', defaultValue: false, required: false, type: 'boolean', subType: 'none' }
5553
],
56-
errors: [],
57-
isRoot: true
54+
errors: []
5855
});
5956

6057
export const test_groups_gui_model1: GuiModel = Object.freeze<GuiModel>({
@@ -67,12 +64,12 @@ export const test_groups_gui_model1: GuiModel = Object.freeze<GuiModel>({
6764
required: true,
6865
elements: [
6966
{ kind: 'field', name: 'simple1', controlType: 'input', label: 'A simple field level 1', tooltip: '', dataObjectPath: 'simple1', defaultValue: '', required: false, type: 'string', subType: 'none' },
70-
{ kind: 'group', name: 'group1', controlType: 'group', label: 'Group at level 1', tooltip: '', dataObjectPath: 'group1', isRoot: false, required: false,
67+
{ kind: 'group', name: 'group1', controlType: 'group', label: 'Group at level 1', tooltip: '', dataObjectPath: 'group1', required: false,
7168
elements: [
7269
{ kind: 'field', name: 'simple2', controlType: 'input', label: 'A simple field level 2', tooltip: '', dataObjectPath: 'group1.simple2', defaultValue: '', required: false, type: 'string', subType: 'none' },
73-
{ kind: 'group', name: 'group2', controlType: 'group', label: 'Group at level 2', tooltip: '', dataObjectPath: 'group1.group2', isRoot: false, required: false,
70+
{ kind: 'group', name: 'group2', controlType: 'group', label: 'Group at level 2', tooltip: '', dataObjectPath: 'group1.group2', required: false,
7471
elements: [
75-
{ kind: 'group', name: 'group3', controlType: 'group', label: 'Group at level 3', tooltip: '', dataObjectPath: 'group1.group2.group3', isRoot: false, required: false,
72+
{ kind: 'group', name: 'group3', controlType: 'group', label: 'Group at level 3', tooltip: '', dataObjectPath: 'group1.group2.group3', required: false,
7673
elements: [
7774
{ kind: 'field', name: 'simple4', controlType: 'input', label: 'A simple field level 4', tooltip: '', dataObjectPath: 'group1.group2.group3.simple4', defaultValue: '', required: false, type: 'string', subType: 'none' }
7875
]
@@ -83,8 +80,7 @@ export const test_groups_gui_model1: GuiModel = Object.freeze<GuiModel>({
8380
]
8481
}
8582
],
86-
errors: [],
87-
isRoot: true
83+
errors: []
8884
});
8985

9086
export const complex_gui_model1: GuiModel = Object.freeze<GuiModel>({
@@ -96,31 +92,30 @@ export const complex_gui_model1: GuiModel = Object.freeze<GuiModel>({
9692
dataObjectPath: '',
9793
required: true,
9894
elements: [
99-
{ kind: 'group', name: 'authentication', controlType: 'group', label: 'Authentication', tooltip: 'an authentication description here', dataObjectPath: 'authentication', isRoot: false, required: true,
95+
{ kind: 'group', name: 'authentication', controlType: 'group', label: 'Authentication', tooltip: 'an authentication description here', dataObjectPath: 'authentication', required: true,
10096
elements: [ { kind: 'field', name: 'user', controlType: 'input', label: 'User', tooltip: 'a username', dataObjectPath: 'authentication.user', defaultValue: '', required: true, type: 'string', subType: 'none' },
10197
{ kind: 'field', name: 'password', controlType: 'input', label: 'Password', tooltip: 'a password', dataObjectPath: 'authentication.password', defaultValue: '', required: true, type: 'string', subType: 'none' },
10298
{ kind: 'field', name: 'scheme', controlType: 'input', label: 'scheme', tooltip: '', dataObjectPath: 'authentication.scheme', defaultValue: 'basic', required: true, type: 'string', subType: 'none' },
10399
{ kind: 'field', name: 'preemptive', controlType: 'yesno', label: 'preemptive', tooltip: '', dataObjectPath: 'authentication.preemptive', defaultValue: true, required: true, type: 'boolean', subType: 'none'}
104100
]
105101
},
106-
{ kind: 'group', name: 'server', controlType: 'group', label: 'Server', tooltip: '', dataObjectPath: 'server', isRoot: false, required: true,
102+
{ kind: 'group', name: 'server', controlType: 'group', label: 'Server', tooltip: '', dataObjectPath: 'server', required: true,
107103
elements: [ { kind: 'field', name: 'host', controlType: 'input', label: 'host', tooltip: '', dataObjectPath: 'server.host', defaultValue: '', required: true, type: 'string', subType: 'none' },
108104
{ kind: 'field', name: 'port', controlType: 'input', label: 'port', tooltip: '', dataObjectPath: 'server.port', defaultValue: 80, required: true, type: 'integer', subType: 'none' },
109105
{ kind: 'field', name: 'protocol', controlType: 'dropdown', label: 'protocol', tooltip: '', dataObjectPath: 'server.protocol', defaultValue: 'http', values: ['http', 'ftp'], required: true, type: 'string', subType: 'none' }
110106
]
111107
},
112-
{ kind: 'group', name: 'testing', controlType: 'group', label: 'Testing', tooltip: '', dataObjectPath: 'testing', isRoot: false, required: false,
108+
{ kind: 'group', name: 'testing', controlType: 'group', label: 'Testing', tooltip: '', dataObjectPath: 'testing', required: false,
113109
elements: [ { kind: 'field', name: 'beforeOperationDelay', controlType: 'input', label: 'beforeOperationDelay', tooltip: '', dataObjectPath: 'testing.beforeOperationDelay', defaultValue: 1, required: true, type: 'integer', subType: 'none' },
114110
{ kind: 'field', name: 'afterOperationDelay', controlType: 'input', label: 'afterOperationDelay', tooltip: '', dataObjectPath: 'testing.afterOperationDelay', defaultValue: 2, required: false, type: 'integer', subType: 'none' }
115111
]
116112
}
117113
],
118-
errors: [],
119-
isRoot: true
114+
errors: []
120115
});
121116

122117
export const invalid_gui_model1: GuiModel = {
123-
kind : 'group', name: '', controlType: 'group', dataObjectPath: '', label: '', tooltip: '', isRoot: true, required: true, elements: [],
118+
kind : 'group', name: '', controlType: 'group', dataObjectPath: '', label: '', tooltip: '', required: true, elements: [],
124119
'errors': [
125120
{ schemaPath: 'properties.username', errorText: 'Unsupported element type string' },
126121
{ schemaPath: 'properties.password', errorText: 'Type elements must be strings (not boolean) ' },

src/test/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
/* tslint:disable:max-line-length */
2+
"use strict";
3+
4+
import 'core-js/library';
25

36
import { JsonSchema } from '../dependencies/json-schema';
47
import { GuiModelMapper } from '../lib/gui-model.mapper';

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"compilerOptions": {
44
"outDir": "dist",
55
"rootDir": "src",
6-
"target": "es6",
6+
"target": "es5",
77
"module": "commonjs",
88
"moduleResolution": "node",
99
"declaration": true,

0 commit comments

Comments
 (0)