redoc/src/services/RedocNormalizedOptions.ts

234 lines
7.9 KiB
TypeScript
Raw Normal View History

2018-03-17 00:58:25 +03:00
import defaultTheme, { ResolvedThemeInterface, resolveTheme, ThemeInterface } from '../theme';
import { querySelector } from '../utils/dom';
2018-01-22 21:30:53 +03:00
import { isNumeric, mergeObjects } from '../utils/helpers';
import { LabelsConfigRaw, setRedocLabels } from './Labels';
import { MDXComponentMeta } from './MarkdownRenderer';
2017-11-20 23:36:21 +03:00
export interface RedocRawOptions {
theme?: ThemeInterface;
2018-01-22 21:30:53 +03:00
scrollYOffset?: number | string | (() => number);
2017-11-20 23:36:21 +03:00
hideHostname?: boolean | string;
2017-11-21 14:00:33 +03:00
expandResponses?: string | 'all';
2017-11-21 14:24:41 +03:00
requiredPropsFirst?: boolean | string;
sortPropsAlphabetically?: boolean | string;
2017-11-21 17:33:22 +03:00
noAutoAuth?: boolean | string;
2017-11-21 17:55:20 +03:00
nativeScrollbars?: boolean | string;
2017-11-22 11:57:51 +03:00
pathInMiddlePanel?: boolean | string;
untrustedSpec?: boolean | string;
hideLoading?: boolean | string;
2018-03-07 18:21:17 +03:00
hideDownloadButton?: boolean | string;
2018-07-17 11:07:34 +03:00
disableSearch?: boolean | string;
onlyRequiredInSamples?: boolean | string;
showExtensions?: boolean | string | string[];
hideSingleRequestSampleTab?: boolean | string;
2019-07-11 12:25:13 +03:00
menuToggle?: boolean | string;
jsonSampleExpandLevel?: number | string | 'all';
2019-12-12 17:59:04 +03:00
hideSchemaTitles?: boolean | string;
2019-12-12 20:08:05 +03:00
payloadSampleIdx?: number;
expandSingleSchemaField?: boolean | string;
unstable_ignoreMimeParameters?: boolean;
allowedMdComponents?: Record<string, MDXComponentMeta>;
labels?: LabelsConfigRaw;
enumSkipQuotes?: boolean | string;
expandDefaultServerVariables?: boolean;
2017-11-21 14:24:41 +03:00
}
2019-12-12 14:16:42 +03:00
function argValueToBoolean(val?: string | boolean, defaultValue?: boolean): boolean {
2018-01-22 21:30:53 +03:00
if (val === undefined) {
2019-12-12 14:16:42 +03:00
return defaultValue || false;
2018-01-22 21:30:53 +03:00
}
if (typeof val === 'string') {
2019-12-12 14:16:42 +03:00
return val === 'false' ? false : true;
2018-01-22 21:30:53 +03:00
}
2017-11-21 14:24:41 +03:00
return val;
2017-11-20 23:36:21 +03:00
}
export class RedocNormalizedOptions {
2017-11-21 14:00:33 +03:00
static normalizeExpandResponses(value: RedocRawOptions['expandResponses']) {
if (value === 'all') {
return 'all';
}
if (typeof value === 'string') {
const res = {};
value.split(',').forEach(code => {
res[code.trim()] = true;
});
return res;
2017-11-21 14:24:41 +03:00
} else if (value !== undefined) {
2017-11-21 14:00:33 +03:00
console.warn(
`expandResponses must be a string but received value "${value}" of type ${typeof value}`,
);
}
2017-11-21 14:24:41 +03:00
return {};
2017-11-20 23:36:21 +03:00
}
static normalizeHideHostname(value: RedocRawOptions['hideHostname']): boolean {
return !!value;
}
static normalizeScrollYOffset(value: RedocRawOptions['scrollYOffset']): () => number {
// just number is not valid selector and leads to crash so checking if isNumeric here
if (typeof value === 'string' && !isNumeric(value)) {
const el = querySelector(value);
if (!el) {
console.warn(
'scrollYOffset value is a selector to non-existing element. Using offset 0 by default',
);
}
const bottom = (el && el.getBoundingClientRect().bottom) || 0;
return () => bottom;
} else if (typeof value === 'number' || isNumeric(value)) {
return () => (typeof value === 'number' ? value : parseFloat(value));
} else if (typeof value === 'function') {
return () => {
const res = value();
if (typeof res !== 'number') {
console.warn(
`scrollYOffset should return number but returned value "${res}" of type ${typeof res}`,
);
}
return res;
};
} else if (value !== undefined) {
console.warn(
'Wrong value for scrollYOffset ReDoc option: should be string, number or function',
);
}
return () => 0;
}
2018-01-22 21:30:53 +03:00
static normalizeShowExtensions(value: RedocRawOptions['showExtensions']): string[] | boolean {
if (typeof value === 'undefined') {
return false;
}
if (value === '') {
return true;
}
if (typeof value !== 'string') {
return value;
}
switch (value) {
case 'true':
return true;
case 'false':
return false;
default:
return value.split(',').map(ext => ext.trim());
}
}
2019-12-12 20:08:05 +03:00
static normalizePayloadSampleIdx(value: RedocRawOptions['payloadSampleIdx']): number {
if (typeof value === 'number') {
return Math.max(0, value); // always greater or equal than 0
}
if (typeof value === 'string') {
return isFinite(value) ? parseInt(value, 10) : 0;
}
return 0;
}
private static normalizeJsonSampleExpandLevel(level?: number | string | 'all'): number {
if (level === 'all') {
return +Infinity;
}
if (!isNaN(Number(level))) {
return Math.ceil(Number(level));
}
return 2;
}
2018-03-16 18:02:31 +03:00
theme: ResolvedThemeInterface;
2018-01-22 21:30:53 +03:00
scrollYOffset: () => number;
hideHostname: boolean;
expandResponses: { [code: string]: boolean } | 'all';
requiredPropsFirst: boolean;
sortPropsAlphabetically: boolean;
2018-01-22 21:30:53 +03:00
noAutoAuth: boolean;
nativeScrollbars: boolean;
pathInMiddlePanel: boolean;
untrustedSpec: boolean;
2018-03-07 18:21:17 +03:00
hideDownloadButton: boolean;
2018-07-17 11:07:34 +03:00
disableSearch: boolean;
onlyRequiredInSamples: boolean;
showExtensions: boolean | string[];
hideSingleRequestSampleTab: boolean;
2019-07-11 12:25:13 +03:00
menuToggle: boolean;
jsonSampleExpandLevel: number;
enumSkipQuotes: boolean;
2019-12-12 17:59:04 +03:00
hideSchemaTitles: boolean;
2019-12-12 20:08:05 +03:00
payloadSampleIdx: number;
expandSingleSchemaField: boolean;
2018-01-22 21:30:53 +03:00
/* tslint:disable-next-line */
unstable_ignoreMimeParameters: boolean;
allowedMdComponents: Record<string, MDXComponentMeta>;
expandDefaultServerVariables: boolean;
constructor(raw: RedocRawOptions, defaults: RedocRawOptions = {}) {
raw = { ...defaults, ...raw };
const hook = raw.theme && raw.theme.extensionsHook;
// migrate from old theme
if ((raw.theme as any)?.menu && !raw.theme?.sidebar) {
console.warn('Theme setting "menu" is deprecated. Rename to "sidebar"');
raw.theme!.sidebar = (raw.theme as any).menu;
}
if ((raw.theme as any)?.codeSample && !raw.theme?.codeBlock) {
console.warn('Theme setting "codeSample" is deprecated. Rename to "codeBlock"');
raw.theme!.codeBlock = (raw.theme as any).codeSample;
}
this.theme = resolveTheme(
mergeObjects({} as any, defaultTheme, { ...raw.theme, extensionsHook: undefined }),
);
this.theme.extensionsHook = hook as any;
2018-06-29 23:49:53 +03:00
// do not support dynamic labels changes. Labels should be configured before
setRedocLabels(raw.labels);
2018-01-22 21:30:53 +03:00
this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset);
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);
this.requiredPropsFirst = argValueToBoolean(raw.requiredPropsFirst);
this.sortPropsAlphabetically = argValueToBoolean(raw.sortPropsAlphabetically);
2018-01-22 21:30:53 +03:00
this.noAutoAuth = argValueToBoolean(raw.noAutoAuth);
this.nativeScrollbars = argValueToBoolean(raw.nativeScrollbars);
this.pathInMiddlePanel = argValueToBoolean(raw.pathInMiddlePanel);
this.untrustedSpec = argValueToBoolean(raw.untrustedSpec);
2018-03-07 18:21:17 +03:00
this.hideDownloadButton = argValueToBoolean(raw.hideDownloadButton);
2018-07-17 11:07:34 +03:00
this.disableSearch = argValueToBoolean(raw.disableSearch);
this.onlyRequiredInSamples = argValueToBoolean(raw.onlyRequiredInSamples);
this.showExtensions = RedocNormalizedOptions.normalizeShowExtensions(raw.showExtensions);
this.hideSingleRequestSampleTab = argValueToBoolean(raw.hideSingleRequestSampleTab);
2019-12-12 14:16:42 +03:00
this.menuToggle = argValueToBoolean(raw.menuToggle, true);
this.jsonSampleExpandLevel = RedocNormalizedOptions.normalizeJsonSampleExpandLevel(
raw.jsonSampleExpandLevel,
);
this.enumSkipQuotes = argValueToBoolean(raw.enumSkipQuotes);
2019-12-12 17:59:04 +03:00
this.hideSchemaTitles = argValueToBoolean(raw.hideSchemaTitles);
2019-12-12 20:08:05 +03:00
this.payloadSampleIdx = RedocNormalizedOptions.normalizePayloadSampleIdx(raw.payloadSampleIdx);
this.expandSingleSchemaField = argValueToBoolean(raw.expandSingleSchemaField);
2020-03-17 13:01:32 +03:00
// eslint-disable-next-line @typescript-eslint/camelcase
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
this.allowedMdComponents = raw.allowedMdComponents || {};
this.expandDefaultServerVariables = argValueToBoolean(raw.expandDefaultServerVariables);
2018-01-22 21:30:53 +03:00
}
}