@asyncapi/html-template
Version:
HTML template for the AsyncAPI generator.
274 lines (253 loc) • 8.66 kB
JavaScript
;
require('source-map-support/register');
var generatorReactSdk = require('@asyncapi/generator-react-sdk');
var parser = require('@asyncapi/parser');
var path = require('path');
var fs = require('fs');
var ReactDOMServer = require('react-dom/server');
var fetch = require('sync-fetch');
var AsyncApiComponent = require('@asyncapi/react-component');
var jsxRuntime = require('/home/runner/work/html-template/html-template/node_modules/@asyncapi/generator-react-sdk/node_modules/react/cjs/react-jsx-runtime.production.min.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var ReactDOMServer__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOMServer);
var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
var AsyncApiComponent__default = /*#__PURE__*/_interopDefaultLegacy(AsyncApiComponent);
function isJsonObject(o) {
return o && typeof o === 'object' && !Array.isArray(o);
}
/**
* Performs a recursive deep merge while assuming only simple JSON types are used.
*/
function mergeInto(from, to) {
for (const key in from) {
if (!Object.hasOwn(from, key)) {
continue;
}
if (isJsonObject(from[key])) {
if (!isJsonObject(to[key])) {
to[key] = {};
}
mergeInto(from[key], to[key]);
} else {
// Override with non-object JSON value
to[key] = from[key];
}
}
}
/**
* Prepares configuration for component.
*/
function prepareConfiguration(params = {}) {
const config = {
show: {
sidebar: true
},
sidebar: {
showOperations: 'byDefault'
}
};
// Apply config override
if (params.config) {
let configOverride;
try {
// Attempt to parse inline stringified JSON
configOverride = JSON.parse(params.config);
} catch (jsonErr) {
// Failed to parse JSON string...
try {
// Attempt to read as JSON file and parse contents
configOverride = JSON.parse(fs__default["default"].readFileSync(params.config, "utf8"));
} catch (err) {
console.error("Failed to parse config override JSON", jsonErr, err);
throw err;
}
}
if (isJsonObject(configOverride)) {
mergeInto(configOverride, config);
}
}
// Apply explicit config properties
if (params.sidebarOrganization === 'byTags') {
config.sidebar.showOperations = 'bySpecTags';
} else if (params.sidebarOrganization === 'byTagsNoRoot') {
config.sidebar.showOperations = 'byOperationsTags';
}
return config;
}
let initLanguages = false;
/**
* Load all language configurations from highlight.js
*/
function loadLanguagesConfig() {
if (initLanguages === true) {
return;
}
/**
* Retrieve the location of highlight.js.
* It's needed because someone can have installed `highlight.js` as global dependency
* or depper than local `node_modules` of this template.
*/
const hljsPackageDir = path__default["default"].dirname(require.resolve("highlight.js/package.json"));
const hljsLanguagesPath = path__default["default"].resolve(hljsPackageDir, 'lib/languages');
const languages = fs__default["default"].readdirSync(hljsLanguagesPath);
for (let langPath of languages) {
const lang = require(path__default["default"].resolve(hljsLanguagesPath, langPath.replace('.js', '')));
AsyncApiComponent.hljs.registerLanguage(lang.name, lang);
}
initLanguages = true;
}
/**
* Generate Base64 value from favicon
*/
function generateBase64Favicon(params) {
const favicon = params.favicon;
// generate Base64 of AsyncAPI logo
if (!favicon) {
return "data:image/x-icon;base64," + fs__default["default"].readFileSync(path__default["default"].resolve(__dirname, '../assets/asyncapi-favicon.ico'), "base64");
}
try {
// Attempt to fetch favicon
const response = fetch__default["default"](favicon);
if (response.status == 200) {
const buffer = response.buffer();
return "data:image/x-icon;base64," + buffer.toString('base64');
}
} catch (fetchErr) {
// Failed to fetch favicon...
try {
// Attempt to read favicon as file
return "data:image/x-icon;base64," + fs__default["default"].readFileSync(favicon, "base64");
} catch (err) {
console.error("Failed to fetch/read favicon", fetchErr, err);
throw err;
}
}
}
/**
* More safe function to include content of given file than default Nunjuck's `include`.
* Attaches raw file's content instead of executing it - problem with some attached files in template.
*/
function includeFile(pathFile) {
const pathToFile = path__default["default"].resolve(__dirname, '../', pathFile);
return fs__default["default"].readFileSync(pathToFile);
}
/**
* Stringifies the specification with escaping circular refs
* and annotates that specification is parsed.
*/
function stringifySpec(asyncapi) {
const stringifiedDoc = parser.stringify(asyncapi);
if (stringifiedDoc === undefined) throw new Error("Unable to stringify parsed AsyncAPI document passed by the generator. Please report an issue in https://github.com/asyncapi/html-template repository.");
return stringifiedDoc;
}
/**
* Stringifies prepared configuration for component.
*/
function stringifyConfiguration(params) {
return JSON.stringify(prepareConfiguration(params));
}
/**
* Renders AsyncApi component by given AsyncAPI spec and with corresponding template configuration.
*/
/**
* @param {AsyncAPIDocumentInterface} asyncapi
* @param {*} params
*/
function renderSpec(asyncapi, params) {
loadLanguagesConfig();
const config = prepareConfiguration(params);
const stringified = stringifySpec(asyncapi);
const component = /*#__PURE__*/jsxRuntime.jsx(AsyncApiComponent__default["default"], {
schema: stringified,
config: config
});
if (typeof global.window === 'undefined' || !global.window.document) {
const {
JSDOM
} = require('jsdom');
const jsdomInstance = new JSDOM('<!doctype html><html><body></body></html>');
global.window = jsdomInstance.window;
global.document = jsdomInstance.window.document;
}
return ReactDOMServer__default["default"].renderToString(component);
}
/**
* @param {{asyncapi: AsyncAPIDocumentInterface, params: any}} param0
*/
function Index({
asyncapi,
params = {}
}) {
const favicon = generateBase64Favicon(params);
const renderedSpec = renderSpec(asyncapi, params);
let asyncapiScript = `<script src="js/asyncapi-ui.min.js" type="application/javascript"></script>`;
if (params !== null && params !== void 0 && params.singleFile) {
asyncapiScript = `<script type="text/javascript">
${includeFile('template/js/asyncapi-ui.min.js')}
</script>`;
}
let styling = `<link href="css/global.min.css" rel="stylesheet">
<link href="css/asyncapi.min.css" rel="stylesheet">`;
if (params !== null && params !== void 0 && params.singleFile) {
styling = `<style type="text/css">
${includeFile("template/css/global.min.css")}
${includeFile("template/css/asyncapi.min.css")}
</style>`;
}
let basehref = '';
if (params.baseHref) {
basehref = `<base href="${params.baseHref}">`;
}
let appJs = `<script type="application/javascript" src="js/app.js"></script>`;
if (params !== null && params !== void 0 && params.singleFile) {
appJs = `<script>${App({
asyncapi,
params
})}</script>`;
}
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
${basehref}
<title>${asyncapi.info().title()} ${asyncapi.info().version()} documentation</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="${favicon}" />
${styling}
</head>
<body>
<div id="root">${renderedSpec}</div>
${asyncapiScript}
${appJs}
</body>
</html>`;
}
function App({
asyncapi,
params = {}
}) {
return `
const schema = ${stringifySpec(asyncapi)};
const config = ${stringifyConfiguration(params)};
const appRoot = document.getElementById('root');
AsyncApiStandalone.render(
{ schema, config, }, appRoot
);
`;
}
function index_html ({
asyncapi,
params = {}
}) {
return /*#__PURE__*/jsxRuntime.jsx(generatorReactSdk.File, {
name: params.outFilename || 'index.html',
children: /*#__PURE__*/jsxRuntime.jsx(Index, {
params: params,
asyncapi: asyncapi
})
});
}
module.exports = index_html;
//# sourceMappingURL=index.html.js.map