diff --git a/docs/examples/schema-title-and-descriptions.html b/docs/examples/schema-title-and-descriptions.html new file mode 100644 index 00000000..50653676 --- /dev/null +++ b/docs/examples/schema-title-and-descriptions.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + +
+
Schema Display Style
+
+ + +
+ +
Font Size
+
+ + + +
+
+
+ + \ No newline at end of file diff --git a/docs/list.html b/docs/list.html index d1c6fa41..577a8b8e 100644 --- a/docs/list.html +++ b/docs/list.html @@ -511,6 +511,10 @@

Mix HTML content

Data types + + Schema Title and Descriptions + + Read and Write annotations diff --git a/docs/specs/events.yaml b/docs/specs/events.yaml index 397edb6d..3f9e411f 100644 --- a/docs/specs/events.yaml +++ b/docs/specs/events.yaml @@ -57,7 +57,7 @@ info: servers: - url: https://reqres.in/api/ paths: - /users: + /users?delay=2: get: description: List of users (paginated) parameters: diff --git a/docs/specs/schema-title-and-descriptions.yaml b/docs/specs/schema-title-and-descriptions.yaml new file mode 100644 index 00000000..cb4ef8a3 --- /dev/null +++ b/docs/specs/schema-title-and-descriptions.yaml @@ -0,0 +1,96 @@ +openapi: 3.0.0 +info: + title: Schema Titles and Description Testcase + description: More detailed description of the titles example API + version: '1' +paths: + /object: + get: + summary: Object + responses: + default: + description: Response description. + content: + application/json: + schema: + title: Root Object Title + description: Root Object Description + type: object + properties: + propString: + title: Prop 1 Title + description: Property 1 description + type: string + propArrayOfString: + type: array + title: Array Title + description: Array Description + items: + title: Array Item Title + description: Array Item Description (premitive) + type: string + propArrayOfObject: + type: array + title: Array Title + description: Array Description + items: + type: object + title: Array Item Title + description: Array Item Description (object) + properties: + name: + type: string + title: Title + description: description + age: + type: integer + title: Title + description: description + + /array-of-string: + get: + summary: Array Of String + responses: + default: + description: Response description. + content: + application/json: + schema: + title: Root Array Title + description: Root Array Description + type: array + items: + title: Array Item Title + description: Array Item Description (premitive) + type: string + /array-of-object: + get: + summary: Array Of Object + responses: + default: + description: Response description. + content: + application/json: + schema: + type: object + title: Root Object Title + description: Root Object Description + properties: + array_attribute: + type: array + minItems: 10 + maxItems: 20 + title: Array Title + description: Array Description + items: + type: object + title: Array Item Title + minProperties: 2 + maxProperties: 2 + description: Array Item Description + properties: + key: + type: string + value: + type: integer + minimum: 20 diff --git a/docs/specs/titles.txt b/docs/specs/titles.txt new file mode 100644 index 00000000..10e90132 --- /dev/null +++ b/docs/specs/titles.txt @@ -0,0 +1,129 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Titles example (title)", + "description": "More detailed description of the titles example API", + "version": "1" + }, + "paths": { + "/inline/object": { + "get": { + "summary": "Example with inline schemas, object", + "responses": { + "default": { + "description": "Response description.", + "content": { + "*/*": { + "schema": { + "title": "Inline object (title)", + "description": "Detailed description of inline object.", + "type": "object", + "properties": { + "prop": { + "title": "Inline property in inline object (title)", + "description": "Detailed description of inline property in inline object.", + "type": "string" + } + } + } + } + } + } + } + } + }, + "/inline/array": { + "get": { + "summary": "Example with inline schemas, array", + "responses": { + "default": { + "description": "Response description.", + "content": { + "*/*": { + "schema": { + "title": "Inline array (title)", + "description": "Detailed description of inline array.", + "type": "array", + "items": { + "title": "Inline item in inline array (title)", + "description": "Detailed description of inline item in inline array.", + "type": "string" + } + } + } + } + } + } + } + }, + "/components/object": { + "get": { + "summary": "Example with schemas in components, object", + "responses": { + "default": { + "description": "Response description.", + "content": { + "*/*": { + "schema": { "$ref": "#/components/schemas/Object" } + } + } + } + } + } + }, + "/components/array": { + "get": { + "summary": "Example with schemas in components, array", + "responses": { + "default": { + "description": "Response description.", + "content": { + "*/*": { + "schema": { "$ref": "#/components/schemas/ArrayOfString" } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "String": { + "title": "Schema String (title)", + "description": "Detailed description of schema String.", + "type": "string" + }, + "ArrayOfString": { + "title": "Schema ArrayOfString (title)", + "description": "Detailed description of schema ArrayOfString.", + "type": "array", + "items": { "$ref": "#/components/schemas/String" } + }, + "Object": { + "title": "Schema Object (title)", + "description": "Detailed description of schema Object.", + "type": "object", + "properties": { + "componentString": { "$ref": "#/components/schemas/String" }, + "inlineString": { + "title": "Inline string property in schema Object (title)", + "description": "Detailed description of inline string property in schema Object.", + "type": "string" + }, + "componentArray": { "$ref": "#/components/schemas/ArrayOfString" }, + "inlineArray": { + "title": "Inline array property in schema Object (title)", + "description": "Detailed description of inline array property in schema Object.", + "type": "array", + "items": { + "title": "Inline item in inline array property in schema Object (title)", + "description": "Detailed description of inline item in inline array property in schema Object.", + "type": "string" + } + } + } + } + } + } + } \ No newline at end of file diff --git a/src/components/schema-table.js b/src/components/schema-table.js index 9a1a0053..ebc69bb9 100644 --- a/src/components/schema-table.js +++ b/src/components/schema-table.js @@ -234,7 +234,7 @@ export default class SchemaTable extends LitElement { ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel, '')}` : html` ${Object.keys(data).map((dataKey) => html` - ${['::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite'].includes(dataKey) + ${['::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite'].includes(dataKey) ? data[dataKey]['::type'] === 'array' || data[dataKey]['::type'] === 'object' ? html`${this.generateTree( data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], @@ -303,7 +303,7 @@ export default class SchemaTable extends LitElement { ${defaultValue ? html`
Default: ${defaultValue}
` : ''} ${allowedValues ? html`
Allowed: ${allowedValues}
` : ''} ${pattern ? html`
Pattern: ${pattern}
` : ''} - ${schemaDescription ? html`${unsafeHTML(marked(schemaDescription))}` : ''} + ${schemaDescription ? html`${unsafeHTML(marked(`${schemaTitle ? `**${schemaTitle}:**` : ''} ${schemaDescription}`))}` : ''} `; diff --git a/src/components/schema-tree.js b/src/components/schema-tree.js index f30e0f20..5fb332f7 100644 --- a/src/components/schema-tree.js +++ b/src/components/schema-tree.js @@ -227,7 +227,7 @@ export default class SchemaTree extends LitElement { ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel, data[0]['::readwrite'])}` : html` ${Object.keys(data).map((dataKey) => html` - ${['::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite'].includes(dataKey) + ${['::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite'].includes(dataKey) ? data[dataKey]['::type'] === 'array' || data[dataKey]['::type'] === 'object' ? html`${this.generateTree( data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], @@ -263,7 +263,7 @@ export default class SchemaTree extends LitElement { } // For Primitive types and array of Primitives - const [type, primitiveReadOrWrite, constraint, defaultValue, allowedValues, pattern, schemaDescription, , deprecated] = data.split('~|~'); + const [type, primitiveReadOrWrite, constraint, defaultValue, allowedValues, pattern, schemaDescription, schemaTitle, deprecated] = data.split('~|~'); if (primitiveReadOrWrite === '🆁' && this.schemaHideReadOnly === 'true') { return; } @@ -310,7 +310,7 @@ export default class SchemaTree extends LitElement { ${defaultValue ? html`
Default: ${defaultValue}
` : ''} ${allowedValues ? html`
Allowed: ${allowedValues}
` : ''} ${pattern ? html`
Pattern: ${pattern}
` : ''} - ${schemaDescription ? html`${unsafeHTML(marked(schemaDescription))}` : ''} + ${schemaDescription ? html`${unsafeHTML(marked(`${schemaTitle ? `**${schemaTitle}:**` : ''} ${schemaDescription}`))}` : ''} `; diff --git a/src/utils/schema-utils.js b/src/utils/schema-utils.js index 3916c4fd..fae35be4 100644 --- a/src/utils/schema-utils.js +++ b/src/utils/schema-utils.js @@ -479,6 +479,32 @@ export function schemaToSampleObj(schema, config = { }) { return obj; } +function generateMarkdownForArrayAndObjectDescription(schema, level = 0) { + let markdown = ''; + if (schema.title) { + markdown = `**${schema.title}:** `; + } + if (schema.minItems) { + markdown = `${markdown} **Min Items:** ${schema.minItems}`; + } + if (schema.maxItems) { + markdown = `${markdown} **Max Items:** ${schema.maxItems}`; + } + if (schema.description) { + markdown = `${markdown} ${schema.description}`; + } + if (level > 0 && schema.items?.description) { + let itemsMarkdown = ''; + if (schema.items.minProperties) { + itemsMarkdown = `**Min Properties:** ${schema.items.minProperties}`; + } + if (schema.items.maxProperties) { + itemsMarkdown = `${itemsMarkdown} **Max Properties:** ${schema.items.maxProperties}`; + } + markdown = `${markdown} ⮕ ${itemsMarkdown} [ ${schema.items.description} ] `; + } + return markdown; +} /** * For changing OpenAPI-Schema to an Object Notation, * This Object would further be an input to UI Components to generate an Object-Tree @@ -597,6 +623,7 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') { } else if (v === 'object') { // If object type iterate all the properties and create an object-type-option const objTypeOption = { + '::title': schema.title || '', '::description': schema.description || '', '::type': 'object', '::deprecated': schema.deprecated || false, @@ -611,6 +638,7 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') { multiTypeOptions[`::OPTION~${i + 1}`] = objTypeOption; } else if (v === 'array') { multiTypeOptions[`::OPTION~${i + 1}`] = { + '::title': schema.title || '', '::description': schema.description || '', '::type': 'array', '::props': schemaInObjectNotation(schema.items, {}, (level + 1)), @@ -620,8 +648,9 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') { multiTypeOptions[`::OPTION~${complexTypes.length + 1}`] = multiPrimitiveTypes?.html || ''; obj['::ONE~OF'] = multiTypeOptions; } - } else if (schema.type === 'object' || schema.properties) { - obj['::description'] = schema.description || ''; + } else if (schema.type === 'object' || schema.properties) { // If Object + obj['::title'] = schema.title || ''; + obj['::description'] = generateMarkdownForArrayAndObjectDescription(schema, level); obj['::type'] = 'object'; obj['::deprecated'] = schema.deprecated || false; obj['::readwrite'] = schema.readOnly ? 'readonly' : schema.writeOnly ? 'writeonly' : ''; @@ -636,11 +665,8 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') { obj[''] = schemaInObjectNotation(schema.additionalProperties, {}); } } else if (schema.type === 'array' || schema.items) { // If Array - obj['::description'] = schema.description - ? schema.description - : schema.items?.description - ? `array<${schema.items.description}>` - : ''; + obj['::title'] = schema.title || ''; + obj['::description'] = generateMarkdownForArrayAndObjectDescription(schema, level); obj['::type'] = 'array'; obj['::deprecated'] = schema.deprecated || false; obj['::readwrite'] = schema.readOnly ? 'readonly' : schema.writeOnly ? 'writeonly' : '';