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

Commit b3b49be

Browse files
authored
Support generating text message body for string schemas (#300)
Support generating text message body for string schemas
2 parents 016861e + c89d21d commit b3b49be

File tree

3 files changed

+84
-27
lines changed

3 files changed

+84
-27
lines changed

packages/fury-adapter-oas3-parser/lib/parser/oas/parseMediaTypeObject.js

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const R = require('ramda');
2-
const contentType = require('content-type');
2+
const contentTyper = require('content-type');
3+
const mediaTyper = require('media-typer');
34
const pipeParseResult = require('../../pipeParseResult');
45
const {
56
isExtension, hasKey, getKey, getValue,
@@ -19,9 +20,52 @@ const unsupportedKeys = ['encoding'];
1920
const isUnsupportedKey = R.anyPass(R.map(hasKey, unsupportedKeys));
2021

2122
function isJSONMediaType(mediaType) {
22-
const type = contentType.parse(mediaType);
23-
const jsonMediaType = /^application\/\S*json$/i;
24-
return jsonMediaType.test(type.type);
23+
const contentType = contentTyper.parse(mediaType);
24+
const { type, suffix, subtype } = mediaTyper.parse(contentType.type);
25+
return type === 'application' && (suffix === 'json' || subtype === 'json');
26+
}
27+
28+
function isTextMediaType(mediaType) {
29+
const contentType = contentTyper.parse(mediaType);
30+
const { type } = mediaTyper.parse(contentType.type);
31+
return type === 'text';
32+
}
33+
34+
const canGenerateMessageBodyForMediaType = R.anyPass([isJSONMediaType, isTextMediaType]);
35+
36+
function generateMessageBody(context, mediaType, dataStructure) {
37+
const elements = {};
38+
const { components } = context.state;
39+
if (components) {
40+
const schemas = components.get('schemas');
41+
if (schemas) {
42+
schemas.content
43+
.filter(e => e.value && e.value.content)
44+
.forEach((e) => {
45+
const element = e.value.content;
46+
elements[element.id.toValue()] = element;
47+
});
48+
}
49+
}
50+
51+
const value = dataStructure.content.valueOf(undefined, elements);
52+
if (!value) {
53+
return undefined;
54+
}
55+
56+
let body;
57+
if (isJSONMediaType(mediaType)) {
58+
body = JSON.stringify(value);
59+
} else if (isTextMediaType(mediaType) && typeof value === 'string') {
60+
body = value;
61+
} else {
62+
return undefined;
63+
}
64+
65+
const asset = new context.namespace.elements.Asset(body);
66+
asset.classes.push('messageBody');
67+
asset.contentType = mediaType;
68+
return asset;
2569
}
2670

2771
const createJSONMessageBodyAsset = R.curry((namespace, mediaType, value) => {
@@ -46,7 +90,7 @@ const parseExampleObjectOrRef = parseReference('examples', parseExampleObject);
4690

4791
const isValidMediaType = (mediaType) => {
4892
try {
49-
contentType.parse(mediaType.toValue());
93+
contentTyper.parse(mediaType.toValue());
5094
} catch (error) {
5195
return false;
5296
}
@@ -133,28 +177,9 @@ function parseMediaTypeObject(context, MessageBodyClass, element) {
133177

134178
const dataStructure = mediaTypeObject.get('schema');
135179

136-
if (!messageBody && dataStructure && isJSONMediaType(mediaType)) {
137-
const elements = {};
138-
const { components } = context.state;
139-
if (components) {
140-
const schemas = components.get('schemas');
141-
if (schemas) {
142-
schemas.content
143-
.filter(e => e.value && e.value.content)
144-
.forEach((e) => {
145-
const element = e.value.content;
146-
elements[element.id.toValue()] = element;
147-
});
148-
}
149-
}
150-
151-
const value = dataStructure.content.valueOf(undefined, elements);
152-
153-
if (value) {
154-
const body = JSON.stringify(value);
155-
const asset = new namespace.elements.Asset(body);
156-
asset.classes.push('messageBody');
157-
asset.contentType = mediaType;
180+
if (!messageBody && dataStructure && canGenerateMessageBodyForMediaType(mediaType)) {
181+
const asset = generateMessageBody(context, mediaType, dataStructure);
182+
if (asset) {
158183
message.push(asset);
159184
}
160185
}

packages/fury-adapter-oas3-parser/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
},
2525
"dependencies": {
2626
"content-type": "^1.0.4",
27+
"media-typer": "^1.0.1",
2728
"ramda": "0.26.1",
2829
"yaml-js": "^0.2.3"
2930
},

packages/fury-adapter-oas3-parser/test/unit/parser/oas/parseMediaTypeObject-test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,5 +348,36 @@ describe('Media Type Object', () => {
348348
expect(message.messageBody.toValue()).to.equal('{"parents":[]}');
349349
expect(message.messageBody.contentType.toValue()).to.equal('application/json');
350350
});
351+
352+
it('generates an messageBody asset for text type with string schema', () => {
353+
const mediaType = new namespace.elements.Member('text/plain', {
354+
schema: {
355+
type: 'string',
356+
example: 'hello world',
357+
},
358+
});
359+
360+
const parseResult = parse(context, messageBodyClass, mediaType);
361+
362+
const message = parseResult.get(0);
363+
expect(message).to.be.instanceof(messageBodyClass);
364+
expect(message.messageBody.toValue()).to.equal('hello world');
365+
expect(message.messageBody.contentType.toValue()).to.equal('text/plain');
366+
});
367+
368+
it('does not generates an messageBody asset for text type with non string type', () => {
369+
const mediaType = new namespace.elements.Member('text/plain', {
370+
schema: {
371+
type: 'number',
372+
example: 5,
373+
},
374+
});
375+
376+
const parseResult = parse(context, messageBodyClass, mediaType);
377+
378+
const message = parseResult.get(0);
379+
expect(message).to.be.instanceof(messageBodyClass);
380+
expect(message.messageBody).to.be.undefined;
381+
});
351382
});
352383
});

0 commit comments

Comments
 (0)