redoc/src/services/RedocNormalizedOptions.ts

101 lines
3.4 KiB
TypeScript
Raw Normal View History

import { ThemeInterface } from '../theme';
2017-11-22 15:00:42 +03:00
import { isNumeric, mergeObjects } from '../utils/helpers';
2017-11-21 14:00:33 +03:00
import defaultTheme from '../theme';
2017-11-20 23:36:21 +03:00
export interface RedocRawOptions {
theme?: ThemeInterface;
scrollYOffset?: number | string | Function;
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;
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;
2017-11-21 14:24:41 +03:00
}
function argValueToBoolean(val?: string | boolean): boolean {
if (val === undefined) return false;
if (typeof val === 'string') return true;
return val;
2017-11-20 23:36:21 +03:00
}
export class RedocNormalizedOptions {
theme: ThemeInterface;
scrollYOffset: () => number;
2017-11-20 23:36:21 +03:00
hideHostname: boolean;
2017-11-21 14:00:33 +03:00
expandResponses: { [code: string]: boolean } | 'all';
2017-11-21 14:24:41 +03:00
requiredPropsFirst: boolean;
2017-11-21 17:33:22 +03:00
noAutoAuth: boolean;
2017-11-21 17:55:20 +03:00
nativeScrollbars: boolean;
2017-11-22 11:57:51 +03:00
pathInMiddlePanel: boolean;
untrustedSpec: boolean;
constructor(raw: RedocRawOptions) {
2017-11-23 12:28:05 +03:00
this.theme = mergeObjects({} as any, defaultTheme, raw.theme || {});
this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset);
2017-11-20 23:36:21 +03:00
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
2017-11-21 14:00:33 +03:00
this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses);
2017-11-21 14:24:41 +03:00
this.requiredPropsFirst = argValueToBoolean(raw.requiredPropsFirst);
2017-11-21 17:33:22 +03:00
this.noAutoAuth = argValueToBoolean(raw.noAutoAuth);
2017-11-21 17:55:20 +03:00
this.nativeScrollbars = argValueToBoolean(raw.nativeScrollbars);
2017-11-22 11:57:51 +03:00
this.pathInMiddlePanel = argValueToBoolean(raw.pathInMiddlePanel);
this.untrustedSpec = argValueToBoolean(raw.untrustedSpec);
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 = document.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;
}
}