Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.

Commit 2e47835

Browse files
committed
feat(oas3): support multiple types in Schema Object
1 parent f781a34 commit 2e47835

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

packages/openapi3-parser/lib/parser/oas/parseSchemaObject.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function constructArrayStructure(namespace, schema) {
8686
return element;
8787
}
8888

89-
function constructStructure(namespace, schema, type) {
89+
const constructStructure = R.curry((namespace, schema, type) => {
9090
let element;
9191

9292
if (type === 'object') {
@@ -106,7 +106,7 @@ function constructStructure(namespace, schema, type) {
106106
}
107107

108108
return element;
109-
}
109+
});
110110

111111
const openapi30Types = ['boolean', 'object', 'array', 'number', 'string', 'integer'];
112112
const openapi31Types = openapi30Types.concat(['null']);
@@ -189,13 +189,7 @@ function parseType(context) {
189189
const parseArrayType = pipeParseResult(namespace,
190190
R.when(isEmpty, createWarning(namespace, `'${name}' 'type' array must contain at least one type`)),
191191
parseArray(context, `${name}' 'type`, parseArrayTypeItem),
192-
ensureTypesAreUnique,
193-
194-
// FIXME support >1 type
195-
R.unless(
196-
e => e.length === 0 || e.length === 1 || (e.length === 2 && e.contains('null')),
197-
createWarning(namespace, `'${name}' 'type' more than one type is current unsupported`)
198-
));
192+
ensureTypesAreUnique);
199193

200194
return R.cond([
201195
[isString, parseStringType],
@@ -385,11 +379,17 @@ function parseSchema(context) {
385379
element = constValue;
386380
} else if (enumerations) {
387381
element = enumerations;
388-
} else if (type.length === 1 || (type.length === 2 && type.includes('null'))) {
389-
const findType = R.find(R.complement(R.equals('nullable')));
382+
} else if (type.length === 1) {
383+
element = constructStructure(namespace, schema, type[0]);
384+
} else if (type.length === 2 && type.includes('null')) {
385+
const findType = R.find(R.complement(R.equals('null')));
390386
element = constructStructure(namespace, schema, findType(type));
391387
} else if (type.length > 1) {
392-
throw new Error('Implementation error: unexpected multiple types');
388+
const removeNull = R.filter(R.complement(R.equals('null')));
389+
const types = removeNull(type);
390+
391+
element = new namespace.elements.Enum();
392+
element.enumerations = R.map(constructStructure(namespace, schema), types);
393393
} else {
394394
element = new namespace.elements.Enum();
395395
element.enumerations = [

packages/openapi3-parser/test/unit/parser/oas/parseSchemaObject-test.js

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -268,18 +268,6 @@ describe('Schema Object', () => {
268268
);
269269
});
270270

271-
it('warns when array items contain more than 1 entry', () => {
272-
// FIXME support more than one entry :)
273-
const schema = new namespace.elements.Object({
274-
type: ['string', 'number'],
275-
});
276-
const parseResult = parse(context, schema);
277-
278-
expect(parseResult).to.contain.warning(
279-
"'Schema Object' 'type' more than one type is current unsupported"
280-
);
281-
});
282-
283271
it('when type contains a single value', () => {
284272
const schema = new namespace.elements.Object({
285273
type: ['string'],
@@ -308,6 +296,44 @@ describe('Schema Object', () => {
308296
expect(string).to.be.instanceof(namespace.elements.String);
309297
expect(string.attributes.getValue('typeAttributes')).to.deep.equal(['nullable']);
310298
});
299+
300+
it('when type contains multiple values', () => {
301+
const schema = new namespace.elements.Object({
302+
type: ['string', 'number'],
303+
});
304+
const parseResult = parse(context, schema);
305+
306+
expect(parseResult.length).to.equal(1);
307+
expect(parseResult.get(0)).to.be.instanceof(namespace.elements.DataStructure);
308+
expect(parseResult).to.not.contain.annotations;
309+
310+
const element = parseResult.get(0).content;
311+
expect(element).to.be.instanceof(namespace.elements.Enum);
312+
313+
expect(element.enumerations.length).to.equal(2);
314+
expect(element.enumerations.get(0)).to.be.instanceof(namespace.elements.String);
315+
expect(element.enumerations.get(1)).to.be.instanceof(namespace.elements.Number);
316+
expect(element.attributes.getValue('typeAttributes')).to.be.undefined;
317+
});
318+
319+
it('when type contains multiple values with null', () => {
320+
const schema = new namespace.elements.Object({
321+
type: ['string', 'number', 'null'],
322+
});
323+
const parseResult = parse(context, schema);
324+
325+
expect(parseResult.length).to.equal(1);
326+
expect(parseResult.get(0)).to.be.instanceof(namespace.elements.DataStructure);
327+
expect(parseResult).to.not.contain.annotations;
328+
329+
const element = parseResult.get(0).content;
330+
expect(element).to.be.instanceof(namespace.elements.Enum);
331+
332+
expect(element.enumerations.length).to.equal(2);
333+
expect(element.enumerations.get(0)).to.be.instanceof(namespace.elements.String);
334+
expect(element.enumerations.get(1)).to.be.instanceof(namespace.elements.Number);
335+
expect(element.attributes.getValue('typeAttributes')).to.deep.equal(['nullable']);
336+
});
311337
});
312338
});
313339

0 commit comments

Comments
 (0)