mirror of
https://github.com/Redocly/redoc.git
synced 2025-04-19 16:22:05 +03:00
fix: unify redoc config
This commit is contained in:
parent
59ee73fefa
commit
30db4dfe76
|
@ -122,7 +122,7 @@ class DemoApp extends React.Component<
|
|||
<RedocStandalone
|
||||
spec={this.state.spec}
|
||||
specUrl={proxiedUrl}
|
||||
options={{ scrollYOffset: 'nav', untrustedSpec: true }}
|
||||
options={{ scrollYOffset: 'nav', sanitize: true }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -22,20 +22,14 @@ export interface ApiInfoProps {
|
|||
|
||||
@observer
|
||||
export class ApiInfo extends React.Component<ApiInfoProps> {
|
||||
handleDownloadClick = e => {
|
||||
if (!e.target.href) {
|
||||
e.target.href = this.props.store.spec.info.downloadLink;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { store } = this.props;
|
||||
const { info, externalDocs } = store.spec;
|
||||
const hideDownloadButton = store.options.hideDownloadButton;
|
||||
|
||||
const downloadFilename = info.downloadFileName;
|
||||
const downloadLink = info.downloadLink;
|
||||
const hideDownloadButtons = store.options.hideDownloadButtons;
|
||||
|
||||
// FIXME: use downloadUrls
|
||||
const downloadUrls = info.downloadUrls;
|
||||
console.log(downloadUrls);
|
||||
const license =
|
||||
(info.license && (
|
||||
<InfoSpan>
|
||||
|
@ -83,17 +77,22 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
|
|||
<ApiHeader>
|
||||
{info.title} {version}
|
||||
</ApiHeader>
|
||||
{!hideDownloadButton && (
|
||||
{!hideDownloadButtons && (
|
||||
<p>
|
||||
{l('downloadSpecification')}:
|
||||
<DownloadButton
|
||||
download={downloadFilename || true}
|
||||
target="_blank"
|
||||
href={downloadLink}
|
||||
onClick={this.handleDownloadClick}
|
||||
>
|
||||
{l('download')}
|
||||
</DownloadButton>
|
||||
{downloadUrls?.map(({ title, url }) => {
|
||||
return (
|
||||
<DownloadButton
|
||||
download={title}
|
||||
target="_blank"
|
||||
href={url}
|
||||
rel="noreferrer"
|
||||
key={title}
|
||||
>
|
||||
{downloadUrls.length > 1 ? title : l('download')}
|
||||
</DownloadButton>
|
||||
);
|
||||
})}
|
||||
</p>
|
||||
)}
|
||||
<StyledMarkdownBlock>
|
||||
|
|
|
@ -45,7 +45,7 @@ const Json = (props: JsonProps) => {
|
|||
// tslint:disable-next-line
|
||||
ref={node => setNode(node!)}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: jsonToHTML(props.data, options.jsonSampleExpandLevel),
|
||||
__html: jsonToHTML(props.data, options.jsonSamplesExpandLevel),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -10,7 +10,7 @@ const StyledMarkdownSpan = styled(StyledMarkdownBlock)`
|
|||
display: inline;
|
||||
`;
|
||||
|
||||
const sanitize = (untrustedSpec, html) => (untrustedSpec ? DOMPurify.sanitize(html) : html);
|
||||
const sanitize = (sanitize, html) => (sanitize ? DOMPurify.sanitize(html) : html);
|
||||
|
||||
export function SanitizedMarkdownHTML({
|
||||
inline,
|
||||
|
@ -25,7 +25,7 @@ export function SanitizedMarkdownHTML({
|
|||
<Wrap
|
||||
className={'redoc-markdown ' + (rest.className || '')}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: sanitize(options.untrustedSpec, rest.html),
|
||||
__html: sanitize(options.sanitize, rest.html),
|
||||
}}
|
||||
data-role={rest['data-role']}
|
||||
{...rest}
|
||||
|
|
|
@ -27,7 +27,7 @@ export const ObjectSchema = observer(
|
|||
skipWriteOnly,
|
||||
level,
|
||||
}: ObjectSchemaProps) => {
|
||||
const { expandSingleSchemaField, showObjectSchemaExamples, schemaExpansionLevel } =
|
||||
const { expandSingleSchemaField, showObjectSchemaExamples, schemasExpansionLevel } =
|
||||
React.useContext(OptionsContext);
|
||||
|
||||
const filteredFields = React.useMemo(
|
||||
|
@ -45,7 +45,7 @@ export const ObjectSchema = observer(
|
|||
);
|
||||
|
||||
const expandByDefault =
|
||||
(expandSingleSchemaField && filteredFields.length === 1) || schemaExpansionLevel >= level!;
|
||||
(expandSingleSchemaField && filteredFields.length === 1) || schemasExpansionLevel >= level!;
|
||||
|
||||
return (
|
||||
<PropertiesTable>
|
||||
|
|
|
@ -6,23 +6,32 @@ import { setRedocLabels } from './Labels';
|
|||
import { SideNavStyleEnum } from './types';
|
||||
import type { LabelsConfigRaw, MDXComponentMeta } from './types';
|
||||
|
||||
export type DownloadUrlsConfig = {
|
||||
title?: string;
|
||||
url: string;
|
||||
}[];
|
||||
|
||||
export interface RedocRawOptions {
|
||||
theme?: ThemeInterface;
|
||||
scrollYOffset?: number | string | (() => number);
|
||||
hideHostname?: boolean | string;
|
||||
expandResponses?: string | 'all';
|
||||
requiredPropsFirst?: boolean | string;
|
||||
requiredPropsFirst?: boolean | string; // remove in next major release
|
||||
sortRequiredPropsFirst?: boolean | string;
|
||||
sortPropsAlphabetically?: boolean | string;
|
||||
sortEnumValuesAlphabetically?: boolean | string;
|
||||
sortOperationsAlphabetically?: boolean | string;
|
||||
sortTagsAlphabetically?: boolean | string;
|
||||
nativeScrollbars?: boolean | string;
|
||||
pathInMiddlePanel?: boolean | string;
|
||||
untrustedSpec?: boolean | string;
|
||||
untrustedSpec?: boolean | string; // remove in next major release
|
||||
sanitize?: boolean | string;
|
||||
hideLoading?: boolean | string;
|
||||
hideDownloadButton?: boolean | string;
|
||||
hideDownloadButton?: boolean | string; // remove in next major release
|
||||
hideDownloadButtons?: boolean | string;
|
||||
downloadFileName?: string;
|
||||
downloadDefinitionUrl?: string;
|
||||
downloadUrls?: DownloadUrlsConfig;
|
||||
disableSearch?: boolean | string;
|
||||
onlyRequiredInSamples?: boolean | string;
|
||||
showExtensions?: boolean | string | string[];
|
||||
|
@ -30,12 +39,14 @@ export interface RedocRawOptions {
|
|||
hideSingleRequestSampleTab?: boolean | string;
|
||||
hideRequestPayloadSample?: boolean;
|
||||
menuToggle?: boolean | string;
|
||||
jsonSampleExpandLevel?: number | string | 'all';
|
||||
jsonSampleExpandLevel?: number | string | 'all'; // remove in next major release
|
||||
jsonSamplesExpandLevel?: number | string | 'all';
|
||||
hideSchemaTitles?: boolean | string;
|
||||
simpleOneOfTypeLabel?: boolean | string;
|
||||
payloadSampleIdx?: number;
|
||||
expandSingleSchemaField?: boolean | string;
|
||||
schemaExpansionLevel?: number | string | 'all';
|
||||
schemaExpansionLevel?: number | string | 'all'; // remove in next major release
|
||||
schemasExpansionLevel?: number | string | 'all';
|
||||
showObjectSchemaExamples?: boolean | string;
|
||||
showSecuritySchemeType?: boolean;
|
||||
hideSecuritySection?: boolean;
|
||||
|
@ -216,17 +227,16 @@ export class RedocNormalizedOptions {
|
|||
scrollYOffset: () => number;
|
||||
hideHostname: boolean;
|
||||
expandResponses: { [code: string]: boolean } | 'all';
|
||||
requiredPropsFirst: boolean;
|
||||
sortRequiredPropsFirst: boolean;
|
||||
sortPropsAlphabetically: boolean;
|
||||
sortEnumValuesAlphabetically: boolean;
|
||||
sortOperationsAlphabetically: boolean;
|
||||
sortTagsAlphabetically: boolean;
|
||||
nativeScrollbars: boolean;
|
||||
pathInMiddlePanel: boolean;
|
||||
untrustedSpec: boolean;
|
||||
hideDownloadButton: boolean;
|
||||
downloadFileName?: string;
|
||||
downloadDefinitionUrl?: string;
|
||||
sanitize: boolean;
|
||||
hideDownloadButtons: boolean;
|
||||
downloadUrls?: DownloadUrlsConfig;
|
||||
disableSearch: boolean;
|
||||
onlyRequiredInSamples: boolean;
|
||||
showExtensions: boolean | string[];
|
||||
|
@ -234,13 +244,13 @@ export class RedocNormalizedOptions {
|
|||
hideSingleRequestSampleTab: boolean;
|
||||
hideRequestPayloadSample: boolean;
|
||||
menuToggle: boolean;
|
||||
jsonSampleExpandLevel: number;
|
||||
jsonSamplesExpandLevel: number;
|
||||
enumSkipQuotes: boolean;
|
||||
hideSchemaTitles: boolean;
|
||||
simpleOneOfTypeLabel: boolean;
|
||||
payloadSampleIdx: number;
|
||||
expandSingleSchemaField: boolean;
|
||||
schemaExpansionLevel: number;
|
||||
schemasExpansionLevel: number;
|
||||
showObjectSchemaExamples: boolean;
|
||||
showSecuritySchemeType?: boolean;
|
||||
hideSecuritySection?: boolean;
|
||||
|
@ -288,17 +298,20 @@ export class RedocNormalizedOptions {
|
|||
this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset);
|
||||
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
|
||||
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);
|
||||
this.requiredPropsFirst = argValueToBoolean(raw.requiredPropsFirst);
|
||||
this.sortRequiredPropsFirst = argValueToBoolean(
|
||||
raw.sortRequiredPropsFirst || raw.requiredPropsFirst,
|
||||
);
|
||||
this.sortPropsAlphabetically = argValueToBoolean(raw.sortPropsAlphabetically);
|
||||
this.sortEnumValuesAlphabetically = argValueToBoolean(raw.sortEnumValuesAlphabetically);
|
||||
this.sortOperationsAlphabetically = argValueToBoolean(raw.sortOperationsAlphabetically);
|
||||
this.sortTagsAlphabetically = argValueToBoolean(raw.sortTagsAlphabetically);
|
||||
this.nativeScrollbars = argValueToBoolean(raw.nativeScrollbars);
|
||||
this.pathInMiddlePanel = argValueToBoolean(raw.pathInMiddlePanel);
|
||||
this.untrustedSpec = argValueToBoolean(raw.untrustedSpec);
|
||||
this.hideDownloadButton = argValueToBoolean(raw.hideDownloadButton);
|
||||
this.downloadFileName = raw.downloadFileName;
|
||||
this.downloadDefinitionUrl = raw.downloadDefinitionUrl;
|
||||
this.sanitize = argValueToBoolean(raw.sanitize || raw.untrustedSpec);
|
||||
this.hideDownloadButtons = argValueToBoolean(raw.hideDownloadButtons || raw.hideDownloadButton);
|
||||
this.downloadUrls =
|
||||
raw.downloadUrls ||
|
||||
([{ title: raw.downloadFileName, url: raw.downloadDefinitionUrl }] as DownloadUrlsConfig);
|
||||
this.disableSearch = argValueToBoolean(raw.disableSearch);
|
||||
this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples);
|
||||
this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions);
|
||||
|
@ -306,15 +319,17 @@ export class RedocNormalizedOptions {
|
|||
this.hideSingleRequestSampleTab = argValueToBoolean(raw.hideSingleRequestSampleTab);
|
||||
this.hideRequestPayloadSample = argValueToBoolean(raw.hideRequestPayloadSample);
|
||||
this.menuToggle = argValueToBoolean(raw.menuToggle, true);
|
||||
this.jsonSampleExpandLevel = RedocNormalizedOptions.normalizeJsonSampleExpandLevel(
|
||||
raw.jsonSampleExpandLevel,
|
||||
this.jsonSamplesExpandLevel = RedocNormalizedOptions.normalizeJsonSampleExpandLevel(
|
||||
raw.jsonSamplesExpandLevel || raw.jsonSampleExpandLevel,
|
||||
);
|
||||
this.enumSkipQuotes = argValueToBoolean(raw.enumSkipQuotes);
|
||||
this.hideSchemaTitles = argValueToBoolean(raw.hideSchemaTitles);
|
||||
this.simpleOneOfTypeLabel = argValueToBoolean(raw.simpleOneOfTypeLabel);
|
||||
this.payloadSampleIdx = RedocNormalizedOptions.normalizePayloadSampleIdx(raw.payloadSampleIdx);
|
||||
this.expandSingleSchemaField = argValueToBoolean(raw.expandSingleSchemaField);
|
||||
this.schemaExpansionLevel = argValueToExpandLevel(raw.schemaExpansionLevel);
|
||||
this.schemasExpansionLevel = argValueToExpandLevel(
|
||||
raw.schemasExpansionLevel || raw.schemaExpansionLevel,
|
||||
);
|
||||
this.showObjectSchemaExamples = argValueToBoolean(raw.showObjectSchemaExamples);
|
||||
this.showSecuritySchemeType = argValueToBoolean(raw.showSecuritySchemeType);
|
||||
this.hideSecuritySection = argValueToBoolean(raw.hideSecuritySection);
|
||||
|
|
|
@ -139,7 +139,7 @@ describe('Models', () => {
|
|||
} as any;
|
||||
|
||||
const opts = new RedocNormalizedOptions({
|
||||
downloadDefinitionUrl: 'https:test.com/filename.yaml',
|
||||
downloadUrls: [{ title: 'Openapi description', url: 'https:test.com/filename.yaml' }],
|
||||
});
|
||||
const info = new ApiInfoModel(parser, opts);
|
||||
expect(info.downloadLink).toEqual('https:test.com/filename.yaml');
|
||||
|
@ -160,6 +160,13 @@ describe('Models', () => {
|
|||
const info = new ApiInfoModel(parser, opts);
|
||||
expect(info.downloadLink).toEqual('https:test.com/filename.yaml');
|
||||
expect(info.downloadFileName).toEqual('test.yaml');
|
||||
|
||||
const opts2 = new RedocNormalizedOptions({
|
||||
downloadUrls: [{ title: 'test.yaml', url: 'https:test.com/filename.yaml' }],
|
||||
});
|
||||
const info2 = new ApiInfoModel(parser, opts2);
|
||||
expect(info2.downloadLink).toEqual('https:test.com/filename.yaml');
|
||||
expect(info2.downloadFileName).toEqual('test.yaml');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { OpenAPIContact, OpenAPIInfo, OpenAPILicense } from '../../types';
|
||||
import { IS_BROWSER } from '../../utils/';
|
||||
import type { OpenAPIParser } from '../OpenAPIParser';
|
||||
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
|
||||
import { DownloadUrlsConfig, RedocNormalizedOptions } from '../RedocNormalizedOptions';
|
||||
|
||||
export class ApiInfoModel implements OpenAPIInfo {
|
||||
title: string;
|
||||
|
@ -13,8 +13,7 @@ export class ApiInfoModel implements OpenAPIInfo {
|
|||
contact?: OpenAPIContact;
|
||||
license?: OpenAPILicense;
|
||||
|
||||
downloadLink?: string;
|
||||
downloadFileName?: string;
|
||||
downloadUrls?: DownloadUrlsConfig;
|
||||
|
||||
constructor(
|
||||
private parser: OpenAPIParser,
|
||||
|
@ -29,13 +28,20 @@ export class ApiInfoModel implements OpenAPIInfo {
|
|||
this.description = this.description.substring(0, firstHeadingLinePos);
|
||||
}
|
||||
|
||||
this.downloadLink = this.getDownloadLink();
|
||||
this.downloadFileName = this.getDownloadFileName();
|
||||
this.downloadUrls = this.getDownloadUrls();
|
||||
}
|
||||
private getDownloadUrls(): DownloadUrlsConfig | undefined {
|
||||
return this.options.downloadUrls
|
||||
?.map(({ title, url }) => ({
|
||||
title: title || 'openapi.json',
|
||||
url: this.getDownloadLink(url) || '',
|
||||
}))
|
||||
.filter(({ title, url }) => title && url);
|
||||
}
|
||||
|
||||
private getDownloadLink(): string | undefined {
|
||||
if (this.options.downloadDefinitionUrl) {
|
||||
return this.options.downloadDefinitionUrl;
|
||||
private getDownloadLink(url?: string): string | undefined {
|
||||
if (url) {
|
||||
return url;
|
||||
}
|
||||
|
||||
if (this.parser.specUrl) {
|
||||
|
@ -49,11 +55,4 @@ export class ApiInfoModel implements OpenAPIInfo {
|
|||
return window.URL.createObjectURL(blob);
|
||||
}
|
||||
}
|
||||
|
||||
private getDownloadFileName(): string | undefined {
|
||||
if (!this.parser.specUrl && !this.options.downloadDefinitionUrl) {
|
||||
return this.options.downloadFileName || 'openapi.json';
|
||||
}
|
||||
return this.options.downloadFileName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ export class OperationModel implements IMenuItem {
|
|||
if (this.options.sortPropsAlphabetically) {
|
||||
return sortByField(_parameters, 'name');
|
||||
}
|
||||
if (this.options.requiredPropsFirst) {
|
||||
if (this.options.sortRequiredPropsFirst) {
|
||||
return sortByRequired(_parameters);
|
||||
}
|
||||
|
||||
|
|
|
@ -463,7 +463,7 @@ function buildFields(
|
|||
if (options.sortPropsAlphabetically) {
|
||||
fields = sortByField(fields, 'name');
|
||||
}
|
||||
if (options.requiredPropsFirst) {
|
||||
if (options.sortRequiredPropsFirst) {
|
||||
// if not sort alphabetically sort in the order from required keyword
|
||||
fields = sortByRequired(fields, !options.sortPropsAlphabetically ? schema.required : undefined);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user