mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-23 00:56:33 +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 { ObjectSchema } from '../ObjectSchema';
|
||||||
import * as simpleDiscriminatorFixture from './fixtures/simple-discriminator.json';
|
import * as simpleDiscriminatorFixture from './fixtures/simple-discriminator.json';
|
||||||
|
|
||||||
|
const options = new RedocNormalizedOptions({});
|
||||||
describe('Components', () => {
|
describe('Components', () => {
|
||||||
describe('SchemaView', () => {
|
describe('SchemaView', () => {
|
||||||
describe('discriminator', () => {
|
describe('discriminator', () => {
|
||||||
it('should correctly render SchemaView', () => {
|
it('should correctly render SchemaView', () => {
|
||||||
const parser = new OpenAPIParser(simpleDiscriminatorFixture);
|
const parser = new OpenAPIParser(simpleDiscriminatorFixture, undefined, options);
|
||||||
|
|
||||||
const schema = new SchemaModel(
|
const schema = new SchemaModel(
|
||||||
parser,
|
parser,
|
||||||
{ $ref: '#/components/schemas/Pet' },
|
{ $ref: '#/components/schemas/Pet' },
|
||||||
'#/components/schemas/Pet',
|
'#/components/schemas/Pet',
|
||||||
new RedocNormalizedOptions({}),
|
options,
|
||||||
);
|
);
|
||||||
const schemaView = shallow(<Schema schema={schema} />);
|
const schemaView = shallow(<Schema schema={schema} />);
|
||||||
expect(toJson(schemaView)).toMatchSnapshot();
|
expect(toJson(schemaView)).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should correctly render discriminator dropdown', () => {
|
it('should correctly render discriminator dropdown', () => {
|
||||||
const parser = new OpenAPIParser(simpleDiscriminatorFixture);
|
const parser = new OpenAPIParser(simpleDiscriminatorFixture, undefined, options);
|
||||||
|
|
||||||
const schema = new SchemaModel(
|
const schema = new SchemaModel(
|
||||||
parser,
|
parser,
|
||||||
{ $ref: '#/components/schemas/Pet' },
|
{ $ref: '#/components/schemas/Pet' },
|
||||||
'#/components/schemas/Pet',
|
'#/components/schemas/Pet',
|
||||||
new RedocNormalizedOptions({}),
|
options,
|
||||||
);
|
);
|
||||||
const schemaView = shallow(
|
const schemaView = shallow(
|
||||||
<ObjectSchema
|
<ObjectSchema
|
||||||
|
|
|
@ -57,6 +57,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -157,6 +158,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -240,6 +242,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -377,6 +380,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -477,6 +481,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -560,6 +565,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -667,6 +673,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -800,6 +807,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -900,6 +908,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -983,6 +992,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -1118,6 +1128,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"theme": Object {
|
||||||
|
@ -1225,6 +1236,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
||||||
"options": RedocNormalizedOptions {
|
"options": RedocNormalizedOptions {
|
||||||
"expandResponses": Object {},
|
"expandResponses": Object {},
|
||||||
"hideHostname": false,
|
"hideHostname": false,
|
||||||
|
"noAutoAuth": false,
|
||||||
"requiredPropsFirst": false,
|
"requiredPropsFirst": false,
|
||||||
"scrollYOffset": [Function],
|
"scrollYOffset": [Function],
|
||||||
"theme": Object {
|
"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 = {
|
type MarkdownHeading = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -5,6 +5,9 @@ import { OpenAPIRef, OpenAPISchema, OpenAPISpec, Referenced } from '../types';
|
||||||
|
|
||||||
import { JsonPointer } from '../utils/JsonPointer';
|
import { JsonPointer } from '../utils/JsonPointer';
|
||||||
import { isNamedDefinition } from '../utils/openapi';
|
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[] };
|
export type MergedOpenAPISchema = OpenAPISchema & { namedParents?: string[] };
|
||||||
|
|
||||||
|
@ -39,8 +42,13 @@ export class OpenAPIParser {
|
||||||
@observable specUrl: string;
|
@observable specUrl: string;
|
||||||
@observable.ref spec: OpenAPISpec;
|
@observable.ref spec: OpenAPISpec;
|
||||||
|
|
||||||
constructor(spec: OpenAPISpec, specUrl?: string) {
|
constructor(
|
||||||
|
spec: OpenAPISpec,
|
||||||
|
specUrl: string | undefined,
|
||||||
|
private options: RedocNormalizedOptions,
|
||||||
|
) {
|
||||||
this.validate(spec);
|
this.validate(spec);
|
||||||
|
this.preprocess(spec);
|
||||||
|
|
||||||
this.spec = 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)
|
* get spec part by JsonPointer ($ref)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,6 +8,7 @@ export interface RedocRawOptions {
|
||||||
hideHostname?: boolean | string;
|
hideHostname?: boolean | string;
|
||||||
expandResponses?: string | 'all';
|
expandResponses?: string | 'all';
|
||||||
requiredPropsFirst?: boolean | string;
|
requiredPropsFirst?: boolean | string;
|
||||||
|
noAutoAuth?: boolean | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function argValueToBoolean(val?: string | boolean): boolean {
|
function argValueToBoolean(val?: string | boolean): boolean {
|
||||||
|
@ -22,6 +23,7 @@ export class RedocNormalizedOptions {
|
||||||
hideHostname: boolean;
|
hideHostname: boolean;
|
||||||
expandResponses: { [code: string]: boolean } | 'all';
|
expandResponses: { [code: string]: boolean } | 'all';
|
||||||
requiredPropsFirst: boolean;
|
requiredPropsFirst: boolean;
|
||||||
|
noAutoAuth: boolean;
|
||||||
|
|
||||||
constructor(raw: RedocRawOptions) {
|
constructor(raw: RedocRawOptions) {
|
||||||
this.theme = { ...(raw.theme || {}), ...defaultTheme }; // todo: merge deep
|
this.theme = { ...(raw.theme || {}), ...defaultTheme }; // todo: merge deep
|
||||||
|
@ -29,6 +31,7 @@ export class RedocNormalizedOptions {
|
||||||
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
|
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
|
||||||
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);
|
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);
|
||||||
this.requiredPropsFirst = argValueToBoolean(raw.requiredPropsFirst);
|
this.requiredPropsFirst = argValueToBoolean(raw.requiredPropsFirst);
|
||||||
|
this.noAutoAuth = argValueToBoolean(raw.noAutoAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static normalizeExpandResponses(value: RedocRawOptions['expandResponses']) {
|
static normalizeExpandResponses(value: RedocRawOptions['expandResponses']) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class SpecStore {
|
||||||
specUrl: string | undefined,
|
specUrl: string | undefined,
|
||||||
private options: RedocNormalizedOptions,
|
private options: RedocNormalizedOptions,
|
||||||
) {
|
) {
|
||||||
this.parser = new OpenAPIParser(spec, specUrl);
|
this.parser = new OpenAPIParser(spec, specUrl, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
|
|
|
@ -8,7 +8,7 @@ describe('Models', () => {
|
||||||
let parser;
|
let parser;
|
||||||
|
|
||||||
beforeEach(() => {
|
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', () => {
|
test('should calculate response type based on code', () => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { mapWithLast } from '../helpers';
|
import { mapWithLast, appendToMdHeading } from '../helpers';
|
||||||
|
|
||||||
describe('Utils', () => {
|
describe('Utils', () => {
|
||||||
describe('helpers', () => {
|
describe('helpers', () => {
|
||||||
|
@ -19,5 +19,24 @@ describe('Utils', () => {
|
||||||
const expected = [];
|
const expected = [];
|
||||||
expect(actual).toEqual(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 {
|
export function isNumeric(n: any): n is Number {
|
||||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
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