From 4ecac89ad8aa5a2d17fde532c7c02f2a5fb8b988 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Sat, 9 Mar 2024 16:51:02 +0100 Subject: [PATCH] update implementation --- examples/simple-react/package.json | 2 +- examples/simple-react/src/App.tsx | 8 +++ examples/simple-react/src/edalearn/System.tsx | 65 +++++++++++++++++ .../simple-react/src/edalearn/application.tsx | 72 +++++++++++++++++++ examples/simple-react/src/edalearn/apps.js | 8 +++ .../simple-react/src/gamingapi/System.tsx | 5 +- .../src/gamingapi/application.tsx | 8 +-- examples/simple-react/types/asyncapi.d.ts | 1 + library/package-lock.json | 25 +++++++ library/package.json | 1 + library/src/helpers/AsyncAPIParserHelper.ts | 52 ++++++++++++++ library/src/index.ts | 1 + 12 files changed, 240 insertions(+), 8 deletions(-) create mode 100644 examples/simple-react/src/edalearn/System.tsx create mode 100644 examples/simple-react/src/edalearn/application.tsx create mode 100644 examples/simple-react/src/edalearn/apps.js create mode 100644 examples/simple-react/types/asyncapi.d.ts create mode 100644 library/src/helpers/AsyncAPIParserHelper.ts diff --git a/examples/simple-react/package.json b/examples/simple-react/package.json index 53f97b4..b7fbe85 100644 --- a/examples/simple-react/package.json +++ b/examples/simple-react/package.json @@ -24,7 +24,7 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "postinstall": "npm link ../../library/node_modules/react-dom ../../library/node_modules/react ../../library/ @asyncapi/parser", + "postinstall": "npm link ../../library/node_modules/react-dom ../../library/node_modules/react ../../library/", "predeploy": "npm run build", "deploy": "gh-pages -d build" }, diff --git a/examples/simple-react/src/App.tsx b/examples/simple-react/src/App.tsx index ed1dd81..3b4ecbc 100644 --- a/examples/simple-react/src/App.tsx +++ b/examples/simple-react/src/App.tsx @@ -6,6 +6,8 @@ import GamingapiSystem from './gamingapi/System'; import GamingapiApplication from './gamingapi/application'; import SocialMediaSystem from './social_media/System'; import SocialMediaApplication from './social_media/application'; +import EdaLearn from './edalearn/System'; +import EdaLearnApplication from './edalearn/application'; export const App = () => { return ( @@ -58,6 +60,12 @@ export const App = () => { + + + + + + diff --git a/examples/simple-react/src/edalearn/System.tsx b/examples/simple-react/src/edalearn/System.tsx new file mode 100644 index 0000000..1ef4c64 --- /dev/null +++ b/examples/simple-react/src/edalearn/System.tsx @@ -0,0 +1,65 @@ +import { useState, useEffect } from 'react'; +import { SystemView, fromURL} from '@asyncapi/edavisualiser'; +import { apps } from './apps'; +import '@asyncapi/edavisualiser/styles/default.css'; +const AsyncapiParser = require('@asyncapi/parser/browser'); + +function Asyncapi() { + const [asyncapiDocuments, setAsyncapiDocuments] = useState>([]); + + useEffect(() => { + const fetchData = async () => { + const data = []; + const parser = new AsyncapiParser.Parser({ + ruleset: { core:false, recommended:false } + }); + for (const [name, asyncapiUrl] of Object.entries(apps)) { + const result = fromURL(parser, asyncapiUrl); + const {document, diagnostics} = await result.parse(); + console.log(diagnostics) + if(document) + data.push({ parsedDoc: document, name }); + } + setAsyncapiDocuments(data); + }; + + fetchData().catch(console.error); + }, []); + + let node; + if (asyncapiDocuments.length > 0) { + node = ( + { + return { + asyncapi: { + document: parsedDoc, + topExtended: ( +
+ + + +
+ ) + }, + } + })} + /> + ); + } else { + node =

Wait...

; + } + return
{node}
; +} + +export default Asyncapi; diff --git a/examples/simple-react/src/edalearn/application.tsx b/examples/simple-react/src/edalearn/application.tsx new file mode 100644 index 0000000..6b24752 --- /dev/null +++ b/examples/simple-react/src/edalearn/application.tsx @@ -0,0 +1,72 @@ +import { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { ApplicationFocusView, fromURL } from '@asyncapi/edavisualiser'; +import { apps } from './apps'; +import '@asyncapi/edavisualiser/styles/default.css'; +const AsyncapiParser = require('@asyncapi/parser/browser'); + + +function Asyncapi() { + const [externalApplications, setAsyncapiDocuments] = useState>([]); + const [focusedApplication, setFocusedApplication] = useState<{ parsedDoc: any, name: string }>(); + let { application } = useParams<{ application: string }>(); + + useEffect(() => { + const fetchData = async () => { + const data = []; + const parser = new AsyncapiParser.Parser({ + ruleset: { core: false, recommended: false } + }); + for (const [name, asyncapiUrl] of Object.entries(apps)) { + const result = fromURL(parser, asyncapiUrl); + const {document} = await result.parse(); + if (application === name) { + setFocusedApplication({ parsedDoc: document, name }); + } else { + data.push({ parsedDoc: document, name }); + } + } + setAsyncapiDocuments(data); + }; + + fetchData().catch(console.error); + }, [application]); + + let node; + if (externalApplications.length > 0 && focusedApplication !== undefined) { + node = ( + { + return { + asyncapi: { + document: parsedDoc, + topExtended: ( + + ) + } + } + })} + /> + ); + } else { + node =

Wait...

; + } + return
{node}
; +} + +export default Asyncapi; diff --git a/examples/simple-react/src/edalearn/apps.js b/examples/simple-react/src/edalearn/apps.js new file mode 100644 index 0000000..d961be4 --- /dev/null +++ b/examples/simple-react/src/edalearn/apps.js @@ -0,0 +1,8 @@ +export const apps = { + customers: + 'https://raw.githubusercontent.com/EDALearn/FoodDeliveryService-KIT-AsyncAPI-In-Action/main/modules/customers/src/main/resources/apis/asyncapi.yml', + orders: + 'https://raw.githubusercontent.com/EDALearn/FoodDeliveryService-KIT-AsyncAPI-In-Action/main/modules/orders/src/main/resources/apis/asyncapi.yml', + restaurants: 'https://raw.githubusercontent.com/EDALearn/FoodDeliveryService-KIT-AsyncAPI-In-Action/main/modules/restaurants/src/main/resources/apis/asyncapi.yml', + delivery: 'https://raw.githubusercontent.com/EDALearn/FoodDeliveryService-KIT-AsyncAPI-In-Action/main/modules/delivery/src/main/resources/apis/asyncapi.yml' +}; diff --git a/examples/simple-react/src/gamingapi/System.tsx b/examples/simple-react/src/gamingapi/System.tsx index 8202ac4..34892ed 100644 --- a/examples/simple-react/src/gamingapi/System.tsx +++ b/examples/simple-react/src/gamingapi/System.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { SystemView } from '@asyncapi/edavisualiser'; +import { SystemView, fromURL } from '@asyncapi/edavisualiser'; import { apps } from './apps'; import '@asyncapi/edavisualiser/styles/default.css'; const AsyncapiParser = require('@asyncapi/parser/browser'); @@ -12,7 +12,8 @@ function Asyncapi() { const parser = new AsyncapiParser.Parser(); const data = []; for (const [name, asyncapiUrl] of Object.entries(apps)) { - const {document} = await AsyncapiParser.fromURL(parser, asyncapiUrl); + const result = fromURL(parser, asyncapiUrl); + const {document} = await result.parse(); data.push({ parsedDoc: document, name }); } setAsyncapiDocuments(data); diff --git a/examples/simple-react/src/gamingapi/application.tsx b/examples/simple-react/src/gamingapi/application.tsx index a0b663e..b6ca997 100644 --- a/examples/simple-react/src/gamingapi/application.tsx +++ b/examples/simple-react/src/gamingapi/application.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; -import { ApplicationFocusView } from '@asyncapi/edavisualiser'; +import { ApplicationFocusView, fromURL } from '@asyncapi/edavisualiser'; import { apps } from './apps'; import '@asyncapi/edavisualiser/styles/default.css'; const AsyncapiParser = require('@asyncapi/parser/browser'); @@ -15,16 +15,14 @@ function Asyncapi() { const data = []; const parser = new AsyncapiParser.Parser(); for (const [name, asyncapiUrl] of Object.entries(apps)) { + const result = fromURL(parser, asyncapiUrl); + const {document} = await result.parse(); if (application === name) { - const result = AsyncapiParser.fromURL(parser, asyncapiUrl); - const {document} = await result.parse(); if(document === undefined) { return; } setFocusedApplication({ parsedDoc: document, name }); } else { - const result = AsyncapiParser.fromURL(parser, asyncapiUrl); - const {document} = await result.parse(); data.push({ parsedDoc: document, name }); } } diff --git a/examples/simple-react/types/asyncapi.d.ts b/examples/simple-react/types/asyncapi.d.ts new file mode 100644 index 0000000..c3d830f --- /dev/null +++ b/examples/simple-react/types/asyncapi.d.ts @@ -0,0 +1 @@ +declare module '@asyncapi/parser/browser/index'; \ No newline at end of file diff --git a/library/package-lock.json b/library/package-lock.json index 22b5d59..ca3d5ef 100644 --- a/library/package-lock.json +++ b/library/package-lock.json @@ -27,6 +27,7 @@ "@types/jsdom": "^16.2.14", "@types/marked": "^4.0.1", "@types/node": "^12.7.2", + "@types/node-fetch": "^2.6.11", "@types/react": "^16.9.2", "@types/react-dom": "^16.8.0", "@types/react-test-renderer": "^17.0.1", @@ -3642,6 +3643,30 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", diff --git a/library/package.json b/library/package.json index bc42d6f..8a40da1 100644 --- a/library/package.json +++ b/library/package.json @@ -67,6 +67,7 @@ "@types/jsdom": "^16.2.14", "@types/marked": "^4.0.1", "@types/node": "^12.7.2", + "@types/node-fetch": "^2.6.11", "@types/react": "^16.9.2", "@types/react-dom": "^16.8.0", "@types/react-test-renderer": "^17.0.1", diff --git a/library/src/helpers/AsyncAPIParserHelper.ts b/library/src/helpers/AsyncAPIParserHelper.ts new file mode 100644 index 0000000..eb3ba82 --- /dev/null +++ b/library/src/helpers/AsyncAPIParserHelper.ts @@ -0,0 +1,52 @@ +import { + Parser, + ParseOptions, + ParseOutput, + ValidateOptions, + Input, + Diagnostic, +} from '@asyncapi/parser'; + +/** + * Functionality taken from the AsyncAPI parser + */ + +export interface FromResult { + parse: (options?: ParseOptions) => Promise; + validate: (options?: ValidateOptions) => Promise; +} + +export function fromURL( + parser: Parser, + source: string, + options?: RequestInit, +): FromResult { + async function fetchUrl(): Promise { + const fetchFn = await getFetch(); + return (await fetchFn(source, options as any)).text(); + } + + return { + async parse(options: ParseOptions = {}) { + const schema = await fetchUrl(); + return parser.parse(schema, { ...options, source }); + }, + async validate(options: ValidateOptions = {}) { + const schema = await fetchUrl(); + return parser.validate(schema, { ...options, source }); + }, + }; +} + +let __fetchFn: typeof fetch | undefined; +async function getFetch(): Promise { + if (__fetchFn) { + return __fetchFn; + } + + if (typeof fetch === 'undefined') { + return (__fetchFn = ((await import('node-fetch')) + .default as unknown) as typeof fetch); + } + return (__fetchFn = fetch); +} diff --git a/library/src/index.ts b/library/src/index.ts index 8e5a515..424ae20 100644 --- a/library/src/index.ts +++ b/library/src/index.ts @@ -7,6 +7,7 @@ export * from './components/nodes/Outgoing'; export * from './components/nodes/AsyncAPIApplication'; export * from './components/layouts'; export * from './types'; +export * from './helpers/AsyncAPIParserHelper'; import { ApplicationView,