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:
Roman Hotsiy 2018-07-17 12:17:06 +03:00
parent edc77a2017
commit c35925a332
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
6 changed files with 26 additions and 26 deletions

View File

@ -20,9 +20,16 @@ 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;
@ -68,10 +75,15 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
<ApiHeader>
{info.title} <span>({info.version})</span>
</ApiHeader>
{downloadLink && (
{!hideDownloadButton && (
<p>
Download OpenAPI specification:
<DownloadButton download={downloadFilename} target="_blank" href={downloadLink}>
<DownloadButton
download={downloadFilename}
target="_blank"
href={downloadLink || '#'}
onClick={this.handleDownloadClick}
>
Download
</DownloadButton>
</p>

View File

@ -15,7 +15,7 @@ export interface StoreState {
activeItemIdx: number;
};
spec: {
url: string;
url?: string;
data: any;
};
searchIndex: any;

View File

@ -39,7 +39,7 @@ class RefCounter {
* Loads and keeps spec. Provides raw spec operations
*/
export class OpenAPIParser {
@observable specUrl: string;
@observable specUrl?: string;
@observable.ref spec: OpenAPISpec;
private _refCounter: RefCounter = new RefCounter();
@ -57,8 +57,6 @@ export class OpenAPIParser {
const href = IS_BROWSER ? window.location.href : '';
if (typeof specUrl === 'string') {
this.specUrl = urlResolve(href, specUrl);
} else {
this.specUrl = href;
}
}

View File

@ -22,7 +22,7 @@ export class SpecStore {
@computed
get info(): ApiInfoModel {
return new ApiInfoModel(this.parser, this.options);
return new ApiInfoModel(this.parser);
}
@computed

View File

@ -11,29 +11,20 @@ export class ApiInfoModel implements OpenAPIInfo {
contact?: OpenAPIContact;
license?: OpenAPILicense;
constructor(private parser: OpenAPIParser, private options: RedocNormalizedOptions) {
constructor(private parser: OpenAPIParser) {
Object.assign(this, parser.spec.info);
}
get downloadLink() {
if (this.options.hideDownloadButton) {
return undefined;
}
get downloadLink(): string | undefined {
if (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)], {
type: 'application/json',
});
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')
);
}
}

View File

@ -11,6 +11,7 @@ import { OpenAPIExternalDocumentation, OpenAPIServer } from '../../types';
import {
getOperationSummary,
getStatusCodeType,
IS_BROWSER,
isAbsolutePath,
isStatusCode,
JsonPointer,
@ -148,25 +149,23 @@ export class OperationModel implements IMenuItem {
}
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function normalizeServers(specUrl: string | undefined, servers: OpenAPIServer[]): OpenAPIServer[] {
const baseUrl = specUrl === undefined ? (IS_BROWSER ? window.location.href : '') : specUrl;
function normalizeServers(specUrl: string, servers: OpenAPIServer[]): OpenAPIServer[] {
if (servers.length === 0) {
return [
{
url: specUrl,
url: baseUrl,
},
];
}
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);
}
const { protocol: specProtocol } = urlParse(specUrl);
const { protocol: specProtocol } = urlParse(baseUrl);
return servers.map(server => {
return {