Skip to content

Commit

Permalink
feat!: switch to react, apiVersion 2 and newest react components (#448)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni authored Oct 4, 2023
1 parent 90d7e41 commit 1fbb3ed
Show file tree
Hide file tree
Showing 18 changed files with 22,264 additions and 4,269 deletions.
28 changes: 0 additions & 28 deletions .github/workflows/pr-testing-with-generator.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ test/output
output
sample
coverage
__transpiled
54 changes: 54 additions & 0 deletions components/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// eslint-disable-next-line no-unused-vars
import { AsyncAPIDocumentInterface } from '@asyncapi/parser';
import { includeFile, generateBase64Favicon, renderSpec, stringifySpec, stringifyConfiguration } from '../helpers/all';

/**
* @param {{asyncapi: AsyncAPIDocumentInterface, params: any}} param0
*/
export 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?.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?.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}">`;
}
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}
<script>
const schema = ${stringifySpec(asyncapi)};
const config = ${stringifyConfiguration(params)};
AsyncApiStandalone.hydrate({ schema, config }, document.getElementById("root"));
</script>
</body>
</html>`
);
}

64 changes: 29 additions & 35 deletions filters/all.js → helpers/all.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
const fs = require('fs');
const path = require('path');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const fetch = require('node-fetch');
const { default: AsyncApiComponent, hljs } = require('@asyncapi/react-component');
const { AsyncAPIDocument } = require('@asyncapi/parser');

const filter = module.exports;
import path from 'path';
import fs from 'fs';
import ReactDOMServer from 'react-dom/server';
import fetch from 'sync-fetch';
import AsyncApiComponent, { hljs } from '@asyncapi/react-component';
import { AsyncAPIDocumentInterface, stringify } from '@asyncapi/parser';

function isJsonObject(o) {
return o && typeof o === 'object' && !Array.isArray(o);
Expand All @@ -17,7 +14,7 @@ function isJsonObject(o) {
*/
function mergeInto(from, to) {
for (const key in from) {
if (!Object.prototype.hasOwnProperty.call(from, key)) {
if (!Object.hasOwn(from, key)) {
continue;
}
if (isJsonObject(from[key])) {
Expand All @@ -35,7 +32,7 @@ function mergeInto(from, to) {
/**
* Prepares configuration for component.
*/
function prepareConfiguration(params = {}) {
export function prepareConfiguration(params = {}) {
const config = { show: { sidebar: true }, sidebar: { showOperations: 'byDefault' } };
// Apply config override
if (params.config) {
Expand Down Expand Up @@ -70,7 +67,7 @@ let initLanguages = false;
/**
* Load all language configurations from highlight.js
*/
function loadLanguagesConfig() {
export function loadLanguagesConfig() {
if (initLanguages === true) {
return;
}
Expand All @@ -91,77 +88,74 @@ function loadLanguagesConfig() {

initLanguages = true;
}
filter.loadLanguagesConfig = loadLanguagesConfig;

/**
* Generate Base64 value from favicon
*/
async function generateBase64Favicon(params, callback) {
export function generateBase64Favicon(params) {
const favicon = params.favicon;

// generate Base64 of AsyncAPI logo
if (!favicon) {
const data = "data:image/x-icon;base64," + fs.readFileSync(path.resolve(__dirname, '../assets/asyncapi-favicon.ico'), "base64");
return callback(null, data);
return "data:image/x-icon;base64," + fs.readFileSync(path.resolve(__dirname, '../assets/asyncapi-favicon.ico'), "base64");
}

try {
// Attempt to fetch favicon
const response = await fetch(favicon);
const response = fetch(favicon);
if (response.status == 200) {
const buffer = await response.buffer()
const data = "data:image/x-icon;base64," + buffer.toString('base64');
callback(null, data);
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
const data = "data:image/x-icon;base64," + fs.readFileSync(favicon, "base64");
callback(null, data);
return "data:image/x-icon;base64," + fs.readFileSync(favicon, "base64");
} catch (err) {
console.error("Failed to fetch/read favicon", fetchErr, err);
callback(err);
throw err;
}
}
}
filter.generateBase64Favicon = generateBase64Favicon;

/**
* 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) {
export function includeFile(pathFile) {
const pathToFile = path.resolve(__dirname, '../', pathFile);
return fs.readFileSync(pathToFile);
}
filter.includeFile = includeFile;

/**
* Stringifies the specification with escaping circular refs
* and annotates that specification is parsed.
*/
function stringifySpec(asyncapi) {
return AsyncAPIDocument.stringify(asyncapi);
export function stringifySpec(asyncapi) {
return stringify(asyncapi);
}
filter.stringifySpec = stringifySpec;

/**
* Stringifies prepared configuration for component.
*/
function stringifyConfiguration(params) {
export function stringifyConfiguration(params) {
return JSON.stringify(prepareConfiguration(params));
}
filter.stringifyConfiguration = stringifyConfiguration;

/**
* Renders AsyncApi component by given AsyncAPI spec and with corresponding template configuration.
*/
function renderSpec(asyncapi, params) {
loadLanguagesConfig();

const component = React.createElement(AsyncApiComponent, { schema: asyncapi, config: prepareConfiguration(params) });

/**
* @param {AsyncAPIDocumentInterface} asyncapi
* @param {*} params
*/
export function renderSpec(asyncapi, params) {
loadLanguagesConfig();
const config = prepareConfiguration(params);
const stringified = stringifySpec(asyncapi);
const component = <AsyncApiComponent schema={stringified} config={config}/>;
return ReactDOMServer.renderToString(component);
}
filter.renderSpec = renderSpec;
16 changes: 0 additions & 16 deletions hooks/02_renameOutFile.js

This file was deleted.

Loading

0 comments on commit 1fbb3ed

Please sign in to comment.