fix: support json serialization for parameter examples

fixes #934
This commit is contained in:
Roman Hotsiy 2019-08-01 11:17:50 +03:00
parent 2afc2e4921
commit 1367380a88
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
4 changed files with 94 additions and 10 deletions

View File

@ -33,11 +33,10 @@ export class FieldDetails extends React.PureComponent<FieldProps> {
let exampleField: JSX.Element | null = null;
if (showExamples) {
if (showExamples && example !== undefined) {
const label = l('example') + ':';
if (field.in && field.style) {
const serializedValue =
example !== undefined ? serializeParameterValue(field, example) : undefined;
if (field.in && (field.style || field.serializationMime)) {
const serializedValue = serializeParameterValue(field, example);
exampleField = <FieldDetail label={label} value={serializedValue} raw={true} />;
} else {
exampleField = <FieldDetail label={label} value={example} />;

View File

@ -44,6 +44,8 @@ export class FieldModel {
explode: boolean;
style?: OpenAPIParameterStyle;
serializationMime?: string;
constructor(
parser: OpenAPIParser,
infoOrRef: Referenced<OpenAPIParameter> & { name?: string; kind?: string },
@ -55,12 +57,22 @@ export class FieldModel {
this.name = infoOrRef.name || info.name;
this.in = info.in;
this.required = !!info.required;
this.schema = new SchemaModel(parser, info.schema || {}, pointer, options);
let fieldSchema = info.schema;
let serializationMime = '';
if (!fieldSchema && info.in && info.content) {
serializationMime = Object.keys(info.content)[0];
fieldSchema = info.content[serializationMime] && info.content[serializationMime].schema;
}
this.schema = new SchemaModel(parser, fieldSchema || {}, pointer, options);
this.description =
info.description === undefined ? this.schema.description || '' : info.description;
this.example = info.example || this.schema.example;
if (info.style) {
if (serializationMime) {
this.serializationMime = serializationMime;
} else if (info.style) {
this.style = info.style;
} else if (this.in) {
this.style = getDefaultStyleValue(this.in);

View File

@ -11,7 +11,7 @@ import {
serializeParameterValue,
} from '../';
import { OpenAPIParser } from '../../services';
import { FieldModel, OpenAPIParser, RedocNormalizedOptions } from '../../services';
import { OpenAPIParameter, OpenAPIParameterLocation, OpenAPIParameterStyle } from '../../types';
import { expandDefaultServerVariables } from '../openapi';
@ -389,6 +389,7 @@ describe('Utils', () => {
explode: boolean;
expected: string;
}
interface TestValueTypeGroup {
value: any;
description: string;
@ -565,5 +566,51 @@ describe('Utils', () => {
});
});
});
describe('advanced serialization', () => {
it('should serialize correctly query parameter with content with application/json', () => {
const parameter: OpenAPIParameter = {
name: 'id',
in: 'query',
content: {
'application/json': {
schema: {
type: 'string',
},
},
},
};
const parser = new OpenAPIParser({ openapi: '3.0' } as any);
const opts = new RedocNormalizedOptions({});
const field = new FieldModel(parser, parameter, '', opts);
expect(serializeParameterValue(field, { name: 'test', age: 23 })).toEqual(
'id={"name":"test","age":23}',
);
});
it('should serialize correctly header parameter with content with application/json', () => {
const parameter: OpenAPIParameter = {
name: 'x-header',
in: 'header',
content: {
'application/json': {
schema: {
type: 'string',
},
},
},
};
const parser = new OpenAPIParser({ openapi: '3.0' } as any);
const opts = new RedocNormalizedOptions({});
const field = new FieldModel(parser, parameter, '', opts);
expect(serializeParameterValue(field, { name: 'test', age: 23 })).toEqual(
'{"name":"test","age":23}',
);
});
});
});
});

View File

@ -308,11 +308,37 @@ function serializeCookieParameter(
}
}
export function serializeParameterValue(parameter: OpenAPIParameter, value: any): string {
const { name, style, explode = false } = parameter;
export function serializeParameterValueWithMime(value: any, mime: string): string {
if (isJsonLike(mime)) {
return JSON.stringify(value);
} else {
console.warn(`Parameter serialization as ${mime} is not supported`);
return '';
}
}
export function serializeParameterValue(
parameter: OpenAPIParameter & { serializationMime?: string },
value: any,
): string {
const { name, style, explode = false, serializationMime } = parameter;
if (serializationMime) {
switch (parameter.in) {
case 'path':
case 'header':
return serializeParameterValueWithMime(value, serializationMime);
case 'cookie':
case 'query':
return `${name}=${serializeParameterValueWithMime(value, serializationMime)}`;
default:
console.warn('Unexpected parameter location: ' + parameter.in);
return '';
}
}
if (!style) {
console.warn(`Missing style attribute for parameter ${name}`);
console.warn(`Missing style attribute or content for parameter ${name}`);
return '';
}