Skip to content

Commit

Permalink
feat(markdown): support patternProperties and additionalProperties
Browse files Browse the repository at this point in the history
fixes #95, fixes #180
  • Loading branch information
trieloff committed Dec 11, 2019
1 parent d35e4ed commit 1386ee3
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 22 deletions.
4 changes: 3 additions & 1 deletion examples/schemas/complex.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@
"required": [
"refabstract"
],
"additionalProperties": true,
"additionalProperties": {
"type":"boolean"
},
"patternProperties": {
"int.*": {
"type": "integer",
Expand Down
126 changes: 105 additions & 21 deletions lib/markdownBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,9 @@ function build({ header, links = {}, includeproperties = [] } = {}) {
* Generates the overview table row for a single property definition
* @param {*} param0
*/
function makepropheader(required = []) {
function makepropheader(required = [], ispattern = false) {
return ([name, definition]) => tableRow([
tableCell(link(`#${name}`, '', text(name))), // Property
tableCell(ispattern ? inlineCode(name) : link(`#${name}`, '', text(name))), // Property
tableCell(type(definition)),
tableCell(text(required.indexOf(name) > -1 ? i18n`Required` : i18n`Optional`)),
tableCell(nullable(definition)),
Expand All @@ -280,8 +280,26 @@ function build({ header, links = {}, includeproperties = [] } = {}) {
* object.
* @param {*} props
*/
function makeproptable(props, required, slugger) {
const proprows = Object.entries(props).map(makepropheader(required, slugger));
function makeproptable(props, patternProps = {}, additionalProps, required, slugger) {
const proprows = Object
.entries(props)
.map(makepropheader(required, false, slugger));
const patternproprows = Object
.entries(patternProps)
.map(makepropheader(required, true, slugger));
const additionalproprows = (() => {
if (additionalProps) {
const any = additionalProps === true;
return [tableRow([
tableCell(text(i18n`Additional Properties`)),
tableCell(any ? text('Any') : type(additionalProps)),
tableCell(text(i18n`Optional`)),
tableCell(any ? text('can be null') : nullable(additionalProps)),
tableCell(link(`${additionalProps[s.slug]}.md`, `${additionalProps[s.id]}#${additionalProps[s.pointer]}`, text(additionalProps[s.titles][0] || i18n`Untitled schema`))),
])];
}
return [];
})();

// const proprows = flist(map(iter(props || {}), makepropheader(required)));

Expand All @@ -294,6 +312,8 @@ function build({ header, links = {}, includeproperties = [] } = {}) {
tableCell(text(i18n`Defined by`)),
]),
...proprows,
...patternproprows,
...additionalproprows,
]);
}

Expand Down Expand Up @@ -568,23 +588,63 @@ function build({ header, links = {}, includeproperties = [] } = {}) {
return [];
}

function makeproplist(properties, required, level = 2) {
function makeproplist(properties = {},
patternProperties = {},
additionalProperties,
required,
level = 2) {
if (!properties) {
return [];
}
return flist(flat(Object.entries(properties).map(([name, definition]) => {
const description = definition[s.meta].longdescription || paragraph(text(i18n`no description`));
return [
...flist(flat(Object.entries(properties).map(([name, definition]) => {
const description = definition[s.meta].longdescription || paragraph(text(i18n`no description`));

return [
heading(level + 1, text(name)),
description,
paragraph(inlineCode(name)),
makefactlist(name, definition, required),
...maketypesection(definition, level + 1),
...makeconstraintssection(definition, level + 1),
...makeexamples(definition, level + 1),
];
})));
return [
heading(level + 1, text(name)),
description,
paragraph(inlineCode(name)),
makefactlist(name, definition, required),
...maketypesection(definition, level + 1),
...makeconstraintssection(definition, level + 1),
...makeexamples(definition, level + 1),
];
}))),
...flist(flat(Object.entries(patternProperties).map(([name, definition]) => {
const description = definition[s.meta].longdescription || paragraph(text(i18n`no description`));

return [
heading(level + 1, [text(i18n`Pattern: `), inlineCode(name)]),
description,
paragraph(inlineCode(name)),
makefactlist(name, definition, required),
...maketypesection(definition, level + 1),
...makeconstraintssection(definition, level + 1),
...makeexamples(definition, level + 1),
];
}))),
...((definition) => {
if (typeof additionalProperties === 'object') {
const description = definition[s.meta].longdescription || paragraph(text(i18n`no description`));
return [
heading(level + 1, text(i18n`Additional Properties`)),
paragraph(text(i18n`Additional properties are allowed, as long as they follow this schema:`)),
description,
makefactlist(i18n`Additional properties`, definition, required),
...maketypesection(definition, level + 1),
...makeconstraintssection(definition, level + 1),
...makeexamples(definition, level + 1),
];
} else if (additionalProperties === true) {
return [
heading(level + 1, text(i18n`Additional Properties`)),
paragraph(text(i18n`Additional properties are allowed and do not have to follow a specific schema`)),
];
}
// nothing
return [];
})(additionalProperties),
];
}

/**
Expand All @@ -594,13 +654,25 @@ function build({ header, links = {}, includeproperties = [] } = {}) {
function makedefinitions(schema, slugger) {
if (schema.definitions) {
const defgroups = Object.entries(schema.definitions).map(([groupname, subschema]) => {
const grouptable = makeproptable(subschema.properties, subschema.required, slugger);
const grouptable = makeproptable(
subschema.properties,
subschema.patternProperties,
subschema.additionalProperties,
subschema.required,
slugger,
);
return [
heading(2, text(i18n`Definitions group ${groupname}`)),
paragraph(text(i18n`Reference this group by using`)),
code('json', JSON.stringify({ $ref: `${subschema[s.id]}#${subschema[s.pointer]}` })),
grouptable,
...makeproplist(subschema.properties, subschema.required, 2),
...makeproplist(
subschema.properties,
subschema.patternProperties,
subschema.additionalProperties,
subschema.required,
2,
),
];
});

Expand All @@ -620,8 +692,20 @@ function build({ header, links = {}, includeproperties = [] } = {}) {
if (schema.properties) {
return [
heading(1, text(i18n`${schema.title} Properties`)),
makeproptable(schema.properties, schema.required, slugger),
...makeproplist(schema.properties, schema.required, 1),
makeproptable(
schema.properties,
schema.patternProperties,
schema.additionalProperties,
schema.required,
slugger,
),
...makeproplist(
schema.properties,
schema.patternProperties,
schema.additionalProperties,
schema.required,
1,
),
];
}
return [];
Expand Down

0 comments on commit 1386ee3

Please sign in to comment.