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

Commit 6b0fc7f

Browse files
committed
feat(oas3): support boolean additionalProperties
1 parent c688d11 commit 6b0fc7f

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

packages/openapi3-parser/CHANGELOG.md

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

3+
## TBD
4+
5+
### Enhancements
6+
7+
- Support for 'Schema Object' `additionalProperties` when the value is boolean.
8+
39
## 0.16.0 (2021-02-23)
410

511
### Enhancements

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

Lines changed: 13 additions & 2 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-
isArray, isString, hasKey, getValue,
9+
isArray, isBoolean, isString, isObject, hasKey, getValue,
1010
} = require('../../predicates');
1111
const parseObject = require('../parseObject');
1212
const parseArray = require('../parseArray');
@@ -43,7 +43,7 @@ const unsupportedJSONSchemaDraft202012 = [
4343
'prefixItems', 'unevaluatedItems', 'contains', 'minContains', 'maxContains',
4444

4545
// Object
46-
'propertiesNames', 'unevaluatedProperties', 'dependentRequired',
46+
'propertyNames', 'unevaluatedProperties', 'dependentRequired',
4747
];
4848
const isUnsupportedKey = R.anyPass(R.map(hasKey, unsupportedKeys));
4949
const isUnsupportedKeyJSONSchemaDraft202012 = R.anyPass(
@@ -71,6 +71,11 @@ function constructObjectStructure(namespace, schema) {
7171
.forEach(member => member.attributes.set('typeAttributes', ['required']));
7272
}
7373

74+
const additionalProperties = schema.get('additionalProperties');
75+
if (additionalProperties && additionalProperties.toValue() === false) {
76+
element.attributes.set('typeAttributes', ['fixedType']);
77+
}
78+
7479
return element;
7580
}
7681

@@ -305,6 +310,11 @@ function parseSchema(context) {
305310

306311
const parseSubSchema = element => parseReference('schemas', R.uncurryN(2, parseSchema), context, element, true);
307312
const parseProperties = parseObject(context, `${name}' 'properties`, R.compose(parseSubSchema, getValue));
313+
const parseAdditionalProperties = R.cond([
314+
[isBoolean, R.identity],
315+
[isObject, createWarning(namespace, `'${name}' 'additionalProperties' containing a Schema Object is currently unsupported`)],
316+
[R.T, createWarning(namespace, `'${name}' 'additionalProperties' must be a boolean value, or a Schema Object`)],
317+
]);
308318

309319
const parseRequiredString = R.unless(isString,
310320
createWarning(namespace, `'${name}' 'required' array value is not a string`));
@@ -334,6 +344,7 @@ function parseSchema(context) {
334344
[hasKey('type'), R.compose(parseType(context), getValue)],
335345
[hasKey('enum'), R.compose(parseEnum(context, name), getValue)],
336346
[hasKey('properties'), R.compose(parseProperties, getValue)],
347+
[hasKey('additionalProperties'), R.compose(parseAdditionalProperties, getValue)],
337348
[hasKey('items'), R.compose(parseSubSchema, getValue)],
338349
[hasKey('required'), R.compose(parseRequired, getValue)],
339350
[hasKey('nullable'), parseNullable],

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

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,75 @@ describe('Schema Object', () => {
665665
});
666666
});
667667

668+
describe('#additionalProperties', () => {
669+
it('warns when additionalProperties is not boolean or object', () => {
670+
const schema = new namespace.elements.Object({
671+
type: 'object',
672+
additionalProperties: 5,
673+
});
674+
const parseResult = parse(context, schema);
675+
676+
expect(parseResult.length).to.equal(2);
677+
expect(parseResult).to.contain.warning(
678+
"'Schema Object' 'additionalProperties' must be a boolean value, or a Schema Object"
679+
);
680+
});
681+
682+
it('warns when additionalProperties is an object', () => {
683+
const schema = new namespace.elements.Object({
684+
type: 'object',
685+
additionalProperties: {},
686+
});
687+
const parseResult = parse(context, schema);
688+
689+
expect(parseResult.length).to.equal(2);
690+
expect(parseResult).to.contain.warning(
691+
"'Schema Object' 'additionalProperties' containing a Schema Object is currently unsupported"
692+
);
693+
});
694+
695+
it('defaults additionalProperties to true', () => {
696+
const schema = new namespace.elements.Object({
697+
type: 'object',
698+
});
699+
const parseResult = parse(context, schema);
700+
701+
expect(parseResult.length).to.equal(1);
702+
const object = parseResult.get(0).content;
703+
expect(object).to.be.instanceof(namespace.elements.Object);
704+
expect(object.length).to.equal(0);
705+
expect(object.attributes.getValue('typeAttributes')).to.be.undefined;
706+
});
707+
708+
it('supports additionalProperties as true', () => {
709+
const schema = new namespace.elements.Object({
710+
type: 'object',
711+
additionalProperties: true,
712+
});
713+
const parseResult = parse(context, schema);
714+
715+
expect(parseResult.length).to.equal(1);
716+
const object = parseResult.get(0).content;
717+
expect(object).to.be.instanceof(namespace.elements.Object);
718+
expect(object.length).to.equal(0);
719+
expect(object.attributes.getValue('typeAttributes')).to.be.undefined;
720+
});
721+
722+
it('supports additionalProperties as false', () => {
723+
const schema = new namespace.elements.Object({
724+
type: 'object',
725+
additionalProperties: false,
726+
});
727+
const parseResult = parse(context, schema);
728+
729+
expect(parseResult.length).to.equal(1);
730+
const object = parseResult.get(0).content;
731+
expect(object).to.be.instanceof(namespace.elements.Object);
732+
expect(object.length).to.equal(0);
733+
expect(object.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);
734+
});
735+
});
736+
668737
describe('#items', () => {
669738
it('warns when items is not an object', () => {
670739
const schema = new namespace.elements.Object({

0 commit comments

Comments
 (0)