@redocly/cli
Version:
[@Redocly](https://redocly.com) CLI is your all-in-one API documentation utility. It builds, manages, improves, and quality-checks your API descriptions, all of which comes in handy for various phases of the API Lifecycle. Create your own rulesets to make
84 lines (82 loc) • 3.66 kB
JavaScript
import { createElement } from 'react';
import { default as redoc } from 'redoc';
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';
import { default as handlebars } from 'handlebars';
import * as path from 'node:path';
import { existsSync, lstatSync, readFileSync } from 'node:fs';
import { isAbsoluteUrl, logger } from '@redocly/openapi-core';
import * as url from 'node:url';
import { exitWithError } from '../../utils/error.js';
const __internalDirname = import.meta.url
? path.dirname(url.fileURLToPath(import.meta.url))
: __dirname;
export function getObjectOrJSON(openapiOptions, config) {
switch (typeof openapiOptions) {
case 'object':
return openapiOptions;
case 'string':
try {
if (existsSync(openapiOptions) && lstatSync(openapiOptions).isFile()) {
return JSON.parse(readFileSync(openapiOptions, 'utf-8'));
}
else {
return JSON.parse(openapiOptions);
}
}
catch (e) {
logger.error(`Encountered error:\n\n${openapiOptions}\n\nis neither a file with a valid JSON object neither a stringified JSON object.`);
exitWithError(e);
}
break;
default: {
if (config?.configPath) {
logger.info(`Found ${config.configPath} and using 'openapi' options\n`);
return config.resolvedConfig?.openapi ?? {};
}
return {};
}
}
return {};
}
export async function getPageHTML(api, pathToApi, { title, disableGoogleFont, templateFileName, templateOptions, redocOptions = {}, redocCurrentVersion, }, configPath) {
logger.info('Prerendering docs\n');
const apiUrl = redocOptions.specUrl || (isAbsoluteUrl(pathToApi) ? pathToApi : undefined);
const store = await redoc.createStore(api, apiUrl, redocOptions);
const sheet = new ServerStyleSheet();
const html = renderToString(sheet.collectStyles(createElement(redoc.Redoc, { store })));
const state = await store.toJS();
const css = sheet.getStyleTags();
templateFileName = templateFileName
? templateFileName
: redocOptions?.htmlTemplate
? path.resolve(configPath ? path.dirname(configPath) : '', redocOptions.htmlTemplate)
: path.join(__internalDirname, './template.hbs');
const template = handlebars.compile(readFileSync(templateFileName).toString());
return template({
redocHTML: `
<div id="redoc">${html || ''}</div>
<script>
${`const __redoc_state = ${sanitizeJSONString(JSON.stringify(state))};` || ''}
var container = document.getElementById('redoc');
Redoc.${'hydrate(__redoc_state, container)'};
</script>`,
redocHead: `<script src="https://cdn.redocly.com/redoc/v${redocCurrentVersion}/bundles/redoc.standalone.js"></script>` +
css,
title: title || api.info.title || 'ReDoc documentation',
disableGoogleFont,
templateOptions,
});
}
export function sanitizeJSONString(str) {
return escapeClosingScriptTag(escapeUnicode(str));
}
// see http://www.thespanner.co.uk/2011/07/25/the-json-specification-is-now-wrong/
export function escapeClosingScriptTag(str) {
return str.replace(/<\/script>/g, '<\\/script>');
}
// see http://www.thespanner.co.uk/2011/07/25/the-json-specification-is-now-wrong/
export function escapeUnicode(str) {
return str.replace(/\u2028|\u2029/g, (m) => '\\u202' + (m === '\u2028' ? '8' : '9'));
}
//# sourceMappingURL=utils.js.map