Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
josephinoo committed Feb 22, 2024
1 parent c22544f commit e93d2bc
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 11 deletions.
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
{
"command": "asyncapi.paste",
"title": "AsyncAPI: Paste as Schema"
},
{
"command": "asyncapi.md",
"title": "AsyncAPI: Convert to Markdown"
}
],
"snippets": [
Expand Down Expand Up @@ -121,6 +125,7 @@
"ts-loader": "^9.2.8",
"typescript": "^4.6.4",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2"
"webpack-cli": "^4.9.2",
"mermaid": "^10.8.0"
}
}
206 changes: 206 additions & 0 deletions src/ConvertMD.ts
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`;

// 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;
}
40 changes: 31 additions & 9 deletions src/PreviewWebPanel.ts
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,
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -66,7 +70,6 @@ export function openAsyncAPI(context: vscode.ExtensionContext, uri: vscode.Uri)
x: message.scrollX,
y: message.scrollY
};

}
}
},
Expand Down Expand Up @@ -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')
Expand All @@ -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;
}
Expand All @@ -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">
${mermaidCode};
</pre>
<script src="${asyncapiComponentJs}"></script>
<script>
const vscode = acquireVsCodeApi();
Expand All @@ -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>
`;
Expand Down
4 changes: 3 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { isAsyncAPIFile, openAsyncAPI, openAsyncapiFiles, previewAsyncAPI } from './PreviewWebPanel';
import { isAsyncAPIFile, openAsyncAPI, openAsyncapiFiles, previewAsyncAPI, previewMarkdown} from './PreviewWebPanel';
import { asyncapiSmartPaste } from './SmartPasteCommand';


Expand Down Expand Up @@ -37,6 +37,8 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand('asyncapi.preview', previewAsyncAPI(context)));

context.subscriptions.push(vscode.commands.registerCommand("asyncapi.paste", asyncapiSmartPaste));

context.subscriptions.push(vscode.commands.registerCommand('asyncapi.md', previewMarkdown(context)));
}

export function deactivate() {}

0 comments on commit e93d2bc

Please sign in to comment.