-
-
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
feat: mermaid markdown #208
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
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[]; | ||
}; | ||
}; | ||
}; | ||
}; | ||
}; | ||
}; | ||
} | ||
export function convertAsyncAPIToMermaid(asyncAPIFilePath:string): string { | ||
const yamlFile = fs.readFileSync(asyncAPIFilePath, 'utf8'); | ||
const asyncAPIDocument: AsyncAPIDocument = yaml.load(yamlFile) as AsyncAPIDocument; | ||
let mermaidCode = `flowchart TD\n`; | ||
|
||
mermaidCode += ` subgraph "${asyncAPIDocument.info.title}"\n`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a good start but I should evolve to use some templating engine for js |
||
|
||
// 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; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import * as vscode from 'vscode'; | ||
import * as path from 'path'; | ||
import { convertAsyncAPIToMermaid } from './ConvertMD'; | ||
|
||
let position : {x:0,y:0} = { | ||
x: 0, | ||
|
@@ -16,6 +17,7 @@ export function previewAsyncAPI(context: vscode.ExtensionContext) { | |
}; | ||
} | ||
|
||
|
||
export const openAsyncapiFiles: { [id: string]: vscode.WebviewPanel } = {}; // vscode.Uri.fsPath => vscode.WebviewPanel | ||
|
||
export function isAsyncAPIFile(document?: vscode.TextDocument) { | ||
|
@@ -56,8 +58,10 @@ export function openAsyncAPI(context: vscode.ExtensionContext, uri: vscode.Uri) | |
}); | ||
|
||
panel.title = path.basename(uri.fsPath); | ||
console.log('Opening HTML'); | ||
console.log(getWebviewContent(context, panel.webview, uri, position)); | ||
panel.webview.html = getWebviewContent(context, panel.webview, uri, position); | ||
|
||
panel.webview.onDidReceiveMessage( | ||
message => { | ||
switch (message.type) { | ||
|
@@ -66,7 +70,6 @@ export function openAsyncAPI(context: vscode.ExtensionContext, uri: vscode.Uri) | |
x: message.scrollX, | ||
y: message.scrollY | ||
}; | ||
|
||
} | ||
} | ||
}, | ||
|
@@ -96,6 +99,23 @@ async function promptForAsyncapiFile() { | |
return uris?.[0]; | ||
} | ||
|
||
export function previewMarkdown(context: vscode.ExtensionContext) { | ||
return "Hello World!"; | ||
|
||
} | ||
|
||
async function convertAsyncAPItoMD(context: vscode.ExtensionContext, uri: vscode.Uri) { | ||
return "Hello World!"; | ||
|
||
} | ||
|
||
function convertToMD(context: vscode.ExtensionContext, webview: vscode.Webview, asyncapiFile: vscode.Uri, position: {x:0,y:0}){ | ||
console.log('Converting to MD'); | ||
const asyncapiWebviewUri = webview.asWebviewUri(asyncapiFile); | ||
console.log(asyncapiWebviewUri); | ||
return "Hello"; | ||
} | ||
|
||
function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Webview, asyncapiFile: vscode.Uri, position: {x:0,y:0}) { | ||
const asyncapiComponentJs = webview.asWebviewUri( | ||
vscode.Uri.joinPath(context.extensionUri, 'dist/node_modules/@asyncapi/react-component/browser/standalone/index.js') | ||
|
@@ -104,13 +124,14 @@ function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Web | |
vscode.Uri.joinPath(context.extensionUri, 'dist/node_modules/@asyncapi/react-component/styles/default.min.css') | ||
); | ||
const asyncapiWebviewUri = webview.asWebviewUri(asyncapiFile); | ||
const mermaidCode = convertAsyncAPIToMermaid(asyncapiFile.fsPath); | ||
const asyncapiBasePath = asyncapiWebviewUri.toString().replace('%2B', '+'); // this is loaded by a different library so it requires unescaping the + character | ||
const html = ` | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<link rel="stylesheet" href="${asyncapiComponentCss}"> | ||
<style> | ||
<style> | ||
html{ | ||
scroll-behavior: smooth; | ||
} | ||
|
@@ -124,10 +145,12 @@ function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Web | |
} | ||
</style> | ||
</head> | ||
|
||
<body x-timestamp="${Date.now()}"> | ||
|
||
<div id="asyncapi"></div> | ||
|
||
<pre class="mermaid"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this would be on a different preview-panel, started by a different command.. |
||
${mermaidCode}; | ||
</pre> | ||
<script src="${asyncapiComponentJs}"></script> | ||
<script> | ||
const vscode = acquireVsCodeApi(); | ||
|
@@ -144,21 +167,20 @@ function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Web | |
parserOptions: { path: '${asyncapiBasePath}' } | ||
}, | ||
}, document.getElementById('asyncapi')); | ||
|
||
window.addEventListener('scrollend', event => { | ||
vscode.postMessage({ | ||
type: 'position', | ||
scrollX: window.scrollX || 0, | ||
scrollY: window.scrollY || 0 | ||
}); | ||
}); | ||
|
||
window.addEventListener("load", (event) => { | ||
setTimeout(()=>{window.scrollBy('${position.x}','${position.y}')},1000) | ||
}); | ||
|
||
</script> | ||
|
||
<script type="module"> | ||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs'; | ||
</script> | ||
</body> | ||
</html> | ||
`; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not create/maintain this interface, use @asyncapi/js-parser for this, of just use