mirror of
https://github.com/Redocly/redoc.git
synced 2025-02-07 21:40:32 +03:00
* fix: x-examples for request body param does not display #1743 * lint * fix ts
This commit is contained in:
parent
913b3a422f
commit
aaa3b3280c
|
@ -18,7 +18,6 @@ import { ResponsesList } from '../Responses/ResponsesList';
|
||||||
import { ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
import { ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
||||||
import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
||||||
|
|
||||||
|
|
||||||
const Description = styled.div`
|
const Description = styled.div`
|
||||||
margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px;
|
margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px;
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { OpenAPIRequestBody, Referenced } from '../../types';
|
||||||
import { OpenAPIParser } from '../OpenAPIParser';
|
import { OpenAPIParser } from '../OpenAPIParser';
|
||||||
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
|
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
|
||||||
import { MediaContentModel } from './MediaContent';
|
import { MediaContentModel } from './MediaContent';
|
||||||
|
import { getContentWithLegacyExamples } from '../../utils';
|
||||||
|
|
||||||
type RequestBodyProps = {
|
type RequestBodyProps = {
|
||||||
parser: OpenAPIParser;
|
parser: OpenAPIParser;
|
||||||
|
@ -18,13 +19,15 @@ export class RequestBodyModel {
|
||||||
|
|
||||||
constructor(props: RequestBodyProps) {
|
constructor(props: RequestBodyProps) {
|
||||||
const { parser, infoOrRef, options, isEvent } = props;
|
const { parser, infoOrRef, options, isEvent } = props;
|
||||||
const isRequest = isEvent ? false : true;
|
const isRequest = !isEvent;
|
||||||
const info = parser.deref(infoOrRef);
|
const info = parser.deref(infoOrRef);
|
||||||
this.description = info.description || '';
|
this.description = info.description || '';
|
||||||
this.required = !!info.required;
|
this.required = !!info.required;
|
||||||
parser.exitRef(infoOrRef);
|
parser.exitRef(infoOrRef);
|
||||||
if (info.content !== undefined) {
|
|
||||||
this.content = new MediaContentModel(parser, info.content, isRequest, options);
|
const mediaContent = getContentWithLegacyExamples(info);
|
||||||
|
if (mediaContent !== undefined) {
|
||||||
|
this.content = new MediaContentModel(parser, mediaContent, isRequest, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,17 +186,20 @@ export interface OpenAPIRequestBody {
|
||||||
description?: string;
|
description?: string;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
content: { [mime: string]: OpenAPIMediaType };
|
content: { [mime: string]: OpenAPIMediaType };
|
||||||
|
|
||||||
|
'x-examples'?: { [mime: string]: { [name: string]: Referenced<OpenAPIExample> } };
|
||||||
|
'x-example'?: { [mime: string]: any };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenAPIResponses {
|
export interface OpenAPIResponses {
|
||||||
[code: string]: OpenAPIResponse;
|
[code: string]: OpenAPIResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenAPIResponse {
|
export interface OpenAPIResponse
|
||||||
description?: string;
|
extends Pick<OpenAPIRequestBody, 'description' | 'x-examples' | 'x-example'> {
|
||||||
headers?: { [name: string]: Referenced<OpenAPIHeader> };
|
headers?: { [name: string]: Referenced<OpenAPIHeader> };
|
||||||
content?: { [mime: string]: OpenAPIMediaType };
|
|
||||||
links?: { [name: string]: Referenced<OpenAPILink> };
|
links?: { [name: string]: Referenced<OpenAPILink> };
|
||||||
|
content?: { [mime: string]: OpenAPIMediaType };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenAPILink {
|
export interface OpenAPILink {
|
||||||
|
|
|
@ -11,10 +11,16 @@ import {
|
||||||
serializeParameterValue,
|
serializeParameterValue,
|
||||||
sortByRequired,
|
sortByRequired,
|
||||||
humanizeNumberRange,
|
humanizeNumberRange,
|
||||||
|
getContentWithLegacyExamples,
|
||||||
} from '../';
|
} from '../';
|
||||||
|
|
||||||
import { FieldModel, OpenAPIParser, RedocNormalizedOptions } from '../../services';
|
import { FieldModel, OpenAPIParser, RedocNormalizedOptions } from '../../services';
|
||||||
import { OpenAPIParameter, OpenAPIParameterLocation, OpenAPIParameterStyle } from '../../types';
|
import {
|
||||||
|
OpenAPIMediaType,
|
||||||
|
OpenAPIParameter,
|
||||||
|
OpenAPIParameterLocation,
|
||||||
|
OpenAPIParameterStyle,
|
||||||
|
} from '../../types';
|
||||||
import { expandDefaultServerVariables } from '../openapi';
|
import { expandDefaultServerVariables } from '../openapi';
|
||||||
|
|
||||||
describe('Utils', () => {
|
describe('Utils', () => {
|
||||||
|
@ -1161,4 +1167,106 @@ describe('Utils', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('OpenAPI getContentWithLegacyExamples', () => {
|
||||||
|
it('should return undefined if no x-examples/x-example and no content', () => {
|
||||||
|
expect(getContentWithLegacyExamples({})).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return unmodified object if no x-examples or x-example', () => {
|
||||||
|
const info = {
|
||||||
|
content: {
|
||||||
|
'application/json': {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const content = getContentWithLegacyExamples(info);
|
||||||
|
expect(content).toStrictEqual(info.content);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a new content object if no content and x-examples', () => {
|
||||||
|
const info = {
|
||||||
|
'x-examples': {
|
||||||
|
'application/json': {
|
||||||
|
name: {
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const content = getContentWithLegacyExamples(info);
|
||||||
|
expect(content).toEqual({
|
||||||
|
'application/json': {
|
||||||
|
examples: {
|
||||||
|
name: {
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a new content object if no content and x-example', () => {
|
||||||
|
const info = {
|
||||||
|
'x-example': {
|
||||||
|
'application/json': 'test',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const content = getContentWithLegacyExamples(info);
|
||||||
|
expect(content).toEqual({
|
||||||
|
'application/json': { example: 'test' },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return copy of content with injected x-example', () => {
|
||||||
|
const info = {
|
||||||
|
'x-example': {
|
||||||
|
'application/json': 'test',
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: { type: 'string' },
|
||||||
|
},
|
||||||
|
'text/plain': { schema: { type: 'string' } },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const content = getContentWithLegacyExamples(info) as { [mime: string]: OpenAPIMediaType };
|
||||||
|
expect(content).toEqual({
|
||||||
|
'application/json': { schema: { type: 'string' }, example: 'test' },
|
||||||
|
'text/plain': { schema: { type: 'string' } },
|
||||||
|
});
|
||||||
|
expect(content).not.toStrictEqual(info.content);
|
||||||
|
expect(content['application/json']).not.toStrictEqual(info.content['application/json']);
|
||||||
|
expect(content['text/plain']).toStrictEqual(info.content['text/plain']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should prefer x-examples over x-example', () => {
|
||||||
|
const info = {
|
||||||
|
'x-example': {
|
||||||
|
'application/json': 'test',
|
||||||
|
},
|
||||||
|
'x-examples': {
|
||||||
|
'application/json': { name: { value: 'test' } },
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: { type: 'string' },
|
||||||
|
},
|
||||||
|
'text/plain': { schema: { type: 'string' } },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const content = getContentWithLegacyExamples(info) as { [mime: string]: OpenAPIMediaType };
|
||||||
|
expect(content).toEqual({
|
||||||
|
'application/json': { schema: { type: 'string' }, examples: { name: { value: 'test' } } },
|
||||||
|
'text/plain': { schema: { type: 'string' } },
|
||||||
|
});
|
||||||
|
expect(content).not.toStrictEqual(info.content);
|
||||||
|
expect(content['application/json']).not.toStrictEqual(info.content['application/json']);
|
||||||
|
expect(content['text/plain']).toStrictEqual(info.content['text/plain']);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
OpenAPIMediaType,
|
OpenAPIMediaType,
|
||||||
OpenAPIParameter,
|
OpenAPIParameter,
|
||||||
OpenAPIParameterStyle,
|
OpenAPIParameterStyle,
|
||||||
|
OpenAPIRequestBody,
|
||||||
|
OpenAPIResponse,
|
||||||
OpenAPISchema,
|
OpenAPISchema,
|
||||||
OpenAPIServer,
|
OpenAPIServer,
|
||||||
Referenced,
|
Referenced,
|
||||||
|
@ -638,3 +640,33 @@ export function pluralizeType(displayType: string): string {
|
||||||
.map(type => type.replace(/^(string|object|number|integer|array|boolean)s?( ?.*)/, '$1s$2'))
|
.map(type => type.replace(/^(string|object|number|integer|array|boolean)s?( ?.*)/, '$1s$2'))
|
||||||
.join(' or ');
|
.join(' or ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getContentWithLegacyExamples(
|
||||||
|
info: OpenAPIRequestBody | OpenAPIResponse,
|
||||||
|
): { [mime: string]: OpenAPIMediaType } | undefined {
|
||||||
|
let mediaContent = info.content;
|
||||||
|
const xExamples = info['x-examples']; // converted from OAS2 body param
|
||||||
|
const xExample = info['x-example']; // converted from OAS2 body param
|
||||||
|
|
||||||
|
if (xExamples) {
|
||||||
|
mediaContent = { ...mediaContent };
|
||||||
|
for (const mime of Object.keys(xExamples)) {
|
||||||
|
const examples = xExamples[mime];
|
||||||
|
mediaContent[mime] = {
|
||||||
|
...mediaContent[mime],
|
||||||
|
examples,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (xExample) {
|
||||||
|
mediaContent = { ...mediaContent };
|
||||||
|
for (const mime of Object.keys(xExample)) {
|
||||||
|
const example = xExample[mime];
|
||||||
|
mediaContent[mime] = {
|
||||||
|
...mediaContent[mime],
|
||||||
|
example,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mediaContent;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user