UNPKG

@asyncapi/html-template

Version:

HTML template for the AsyncAPI generator.

274 lines (253 loc) 8.66 kB
'use strict'; 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