Skip to content

Commit e4ad226

Browse files
authored
Merge pull request #53 from tomcollins/copy-additional-properties-from-ref
Improve rendering of $ref links and objects with child properties.
2 parents 8bdbc06 + 2ffe3a0 commit e4ad226

File tree

5 files changed

+70
-21
lines changed

5 files changed

+70
-21
lines changed

lib/merger.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ const resolveRef = (
3939
if (resolvedRef.$ref) {
4040
// @todo technically this could also require resolution
4141
mergedProperty.$ref = resolvedRef.$ref;
42-
// @todo technically this could also require resolution
4342
} else {
43+
// @todo technically this could also require resolution
4444
mergedProperty.$ref = ref;
4545
}
4646
if (resolvedRef.items && resolvedRef.items.$ref) {

lib/renderer-markdown.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@ const refToLink = (ref, label) => {
2525
let filename = refParts[refParts.length - 1];
2626
filename = filename.substr(0, filename.length - 5);
2727

28-
filename = ref.replace(".json", ".html");
28+
filename = ref.replace(".json", ".html").replace(".yml", ".html");
29+
30+
// if we have a definition copnvert it to a html anchor to the property
31+
filenameParts = filename.split("#");
32+
33+
if (filenameParts.length === 2 && filenameParts[1].match(/^\/definitions/)) {
34+
filename =
35+
filenameParts[0] + "#" + filenameParts[1].replace("/definitions/", "");
36+
}
2937

3038
label = label || filename;
3139
label = typeToLinkLabel(label, ref);
@@ -70,16 +78,36 @@ Handlebars.registerHelper("enumValues", function (enums) {
7078
return new Handlebars.SafeString(html + "</ul>");
7179
});
7280

81+
Handlebars.registerHelper("isDefined", function (value) {
82+
return value !== undefined;
83+
});
84+
85+
Handlebars.registerHelper("isArrayOfStringLikeValues", function (value) {
86+
return Array.isArray(value) && !value.find((v) => typeof v === "object");
87+
});
88+
7389
Handlebars.registerHelper("jsonSchemaType", function (property) {
7490
return new Handlebars.SafeString(jsonSchemaType(property));
7591
});
7692

93+
Handlebars.registerHelper("isExternalRef", function (value) {
94+
return (
95+
typeof value === "string" &&
96+
(value.match(/^(.+)#/) || value.match(/^(.+)\.(json|yml)$/))
97+
);
98+
});
99+
Handlebars.registerHelper("refToLink", function (ref, label) {
100+
return refToLink(ref, label);
101+
});
102+
77103
const attributeRow = (name, property) => {
78104
let html =
79105
"<tr>" +
80-
'<td colspan="2">' +
106+
'<td colspan="2"><a href="#' +
107+
name.toLowerCase() +
108+
'">' +
81109
name +
82-
"</td>" +
110+
"</a></td>" +
83111
"<td>" +
84112
jsonSchemaType(property) +
85113
"</td>" +

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-schema-static-docs",
3-
"version": "0.12.3",
3+
"version": "0.13.0",
44
"description": "",
55
"main": "lib/json-schema-static-docs.js",
66
"bin": {

templates/schema.hbs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,41 @@
3030

3131
{{#each schema.properties}}
3232

33-
## {{ @key }}
34-
35-
{{> property }}
33+
{{> property propertyKey=@key }}
3634

3735
{{/each}}
3836

37+
38+
39+
3940
{{#*inline "property"}}
4041

42+
{{#if (isDefined parentKey)}}
43+
### {{ parentKey }}.{{ propertyKey }}
44+
{{else}}
45+
## {{ propertyKey }}
46+
{{/if}}
47+
48+
{{#if (isExternalRef this.$ref)}}
49+
<p>Defined in {{{ refToLink this.$ref this.$ref }}}</p>
50+
{{/if}}
51+
52+
4153
{{#if this.description}}<p>{{ this.description }}</p>{{/if}}
4254

4355
{{> propertyTable}}
4456

57+
{{#unless (isDefined this.$ref)}}
4558
{{#if this.properties}}
46-
4759
{{#each this.properties}}
48-
### {{ @key }}
49-
{{> property }}
60+
{{> property parentKey=../propertyKey propertyKey=@key }}
5061
{{/each}}
51-
5262
{{/if}}
63+
{{/unless}}
64+
5365
{{/inline}}
5466

67+
5568
{{#*inline "propertyTable"}}
5669
<table>
5770
<thead>
@@ -61,14 +74,18 @@
6174
</tr>
6275
</thead>
6376
<tbody>
77+
{{#if this.title}}
6478
<tr>
6579
<td>Title</td>
6680
<td colspan="2">{{ this.title }}</td>
6781
</tr>
82+
{{/if}}
83+
{{#if (isDefined this.isRequired)}}
6884
<tr>
6985
<td>Required</td>
7086
<td colspan="2">{{#if this.isRequired}}Yes{{else}}No{{/if}}</td>
7187
</tr>
88+
{{/if}}
7289
{{propertyTypeRow this }}
7390
{{#if this.enum}}<tr>
7491
<td>Enum</td>
@@ -86,6 +103,10 @@
86103
<td>Pattern</td>
87104
<td colspan="2">{{this.pattern}}</td>
88105
</tr>{{/if}}
106+
{{!-- {{#if (isArrayOfStringLikeValues this.examples) }}<tr>
107+
<td>Examples</td>
108+
<td colspan="2"><ul>{{#each this.examples}}<li>{{ this }}</li>{{/each}}</ul></td>
109+
</tr>{{/if}} --}}
89110
</tbody>
90111
</table>
91112
{{/inline}}

tests/renderer-markdown.test.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ test("renders attributes", async () => {
6565
let expectedText =
6666
"## Attributes\n\n" +
6767
'<table><thead><tr><th colspan="2">Name</th><th>Type</th></tr></thead>' +
68-
'<tr><td colspan="2">property1</td><td>String</td></tr>' +
69-
'<tr><td colspan="2">property2</td><td>[string, integer]</td></tr>' +
70-
'<tr><td colspan="2">property3</td><td>Array [<a href="property3.html">Property3.html</a>]</td></tr>' +
68+
'<tr><td colspan="2"><a href="#property1">property1</a></td><td>String</td></tr>' +
69+
'<tr><td colspan="2"><a href="#property2">property2</a></td><td>[string, integer]</td></tr>' +
70+
'<tr><td colspan="2"><a href="#property3">property3</a></td><td>Array [<a href="property3.html">Property3.html</a>]</td></tr>' +
7171
"</tbody></table>";
7272

7373
expect(result).toEqual(expect.stringContaining(expectedText));
@@ -92,19 +92,19 @@ test("renders string property enums", async () => {
9292
});
9393

9494
test("renders array property types", async () => {
95-
expect.assertions(1);
95+
expect.assertions(2);
9696
rendererMarkdown = new RendererMarkdown(defaultTemplatePath);
9797
await rendererMarkdown.setup();
9898
let result = rendererMarkdown.renderSchema(mergedSchema);
9999

100100
result = result.match(/## property3(.*\n)*/)[0];
101101
result = removeFormatting(result);
102102

103-
let expectedText =
104-
"" +
105-
'<tr><td>Title</td><td colspan="2">Property 3</td></tr>' +
106-
'<tr><td>Required</td><td colspan="2">No</td></tr>' +
103+
let expectedTitle = '<tr><td>Title</td><td colspan="2">Property 3</td></tr>';
104+
expect(result).toEqual(expect.stringContaining(expectedTitle));
105+
106+
let expectedType =
107107
'<tr><td>Type</td><td colspan="2">Array [<a href="property3.html">Property3.html</a>]</td></tr>';
108108

109-
expect(result).toEqual(expect.stringContaining(expectedText));
109+
expect(result).toEqual(expect.stringContaining(expectedType));
110110
});

0 commit comments

Comments
 (0)