Skip to content

Commit c35925a

Browse files
committed
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
1 parent edc77a2 commit c35925a

File tree

6 files changed

+26
-26
lines changed

6 files changed

+26
-26
lines changed

src/components/ApiInfo/ApiInfo.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,16 @@ export interface ApiInfoProps {
2020

2121
@observer
2222
export class ApiInfo extends React.Component<ApiInfoProps> {
23+
handleDownloadClick = e => {
24+
if (!e.target.href) {
25+
e.target.href = this.props.store.spec.info.downloadLink;
26+
}
27+
};
28+
2329
render() {
2430
const { store } = this.props;
2531
const { info, externalDocs } = store.spec;
32+
const hideDownloadButton = store.options.hideDownloadButton;
2633

2734
const downloadFilename = info.downloadFileName;
2835
const downloadLink = info.downloadLink;
@@ -68,10 +75,15 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
6875
<ApiHeader>
6976
{info.title} <span>({info.version})</span>
7077
</ApiHeader>
71-
{downloadLink && (
78+
{!hideDownloadButton && (
7279
<p>
7380
Download OpenAPI specification:
74-
<DownloadButton download={downloadFilename} target="_blank" href={downloadLink}>
81+
<DownloadButton
82+
download={downloadFilename}
83+
target="_blank"
84+
href={downloadLink || '#'}
85+
onClick={this.handleDownloadClick}
86+
>
7587
Download
7688
</DownloadButton>
7789
</p>

src/services/AppStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface StoreState {
1515
activeItemIdx: number;
1616
};
1717
spec: {
18-
url: string;
18+
url?: string;
1919
data: any;
2020
};
2121
searchIndex: any;

src/services/OpenAPIParser.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class RefCounter {
3939
* Loads and keeps spec. Provides raw spec operations
4040
*/
4141
export class OpenAPIParser {
42-
@observable specUrl: string;
42+
@observable specUrl?: string;
4343
@observable.ref spec: OpenAPISpec;
4444

4545
private _refCounter: RefCounter = new RefCounter();
@@ -57,8 +57,6 @@ export class OpenAPIParser {
5757
const href = IS_BROWSER ? window.location.href : '';
5858
if (typeof specUrl === 'string') {
5959
this.specUrl = urlResolve(href, specUrl);
60-
} else {
61-
this.specUrl = href;
6260
}
6361
}
6462

src/services/SpecStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class SpecStore {
2222

2323
@computed
2424
get info(): ApiInfoModel {
25-
return new ApiInfoModel(this.parser, this.options);
25+
return new ApiInfoModel(this.parser);
2626
}
2727

2828
@computed

src/services/models/ApiInfo.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,20 @@ export class ApiInfoModel implements OpenAPIInfo {
1111
contact?: OpenAPIContact;
1212
license?: OpenAPILicense;
1313

14-
constructor(private parser: OpenAPIParser, private options: RedocNormalizedOptions) {
14+
constructor(private parser: OpenAPIParser) {
1515
Object.assign(this, parser.spec.info);
1616
}
1717

18-
get downloadLink() {
19-
if (this.options.hideDownloadButton) {
20-
return undefined;
21-
}
22-
18+
get downloadLink(): string | undefined {
2319
if (this.parser.specUrl) {
2420
return this.parser.specUrl;
2521
}
2622

27-
if (IS_BROWSER && window.Blob && window.URL) {
23+
if (IS_BROWSER && window.Blob && window.URL && window.URL.createObjectURL) {
2824
const blob = new Blob([JSON.stringify(this.parser.spec, null, 2)], {
2925
type: 'application/json',
3026
});
3127
return window.URL.createObjectURL(blob);
32-
} else if (!IS_BROWSER) {
33-
return (
34-
'data:application/octet-stream;base64,' +
35-
new Buffer(JSON.stringify(this.parser.spec, null, 2)).toString('base64')
36-
);
3728
}
3829
}
3930

src/services/models/Operation.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { OpenAPIExternalDocumentation, OpenAPIServer } from '../../types';
1111
import {
1212
getOperationSummary,
1313
getStatusCodeType,
14+
IS_BROWSER,
1415
isAbsolutePath,
1516
isStatusCode,
1617
JsonPointer,
@@ -148,25 +149,23 @@ export class OperationModel implements IMenuItem {
148149
}
149150
}
150151

151-
function isNumeric(n) {
152-
return !isNaN(parseFloat(n)) && isFinite(n);
153-
}
152+
function normalizeServers(specUrl: string | undefined, servers: OpenAPIServer[]): OpenAPIServer[] {
153+
const baseUrl = specUrl === undefined ? (IS_BROWSER ? window.location.href : '') : specUrl;
154154

155-
function normalizeServers(specUrl: string, servers: OpenAPIServer[]): OpenAPIServer[] {
156155
if (servers.length === 0) {
157156
return [
158157
{
159-
url: specUrl,
158+
url: baseUrl,
160159
},
161160
];
162161
}
163162

164163
function normalizeUrl(url: string): string {
165-
url = isAbsolutePath(url) ? url : joinPaths(specUrl, url);
164+
url = isAbsolutePath(url) ? url : joinPaths(baseUrl, url);
166165
return stripTrailingSlash(url.startsWith('//') ? `${specProtocol}${url}` : url);
167166
}
168167

169-
const { protocol: specProtocol } = urlParse(specUrl);
168+
const { protocol: specProtocol } = urlParse(baseUrl);
170169

171170
return servers.map(server => {
172171
return {

0 commit comments

Comments
 (0)