diff --git a/src/utils/schema-utils.js b/src/utils/schema-utils.js index a1ebb4e4..a4cd21da 100644 --- a/src/utils/schema-utils.js +++ b/src/utils/schema-utils.js @@ -329,7 +329,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = ' // If allOf is an array of multiple elements, then all the keys makes a single object const objWithAllProps = {}; allOf.map((v, i) => { - if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf) { + if (v.type === 'object' || v.properties || v.patternProperties || v.allOf || v.anyOf || v.oneOf) { const propSuffix = (v.anyOf || v.oneOf) && i > 0 ? i : ''; const partialObj = schemaInObjectNotation(v, options, (level + 1), propSuffix); Object.assign(objWithAllProps, partialObj); @@ -358,7 +358,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = ' let readOnly = true; (anyOf || oneOf || []).forEach((v, index) => { - if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf || v.type === 'array' || v.items) { + if (v.type === 'object' || v.properties || v.patternProperties || v.allOf || v.anyOf || v.oneOf || v.type === 'array' || v.items) { const partialObj = schemaInObjectNotation(v, options); if (partialObj) { objWithAnyOfProps[`::OPTION~${index + 1}${v.title ? `~${v.title}` : ''}`] = partialObj; @@ -455,6 +455,9 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = ' objTypeOption[key] = schemaInObjectNotation(schemaProperties[key], options, (level + 1)); } } + for (const key in schemaPatternProperties) { + objTypeOption[``] = schemaInObjectNotation(schemaPatternProperties[key], options, (level + 1)); + } if (schema.additionalProperties) { objTypeOption[''] = schemaInObjectNotation(schema.additionalProperties, options); @@ -481,7 +484,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = ' return obj; } - if (propertyType === 'object' || schemaProperties || schema.circularReference) { + if (propertyType === 'object' || schemaProperties || schemaPatternProperties || schema.circularReference) { const obj = { '::type': '' }; obj['::title'] = schema.title || ''; obj['::description'] = schema.description || ''; diff --git a/tests/schema-utils.test.js b/tests/schema-utils.test.js index 9e6e41ff..00a23849 100644 --- a/tests/schema-utils.test.js +++ b/tests/schema-utils.test.js @@ -2,7 +2,7 @@ import test from 'ava'; import { expect } from 'chai'; import xmlFormatter from '../src/utils/xml/xml.js'; -import { getExampleValuesFromSchema } from '../src/utils/schema-utils.js'; +import { getExampleValuesFromSchema, schemaInObjectNotation } from '../src/utils/schema-utils.js'; test('schema-utils.js getExampleValuesFromSchema', t => { const schema = { @@ -70,3 +70,30 @@ test('schema-utils.js getExampleValuesFromSchema', t => { expect(formattedResult).to.eql(expectedFormattedResult); t.pass(); }); + +const patternProperties = { '[a-z]{2}': { type: 'object', properties: { name: { type: 'string' } } } }; +const patternKey = ''; +const findPatternOwner = node => { + if (!node || typeof node !== 'object') { return undefined; } + if (node[patternKey]) { return node; } + return Object.values(node).map(findPatternOwner).find(n => n); +}; +[ + ['a multi-type object', { type: ['object', 'null'], patternProperties }], + ['array items of a multi-type object', { type: 'array', items: { type: ['object', 'null'], patternProperties } }], + ['additionalProperties of a multi-type object', { type: 'object', additionalProperties: { type: ['object', 'null'], patternProperties } }], + ['a typed one-of option', { oneOf: [{ type: 'object', patternProperties }, { type: 'null' }] }], + ['a typed any-of option', { anyOf: [{ type: 'object', patternProperties }, { type: 'string' }] }], + ['an untyped one-of option', { oneOf: [{ patternProperties }, { type: 'null' }] }], + ['an untyped any-of option', { anyOf: [{ patternProperties }, { type: 'string' }] }], + ['a typed all-of member', { allOf: [{ type: 'object', patternProperties }] }], + ['an untyped all-of member', { allOf: [{ patternProperties }] }], + ['an untyped object', { patternProperties }] +].forEach(([name, schema]) => { + test(`schema-utils.js schemaInObjectNotation renders patternProperties of ${name}`, t => { + const owner = findPatternOwner(schemaInObjectNotation(schema, {})); + expect(owner, 'pattern key rendered').to.not.equal(undefined); + expect(owner[patternKey]).to.have.property('name'); + t.pass(); + }); +});