mirror of
https://github.com/Redocly/redoc.git
synced 2026-01-07 08:40:53 +03:00
Co-authored-by: Roman Hotsiy <gotsijroman@gmail.com> Co-authored-by: Alex Varchuk <olexandr.varchuk@gmail.com> Co-authored-by: Oprysk Vyacheslav <vyacheslav@redocly.com> Co-authored-by: Ivan Kropyvnytskyi <130547411+ivankropyvnytskyi@users.noreply.github.com> Co-authored-by: Yevhen Pylyp <yevhen.pylyp@redocly.com> Co-authored-by: Vladyslav Makarenko <vladyslav.makarenko@redocly.com> Co-authored-by: Yevhenii Medviediev <yevhenii.medviediev@redocly.com> Co-authored-by: Oleksii Horbachevskyi <oleksii.horbachevskyi@redocly.com> Co-authored-by: volodymyr-rutskyi <rutskyi.v@gmail.com> Co-authored-by: Adam Altman <adam@redoc.ly> Co-authored-by: Andrew Tatomyr <andrew.tatomyr@redocly.com> Co-authored-by: Anastasiia Derymarko <anastasiia@redocly.com> Co-authored-by: Roman Marshevskyy <roman.marshevskyy@redoc.ly> Co-authored-by: Lorna Mitchell <lorna.mitchell@redocly.com> Co-authored-by: Taylor Krusen <taylor.krusen@redocly.com>
115 lines
3.3 KiB
TypeScript
115 lines
3.3 KiB
TypeScript
import { createElement } from 'react';
|
|
import { createRoot, hydrateRoot } from 'react-dom/client';
|
|
|
|
import type { ErrorInfo } from 'react';
|
|
import type { RedocConfig } from '@redocly/config';
|
|
import type { OpenAPIDefinition } from './types/open-api.js';
|
|
import type { StoreProviderProps } from './components/RedoclyOpenAPIDocs/types.js';
|
|
|
|
type GenericObject = Record<string, any>;
|
|
|
|
import { querySelector } from './utils/dom.js';
|
|
import { RedoclyOpenAPIDocs } from './components/RedoclyOpenAPIDocs/RedoclyOpenAPIDocs.js';
|
|
import { RedoclyOpenAPIDocsStandalone } from './components/RedoclyOpenAPIDocs/RedoclyOpenAPIDocsStandalone.js';
|
|
|
|
export { setSecurityDetails, setSecurityDetailsVariants } from './utils/security-details.js';
|
|
export { setParameterValue } from './utils/parameters.js';
|
|
|
|
function attributesMap(element: Element) {
|
|
const res = {};
|
|
const elAttrs = element.attributes;
|
|
// tslint:disable-next-line
|
|
for (let i = 0; i < elAttrs.length; i++) {
|
|
const attrib = elAttrs[i];
|
|
res[attrib.name] = attrib.value;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
function parseOptionsFromElement(element: Element) {
|
|
const attrMap = attributesMap(element);
|
|
const res = {};
|
|
for (const attrName in attrMap) {
|
|
const optionName = attrName.replace(/-(.)/g, (_, $1) => $1.toUpperCase());
|
|
res[optionName] = attrMap[attrName];
|
|
// TODO: normalize options
|
|
}
|
|
return res;
|
|
}
|
|
|
|
export function hydrate(
|
|
store: StoreProviderProps,
|
|
element: Element | null = document.querySelector('redoc'),
|
|
): void {
|
|
hydrateRoot(element as Element, <RedoclyOpenAPIDocs store={store} typeOfUsage="cli" />, {
|
|
onRecoverableError: (error: Error, errorInfo: ErrorInfo) => {
|
|
if (error.message.includes('Minified React error #418')) {
|
|
// we use memory router for ssr and hash router for client
|
|
return;
|
|
}
|
|
console.error(error.message, errorInfo);
|
|
},
|
|
});
|
|
}
|
|
|
|
export function init(
|
|
definitionOrDefinitionUrl: string | OpenAPIDefinition,
|
|
options: RedocConfig & { router?: 'hash' | 'history'; disableTelemetry?: boolean } = {},
|
|
element: Element | null = querySelector('redoc'),
|
|
): void {
|
|
if (element === null) {
|
|
throw new Error('"element" argument is not provided and <redoc> tag is not found on the page');
|
|
}
|
|
const {
|
|
router,
|
|
disableTelemetry = false,
|
|
typeOfUsage = 'html',
|
|
...restOptions
|
|
} = {
|
|
...options,
|
|
...parseOptionsFromElement(element),
|
|
};
|
|
|
|
let definitionUrl: string | undefined;
|
|
let definition: GenericObject | undefined;
|
|
|
|
if (typeof definitionOrDefinitionUrl === 'string') {
|
|
definitionUrl = definitionOrDefinitionUrl;
|
|
} else if (typeof definitionOrDefinitionUrl === 'object') {
|
|
definition = definitionOrDefinitionUrl;
|
|
}
|
|
|
|
const root = createRoot(element);
|
|
|
|
root.render(
|
|
createElement(
|
|
RedoclyOpenAPIDocsStandalone,
|
|
{
|
|
definition,
|
|
definitionUrl,
|
|
disableTelemetry,
|
|
options: restOptions,
|
|
router: router ?? 'hash',
|
|
typeOfUsage: typeOfUsage ?? 'html',
|
|
},
|
|
['Loading...'],
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* autoinit ReDoc if <redoc> tag is found on the page with "spec-url" attr
|
|
*/
|
|
function autoInit() {
|
|
const element = querySelector('redoc');
|
|
if (!element) {
|
|
return;
|
|
}
|
|
const specUrl = element.getAttribute('spec-url');
|
|
if (specUrl) {
|
|
init(specUrl, {}, element);
|
|
}
|
|
}
|
|
|
|
autoInit();
|