Skip to content

Commit

Permalink
feat: Add download file option (#1699)
Browse files Browse the repository at this point in the history
Co-authored-by: Zach Whaley <zachbwhaley@gmail.com>
Co-authored-by: Roman Hotsiy <gotsijroman@gmail.com>
Co-authored-by: anastasiia-developer <anastasiia@redocly.com>
Co-authored-by: Ivana Isadora Devcic <33730345+skadinna@users.noreply.github.com>
  • Loading branch information
4 people authored May 10, 2022
1 parent 494122f commit b601c9a
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 5 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ You can use all of the following options with the standalone version of the <red
* `generatedPayloadSamplesMaxDepth` - set the maximum render depth for JSON payload samples (responses and request body). The default value is `10`.
* `maxDisplayedEnumValues` - display only specified number of enum values. hide rest values under spoiler.
* `hideDownloadButton` - do not show "Download" spec button. **THIS DOESN'T MAKE YOUR SPEC PRIVATE**, it just hides the button.
* `downloadFileName` - set a custom file name for the downloaded API definition file.
* `downloadDefinitionUrl` - If the 'Download' button is visible in the API reference documentation (hideDownloadButton=false), the URL configured here will open when that button is selected. Provide it as an absolute URL with the full URI scheme.
* `hideHostname` - if set, the protocol and hostname is not shown in the operation definition.
* `hideLoading` - do not show loading animation. Useful for small docs.
* `hideFab` - do not show FAB in mobile view. Useful for implementing a custom floating action button.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -329,6 +331,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -556,6 +560,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -850,6 +856,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -1102,6 +1110,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -1329,6 +1339,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -1579,6 +1591,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -1870,6 +1884,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -2122,6 +2138,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down Expand Up @@ -2349,6 +2367,8 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
"options": RedocNormalizedOptions {
"allowedMdComponents": Object {},
"disableSearch": false,
"downloadDefinitionUrl": undefined,
"downloadFileName": undefined,
"enumSkipQuotes": false,
"expandDefaultServerVariables": false,
"expandResponses": Object {},
Expand Down
6 changes: 6 additions & 0 deletions src/services/RedocNormalizedOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export interface RedocRawOptions {
untrustedSpec?: boolean | string;
hideLoading?: boolean | string;
hideDownloadButton?: boolean | string;
downloadFileName?: string;
downloadDefinitionUrl?: string;
disableSearch?: boolean | string;
onlyRequiredInSamples?: boolean | string;
showExtensions?: boolean | string | string[];
Expand Down Expand Up @@ -226,6 +228,8 @@ export class RedocNormalizedOptions {
pathInMiddlePanel: boolean;
untrustedSpec: boolean;
hideDownloadButton: boolean;
downloadFileName?: string;
downloadDefinitionUrl?: string;
disableSearch: boolean;
onlyRequiredInSamples: boolean;
showExtensions: boolean | string[];
Expand Down Expand Up @@ -293,6 +297,8 @@ export class RedocNormalizedOptions {
this.pathInMiddlePanel = argValueToBoolean(raw.pathInMiddlePanel);
this.untrustedSpec = argValueToBoolean(raw.untrustedSpec);
this.hideDownloadButton = argValueToBoolean(raw.hideDownloadButton);
this.downloadFileName = raw.downloadFileName;
this.downloadDefinitionUrl = raw.downloadDefinitionUrl;
this.disableSearch = argValueToBoolean(raw.disableSearch);
this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples);
this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions);
Expand Down
2 changes: 1 addition & 1 deletion src/services/SpecStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class SpecStore {
private options: RedocNormalizedOptions,
) {
this.parser = new OpenAPIParser(spec, specUrl, options);
this.info = new ApiInfoModel(this.parser);
this.info = new ApiInfoModel(this.parser, this.options);
this.externalDocs = this.parser.spec.externalDocs;
this.contentItems = MenuBuilder.buildStructure(this.parser, this.options);
this.securitySchemes = new SecuritySchemesModel(this.parser);
Expand Down
75 changes: 75 additions & 0 deletions src/services/__tests__/models/ApiInfo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,80 @@ describe('Models', () => {
const { license = { identifier: null } } = new ApiInfoModel(parser);
expect(license.identifier).toEqual('MIT');
});

test('should correctly populate default download file name', () => {
parser.spec = {
openapi: '3.0.0',
info: {
description: 'Test description',
},
} as any;

const info = new ApiInfoModel(parser);
expect(info.downloadFileName).toEqual('openapi.json');
});

test('should correctly populate default download file is undefined when using specUrl', () => {
parser = new OpenAPIParser(
{
openapi: '3.0.0',
info: {
description: 'Test description',
},
} as any,
'/demo/openapi.yaml',
opts,
);

const info = new ApiInfoModel(parser);
expect(info.downloadFileName).toEqual(undefined);
});

test('should correctly populate download file name', () => {
parser.spec = {
info: {
description: 'Test description',
},
} as any;

const opts = new RedocNormalizedOptions({
downloadFileName: 'test.yaml',
});

const info = new ApiInfoModel(parser, opts);
expect(info.downloadFileName).toEqual('test.yaml');
});

test('should correctly populate download link', () => {
parser.spec = {
openapi: '3.0.0',
info: {
description: 'Test description',
},
} as any;

const opts = new RedocNormalizedOptions({
downloadDefinitionUrl: 'https:test.com/filename.yaml',
});
const info = new ApiInfoModel(parser, opts);
expect(info.downloadLink).toEqual('https:test.com/filename.yaml');
});

test('should correctly populate download link and download file name', () => {
parser.spec = {
openapi: '3.0.0',
info: {
description: 'Test description',
},
} as any;

const opts = new RedocNormalizedOptions({
downloadDefinitionUrl: 'https:test.com/filename.yaml',
downloadFileName: 'test.yaml',
});
const info = new ApiInfoModel(parser, opts);
expect(info.downloadLink).toEqual('https:test.com/filename.yaml');
expect(info.downloadFileName).toEqual('test.yaml');
});
});
});
16 changes: 12 additions & 4 deletions src/services/models/ApiInfo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { OpenAPIContact, OpenAPIInfo, OpenAPILicense } from '../../types';
import { IS_BROWSER } from '../../utils/';
import { OpenAPIParser } from '../OpenAPIParser';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';

export class ApiInfoModel implements OpenAPIInfo {
title: string;
Expand All @@ -15,7 +16,10 @@ export class ApiInfoModel implements OpenAPIInfo {
downloadLink?: string;
downloadFileName?: string;

constructor(private parser: OpenAPIParser) {
constructor(
private parser: OpenAPIParser,
private options: RedocNormalizedOptions = new RedocNormalizedOptions({}),
) {
Object.assign(this, parser.spec.info);
this.description = parser.spec.info.description || '';
this.summary = parser.spec.info.summary || '';
Expand All @@ -30,6 +34,10 @@ export class ApiInfoModel implements OpenAPIInfo {
}

private getDownloadLink(): string | undefined {
if (this.options.downloadDefinitionUrl) {
return this.options.downloadDefinitionUrl;
}

if (this.parser.specUrl) {
return this.parser.specUrl;
}
Expand All @@ -43,9 +51,9 @@ export class ApiInfoModel implements OpenAPIInfo {
}

private getDownloadFileName(): string | undefined {
if (!this.parser.specUrl) {
return 'swagger.json';
if (!this.parser.specUrl && !this.options.downloadDefinitionUrl) {
return this.options.downloadFileName || 'openapi.json';
}
return undefined;
return this.options.downloadFileName;
}
}

0 comments on commit b601c9a

Please sign in to comment.