mirror of
https://github.com/Redocly/redoc.git
synced 2025-02-07 13:30:33 +03:00
fix: fix Download button url when spec as object was provided
+ do not output huge base64 encoded link when SSR, instead use button handler fixes #462 related #540
This commit is contained in:
parent
edc77a2017
commit
c35925a332
|
@ -20,9 +20,16 @@ export interface ApiInfoProps {
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class ApiInfo extends React.Component<ApiInfoProps> {
|
export class ApiInfo extends React.Component<ApiInfoProps> {
|
||||||
|
handleDownloadClick = e => {
|
||||||
|
if (!e.target.href) {
|
||||||
|
e.target.href = this.props.store.spec.info.downloadLink;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { store } = this.props;
|
const { store } = this.props;
|
||||||
const { info, externalDocs } = store.spec;
|
const { info, externalDocs } = store.spec;
|
||||||
|
const hideDownloadButton = store.options.hideDownloadButton;
|
||||||
|
|
||||||
const downloadFilename = info.downloadFileName;
|
const downloadFilename = info.downloadFileName;
|
||||||
const downloadLink = info.downloadLink;
|
const downloadLink = info.downloadLink;
|
||||||
|
@ -68,10 +75,15 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
|
||||||
<ApiHeader>
|
<ApiHeader>
|
||||||
{info.title} <span>({info.version})</span>
|
{info.title} <span>({info.version})</span>
|
||||||
</ApiHeader>
|
</ApiHeader>
|
||||||
{downloadLink && (
|
{!hideDownloadButton && (
|
||||||
<p>
|
<p>
|
||||||
Download OpenAPI specification:
|
Download OpenAPI specification:
|
||||||
<DownloadButton download={downloadFilename} target="_blank" href={downloadLink}>
|
<DownloadButton
|
||||||
|
download={downloadFilename}
|
||||||
|
target="_blank"
|
||||||
|
href={downloadLink || '#'}
|
||||||
|
onClick={this.handleDownloadClick}
|
||||||
|
>
|
||||||
Download
|
Download
|
||||||
</DownloadButton>
|
</DownloadButton>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -15,7 +15,7 @@ export interface StoreState {
|
||||||
activeItemIdx: number;
|
activeItemIdx: number;
|
||||||
};
|
};
|
||||||
spec: {
|
spec: {
|
||||||
url: string;
|
url?: string;
|
||||||
data: any;
|
data: any;
|
||||||
};
|
};
|
||||||
searchIndex: any;
|
searchIndex: any;
|
||||||
|
|
|
@ -39,7 +39,7 @@ class RefCounter {
|
||||||
* Loads and keeps spec. Provides raw spec operations
|
* Loads and keeps spec. Provides raw spec operations
|
||||||
*/
|
*/
|
||||||
export class OpenAPIParser {
|
export class OpenAPIParser {
|
||||||
@observable specUrl: string;
|
@observable specUrl?: string;
|
||||||
@observable.ref spec: OpenAPISpec;
|
@observable.ref spec: OpenAPISpec;
|
||||||
|
|
||||||
private _refCounter: RefCounter = new RefCounter();
|
private _refCounter: RefCounter = new RefCounter();
|
||||||
|
@ -57,8 +57,6 @@ export class OpenAPIParser {
|
||||||
const href = IS_BROWSER ? window.location.href : '';
|
const href = IS_BROWSER ? window.location.href : '';
|
||||||
if (typeof specUrl === 'string') {
|
if (typeof specUrl === 'string') {
|
||||||
this.specUrl = urlResolve(href, specUrl);
|
this.specUrl = urlResolve(href, specUrl);
|
||||||
} else {
|
|
||||||
this.specUrl = href;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class SpecStore {
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
get info(): ApiInfoModel {
|
get info(): ApiInfoModel {
|
||||||
return new ApiInfoModel(this.parser, this.options);
|
return new ApiInfoModel(this.parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
|
|
|
@ -11,29 +11,20 @@ export class ApiInfoModel implements OpenAPIInfo {
|
||||||
contact?: OpenAPIContact;
|
contact?: OpenAPIContact;
|
||||||
license?: OpenAPILicense;
|
license?: OpenAPILicense;
|
||||||
|
|
||||||
constructor(private parser: OpenAPIParser, private options: RedocNormalizedOptions) {
|
constructor(private parser: OpenAPIParser) {
|
||||||
Object.assign(this, parser.spec.info);
|
Object.assign(this, parser.spec.info);
|
||||||
}
|
}
|
||||||
|
|
||||||
get downloadLink() {
|
get downloadLink(): string | undefined {
|
||||||
if (this.options.hideDownloadButton) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.parser.specUrl) {
|
if (this.parser.specUrl) {
|
||||||
return this.parser.specUrl;
|
return this.parser.specUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_BROWSER && window.Blob && window.URL) {
|
if (IS_BROWSER && window.Blob && window.URL && window.URL.createObjectURL) {
|
||||||
const blob = new Blob([JSON.stringify(this.parser.spec, null, 2)], {
|
const blob = new Blob([JSON.stringify(this.parser.spec, null, 2)], {
|
||||||
type: 'application/json',
|
type: 'application/json',
|
||||||
});
|
});
|
||||||
return window.URL.createObjectURL(blob);
|
return window.URL.createObjectURL(blob);
|
||||||
} else if (!IS_BROWSER) {
|
|
||||||
return (
|
|
||||||
'data:application/octet-stream;base64,' +
|
|
||||||
new Buffer(JSON.stringify(this.parser.spec, null, 2)).toString('base64')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { OpenAPIExternalDocumentation, OpenAPIServer } from '../../types';
|
||||||
import {
|
import {
|
||||||
getOperationSummary,
|
getOperationSummary,
|
||||||
getStatusCodeType,
|
getStatusCodeType,
|
||||||
|
IS_BROWSER,
|
||||||
isAbsolutePath,
|
isAbsolutePath,
|
||||||
isStatusCode,
|
isStatusCode,
|
||||||
JsonPointer,
|
JsonPointer,
|
||||||
|
@ -148,25 +149,23 @@ export class OperationModel implements IMenuItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNumeric(n) {
|
function normalizeServers(specUrl: string | undefined, servers: OpenAPIServer[]): OpenAPIServer[] {
|
||||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
const baseUrl = specUrl === undefined ? (IS_BROWSER ? window.location.href : '') : specUrl;
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeServers(specUrl: string, servers: OpenAPIServer[]): OpenAPIServer[] {
|
|
||||||
if (servers.length === 0) {
|
if (servers.length === 0) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
url: specUrl,
|
url: baseUrl,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeUrl(url: string): string {
|
function normalizeUrl(url: string): string {
|
||||||
url = isAbsolutePath(url) ? url : joinPaths(specUrl, url);
|
url = isAbsolutePath(url) ? url : joinPaths(baseUrl, url);
|
||||||
return stripTrailingSlash(url.startsWith('//') ? `${specProtocol}${url}` : url);
|
return stripTrailingSlash(url.startsWith('//') ? `${specProtocol}${url}` : url);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { protocol: specProtocol } = urlParse(specUrl);
|
const { protocol: specProtocol } = urlParse(baseUrl);
|
||||||
|
|
||||||
return servers.map(server => {
|
return servers.map(server => {
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user