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

Commit a76c680

Browse files
committed
refactor(oas3): normalise OpenAPI type as an array
1 parent 615cb37 commit a76c680

File tree

1 file changed

+40
-24
lines changed

1 file changed

+40
-24
lines changed

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

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const {
66
} = require('../annotations');
77
const pipeParseResult = require('../../pipeParseResult');
88
const {
9-
isString, hasKey, hasValue, getValue,
9+
isString, hasKey, getValue,
1010
} = require('../../predicates');
1111
const parseObject = require('../parseObject');
1212
const parseArray = require('../parseArray');
@@ -66,10 +66,32 @@ function constructArrayStructure(namespace, schema) {
6666
return element;
6767
}
6868

69+
function constructStructure(namespace, schema, type) {
70+
let element;
71+
72+
if (type === 'object') {
73+
element = constructObjectStructure(namespace, schema);
74+
} else if (type === 'array') {
75+
element = constructArrayStructure(namespace, schema);
76+
} else if (type === 'string') {
77+
element = new namespace.elements.String();
78+
} else if (type === 'number' || type === 'integer') {
79+
element = new namespace.elements.Number();
80+
} else if (type === 'boolean') {
81+
element = new namespace.elements.Boolean();
82+
} else if (type === 'null') {
83+
element = new namespace.elements.Null();
84+
} else {
85+
throw new Error(`Internal Inconsistency: constructStructure called with unexpected type: '${type}'`);
86+
}
87+
88+
return element;
89+
}
90+
6991
const openapi30Types = ['boolean', 'object', 'array', 'number', 'string', 'integer'];
7092
const openapi31Types = openapi30Types.concat(['null']);
71-
const isValidOpenAPI30Type = R.anyPass(R.map(hasValue, openapi30Types));
72-
const isValidOpenAPI31Type = R.anyPass(R.map(hasValue, openapi31Types));
93+
const isValidOpenAPI30Type = R.anyPass(R.map(R.equals, openapi30Types));
94+
const isValidOpenAPI31Type = R.anyPass(R.map(R.equals, openapi31Types));
7395

7496
const typeToElementNameMap = {
7597
array: 'array',
@@ -81,6 +103,10 @@ const typeToElementNameMap = {
81103
string: 'string',
82104
};
83105

106+
/*
107+
* Parse StringElement containing OpenAPI Schema type
108+
* Normalises result into an ArrayElement of StringElement
109+
*/
84110
function parseType(context) {
85111
let types;
86112
let isValidType;
@@ -94,16 +120,14 @@ function parseType(context) {
94120
}
95121

96122
const ensureValidType = R.unless(
97-
isValidType,
98-
R.compose(
99-
createWarning(context.namespace, `'${name}' 'type' must be either ${types.join(', ')}`),
100-
getValue
101-
)
123+
element => isValidType(element.toValue()),
124+
createWarning(context.namespace, `'${name}' 'type' must be either ${types.join(', ')}`)
102125
);
103126

104127
return pipeParseResult(context.namespace,
105-
parseString(context, name, false),
106-
ensureValidType);
128+
R.unless(isString, value => createWarning(context.namespace, `'${name}' 'type' is not a string`, value)),
129+
ensureValidType,
130+
type => new context.namespace.elements.Array([type]));
107131
}
108132

109133
// Returns whether the given element value matches the provided schema type
@@ -215,7 +239,7 @@ function parseSchema(context) {
215239
});
216240

217241
const parseMember = R.cond([
218-
[hasKey('type'), parseType(context)],
242+
[hasKey('type'), R.compose(parseType(context), getValue)],
219243
[hasKey('enum'), R.compose(parseEnum(context, name), getValue)],
220244
[hasKey('properties'), R.compose(parseProperties, getValue)],
221245
[hasKey('items'), R.compose(parseSubSchema, getValue)],
@@ -242,24 +266,16 @@ function parseSchema(context) {
242266

243267
const oneOf = schema.get('oneOf');
244268
const enumerations = schema.get('enum');
245-
const type = schema.getValue('type');
269+
const type = schema.getValue('type') || [];
246270

247271
if (oneOf) {
248272
element = oneOf;
249273
} else if (enumerations) {
250274
element = enumerations;
251-
} else if (type === 'object') {
252-
element = constructObjectStructure(namespace, schema);
253-
} else if (type === 'array') {
254-
element = constructArrayStructure(namespace, schema);
255-
} else if (type === 'string') {
256-
element = new namespace.elements.String();
257-
} else if (type === 'number' || type === 'integer') {
258-
element = new namespace.elements.Number();
259-
} else if (type === 'boolean') {
260-
element = new namespace.elements.Boolean();
261-
} else if (type === 'null') {
262-
element = new namespace.elements.Null();
275+
} else if (type.length > 1) {
276+
throw new Error('Implementation error: unexpected multiple types');
277+
} else if (type.length === 1) {
278+
element = constructStructure(namespace, schema, type[0]);
263279
} else {
264280
element = new namespace.elements.Enum();
265281
element.enumerations = [

0 commit comments

Comments
 (0)