Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add download file option #1699

Merged
merged 14 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,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 @@ -74,6 +74,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 @@ -324,6 +326,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 @@ -550,6 +554,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 @@ -841,6 +847,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 @@ -1091,6 +1099,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 @@ -1317,6 +1327,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 @@ -1566,6 +1578,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 @@ -1854,6 +1868,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 @@ -2104,6 +2120,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 @@ -2330,6 +2348,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 @@ -225,6 +227,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 @@ -291,6 +295,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;
}
}