adapt-authoring-jsonschema 0.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,74 +1,74 @@
1
- export default class SchemasReference {
2
- constructor(app, config, dir, utils) {
3
- this.app = app;
4
- this.utils = utils;
5
- }
6
- async run() {
7
- this.schemas = await this.loadSchemas();
8
- this.manualFile = 'schemas-reference.md';
9
- this.contents = Object.keys(this.schemas);
10
- this.replace = { 'LIST': this.generateList() };
11
- }
12
- async loadSchemas() {
13
- const schema = await this.app.waitForModule('jsonschema');
14
- return Object.keys(schema.schemas)
15
- .sort((a, b) => a.localeCompare(b))
16
- .reduce((schemas, s) => Object.assign(schemas, { [s]: schema.schemas[s].raw }), {});
17
- }
18
- generateList() {
19
- return Object.entries(this.schemas).reduce((output, [dep, schema]) => {
20
- return `${output}<h3 id="${dep.toLowerCase()}" class="dep">${dep}</h3>
21
-
22
- ${this.schemaToMd(schema)}
23
-
24
- `;
25
- }, '');
26
- }
27
- schemaToMd(schema) {
28
- let output = '';
29
- if(schema.description) {
30
- output += `<div class="desc">${schema.description}</div>\n\n`;
31
- }
32
- let s;
33
- if(schema.properties) {
34
- s = schema;
35
- } else if(schema.$patch) {
36
- s = schema.$patch.with;
37
- const ref = schema.$patch.source.$ref;
38
- output += `<div class="extension">Patches <a href="#/schemas-reference?id=${ref}">${ref}</a></div>`;
39
- } else if(schema.$merge) {
40
- s = schema.$merge.with;
41
- const ref = schema.$merge?.source?.$ref;
42
- output += `<div class="extension">${ref ? `Merges with <a href="#/schemas-reference?id=${ref}">${ref}</a>` : 'This is a merge schema'}</div>\n\n`;
43
- }
44
- const { properties, required } = s;
45
-
46
- if(!properties) {
47
- return;
48
- }
49
- if(required) {
50
- output += `<div class="required">Fields in bold are required.</div>\n\n`;
51
- }
52
- const table = `<tr><th>Attribute</th><th>Type</th><th>Default</th><th>Description</th></tr>${this.tableRowsFromProps(properties, required)}`;
53
- return `${output}<table class="schema">${table}</table>`;
54
- }
55
- tableRowsFromProps(properties, required = [], parent) {
56
- return Object.entries(properties).reduce((output, [attr, config]) => {
57
- const attrKey = (parent ? parent + '.' : '') + attr;
58
- output += `<tr class="${config.default === undefined && required && required.includes(attr) ? 'required' : ''}">\n`;
59
- output += `<td>${attrKey}</td>\n`;
60
- output += `<td>${config.type}</td>\n`;
61
- output += `<td>${config.default !== undefined ? this.defaultToMd(config.default) : ''}</td>\n`;
62
- output += `<td>${config.description || ' '}</td>\n`;
63
- output += `</tr>\n`;
64
- if(config.properties) output += this.tableRowsFromProps(config.properties, config.required, attrKey);
65
- return output;
66
- }, '');
67
- }
68
- /**
69
- * Returns a string formatted nicely for markdown
70
- */
71
- defaultToMd(val) {
72
- return `<pre>${JSON.stringify(val)}</pre>`;
73
- }
74
- }
1
+ export default class SchemasReference {
2
+ constructor(app, config, dir, utils) {
3
+ this.app = app;
4
+ this.utils = utils;
5
+ }
6
+ async run() {
7
+ this.schemas = await this.loadSchemas();
8
+ this.manualFile = 'schemas-reference.md';
9
+ this.contents = Object.keys(this.schemas);
10
+ this.replace = { 'LIST': this.generateList() };
11
+ }
12
+ async loadSchemas() {
13
+ const schema = await this.app.waitForModule('jsonschema');
14
+ return Object.keys(schema.schemas)
15
+ .sort((a, b) => a.localeCompare(b))
16
+ .reduce((schemas, s) => Object.assign(schemas, { [s]: schema.schemas[s].raw }), {});
17
+ }
18
+ generateList() {
19
+ return Object.entries(this.schemas).reduce((output, [dep, schema]) => {
20
+ return `${output}<h3 id="${dep.toLowerCase()}" class="dep">${dep}</h3>
21
+
22
+ ${this.schemaToMd(schema)}
23
+
24
+ `;
25
+ }, '');
26
+ }
27
+ schemaToMd(schema) {
28
+ let output = '';
29
+ if(schema.description) {
30
+ output += `<div class="desc">${schema.description}</div>\n\n`;
31
+ }
32
+ let s;
33
+ if(schema.properties) {
34
+ s = schema;
35
+ } else if(schema.$patch) {
36
+ s = schema.$patch.with;
37
+ const ref = schema.$patch.source.$ref;
38
+ output += `<div class="extension">Patches <a href="#/schemas-reference?id=${ref}">${ref}</a></div>`;
39
+ } else if(schema.$merge) {
40
+ s = schema.$merge.with;
41
+ const ref = schema.$merge?.source?.$ref;
42
+ output += `<div class="extension">${ref ? `Merges with <a href="#/schemas-reference?id=${ref}">${ref}</a>` : 'This is a merge schema'}</div>\n\n`;
43
+ }
44
+ const { properties, required } = s;
45
+
46
+ if(!properties) {
47
+ return;
48
+ }
49
+ if(required) {
50
+ output += `<div class="required">Fields in bold are required.</div>\n\n`;
51
+ }
52
+ const table = `<tr><th>Attribute</th><th>Type</th><th>Default</th><th>Description</th></tr>${this.tableRowsFromProps(properties, required)}`;
53
+ return `${output}<table class="schema">${table}</table>`;
54
+ }
55
+ tableRowsFromProps(properties, required = [], parent) {
56
+ return Object.entries(properties).reduce((output, [attr, config]) => {
57
+ const attrKey = (parent ? parent + '.' : '') + attr;
58
+ output += `<tr class="${config.default === undefined && required && required.includes(attr) ? 'required' : ''}">\n`;
59
+ output += `<td>${attrKey}</td>\n`;
60
+ output += `<td>${config.type}</td>\n`;
61
+ output += `<td>${config.default !== undefined ? this.defaultToMd(config.default) : ''}</td>\n`;
62
+ output += `<td>${config.description || ' '}</td>\n`;
63
+ output += `</tr>\n`;
64
+ if(config.properties) output += this.tableRowsFromProps(config.properties, config.required, attrKey);
65
+ return output;
66
+ }, '');
67
+ }
68
+ /**
69
+ * Returns a string formatted nicely for markdown
70
+ */
71
+ defaultToMd(val) {
72
+ return `<pre>${JSON.stringify(val)}</pre>`;
73
+ }
74
+ }
@@ -1,7 +1,7 @@
1
- # Schemas reference
2
-
3
- This page documents all schemas defined in the authoring tool core bundle. Where relevant, any schema inheritance is noted, along with which fields are required.
4
-
5
- {{{TABLE_OF_CONTENTS}}}
6
-
1
+ # Schemas reference
2
+
3
+ This page documents all schemas defined in the authoring tool core bundle. Where relevant, any schema inheritance is noted, along with which fields are required.
4
+
5
+ {{{TABLE_OF_CONTENTS}}}
6
+
7
7
  {{{LIST}}}
@@ -1,144 +1,144 @@
1
- # Schema examples
2
-
3
- This page presents some example schema definitions (along with their UI representation) which may be useful in defining your own schemas.
4
-
5
- ## Quick navigation
6
- - [String](#string)
7
- - [String with text area](#string-with-text-area)
8
- - [Number](#number)
9
- - [Boolean with checkbox](#boolean-with-checkbox)
10
- - [Image](#image)
11
- - [Select](#select)
12
- - [Object](#object)
13
- - [Array](#array)
14
-
15
- ## String
16
-
17
- > Simple string values do not need custom `_backboneForms` configuration.
18
-
19
- ```
20
- "title": {
21
- "type": "string",
22
- "title": "Title",
23
- "default": "Default title",
24
- "_adapt": {
25
- "translatable": true
26
- }
27
- }
28
- ```
29
-
30
- <img width="815" alt="Screenshot 2023-01-16 at 17 06 30" src="https://user-images.githubusercontent.com/11569678/212891159-e73fbe91-0169-429e-86c7-3f8231617b3b.png">
31
-
32
- ## String with text area
33
-
34
- ```
35
- "body": {
36
- "type": "string",
37
- "title": "Body",
38
- "default": "",
39
- "_adapt": {
40
- "translatable": true
41
- },
42
- "_backboneForms": "TextArea"
43
- }
44
- ```
45
-
46
- <img width="820" alt="Screenshot 2023-01-16 at 17 07 11" src="https://user-images.githubusercontent.com/11569678/212891179-f7477a54-3be5-4c39-aa60-7df67d86b7d2.png">
47
-
48
- ## Number
49
-
50
- > Number values do not need custom `_backboneForms` configuration.
51
-
52
- ```
53
- "_left": {
54
- "type": "number",
55
- "title": "Pin horizontal position (%)",
56
- "description": "",
57
- "default": 0
58
- }
59
- ```
60
-
61
- <img width="484" alt="Screenshot 2023-01-16 at 17 10 50" src="https://user-images.githubusercontent.com/11569678/212891200-f9968fe2-8882-4248-8bb2-d6b2f8151e56.png">
62
-
63
- ## Boolean with checkbox
64
-
65
- > Boolean values do not need custom `_backboneForms` configuration.
66
-
67
- ```
68
- "_isMobileTextBelowImage": {
69
- "type": "boolean",
70
- "title": "Move text area below image on mobile",
71
- "description": "If enabled, on mobile, the text area drops below the image instead of being behind the strapline button",
72
- "default": false
73
- }
74
- ```
75
-
76
- <img width="336" alt="Screenshot 2023-01-16 at 17 29 09" src="https://user-images.githubusercontent.com/11569678/212891377-4c3e130d-5f2a-4de5-b1e2-b1747ed2da0e.png">
77
-
78
- ## Image
79
-
80
- In addition to the `type`, an asset sub-schema can define the type of the asset using the `media` property (see [this page](/schemas-introduction#custom-backbone-forms-properties) for more information).
81
-
82
- ```
83
- "src": {
84
- "type": "string",
85
- "isObjectId": true,
86
- "title": "Source",
87
- "description": "This is the image that appears behind the pins",
88
- "_backboneForms": {
89
- "type": "Asset",
90
- "media": "image"
91
- }
92
- }
93
- ```
94
-
95
- <img width="331" alt="Screenshot 2023-01-16 at 17 29 41" src="https://user-images.githubusercontent.com/11569678/212891422-c240c248-1bfd-4c2d-af63-a01aa281ba45.png">
96
-
97
- ## Select
98
-
99
- ```
100
- "_setCompletionOn": {
101
- "type": "string",
102
- "title": "Completion criteria",
103
- "description": "Whether completion is based on the learner having viewed all the narrative items - or just having viewed the component",
104
- "default": "allItems",
105
- "enum": [
106
- "inview",
107
- "allItems"
108
- ],
109
- "_backboneForms": "Select"
110
- }
111
- ```
112
-
113
- <img width="178" alt="Screenshot 2023-01-16 at 17 31 00" src="https://user-images.githubusercontent.com/11569678/212891453-5c482ea5-ef4f-425f-9756-cdb5b71d7e69.png">
114
-
115
- ## Object
116
-
117
- ```
118
- "_graphic": {
119
- "type": "object",
120
- "title": "Graphic",
121
- "default": {},
122
- "properties": {
123
- ...omitted for brevity
124
- }
125
- }
126
- ```
127
-
128
- <img width="485" alt="Screenshot 2023-01-16 at 17 33 08" src="https://user-images.githubusercontent.com/11569678/212891476-fab8198d-2dca-4ce5-af0b-4f07729780f4.png">
129
-
130
- ## Array
131
-
132
- The items value is its own schema, and can take any of the standard types.
133
-
134
- ```
135
- "_items": {
136
- "type": "array",
137
- "title": "Items",
138
- "items": {
139
- ...
140
- }
141
- }
142
- ```
143
-
1
+ # Schema examples
2
+
3
+ This page presents some example schema definitions (along with their UI representation) which may be useful in defining your own schemas.
4
+
5
+ ## Quick navigation
6
+ - [String](#string)
7
+ - [String with text area](#string-with-text-area)
8
+ - [Number](#number)
9
+ - [Boolean with checkbox](#boolean-with-checkbox)
10
+ - [Image](#image)
11
+ - [Select](#select)
12
+ - [Object](#object)
13
+ - [Array](#array)
14
+
15
+ ## String
16
+
17
+ > Simple string values do not need custom `_backboneForms` configuration.
18
+
19
+ ```
20
+ "title": {
21
+ "type": "string",
22
+ "title": "Title",
23
+ "default": "Default title",
24
+ "_adapt": {
25
+ "translatable": true
26
+ }
27
+ }
28
+ ```
29
+
30
+ <img width="815" alt="Screenshot 2023-01-16 at 17 06 30" src="https://user-images.githubusercontent.com/11569678/212891159-e73fbe91-0169-429e-86c7-3f8231617b3b.png">
31
+
32
+ ## String with text area
33
+
34
+ ```
35
+ "body": {
36
+ "type": "string",
37
+ "title": "Body",
38
+ "default": "",
39
+ "_adapt": {
40
+ "translatable": true
41
+ },
42
+ "_backboneForms": "TextArea"
43
+ }
44
+ ```
45
+
46
+ <img width="820" alt="Screenshot 2023-01-16 at 17 07 11" src="https://user-images.githubusercontent.com/11569678/212891179-f7477a54-3be5-4c39-aa60-7df67d86b7d2.png">
47
+
48
+ ## Number
49
+
50
+ > Number values do not need custom `_backboneForms` configuration.
51
+
52
+ ```
53
+ "_left": {
54
+ "type": "number",
55
+ "title": "Pin horizontal position (%)",
56
+ "description": "",
57
+ "default": 0
58
+ }
59
+ ```
60
+
61
+ <img width="484" alt="Screenshot 2023-01-16 at 17 10 50" src="https://user-images.githubusercontent.com/11569678/212891200-f9968fe2-8882-4248-8bb2-d6b2f8151e56.png">
62
+
63
+ ## Boolean with checkbox
64
+
65
+ > Boolean values do not need custom `_backboneForms` configuration.
66
+
67
+ ```
68
+ "_isMobileTextBelowImage": {
69
+ "type": "boolean",
70
+ "title": "Move text area below image on mobile",
71
+ "description": "If enabled, on mobile, the text area drops below the image instead of being behind the strapline button",
72
+ "default": false
73
+ }
74
+ ```
75
+
76
+ <img width="336" alt="Screenshot 2023-01-16 at 17 29 09" src="https://user-images.githubusercontent.com/11569678/212891377-4c3e130d-5f2a-4de5-b1e2-b1747ed2da0e.png">
77
+
78
+ ## Image
79
+
80
+ In addition to the `type`, an asset sub-schema can define the type of the asset using the `media` property (see [this page](/schemas-introduction#custom-backbone-forms-properties) for more information).
81
+
82
+ ```
83
+ "src": {
84
+ "type": "string",
85
+ "isObjectId": true,
86
+ "title": "Source",
87
+ "description": "This is the image that appears behind the pins",
88
+ "_backboneForms": {
89
+ "type": "Asset",
90
+ "media": "image"
91
+ }
92
+ }
93
+ ```
94
+
95
+ <img width="331" alt="Screenshot 2023-01-16 at 17 29 41" src="https://user-images.githubusercontent.com/11569678/212891422-c240c248-1bfd-4c2d-af63-a01aa281ba45.png">
96
+
97
+ ## Select
98
+
99
+ ```
100
+ "_setCompletionOn": {
101
+ "type": "string",
102
+ "title": "Completion criteria",
103
+ "description": "Whether completion is based on the learner having viewed all the narrative items - or just having viewed the component",
104
+ "default": "allItems",
105
+ "enum": [
106
+ "inview",
107
+ "allItems"
108
+ ],
109
+ "_backboneForms": "Select"
110
+ }
111
+ ```
112
+
113
+ <img width="178" alt="Screenshot 2023-01-16 at 17 31 00" src="https://user-images.githubusercontent.com/11569678/212891453-5c482ea5-ef4f-425f-9756-cdb5b71d7e69.png">
114
+
115
+ ## Object
116
+
117
+ ```
118
+ "_graphic": {
119
+ "type": "object",
120
+ "title": "Graphic",
121
+ "default": {},
122
+ "properties": {
123
+ ...omitted for brevity
124
+ }
125
+ }
126
+ ```
127
+
128
+ <img width="485" alt="Screenshot 2023-01-16 at 17 33 08" src="https://user-images.githubusercontent.com/11569678/212891476-fab8198d-2dca-4ce5-af0b-4f07729780f4.png">
129
+
130
+ ## Array
131
+
132
+ The items value is its own schema, and can take any of the standard types.
133
+
134
+ ```
135
+ "_items": {
136
+ "type": "array",
137
+ "title": "Items",
138
+ "items": {
139
+ ...
140
+ }
141
+ }
142
+ ```
143
+
144
144
  <img width="79" alt="Screenshot 2023-01-16 at 17 33 43" src="https://user-images.githubusercontent.com/11569678/212891491-b6102f17-7631-4ef3-b3cc-1c0dadfd3522.png">
@@ -1,78 +1,78 @@
1
- # Introduction to schemas
2
-
3
- The Adapt authoring tool uses the JSON Schema specification (draft 2020-12) to define its data schemas. This page will give you a brief explanation of why we use JSON schema.
4
-
5
- ## What is a schema?
6
-
7
- At its most basic level, a schema is a 'blueprint' which is applied to information coming into the application.
8
-
9
- As with architectural blueprints, a database schema defines how data should be structured and named, as well as other expectations such as the specific 'type' of the data (e.g. strings, numbers) as well as other restrictions (e.g. a fixed length for strings).
10
-
11
- ## Why use a schema?
12
-
13
- Schemas are **MASSIVELY** useful because they set the expectations for data moving into and out of an application. This benefits third-parties because it makes it easier to design interactions with the application, and it benefits the application itself because it can assume that data entering from external sources is in an expected and valid format.
14
-
15
- > **Note**: schemas only become useful when a 'validation' process is used, which compares data to the schema which defines that data. Without validation, we have no idea whether the data is safe to use or not.
16
-
17
- ## Why JSON Schemas?
18
- _**TLDR;** JSON just 'works' with Javascript._
19
-
20
- The JSON Schema specification is a schema spec based on Javascript Object Notation (JSON) and was designed specifically for annotating and validating JSON documents, which are the standard for data representation in Javascript code (and therefore Node.js). We also currently use MongoDB as our database which uses JSON-like documents.
21
-
22
- Additionally, the JSON Schema specification has matured to a point where it is incredibly well supported by a host of third-party libraries from data validators to UI form renderers.
23
-
24
- ## Defining a schema
25
-
26
- When defining a schema, you need to think about the kind of data you need, and how that data is best structured to make it easy to work with.
27
-
28
- ### Data types
29
-
30
- JSON uses the following types:
31
- - **object**: `{ "a": 1, "b": 2 }`
32
- - **array**: `[1,2,3]`
33
- - **number**: `369`
34
- - **string**: `"Hello world"`
35
- - **boolean**: `true`/`false`
36
- - **null**: `null`
37
-
38
- Combined, these types allow a huge amount of flexibility in the way that you want to define your data.
39
-
40
- e.g.
41
- ```
42
- {
43
- "$anchor": "example-schema",
44
- "$schema": "https://json-schema.org/draft/2020-12/schema",
45
- "type": "object",
46
- "required": ["myRequiredAttribute"],
47
- "properties": {
48
- "myRequiredAttribute": {
49
- "type": "string",
50
- },
51
- "aStringAttribute": {
52
- "type": "number",
53
- "default": 12345
54
- },
55
- "aStringAttributeWithRestrictedValues": {
56
- "type": "string",
57
- "default": "false",
58
- "enum": ["false", "soft", "hard"],
59
- },
60
- "nestedObjectAttribute": {
61
- "type": "object",
62
- "default": {},
63
- "properties": {
64
- "nestedProperty": {
65
- "type": "boolean",
66
- "default": true
67
- }
68
- }
69
- }
70
- }
71
- }
72
- ```
73
-
74
- > For more in-depth information on JSON schemas, the [Understanding JSON Schema](https://json-schema.org/understanding-json-schema/) ebook is a great place to start.
75
-
76
- ## Next steps
77
-
1
+ # Introduction to schemas
2
+
3
+ The Adapt authoring tool uses the JSON Schema specification (draft 2020-12) to define its data schemas. This page will give you a brief explanation of why we use JSON schema.
4
+
5
+ ## What is a schema?
6
+
7
+ At its most basic level, a schema is a 'blueprint' which is applied to information coming into the application.
8
+
9
+ As with architectural blueprints, a database schema defines how data should be structured and named, as well as other expectations such as the specific 'type' of the data (e.g. strings, numbers) as well as other restrictions (e.g. a fixed length for strings).
10
+
11
+ ## Why use a schema?
12
+
13
+ Schemas are **MASSIVELY** useful because they set the expectations for data moving into and out of an application. This benefits third-parties because it makes it easier to design interactions with the application, and it benefits the application itself because it can assume that data entering from external sources is in an expected and valid format.
14
+
15
+ > **Note**: schemas only become useful when a 'validation' process is used, which compares data to the schema which defines that data. Without validation, we have no idea whether the data is safe to use or not.
16
+
17
+ ## Why JSON Schemas?
18
+ _**TLDR;** JSON just 'works' with Javascript._
19
+
20
+ The JSON Schema specification is a schema spec based on Javascript Object Notation (JSON) and was designed specifically for annotating and validating JSON documents, which are the standard for data representation in Javascript code (and therefore Node.js). We also currently use MongoDB as our database which uses JSON-like documents.
21
+
22
+ Additionally, the JSON Schema specification has matured to a point where it is incredibly well supported by a host of third-party libraries from data validators to UI form renderers.
23
+
24
+ ## Defining a schema
25
+
26
+ When defining a schema, you need to think about the kind of data you need, and how that data is best structured to make it easy to work with.
27
+
28
+ ### Data types
29
+
30
+ JSON uses the following types:
31
+ - **object**: `{ "a": 1, "b": 2 }`
32
+ - **array**: `[1,2,3]`
33
+ - **number**: `369`
34
+ - **string**: `"Hello world"`
35
+ - **boolean**: `true`/`false`
36
+ - **null**: `null`
37
+
38
+ Combined, these types allow a huge amount of flexibility in the way that you want to define your data.
39
+
40
+ e.g.
41
+ ```
42
+ {
43
+ "$anchor": "example-schema",
44
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
45
+ "type": "object",
46
+ "required": ["myRequiredAttribute"],
47
+ "properties": {
48
+ "myRequiredAttribute": {
49
+ "type": "string",
50
+ },
51
+ "aStringAttribute": {
52
+ "type": "number",
53
+ "default": 12345
54
+ },
55
+ "aStringAttributeWithRestrictedValues": {
56
+ "type": "string",
57
+ "default": "false",
58
+ "enum": ["false", "soft", "hard"],
59
+ },
60
+ "nestedObjectAttribute": {
61
+ "type": "object",
62
+ "default": {},
63
+ "properties": {
64
+ "nestedProperty": {
65
+ "type": "boolean",
66
+ "default": true
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ > For more in-depth information on JSON schemas, the [Understanding JSON Schema](https://json-schema.org/understanding-json-schema/) ebook is a great place to start.
75
+
76
+ ## Next steps
77
+
78
78
  When you're ready to start writing your own schemas, check out [this page](/writing-a-schema).