diff --git a/lib/formatInfo.js b/lib/formatInfo.js index 5fc92277..052afcf3 100644 --- a/lib/formatInfo.js +++ b/lib/formatInfo.js @@ -98,6 +98,17 @@ function getstatus(schema) { return schema[keyword`meta:status`] || undefined; } +function getrestrictions(schema) { + if (schema[keyword`readOnly`] === true && schema[keyword`writeOnly`] === true) { + return 'secret'; + } else if (schema[keyword`readOnly`] === true) { + return 'readOnly'; + } else if (schema[keyword`writeOnly`] === true) { + return 'writeOnly'; + } + return undefined; +} + function formatmeta(schema) { return { abstract: isabstract(schema), @@ -107,6 +118,7 @@ function formatmeta(schema) { custom: iscustom(schema), additional: schema[keyword`additionalProperties`] !== false, definedin: getdefined(schema), + restrictions: getrestrictions(schema), ...parsedescription(plaindescription(schema)), }; } diff --git a/lib/markdownBuilder.js b/lib/markdownBuilder.js index 3f15e216..716083b4 100644 --- a/lib/markdownBuilder.js +++ b/lib/markdownBuilder.js @@ -203,6 +203,14 @@ function build({ falselabel: i18n`Forbidden`, undefinedlabel: i18n`Unknown additional properties`, }, + { + name: 'restrictions', + title: i18n`Access Restrictions`, + readOnlylabel: i18n`Read only`, + writeOnlylabel: i18n`Write only`, + secretlabel: i18n`cannot be read or written`, + undefinedlabel: i18n`none`, + }, { name: 'definedin', title: i18n`Defined In`, @@ -653,6 +661,29 @@ function build({ return []; } + function makerestrictions(schema, level = 1) { + if (schema[keyword`readOnly`] && schema[keyword`writeOnly`]) { + return [ + heading(level + 1, text(i18n`${simpletitle(schema)} Access Restrictions`)), + paragraph(text(i18n`The value of this property is managed exclusively by the owning authority and never exposed to the outside. It can neither be read nor written.`)), + ]; + } + if (schema[keyword`readOnly`]) { + return [ + heading(level + 1, text(i18n`${simpletitle(schema)} Access Restrictions`)), + paragraph(text(i18n`The value of this property is managed exclusively by the owning authority, and attempts by an application to modify the value of this property are expected to be ignored or rejected by that owning authority`)), + ]; + } + if (schema[keyword`writeOnly`]) { + return [ + heading(level + 1, text(i18n`${simpletitle(schema)} Access Restrictions`)), + paragraph(text(i18n`The value of this property is never present when the instance is retrieved from the owning authority. It can be present when sent to the owning authority to update or create the document (or the resource it represents), but it will not be included in any updated or newly created version of the instance.`)), + ]; + } + return []; + } + + function makeproplist(properties = {}, patternProperties = {}, additionalProperties, @@ -671,6 +702,7 @@ function build({ ...makeconstraintssection(definition, level + 1), ...makedefault(definition, level + 1), ...makeexamples(definition, level + 1), + ...makerestrictions(definition, level + 1), ]; }))), ...flist(flat(Object.entries(patternProperties || {}).map(([name, definition]) => { @@ -685,6 +717,7 @@ function build({ ...makeconstraintssection(definition, level + 1), ...makedefault(definition, level + 1), ...makeexamples(definition, level + 1), + ...makerestrictions(definition, level + 1), ]; }))), ...((definition) => { @@ -699,6 +732,7 @@ function build({ ...makeconstraintssection(definition, level + 1), ...makedefault(definition, level + 1), ...makeexamples(definition, level + 1), + ...makerestrictions(definition, level + 1), ]; } else if (additionalProperties === true) { return [ diff --git a/schemasupport.md b/schemasupport.md index 3c4a74b2..4217ce63 100644 --- a/schemasupport.md +++ b/schemasupport.md @@ -1,6 +1,6 @@ # JSON Schema Spec Coverage Report -This report lists the keywords of the JSON Schema spec that are covered in the tests. The overall coverage is 76% +This report lists the keywords of the JSON Schema spec that are covered in the tests. The overall coverage is 78% ## The JSON Schema Core Vocabulary @@ -135,7 +135,7 @@ Coverage for [A Vocabulary for the Contents of String-Encoded Data](https://json ## A Vocabulary for Basic Meta-Data Annotations -Coverage for [A Vocabulary for Basic Meta-Data Annotations](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9) is 71%. +Coverage for [A Vocabulary for Basic Meta-Data Annotations](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9) is 100%. | Keyword | Supported | | :------------ | --------- | @@ -143,6 +143,6 @@ Coverage for [A Vocabulary for Basic Meta-Data Annotations](https://json-schema. | `deprecated` | Yes | | `description` | Yes | | `examples` | Yes | -| `readOnly` | No | +| `readOnly` | Yes | | `title` | Yes | -| `writeOnly` | No | +| `writeOnly` | Yes | diff --git a/test/fixtures/readme-1/abstract.schema.json b/test/fixtures/readme-1/abstract.schema.json index f56e2a94..0ae16f3d 100644 --- a/test/fixtures/readme-1/abstract.schema.json +++ b/test/fixtures/readme-1/abstract.schema.json @@ -8,6 +8,8 @@ "$schema": "http://json-schema.org/draft-06/schema#", "$id": "https://example.com/schemas/abstract", "title": "Abstract", + "readOnly": true, + "writeOnly": true, "description": "This is an abstract schema. It has `definitions`, but does not declare any properties", "type": "object", "definitions": { @@ -18,14 +20,16 @@ "type": "string", "description": "A unique identifier given to every addressable thing.", "version": "1.0.0", - "testProperty": "test" + "testProperty": "test", + "readOnly": true }, "nonfoo": { "type": "boolean", "const": false, "description": "This is not foo.", "version": "1.0.0", - "testProperty": "test" + "testProperty": "test", + "writeOnly": true } } }, @@ -36,7 +40,9 @@ "type": "string", "description": "A unique identifier given to every addressable thing.", "version": "1.0.0", - "testProperty": "test" + "testProperty": "test", + "readOnly": true, + "writeOnly": true } } } diff --git a/test/fixtures/readme-1/complex.schema.json b/test/fixtures/readme-1/complex.schema.json index cd8de566..8f890245 100644 --- a/test/fixtures/readme-1/complex.schema.json +++ b/test/fixtures/readme-1/complex.schema.json @@ -9,6 +9,7 @@ "$id": "https://example.com/schemas/complex", "title": "Complex References", "type": "object", + "readOnly": true, "description": "This is an example schema that uses types defined in other schemas.", "properties": { "refabstract": { diff --git a/test/fixtures/readme-1/simple.schema.json b/test/fixtures/readme-1/simple.schema.json index 9f09778a..a29f639f 100644 --- a/test/fixtures/readme-1/simple.schema.json +++ b/test/fixtures/readme-1/simple.schema.json @@ -9,6 +9,7 @@ "$id": "https://example.com/schemas/simple", "title": "Simple", "deprecated": true, + "writeOnly": true, "description": "This is a *very* simple example of a JSON schema. There is only one property.", "type": "object", "properties": { diff --git a/test/markdownBuilder.test.js b/test/markdownBuilder.test.js index 8591b5f9..e853cb81 100644 --- a/test/markdownBuilder.test.js +++ b/test/markdownBuilder.test.js @@ -248,6 +248,10 @@ describe('Testing Markdown Builder: readme-1', () => { it('Abstract Schema looks OK', () => { assertMarkdown(results.abstract) .equals('heading > text', { type: 'text', value: 'Abstract Schema' }) + .contains('cannot be read or written') + .contains('nonfoo Access Restrictions') + .contains('bar Access Restrictions') + .contains('### foo Access Restrictions') .fuzzy` ## Definitions group second @@ -274,6 +278,7 @@ Reference this group by using it('Complex Schema looks OK', () => { assertMarkdown(results.complex) + .contains('Read only') .contains('# Complex References Schema'); }); @@ -281,6 +286,7 @@ Reference this group by using assertMarkdown(results.simple) .contains('Deprecated') .contains('"Simply Untitled"') + .contains('Write only') .contains('# Simple Schema'); }); });