Skip to content
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: initial try to get the parser working #1026

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion apps/studio-next/next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,47 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}
const nextConfig = {
/**
* @param {import('next/dist/server/config-shared').NextJsWebpackConfig} config
* @returns
*/
webpack: (
config,
{ isServer }
) => {
const fallback = config.resolve.fallback || (config.resolve.fallback = {});

Object.assign(fallback, {
assert: require.resolve("assert/"),
buffer: require.resolve("buffer"),
http: require.resolve("stream-http"),
https: require.resolve("https-browserify"),
path: require.resolve("path-browserify"),
stream: require.resolve("stream-browserify"),
zlib: require.resolve("browserify-zlib"),
url: require.resolve("url/"),
util: require.resolve("util/"),
});

if (!isServer) {
fallback.fs = false;
fallback.path = false;
fallback.util = false;
}

config.resolve.fallback = fallback;

config.module.rules.push({
test: /\.node/,
use: 'raw-loader',
});

config.externals.push({
'utf-8-validate': 'commonjs utf-8-validate',
bufferutil: 'commonjs bufferutil',
})

return config;
}
}

module.exports = nextConfig
23 changes: 23 additions & 0 deletions apps/studio-next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,43 @@
"lint": "next lint"
},
"dependencies": {
"@asyncapi/avro-schema-parser": "^3.0.18",
"@asyncapi/openapi-schema-parser": "^3.0.18",
"@asyncapi/parser": "^3.0.10",
"@asyncapi/protobuf-schema-parser": "^3.2.8",
"@asyncapi/react-component": "^1.0.0-next.54",
"@codemirror/commands": "^6.3.3",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-yaml": "^6.0.0",
"@codemirror/language": "^6.10.1",
"@codemirror/state": "^6.4.1",
"@codemirror/theme-one-dark": "^6.1.2",
"@types/node": "20.4.6",
"@types/react": "18.2.18",
"@types/react-dom": "18.2.7",
"ajv": "^8.0.1",
"assert": "^2.1.0",
"autoprefixer": "10.4.14",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"canvas": "^2.11.2",
"codemirror": "^6.0.1",
"encoding": "^0.1.13",
"eslint": "8.46.0",
"eslint-config-next": "13.4.12",
"https-browserify": "^1.0.0",
"next": "13.5.1",
"path-browserify": "^1.0.1",
"postcss": "8.4.31",
"raw-loader": "^4.0.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"tailwindcss": "3.3.3",
"typescript": "5.1.6",
"url": "^0.11.3",
"util": "^0.12.5",
"zustand": "^4.5.2"
}
}
4 changes: 3 additions & 1 deletion apps/studio-next/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Editor } from '@/components/Editor/Editor';
import { HTMLWrapper } from '@/components/Template';

export default function Home() {
return (
<main className="flex flex-col w-full h-screen">
<main className="flex flex-row w-full h-screen">
<Editor />
<HTMLWrapper />
</main>
)
}
62 changes: 62 additions & 0 deletions apps/studio-next/src/components/Template/HTMLWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use client';

import React, { useState, useEffect } from 'react';

import { useDocumentsState } from '../../state';
import { AsyncAPIDocumentInterface } from '@asyncapi/parser/cjs';
import { AsyncApiComponentWP } from '@asyncapi/react-component';
import '@asyncapi/react-component/styles/default.min.css';

interface HTMLWrapperProps {}

export const HTMLWrapper: React.FunctionComponent<HTMLWrapperProps> = () => {
const [parsedSpec, setParsedSpec] = useState<AsyncAPIDocumentInterface | null>(null);
const document = useDocumentsState(state => state.documents['asyncapi']?.document) || null;
const [loading, setloading] = useState(false);

useEffect(() => {
if (parsedSpec === null) {
setParsedSpec(document);
}
}, [document]); // eslint-disable-line

useEffect(() => {
if (!document) {
setloading(true);
const timer = setTimeout(() => {
setloading(false);
}, 1000);
return () => clearTimeout(timer);
}
},[document])
if (!document) {
return (
<div className="flex flex-1 overflow-hidden h-full justify-center items-center text-2xl mx-auto px-6 text-center">
{loading ?(
<div className="rotating-wheel"></div>
) : (
<p>Empty or invalid document. Please fix errors/define AsyncAPI document.</p>
)
}
</div>
);
}

return (
parsedSpec && (
<div className="flex flex-1 flex-col h-full overflow-hidden">
<div className="overflow-auto">
<AsyncApiComponentWP
schema={parsedSpec}
config={{
show: {
errors: false,
// sidebar: appState.getState().readOnly,
},
}}
/>
</div>
</div>
)
);
};
13 changes: 13 additions & 0 deletions apps/studio-next/src/components/Template/Template.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

import { HTMLWrapper } from './HTMLWrapper';

interface TemplateProps {}

export const Template: React.FunctionComponent<TemplateProps> = () => {
return (
<div className="flex flex-1 flex-col h-full overflow-hidden">
<HTMLWrapper />
</div>
);
};
32 changes: 32 additions & 0 deletions apps/studio-next/src/components/Template/TemplateSidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
// import { VscRefresh } from 'react-icons/vsc';

import { useSettingsState, otherState } from '../../state';

interface TemplateSidebarProps {}

export const TemplateSidebar: React.FunctionComponent<TemplateSidebarProps> = () => {
const autoRendering = useSettingsState(state => state.templates.autoRendering);

return (
<div
className="flex flex-row items justify-between bg-gray-800 border-b border-gray-700 text-sm"
style={{ height: '30px', lineHeight: '30px' }}
>
{autoRendering ? (
<div />
) : (
<div className="ml-2 text-gray-500 text-xs flex" style={{ height: '30px', lineHeight: '30px' }}>
<button type="button" className="text-xs" onClick={() => otherState.setState({ templateRerender: true })}>
<div className="inline-block">
{/* <VscRefresh className="w-4 h-4 mt-1" /> */}
</div>
</button>
<span className="ml-2 italic">
Rerender
</span>
</div>
)}
</div>
);
};
2 changes: 2 additions & 0 deletions apps/studio-next/src/components/Template/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './Template';
export * from './HTMLWrapper';
57 changes: 57 additions & 0 deletions apps/studio-next/src/examples/ibmmq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
asyncapi: 3.0.0
info:
title: Record Label Service
version: 1.1.0
description: This service is in charge of processing music
license:
name: Apache License 2.0
url: 'https://www.apache.org/licenses/LICENSE-2.0'
servers:
production:
host: 'localhost:1414'
pathname: /QM1/DEV.APP.SVRCONN
protocol: ibmmq-secure
description: Production Instance 1
bindings:
ibmmq:
cipherSpec: ANY_TLS12
channels:
songReleased:
address: song/released
messages:
Song:
$ref: '#/components/messages/Song'
operations:
receiveSong:
action: receive
channel:
$ref: '#/channels/songReleased'
messages:
- $ref: '#/channels/songReleased/messages/Song'
sendSong:
action: send
channel:
$ref: '#/channels/songReleased'
messages:
- $ref: '#/channels/songReleased/messages/Song'
components:
messages:
Song:
payload:
type: object
properties:
title:
type: string
description: Song title
artist:
type: string
description: Song artist
album:
type: string
description: Song album
genre:
type: string
description: Primary song genre
length:
type: integer
description: Track length in seconds
85 changes: 85 additions & 0 deletions apps/studio-next/src/examples/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// @ts-nocheck

// protocol examples
import kafka from './streetlights-kafka.yml';
import websocket from './websocket-gemini.yml';
import mqtt from './streetlights-mqtt.yml';
import simple from './simple.yml';
import ibmmq from './ibmmq.yml';

// tutorial example
import invalid from './tutorials/invalid.yml';

// real world examples
import slack from './real-world/slack-rtm.yml';
import gitterStreaming from './real-world/gitter-streaming.yml';
import kraken from './real-world/kraken-api-request-reply-filter.yml';

const templateTypes = {
protocol: 'protocol-example',
realExample: 'real-example',
tutorial: 'tutorial-example'
};

export default [
{
title: 'Simple Example',
description: () => <>A basic example of a service that is in charge of processing user signups. Great place to start learning AsyncAPI.</>,
template: simple,
type: templateTypes.protocol
},
{
title: 'Invalid Example',
description: () => <>An example of an invalid AsyncAPI document. This is only for educational purposes, to learn document validation.</>,
template: invalid,
type: templateTypes.tutorial
},
{
title: 'Apache Kafka',
description: () => <>A framework implementation of a software bus using stream-processing. Open Source developed by the Apache Software Foundation.</>,
template: kafka,
type: templateTypes.protocol
},
{
title: 'WebSocket',
description: () => <>A computer communications protocol, providing full-duplex communication channels over a single TCP connection.</>,
template: websocket,
type: templateTypes.protocol
},
{
title: 'MQTT',
description: () => <>An OASIS standard messaging protocol for the Internet of Things. Ideal for connecting remote devices with limited processing power and bandwidth.</>,
template: mqtt,
type: templateTypes.protocol
},
{
title: 'IBM MQ',
description: () => <>A robust, reliable, and secure messaging solution. IBM MQ simplifies and accelerates the integration of different applications across multiple platforms and supports a wide range of APIs and languages.</>,
template: ibmmq,
type: templateTypes.protocol
},
{
title: 'HTTP',
description: () => <>A protocol for fetching resources. It is the foundation of any data exchange on the Web and it is a client-server protocol.</>,
template: gitterStreaming,
type: templateTypes.protocol
},
{
title: 'Slack Real Time Messaging API',
description: () => <>Slack Real time messaging API. Using HTTP protocol.</>,
template: slack,
type: templateTypes.realExample
},
{
title: 'Gitter Streaming API',
description: () => <>Gitter Streaming API from https://stream.gitter.im. Using HTTP protocol.</>,
template: gitterStreaming,
type: templateTypes.realExample
},
{
title: 'Kraken Websockets API',
description: () => <>This Kraken Websocket specification. Using Websocket with request / reply</>,
template: kraken,
type: templateTypes.realExample
}
];
Loading
Loading