mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 10:33:44 +03:00
Implement noAutoAuth option
This commit is contained in:
parent
a28e24ec92
commit
f607b98866
|
@ -8,30 +8,31 @@ import { Schema } from '../Schema';
|
|||
import { ObjectSchema } from '../ObjectSchema';
|
||||
import * as simpleDiscriminatorFixture from './fixtures/simple-discriminator.json';
|
||||
|
||||
const options = new RedocNormalizedOptions({});
|
||||
describe('Components', () => {
|
||||
describe('SchemaView', () => {
|
||||
describe('discriminator', () => {
|
||||
it('should correctly render SchemaView', () => {
|
||||
const parser = new OpenAPIParser(simpleDiscriminatorFixture);
|
||||
const parser = new OpenAPIParser(simpleDiscriminatorFixture, undefined, options);
|
||||
|
||||
const schema = new SchemaModel(
|
||||
parser,
|
||||
{ $ref: '#/components/schemas/Pet' },
|
||||
'#/components/schemas/Pet',
|
||||
new RedocNormalizedOptions({}),
|
||||
options,
|
||||
);
|
||||
const schemaView = shallow(<Schema schema={schema} />);
|
||||
expect(toJson(schemaView)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should correctly render discriminator dropdown', () => {
|
||||
const parser = new OpenAPIParser(simpleDiscriminatorFixture);
|
||||
const parser = new OpenAPIParser(simpleDiscriminatorFixture, undefined, options);
|
||||
|
||||
const schema = new SchemaModel(
|
||||
parser,
|
||||
{ $ref: '#/components/schemas/Pet' },
|
||||
'#/components/schemas/Pet',
|
||||
new RedocNormalizedOptions({}),
|
||||
options,
|
||||
);
|
||||
const schemaView = shallow(
|
||||
<ObjectSchema
|
||||
|
|
|
@ -57,6 +57,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -157,6 +158,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -240,6 +242,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -377,6 +380,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -477,6 +481,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -560,6 +565,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -667,6 +673,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -800,6 +807,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -900,6 +908,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -983,6 +992,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -1118,6 +1128,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
@ -1225,6 +1236,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
|||
"options": RedocNormalizedOptions {
|
||||
"expandResponses": Object {},
|
||||
"hideHostname": false,
|
||||
"noAutoAuth": false,
|
||||
"requiredPropsFirst": false,
|
||||
"scrollYOffset": [Function],
|
||||
"theme": Object {
|
||||
|
|
|
@ -13,7 +13,10 @@ const md = new Remarkable('default', {
|
|||
},
|
||||
});
|
||||
|
||||
const COMPONENT_REGEXP = '^\\s*<!-- ReDoc-Inject:\\s+?{component}\\s+?-->\\s*$';
|
||||
export const COMPONENT_REGEXP = '^\\s*<!-- ReDoc-Inject:\\s+?{component}\\s+?-->\\s*$';
|
||||
export function buildComponentComment(name: string) {
|
||||
return `<!-- ReDoc-Inject: <${name}> -->`;
|
||||
}
|
||||
|
||||
type MarkdownHeading = {
|
||||
name: string;
|
||||
|
|
|
@ -5,6 +5,9 @@ import { OpenAPIRef, OpenAPISchema, OpenAPISpec, Referenced } from '../types';
|
|||
|
||||
import { JsonPointer } from '../utils/JsonPointer';
|
||||
import { isNamedDefinition } from '../utils/openapi';
|
||||
import { COMPONENT_REGEXP, buildComponentComment } from './MarkdownRenderer';
|
||||
import { RedocNormalizedOptions } from './RedocNormalizedOptions';
|
||||
import { appendToMdHeading } from '../utils/index';
|
||||
|
||||
export type MergedOpenAPISchema = OpenAPISchema & { namedParents?: string[] };
|
||||
|
||||
|
@ -39,8 +42,13 @@ export class OpenAPIParser {
|
|||
@observable specUrl: string;
|
||||
@observable.ref spec: OpenAPISpec;
|
||||
|
||||
constructor(spec: OpenAPISpec, specUrl?: string) {
|
||||
constructor(
|
||||
spec: OpenAPISpec,
|
||||
specUrl: string | undefined,
|
||||
private options: RedocNormalizedOptions,
|
||||
) {
|
||||
this.validate(spec);
|
||||
this.preprocess(spec);
|
||||
|
||||
this.spec = spec;
|
||||
|
||||
|
@ -59,6 +67,22 @@ export class OpenAPIParser {
|
|||
}
|
||||
}
|
||||
|
||||
preprocess(spec: OpenAPISpec) {
|
||||
if (!this.options.noAutoAuth && spec.info) {
|
||||
// Automatically inject Authentication section with SecurityDefinitions component
|
||||
const description = spec.info.description || '';
|
||||
const securityRegexp = new RegExp(
|
||||
COMPONENT_REGEXP.replace('{component}', '<security-definitions>'),
|
||||
'gmi',
|
||||
);
|
||||
debugger;
|
||||
if (!securityRegexp.test(description)) {
|
||||
const comment = buildComponentComment('security-definitions');
|
||||
spec.info.description = appendToMdHeading(description, 'Authentication', comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get spec part by JsonPointer ($ref)
|
||||
*/
|
||||
|
|
|
@ -8,6 +8,7 @@ export interface RedocRawOptions {
|
|||
hideHostname?: boolean | string;
|
||||
expandResponses?: string | 'all';
|
||||
requiredPropsFirst?: boolean | string;
|
||||
noAutoAuth?: boolean | string;
|
||||
}
|
||||
|
||||
function argValueToBoolean(val?: string | boolean): boolean {
|
||||
|
@ -22,6 +23,7 @@ export class RedocNormalizedOptions {
|
|||
hideHostname: boolean;
|
||||
expandResponses: { [code: string]: boolean } | 'all';
|
||||
requiredPropsFirst: boolean;
|
||||
noAutoAuth: boolean;
|
||||
|
||||
constructor(raw: RedocRawOptions) {
|
||||
this.theme = { ...(raw.theme || {}), ...defaultTheme }; // todo: merge deep
|
||||
|
@ -29,6 +31,7 @@ export class RedocNormalizedOptions {
|
|||
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
|
||||
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);
|
||||
this.requiredPropsFirst = argValueToBoolean(raw.requiredPropsFirst);
|
||||
this.noAutoAuth = argValueToBoolean(raw.noAutoAuth);
|
||||
}
|
||||
|
||||
static normalizeExpandResponses(value: RedocRawOptions['expandResponses']) {
|
||||
|
|
|
@ -19,7 +19,7 @@ export class SpecStore {
|
|||
specUrl: string | undefined,
|
||||
private options: RedocNormalizedOptions,
|
||||
) {
|
||||
this.parser = new OpenAPIParser(spec, specUrl);
|
||||
this.parser = new OpenAPIParser(spec, specUrl, options);
|
||||
}
|
||||
|
||||
@computed
|
||||
|
|
|
@ -8,7 +8,7 @@ describe('Models', () => {
|
|||
let parser;
|
||||
|
||||
beforeEach(() => {
|
||||
parser = new OpenAPIParser({ openapi: '3.0.0' } as any);
|
||||
parser = new OpenAPIParser({ openapi: '3.0.0' } as any, undefined, opts);
|
||||
});
|
||||
|
||||
test('should calculate response type based on code', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { mapWithLast } from '../helpers';
|
||||
import { mapWithLast, appendToMdHeading } from '../helpers';
|
||||
|
||||
describe('Utils', () => {
|
||||
describe('helpers', () => {
|
||||
|
@ -19,5 +19,24 @@ describe('Utils', () => {
|
|||
const expected = [];
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
test('appendToMdHeading heading exists not last', () => {
|
||||
const val = appendToMdHeading(
|
||||
'# Authentication\n Hello\n# Next heading',
|
||||
'Authentication',
|
||||
'<test>',
|
||||
);
|
||||
expect(val).toEqual('# Authentication\n Hello\n\n<test>\n\n# Next heading');
|
||||
});
|
||||
|
||||
test('appendToMdHeading heading exists last', () => {
|
||||
const val = appendToMdHeading('# Authentication\n Hello', 'Authentication', '<test>');
|
||||
expect(val).toEqual('# Authentication\n Hello\n\n<test>\n');
|
||||
});
|
||||
|
||||
test('appendToMdHeading empty string', () => {
|
||||
const val = appendToMdHeading('', 'Authentication', '<test>');
|
||||
expect(val).toEqual('# Authentication\n\n<test>');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -67,3 +67,16 @@ export function isAbsolutePath(path: string): boolean {
|
|||
export function isNumeric(n: any): n is Number {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
}
|
||||
|
||||
export function appendToMdHeading(md: string, heading: string, content: string) {
|
||||
// if heading is already in md and append to the end of it
|
||||
const testRegex = new RegExp(`(^|\\n)#\\s?${heading}\\s*\\n`, 'i');
|
||||
const replaceRegex = new RegExp(`((\\n|^)#\\s*${heading}\\s*(\\n|$)(?:.|\\n)*?)(\\n#|$)`, 'i');
|
||||
if (testRegex.test(md)) {
|
||||
return md.replace(replaceRegex, `$1\n\n${content}\n$4`);
|
||||
} else {
|
||||
// else append heading itself
|
||||
const br = md === '' || md.endsWith('\n\n') ? '' : md.endsWith('\n') ? '\n' : '\n\n';
|
||||
return `${md}${br}# ${heading}\n\n${content}`;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user