Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/fury-adapter-oas3-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
- Added primitive support for 'examples' in 'Media Type Object'. The first
example value is used for JSON media types.

- Added primitive support for generating a JSON message body from a schema for
JSON media types. Referencing is not supported for this feature.
- Added support for generating a JSON message body from a schema for
JSON media types.

- Added support for header parameters.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,14 @@ function parseComponentsObject(context, element) {
validateIsObject,
R.compose(parseObject(context, name, parseMember), getValue),
(object) => {
context.state.components.push(new namespace.elements.Member(member.key, object));
const contextMember = context.state.components.getMember(member.key.toValue());

if (contextMember) {
contextMember.value = object;
} else {
context.state.components.push(new namespace.elements.Member(member.key, object));
}

return object;
})(member);
};
Expand Down Expand Up @@ -169,7 +176,8 @@ function parseComponentsObject(context, element) {
[R.T, createInvalidMemberWarning(namespace, name)],
]);

return parseObject(context, name, parseMember)(element);
const order = ['schemas'];
return parseObject(context, name, parseMember, [], order)(element);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,18 @@ function parseMediaTypeObject(context, MessageBodyClass, element) {
const dataStructure = mediaTypeObject.get('schema');

if (!messageBody && dataStructure && isJSONMediaType(mediaType)) {
const value = dataStructure.content.valueOf();
let elements = [];
const { components } = context.state;
if (components) {
const schemas = components.get('schemas');
if (schemas) {
elements = schemas.content
.filter(e => e.value && e.value.content)
.map(e => e.value.content);
}
}

const value = dataStructure.content.valueOf(undefined, elements);

if (value) {
const body = JSON.stringify(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
"content": "application/json"
}
},
"content": "{}"
"content": "{\"name\":\"\",\"company\":{\"name\":\"\"}}"
},
{
"element": "dataStructure",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,27 @@
}
},
"content": [
{
"element": "asset",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "messageBody"
}
]
}
},
"attributes": {
"contentType": {
"element": "string",
"content": "application/json"
}
},
"content": "{}"
},
{
"element": "dataStructure",
"content": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
"content": "application/json"
}
},
"content": "[]"
"content": "[{\"id\":0,\"name\":\"\",\"tag\":\"\"}]"
},
{
"element": "dataStructure",
Expand Down Expand Up @@ -329,7 +329,7 @@
"content": "application/json"
}
},
"content": "[]"
"content": "[{\"id\":0,\"name\":\"\",\"tag\":\"\"}]"
},
{
"element": "dataStructure",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@
"content": "application/json"
}
},
"content": "[]"
"content": "[{\"id\":0,\"name\":\"\",\"tag\":\"\"}]"
},
{
"element": "dataStructure",
Expand Down Expand Up @@ -854,7 +854,7 @@
"content": "application/json"
}
},
"content": "[]"
"content": "[{\"id\":0,\"name\":\"\",\"tag\":\"\"}]"
},
{
"element": "dataStructure",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,5 +260,75 @@ describe('Media Type Object', () => {
expect(message.messageBody.toValue()).to.equal('{"name":"doe"}');
expect(message.messageBody.contentType.toValue()).to.equal('application/json');
});

it('generates a messageBody asset for JSON type with referenced schema with no examples', () => {
context.state.components = new namespace.elements.Object({
schemas: {
Name: new namespace.elements.DataStructure(
new namespace.elements.String('doe', {
id: 'Name',
})
),
},
});

const mediaType = new namespace.elements.Member('application/json', {
schema: {
type: 'object',
properties: {
name: {
$ref: '#/components/schemas/Name',
},
},
},
});

const parseResult = parse(context, messageBodyClass, mediaType);

const message = parseResult.get(0);
expect(message).to.be.instanceof(messageBodyClass);
expect(message.messageBody.toValue()).to.equal('{"name":"doe"}');
expect(message.messageBody.contentType.toValue()).to.equal('application/json');
});

it('generates a messageBody asset for JSON type with circular referenced schema with no examples', () => {
const node = new namespace.Element();
node.element = 'Node';

const nodes = new namespace.Element();
nodes.element = 'Nodes';

context.state.components = new namespace.elements.Object({
schemas: {
Nodes: new namespace.elements.DataStructure(
new namespace.elements.Array({
node,
}, {
id: 'Nodes',
})
),
Node: new namespace.elements.DataStructure(
new namespace.elements.Object({
parents: nodes,
}, {
id: 'Node',
})
),
},
});

const mediaType = new namespace.elements.Member('application/json', {
schema: {
$ref: '#/components/schemas/Node',
},
});

const parseResult = parse(context, messageBodyClass, mediaType);

const message = parseResult.get(0);
expect(message).to.be.instanceof(messageBodyClass);
expect(message.messageBody.toValue()).to.equal('{"parents":[]}');
expect(message.messageBody.contentType.toValue()).to.equal('application/json');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -175,19 +175,14 @@ describe('Response Object', () => {
},
});

const dataStructure = new namespace.elements.DataStructure();
dataStructure.id = 'Node';

const pets = new namespace.elements.Array();
pets.id = 'Pets';
context.state.components = new namespace.elements.Object({
schemas: {
Node: dataStructure,
Pets: new namespace.elements.DataStructure(pets),
},
});

context.state.components.set('schemas', new namespace.elements.Object([
new namespace.elements.Member('Pets', new namespace.elements.Array()),
]));

const parseResult = parse(context, response);

expect(parseResult.get(0).headers.length).to.be.equal(2);
Expand Down
60 changes: 40 additions & 20 deletions packages/minim-api-description/lib/define-value-of.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,61 +98,81 @@ module.exports = (namespace) => {
const isEnumElement = e => (e.element === 'enum' || e instanceof EnumElement);
const isPlural = e => (e instanceof ArrayElement) || (e instanceof ObjectElement);

function mapValue(e, options, f) {
function mapValue(e, options, f, elements) {
const opts = updateTypeAttributes(e, options);
if (e.content && (!isPlural(e) || e.content.length > 0)) {
const result = f(e, opts, 'content');
const result = f(e, opts, elements, 'content');
if (undefined !== result) {
return result;
}
}
const sample = findFirstSample(e);
if (sample) {
const result = f(sample, opts, 'sample');
const result = f(sample, opts, elements, 'sample');
if (undefined !== result) {
return result;
}
}
const dflt = findDefault(e);
if (dflt) {
const result = f(dflt, opts, 'default');
const result = f(dflt, opts, elements, 'default');
if (undefined !== result) {
return result;
}
}
if (isFlag(NULLABLE_FLAG, opts)) {
const result = f(new NullElement(), opts, 'nullable');
const result = f(new NullElement(), opts, elements, 'nullable');
if (undefined !== result) {
return result;
}
}

if (elements) {
if (e.element === 'ref') {
const result = elements.filter(el => el.id.equals(e.content))[0];
const inheritedElements = elements.filter(el => !el.id.equals(e.content));

if (e.path && e.path.toValue() === 'content') {
return mapValue(result.content, opts, f, inheritedElements);
}

return mapValue(result, opts, f, inheritedElements);
}

const result = elements.filter(el => el.id.equals(e.element))[0];
if (result) {
const inheritedElements = elements.filter(el => !el.id.equals(e.element));
return mapValue(result, opts, f, inheritedElements);
}
}

if (isEnumElement(e)) {
const enums = e.enumerations;
if (enums && enums.content && enums.content[0]) {
const result = f(enums.content[0], opts, 'generated');
const result = f(enums.content[0], opts, elements, 'generated');
if (undefined !== result) {
return result;
}
}
}
const trivial = trivialValue(e);
if (trivial) {
const result = f(trivial, opts, 'generated');
const result = f(trivial, opts, elements, 'generated');
if (undefined !== result) {
return result;
}
}
if (isPlural(e) && e.content.length === 0) {
return f(e, opts, 'generated');
return f(e, opts, elements, 'generated');
}

return undefined;
}

function reduceValue(e, options) {
function reduceValue(e, options, elements) {
const opts = updateTypeAttributes(e, options);
if (undefined === e.content) {
return mapValue(e, opts, e => e.content);
return mapValue(e, opts, e => e.content, elements);
}
if (isPrimitive(e)) {
return e.content;
Expand All @@ -161,7 +181,7 @@ module.exports = (namespace) => {
return null;
}
if (isEnumElement(e)) {
return mapValue(e.content, inheritFlags(opts), reduceValue);
return mapValue(e.content, inheritFlags(opts), reduceValue, elements);
}
if (e instanceof ObjectElement) {
let result = {};
Expand All @@ -171,7 +191,7 @@ module.exports = (namespace) => {
&& !isFlag(FIXED_TYPE_FLAG, opts)
&& !hasTypeAttribute(item, 'required'));

const k = mapValue(item.key, inheritFlags(opts), reduceValue);
const k = mapValue(item.key, inheritFlags(opts), reduceValue, elements);

if (undefined === k) {
if (skippable) {
Expand All @@ -181,7 +201,7 @@ module.exports = (namespace) => {
return true;
}

const v = mapValue(item.value, inheritFlags(opts), reduceValue);
const v = mapValue(item.value, inheritFlags(opts), reduceValue, elements);
if (undefined === v) {
if (skippable) {
return false;
Expand All @@ -196,7 +216,7 @@ module.exports = (namespace) => {
return result;
}
if (e instanceof ArrayElement) {
const result = e.map(item => mapValue(item, inheritFlags(opts), reduceValue));
const result = e.map(item => mapValue(item, inheritFlags(opts), reduceValue, elements));
if (!isFlag(FIXED_FLAG, opts) && !isFlag(FIXED_TYPE_FLAG, opts)) {
return result.filter(item => item !== undefined);
}
Expand All @@ -210,17 +230,17 @@ module.exports = (namespace) => {

if (!Object.getOwnPropertyNames(Element.prototype).includes('valueOf')) {
Object.defineProperty(Element.prototype, 'valueOf', {
value(flags) {
value(flags, elements) {
if (flags !== undefined && flags.source) {
return mapValue(this, 0, (value, opts, source) => {
const result = reduceValue(value, opts);
return mapValue(this, 0, (value, opts, elements, source) => {
const result = reduceValue(value, opts, elements);
if (undefined === result) {
return undefined;
}
return [reduceValue(value, opts), source];
});
return [reduceValue(value, opts, elements), source];
}, elements);
}
return mapValue(this, 0, (value, opts) => reduceValue(value, opts));
return mapValue(this, 0, (value, opts) => reduceValue(value, opts, elements), elements);
},
});
}
Expand Down
Loading