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

Commit 75e2672

Browse files
committed
feat(oas3): support parameter object schema with type
1 parent 96550cd commit 75e2672

File tree

7 files changed

+280
-146
lines changed

7 files changed

+280
-146
lines changed

packages/openapi3-parser/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# API Elements: OpenAPI 3 Parser Changelog
22

3+
## TBD
4+
5+
### Enhancements
6+
7+
- Minimal support for 'Parameter Object' schemas, simplest schemas using 'type'
8+
are supported.
9+
310
## 0.15.1 (2020-11-10)
411

512
### Bug Fixes

packages/openapi3-parser/STATUS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ Key:
124124
| style ||
125125
| explode | ~ |
126126
| allowReserved ||
127-
| schema | |
127+
| schema | ~ (minimal) |
128128
| example ||
129129
| examples ||
130130

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ const pipeParseResult = require('../../pipeParseResult');
1212
const parseObject = require('../parseObject');
1313
const parseString = require('../parseString');
1414
const parseBoolean = require('../parseBoolean');
15+
const parseSchemaObject = require('./parseParameterObjectSchemaObject');
1516

1617
const name = 'Parameter Object';
1718
const requiredKeys = ['name', 'in'];
1819
const unsupportedKeys = [
1920
'deprecated', 'allowEmptyValue', 'style', 'allowReserved',
20-
'schema', 'examples', 'content',
21+
'examples', 'content',
2122
];
2223
const isUnsupportedKey = R.anyPass(R.map(hasKey, unsupportedKeys));
2324

@@ -102,6 +103,7 @@ function parseParameterObject(context, object) {
102103
[hasKey('required'), parseBoolean(context, name, false)],
103104
[hasKey('explode'), parseBoolean(context, name, false)],
104105
[hasKey('example'), e => e.clone()],
106+
[hasKey('schema'), R.pipe(getValue, parseSchemaObject(context))],
105107

106108
[isUnsupportedKey, createUnsupportedMemberWarning(namespace, name)],
107109

@@ -166,6 +168,14 @@ function parseParameterObject(context, object) {
166168
const example = parameter.get('example');
167169
const member = new namespace.elements.Member(parameter.get('name'), example);
168170

171+
if (example === undefined) {
172+
const schema = parameter.get('schema');
173+
174+
if (schema) {
175+
member.value = schema;
176+
}
177+
}
178+
169179
const description = parameter.get('description');
170180
if (description) {
171181
member.description = description;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
const R = require('ramda');
2+
const {
3+
isExtension, hasKey, hasValue, getValue,
4+
} = require('../../predicates');
5+
const {
6+
createWarning,
7+
createUnsupportedMemberWarning,
8+
createInvalidMemberWarning,
9+
} = require('../annotations');
10+
const pipeParseResult = require('../../pipeParseResult');
11+
const parseObject = require('../parseObject');
12+
const parseString = require('../parseString');
13+
14+
const name = 'Schema Object';
15+
const unsupportedKeys = [
16+
'$ref', 'multipleOf', 'maximum', 'exclusiveMaximum', 'minimum',
17+
'exclusiveMinimum', 'maxLength', 'minLength', 'pattern', 'maxItems',
18+
'minItems', 'uniqueItems', 'maxProperties', 'minProperties', 'enum',
19+
'properties', 'items', 'required', 'nullable', 'title', 'description',
20+
'default', 'oneOf', 'allOf', 'anyOf', 'not', 'additionalProperties',
21+
'format', 'discriminator', 'readOnly', 'writeOnly', 'xml', 'externalDocs',
22+
'deprecated', 'example',
23+
];
24+
const isUnsupportedKey = R.anyPass(R.map(hasKey, unsupportedKeys));
25+
26+
// purposely in the order defined in the JSON Schema spec, integer is an OAS 3 specific addition and thus is at the end
27+
const types = ['boolean', 'object', 'array', 'number', 'string', 'integer'];
28+
const isValidType = R.anyPass(R.map(hasValue, types));
29+
30+
/**
31+
* Parse Parameter Object's Schema Object
32+
*
33+
* @note Parameter Object's schema should be parsed using the standard schema
34+
* object parser (which also will handle references). At the moment many
35+
* other tooling does not expect references or complex elements in the
36+
* API Elements result and thus a simple schema object parser is used
37+
* directly so we can support simple cases.
38+
*/
39+
function parseSchemaObject(context) {
40+
const { namespace } = context;
41+
42+
const ensureValidType = R.unless(
43+
isValidType,
44+
R.compose(
45+
createWarning(namespace, `'${name}' 'type' must be either ${types.join(', ')}`),
46+
getValue
47+
)
48+
);
49+
50+
const parseType = pipeParseResult(namespace,
51+
parseString(context, name, false),
52+
ensureValidType);
53+
54+
const parseMember = R.cond([
55+
[hasKey('type'), parseType],
56+
57+
[isUnsupportedKey, createUnsupportedMemberWarning(namespace, name)],
58+
[isExtension, () => new namespace.elements.ParseResult()],
59+
[R.T, createInvalidMemberWarning(namespace, name)],
60+
]);
61+
62+
return pipeParseResult(namespace,
63+
parseObject(context, name, parseMember, []),
64+
(schema) => {
65+
const type = schema.getValue('type');
66+
let element;
67+
68+
if (type === 'object') {
69+
element = new namespace.elements.Object();
70+
} else if (type === 'array') {
71+
element = new namespace.elements.Array();
72+
} else if (type === 'string') {
73+
element = new namespace.elements.String();
74+
} else if (type === 'number' || type === 'integer') {
75+
element = new namespace.elements.Number();
76+
} else if (type === 'boolean') {
77+
element = new namespace.elements.Boolean();
78+
} else {
79+
element = new namespace.elements.ParseResult([]);
80+
}
81+
82+
return element;
83+
});
84+
}
85+
86+
module.exports = parseSchemaObject;

packages/openapi3-parser/test/integration/fixtures/petstore.json

Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@
126126
"key": {
127127
"element": "string",
128128
"content": "limit"
129+
},
130+
"value": {
131+
"element": "number"
129132
}
130133
}
131134
}
@@ -494,6 +497,9 @@
494497
"key": {
495498
"element": "string",
496499
"content": "petId"
500+
},
501+
"value": {
502+
"element": "string"
497503
}
498504
}
499505
}
@@ -964,25 +970,25 @@
964970
"attributes": {
965971
"line": {
966972
"element": "number",
967-
"content": 21
973+
"content": 23
968974
},
969975
"column": {
970976
"element": "number",
971-
"content": 11
977+
"content": 13
972978
}
973979
},
974-
"content": 414
980+
"content": 460
975981
},
976982
{
977983
"element": "number",
978984
"attributes": {
979985
"line": {
980986
"element": "number",
981-
"content": 21
987+
"content": 23
982988
},
983989
"column": {
984990
"element": "number",
985-
"content": 17
991+
"content": 19
986992
}
987993
},
988994
"content": 6
@@ -994,7 +1000,7 @@
9941000
]
9951001
}
9961002
},
997-
"content": "'Parameter Object' contains unsupported key 'schema' (2 occurances)"
1003+
"content": "'Schema Object' contains unsupported key 'format' (3 occurances)"
9981004
},
9991005
{
10001006
"element": "annotation",
@@ -1115,66 +1121,6 @@
11151121
}
11161122
},
11171123
"content": "'Header Object' contains unsupported key 'schema'"
1118-
},
1119-
{
1120-
"element": "annotation",
1121-
"meta": {
1122-
"classes": {
1123-
"element": "array",
1124-
"content": [
1125-
{
1126-
"element": "string",
1127-
"content": "warning"
1128-
}
1129-
]
1130-
}
1131-
},
1132-
"attributes": {
1133-
"sourceMap": {
1134-
"element": "array",
1135-
"content": [
1136-
{
1137-
"element": "sourceMap",
1138-
"content": [
1139-
{
1140-
"element": "array",
1141-
"content": [
1142-
{
1143-
"element": "number",
1144-
"attributes": {
1145-
"line": {
1146-
"element": "number",
1147-
"content": 92
1148-
},
1149-
"column": {
1150-
"element": "number",
1151-
"content": 11
1152-
}
1153-
},
1154-
"content": 2192
1155-
},
1156-
{
1157-
"element": "number",
1158-
"attributes": {
1159-
"line": {
1160-
"element": "number",
1161-
"content": 92
1162-
},
1163-
"column": {
1164-
"element": "number",
1165-
"content": 17
1166-
}
1167-
},
1168-
"content": 6
1169-
}
1170-
]
1171-
}
1172-
]
1173-
}
1174-
]
1175-
}
1176-
},
1177-
"content": "'Schema Object' contains unsupported key 'format' (2 occurances)"
11781124
}
11791125
]
11801126
}

0 commit comments

Comments
 (0)