-
-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternative Preview Option with Markdown and MermaidJS Diagrams #161
Comments
I may have misunderstood the scope of this issue, it sounds like the idea is to have some kind of alternative preview mode. If mermaid diagrams could be inlined in markdown anywhere in the documentation would that cover this issue too? Or mean it's not necessary to have an alternative preview? I've added an issue to Also, the scrolling sync thing sounds like an unrelated/separate feature :) |
This issue has been automatically marked as stale because it has not had recent activity 😴 It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation. There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model. Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here. Thank you for your patience ❤️ |
Hi @ivangsa, I am Nikhil, SWE at Daimler Trucks. I find this task very interesting and would like to contribute here as part of GSOC2024.
The above Message Payload refers to the Users component and the below is the class diagram view: classDiagram
class User {
id: string
fullName: string
email: string
age: integer
}
Should I only pick all the possible Message Payloads from the Asyncapi Document and show it like above or also the relations need to be shown. If you can share more info on this then it will help me to follow up. Thanks in Advance! |
Not sure if you saw already, but I previously made a PR that adds mermaid support. It worked just fine, you would just include the mermaid in any description markdown and it rendered inline in the preview. However, there were some suggestions for improvements (a different approach that I didn't understand, embedding the mermaid code instead of referencing out to mermaid.js - I'm not a JS/React developer so I didn't really know how to implement it), and they were in the middle of trying to land a long-lived release branch and trying to get everything sorted, so instead of fixing and merging that PR they just said to make a new one on the new version-branch. In any case, it really didn't seem very important to them, despite being super powerful as a documentation tool, so you might not get much support... but, if you do want to get this working that PR is probably a good place to start. It shows a working solution (albeit on an old version/branch) plus the feedback comments of what structural changes were needed. |
Hi @nikhilkalburgi Regarding mermaid representation, create the representation you would like to see as an user.. I would definetely do the payloads schemas with relationships... and more @j-h-a I'm sorry you got a PR waiting so long.. I think these diagrams are very expressive... Any way, that PR is on a different component, that uses React... this is about plain markdown+mermaid |
Hi @ivangsa, I'm interested in being part of this project. Could you provide me with more relevant information to get to know it better? I did something small. flowchart TD
subgraph "Streetlights Kafka API"
subgraph "Servers"
scram-connections["scram-connections"]
mtls-connections["mtls-connections"]
end
subgraph "Channels"
lightingMeasured["lightingMeasured"]
lightTurnOn["lightTurnOn"]
lightTurnOff["lightTurnOff"]
lightsDim["lightsDim"]
end
subgraph "Operations"
receiveLightMeasurement["receiveLightMeasurement"]
turnOn["turnOn"]
turnOff["turnOff"]
dimLight["dimLight"]
end
subgraph "Messages"
lightMeasured["lightMeasured"]
turnOn["turnOn"]
turnOff["turnOff"]
dimLight["dimLight"]
end
end
scram-connections --> lightingMeasured
scram-connections --> lightTurnOn
scram-connections --> lightTurnOff
scram-connections --> lightsDim
mtls-connections --> lightingMeasured
mtls-connections --> lightTurnOn
mtls-connections --> lightTurnOff
mtls-connections --> lightsDim
lightingMeasured --> receiveLightMeasurement
lightTurnOn --> turnOn
lightTurnOff --> turnOff
lightsDim --> dimLight
|
Hi @josephinoo Can you generate this programatically? parsing an asyncapi.yml file and returning this output as a string... |
Hi @ivangsa,
Example: Info Object translated to Markdown Sample Code:
2. For mermaid Support
3. Need to implement the Logic to convert the other objects like messages, servers, channels, operations to mermaidjs diagrams like flowchart shared by @josephinoo. Creating a function that uses all these objects and build the markdown for the diagrams. 4. Apart from this, we can add copy button to export the generated markdown and also use avro-parser from asyncapi itself to convert the avro syntax as well and I had raised a PR to keep the preview in sync with asyncapi #206 (Merged) that can also work for this new preview Eventually, I am trying to render the whole asyncapi.yaml to markdown + create mermaid diagrams by consolidating the info from all the required objects. I have also shared a proposal with you on your slack Dms and would like to have your feedback to continue with you and contribute to the project. |
Hi @nikhilkalburgi, I've created a prototype that obviously needs improvements, but I'm working on it. @ivangsa, I'm figuring out how to enhance it and I want to understand a few more things to make it perfect. Also, I'm considering changing the color in the different subgraphs to make the information more visible. import * as fs from 'fs';
import * as yaml from 'js-yaml';
interface AsyncAPIDocument {
asyncapi: string;
info: {
title: string;
version: string;
description: string;
};
servers: {
[key: string]: {
host: string;
protocol: string;
description: string;
};
};
channels: {
[key: string]: {
address: string;
description: string;
messages: {
[key: string]: {
$ref: string;
};
};
parameters?: {
[key: string]: {
$ref: string;
};
};
};
};
operations: {
[key: string]: {
action: string;
channel: {
$ref: string;
};
summary: string;
traits?: {
[key: string]: {
$ref: string;
};
};
messages?: {
[key: string]: {
$ref: string;
};
};
};
};
components?: {
messages?: {
[key: string]: {
name: string;
title: string;
summary: string;
contentType: string;
traits?: {
[key: string]: {
$ref: string;
};
};
payload?: {
$ref: string;
};
};
};
schemas?: {
[key: string]: {
type: string;
properties: {
[key: string]: {
type: string;
minimum?: number;
maximum?: number;
description?: string;
enum?: string[];
format?: string;
items?: {
type: string;
};
$ref?: string;
};
};
description?: string;
};
};
securitySchemes?: {
[key: string]: {
type: string;
description: string;
};
};
parameters?: {
[key: string]: {
description: string;
schema: {
type: string;
format?: string;
minimum?: number;
maximum?: number;
};
};
};
messageTraits?: {
[key: string]: {
headers: {
type: string;
properties: {
[key: string]: {
type: string;
minimum?: number;
maximum?: number;
};
};
};
};
};
operationTraits?: {
[key: string]: {
bindings: {
kafka: {
clientId: {
type: string;
enum: string[];
};
};
};
};
};
};
}
function convertAsyncAPIToMermaid(asyncAPIDocument: AsyncAPIDocument): string {
let mermaidCode = `flowchart TD\n`;
// Add Streetlights Kafka API node
mermaidCode += ` subgraph "${asyncAPIDocument.info.title}"\n`;
// Add Servers subgraph
mermaidCode += ` subgraph "Servers"\n`;
Object.entries(asyncAPIDocument.servers).forEach(([serverName, serverInfo]) => {
mermaidCode += ` ${serverName}["${serverName}"]\n`;
});
mermaidCode += ` end\n`;
// Add Channels subgraph
mermaidCode += ` subgraph "Channels"\n`;
Object.entries(asyncAPIDocument.channels).forEach(([channelName, channelInfo]) => {
mermaidCode += ` ${channelName}["${channelName}"]\n`;
});
mermaidCode += ` end\n`;
// Add Operations subgraph
mermaidCode += ` subgraph "Operations"\n`;
Object.entries(asyncAPIDocument.operations).forEach(([operationName, operationInfo]) => {
mermaidCode += ` ${operationName}["${operationName}"]\n`;
});
mermaidCode += ` end\n`;
// Add Messages subgraph
mermaidCode += ` subgraph "Messages"\n`;
Object.entries(asyncAPIDocument.components.messages).forEach(([messageName, messageInfo]) => {
mermaidCode += ` ${messageName}["${messageName}"]\n`;
});
mermaidCode += ` end\n`;
mermaidCode += ` end\n`;
// Add connections between servers and channels
Object.entries(asyncAPIDocument.servers).forEach(([serverName]) => {
Object.entries(asyncAPIDocument.channels).forEach(([channelName]) => {
mermaidCode += ` ${serverName} --> ${channelName}\n`;
});
});
// Add connections between channels and operations
Object.entries(asyncAPIDocument.channels).forEach(([channelName, channelInfo]) => {
Object.entries(asyncAPIDocument.operations).forEach(([operationName]) => {
if (channelInfo.messages && channelInfo.messages[operationName]) {
mermaidCode += ` ${channelName} --> ${operationName}\n`;
}
});
});
// Add connections between channels and messages
Object.entries(asyncAPIDocument.channels).forEach(([channelName, channelInfo]) => {
Object.entries(asyncAPIDocument.components.messages).forEach(([messageName]) => {
if (channelInfo.messages && channelInfo.messages[messageName]) {
mermaidCode += ` ${channelName} --> ${messageName}\n`;
}
});
});
// Add connections between operations and messages
Object.entries(asyncAPIDocument.operations).forEach(([operationName, operationInfo]) => {
Object.entries(asyncAPIDocument.components.messages).forEach(([messageName]) => {
if (operationInfo.messages && operationInfo.messages[messageName]) {
mermaidCode += ` ${operationName} --> ${messageName}\n`;
}
});
});
return mermaidCode;
}
try {
const yamlFile = fs.readFileSync('asyncapi.yaml', 'utf8');
const asyncAPIDocument: AsyncAPIDocument = yaml.load(yamlFile) as AsyncAPIDocument;
const mermaidCode = convertAsyncAPIToMermaid(asyncAPIDocument);
console.log(mermaidCode);
} catch (err) {
console.error('Error......:', err);
}``` |
hey, you guys know how to use version control right? you can start codiging as a team and pull requests to this new branch Thanks for all your effort and Happy Coding!! |
Yes @ivangsa , I know and have already raised one to this project before. We can initially finalize the timeline and prototype together and implement it to build this feature. |
Provide and alternative preview based on markdown that visualizes message payload as MermaidJS Class Diagrams
https://mermaid.js.org/syntax/classDiagram.html
The text was updated successfully, but these errors were encountered: