diff --git a/packages/openapi3-parser/lib/parser/oas/parseSchemaObject.js b/packages/openapi3-parser/lib/parser/oas/parseSchemaObject.js index 67622b37..6f1ad4e3 100644 --- a/packages/openapi3-parser/lib/parser/oas/parseSchemaObject.js +++ b/packages/openapi3-parser/lib/parser/oas/parseSchemaObject.js @@ -86,7 +86,7 @@ function constructArrayStructure(namespace, schema) { return element; } -function constructStructure(namespace, schema, type) { +const constructStructure = R.curry((namespace, schema, type) => { let element; if (type === 'object') { @@ -106,7 +106,7 @@ function constructStructure(namespace, schema, type) { } return element; -} +}); const openapi30Types = ['boolean', 'object', 'array', 'number', 'string', 'integer']; const openapi31Types = openapi30Types.concat(['null']); @@ -189,13 +189,7 @@ function parseType(context) { const parseArrayType = pipeParseResult(namespace, R.when(isEmpty, createWarning(namespace, `'${name}' 'type' array must contain at least one type`)), parseArray(context, `${name}' 'type`, parseArrayTypeItem), - ensureTypesAreUnique, - - // FIXME support >1 type - R.unless( - e => e.length === 0 || e.length === 1 || (e.length === 2 && e.contains('null')), - createWarning(namespace, `'${name}' 'type' more than one type is current unsupported`) - )); + ensureTypesAreUnique); return R.cond([ [isString, parseStringType], @@ -385,11 +379,17 @@ function parseSchema(context) { element = constValue; } else if (enumerations) { element = enumerations; - } else if (type.length === 1 || (type.length === 2 && type.includes('null'))) { - const findType = R.find(R.complement(R.equals('nullable'))); + } else if (type.length === 1) { + element = constructStructure(namespace, schema, type[0]); + } else if (type.length === 2 && type.includes('null')) { + const findType = R.find(R.complement(R.equals('null'))); element = constructStructure(namespace, schema, findType(type)); } else if (type.length > 1) { - throw new Error('Implementation error: unexpected multiple types'); + const removeNull = R.filter(R.complement(R.equals('null'))); + const types = removeNull(type); + + element = new namespace.elements.Enum(); + element.enumerations = R.map(constructStructure(namespace, schema), types); } else { element = new namespace.elements.Enum(); element.enumerations = [ diff --git a/packages/openapi3-parser/test/unit/parser/oas/parseSchemaObject-test.js b/packages/openapi3-parser/test/unit/parser/oas/parseSchemaObject-test.js index e865a0ed..6b479c02 100644 --- a/packages/openapi3-parser/test/unit/parser/oas/parseSchemaObject-test.js +++ b/packages/openapi3-parser/test/unit/parser/oas/parseSchemaObject-test.js @@ -268,18 +268,6 @@ describe('Schema Object', () => { ); }); - it('warns when array items contain more than 1 entry', () => { - // FIXME support more than one entry :) - const schema = new namespace.elements.Object({ - type: ['string', 'number'], - }); - const parseResult = parse(context, schema); - - expect(parseResult).to.contain.warning( - "'Schema Object' 'type' more than one type is current unsupported" - ); - }); - it('when type contains a single value', () => { const schema = new namespace.elements.Object({ type: ['string'], @@ -308,6 +296,44 @@ describe('Schema Object', () => { expect(string).to.be.instanceof(namespace.elements.String); expect(string.attributes.getValue('typeAttributes')).to.deep.equal(['nullable']); }); + + it('when type contains multiple values', () => { + const schema = new namespace.elements.Object({ + type: ['string', 'number'], + }); + const parseResult = parse(context, schema); + + expect(parseResult.length).to.equal(1); + expect(parseResult.get(0)).to.be.instanceof(namespace.elements.DataStructure); + expect(parseResult).to.not.contain.annotations; + + const element = parseResult.get(0).content; + expect(element).to.be.instanceof(namespace.elements.Enum); + + expect(element.enumerations.length).to.equal(2); + expect(element.enumerations.get(0)).to.be.instanceof(namespace.elements.String); + expect(element.enumerations.get(1)).to.be.instanceof(namespace.elements.Number); + expect(element.attributes.getValue('typeAttributes')).to.be.undefined; + }); + + it('when type contains multiple values with null', () => { + const schema = new namespace.elements.Object({ + type: ['string', 'number', 'null'], + }); + const parseResult = parse(context, schema); + + expect(parseResult.length).to.equal(1); + expect(parseResult.get(0)).to.be.instanceof(namespace.elements.DataStructure); + expect(parseResult).to.not.contain.annotations; + + const element = parseResult.get(0).content; + expect(element).to.be.instanceof(namespace.elements.Enum); + + expect(element.enumerations.length).to.equal(2); + expect(element.enumerations.get(0)).to.be.instanceof(namespace.elements.String); + expect(element.enumerations.get(1)).to.be.instanceof(namespace.elements.Number); + expect(element.attributes.getValue('typeAttributes')).to.deep.equal(['nullable']); + }); }); });