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

Commit f4d25cd

Browse files
committed
feat(oas2): support additionalProperties with subschema
1 parent fd2584f commit f4d25cd

File tree

2 files changed

+100
-4
lines changed

2 files changed

+100
-4
lines changed

packages/openapi2-parser/lib/schema.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,29 @@ class DataStructureGenerator {
114114
// Create member elements for required keys which are not defined in properties
115115
const missingRequiredProperties = required.filter(name => properties[name] === undefined);
116116
const requiredMembers = missingRequiredProperties.map((name) => {
117-
const member = new this.minim.elements.Member(name);
117+
let member;
118+
119+
if (schema.additionalProperties !== undefined && typeof schema.additionalProperties !== 'boolean') {
120+
member = this.generateMember(name, schema.additionalProperties);
121+
} else {
122+
member = new this.minim.elements.Member(name);
123+
}
124+
118125
member.attributes.set('typeAttributes', ['required']);
119126
return member;
120127
});
121128
element.content.push(...requiredMembers);
122129

123-
if (schema.additionalProperties === false) {
130+
if (schema.additionalProperties !== undefined && schema.additionalProperties !== true) {
124131
const typeAttributes = element.attributes.get('typeAttributes') || new this.minim.elements.Array([]);
125-
typeAttributes.push('fixed-type');
132+
typeAttributes.push('fixedType');
126133
element.attributes.set('typeAttributes', typeAttributes);
134+
135+
if (schema.additionalProperties !== false) {
136+
const member = this.generateMember('', schema.additionalProperties);
137+
member.attributes.set('variable', true);
138+
element.content.push(member);
139+
}
127140
}
128141

129142
return element;

packages/openapi2-parser/test/schema-test.js

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,90 @@ describe('JSON Schema to Data Structure', () => {
720720
expect(dataStructure.content).to.be.instanceof(ObjectElement);
721721

722722
expect(dataStructure.content.length).to.equal(0);
723-
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixed-type']);
723+
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);
724+
});
725+
726+
it('produces object with additionalProperties as false with required properties', () => {
727+
const schema = {
728+
type: 'object',
729+
required: ['type'],
730+
additionalProperties: false,
731+
};
732+
733+
const dataStructure = schemaToDataStructure(schema);
734+
735+
expect(dataStructure.element).to.equal('dataStructure');
736+
expect(dataStructure.content).to.be.instanceof(ObjectElement);
737+
738+
expect(dataStructure.content.length).to.equal(1);
739+
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);
740+
741+
const type = dataStructure.content.getMember('type');
742+
expect(type).to.be.instanceof(MemberElement);
743+
expect(type.attributes.getValue('variable')).to.be.undefined;
744+
expect(type.attributes.getValue('typeAttributes')).to.deep.equal(['required']);
745+
expect(type.value).to.be.undefined;
746+
});
747+
748+
it('produces object with additionalProperties containing a structure', () => {
749+
const schema = {
750+
type: 'object',
751+
additionalProperties: {
752+
type: 'string',
753+
},
754+
};
755+
756+
const dataStructure = schemaToDataStructure(schema);
757+
758+
expect(dataStructure.element).to.equal('dataStructure');
759+
expect(dataStructure.content).to.be.instanceof(ObjectElement);
760+
761+
expect(dataStructure.content.length).to.equal(1);
762+
763+
const member = dataStructure.content.getMember('');
764+
expect(member).to.be.instanceof(MemberElement);
765+
expect(member.attributes.getValue('variable')).to.be.true;
766+
expect(member.value).to.be.instanceof(StringElement);
767+
768+
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);
769+
});
770+
771+
it('produces object with required additionalProperties containing a structure', () => {
772+
const schema = {
773+
type: 'object',
774+
additionalProperties: {
775+
type: 'string',
776+
},
777+
required: ['type', 'mode'],
778+
};
779+
780+
const dataStructure = schemaToDataStructure(schema);
781+
782+
expect(dataStructure.element).to.equal('dataStructure');
783+
expect(dataStructure.content).to.be.instanceof(ObjectElement);
784+
expect(dataStructure.content.attributes.getValue('typeAttributes')).to.deep.equal(['fixedType']);
785+
786+
expect(dataStructure.content.length).to.equal(3);
787+
788+
// Variable property
789+
const variable = dataStructure.content.getMember('');
790+
expect(variable).to.be.instanceof(MemberElement);
791+
expect(variable.attributes.getValue('variable')).to.be.true;
792+
expect(variable.value).to.be.instanceof(StringElement);
793+
794+
// Required 'type' property
795+
const type = dataStructure.content.getMember('type');
796+
expect(type).to.be.instanceof(MemberElement);
797+
expect(type.attributes.getValue('variable')).to.be.undefined;
798+
expect(type.attributes.getValue('typeAttributes')).to.deep.equal(['required']);
799+
expect(type.value).to.be.instanceof(StringElement);
800+
801+
// Required 'mode' property
802+
const mode = dataStructure.content.getMember('mode');
803+
expect(mode).to.be.instanceof(MemberElement);
804+
expect(mode.attributes.getValue('variable')).to.be.undefined;
805+
expect(mode.attributes.getValue('typeAttributes')).to.deep.equal(['required']);
806+
expect(mode.value).to.be.instanceof(StringElement);
724807
});
725808
});
726809

0 commit comments

Comments
 (0)