diff --git a/apps/studio/.eslintignore b/apps/studio/.eslintignore
deleted file mode 100644
index b97cc9245..000000000
--- a/apps/studio/.eslintignore
+++ /dev/null
@@ -1,2 +0,0 @@
-build
-.turbo
diff --git a/apps/studio/.eslintrc b/apps/studio/.eslintrc
deleted file mode 100644
index c1da477ee..000000000
--- a/apps/studio/.eslintrc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "env": {
- "es6": true,
- "browser": true,
- "node": true
- },
- "plugins": ["security"],
- "extends":["eslint-config-custom", "eslint-config-custom/react"]
-}
diff --git a/apps/studio/.gitignore b/apps/studio/.gitignore
deleted file mode 100644
index db15c18a7..000000000
--- a/apps/studio/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.DS_Store
-/node_modules
-.vscode/
-/lib
-/build
\ No newline at end of file
diff --git a/apps/studio/CHANGELOG.md b/apps/studio/CHANGELOG.md
deleted file mode 100644
index c285625db..000000000
--- a/apps/studio/CHANGELOG.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# @asyncapi/studio
-
-## 0.21.4
-
-### Patch Changes
-
-- 877810d: fix: temporarily hard-lock `@asyncapi/converter` on `v1.5.0` as a hotfix (#1138)
-
-## 0.21.3
-
-### Patch Changes
-
-- 943fec1: fix: report correct `range` values in error diagnostics for YAML files
-
-## 0.21.2
-
-### Patch Changes
-
-- c3248c8: fix: fix the validation error for payload of type `date` (https://github.com/asyncapi/parser-js/issues/980)
-
-## 0.21.1
-
-### Patch Changes
-
-- 481b28c: fix: Incorrect rendering of security schemas: by reference and inline, #1066
-
-## 0.21.0
-
-### Minor Changes
-
-- 26dc05f: Fix side bar color and update @asyncapi/html-template.
-
-## 0.20.2
-
-### Patch Changes
-
-- 5c7b4c1: scrollTo navigation to right code block in yaml.
-
-## 0.20.1
-
-### Patch Changes
-
-- 6995cdf: bump dependencies
-
-## 0.20.0
-
-### Minor Changes
-
-- 5129432: start publishing studio.
-
-## 0.19.1
-
-### Patch Changes
-
-- 9187c17: fix studio breaking when trying to generate code/document
-
-## 0.19.0
-
-### Minor Changes
-
-- 94215e6: Support spec V3.0.0 in studio
diff --git a/apps/studio/Dockerfile b/apps/studio/Dockerfile
deleted file mode 100644
index 23ba67e73..000000000
--- a/apps/studio/Dockerfile
+++ /dev/null
@@ -1,52 +0,0 @@
-# Use a UUID as placeholder value to have a unique string to replace.
-ARG BASE_URL_PLACEHOLDER=189b303e-37a0-4f6f-8c0a-50333bc3c36e
-
-
-FROM node:18-alpine AS base
-
-FROM base AS builder
-RUN apk add --no-cache libc6-compat
-RUN apk update
-# Set working directory
-WORKDIR /app
-RUN npm install --global turbo
-COPY . .
-RUN turbo prune --scope=@asyncapi/studio --docker
-
-# Add lockfile and package.json's of isolated subworkspace
-FROM base AS installer
-
-ARG BASE_URL_PLACEHOLDER
-
-RUN apk add --no-cache libc6-compat
-RUN apk update
-WORKDIR /app
-
-# First install the dependencies (as they change less often)
-
-COPY .gitignore .gitignore
-COPY --from=builder /app/out/json/ .
-COPY --from=builder /app/out/package-lock.json ./package-lock.json
-RUN PUPPETEER_SKIP_DOWNLOAD=true npm ci
-
-# Build the project
-COPY --from=builder /app/out/full/ .
-RUN PUBLIC_URL=${BASE_URL_PLACEHOLDER} npm run build:studio
-
-
-FROM docker.io/library/nginx:1.25.5-alpine as runtime
-
-ARG BASE_URL_PLACEHOLDER
-# The base Nginx image automatically executes all shell scripts
-# within the /docker-entrypoint.d/ directory ("entrypoint scripts")
-# when the container is started. See the relevant logic at
-# https://github.com/nginxinc/docker-nginx/blob/master/entrypoint/docker-entrypoint.sh#L16.
-ARG ENTRYPOINT_SCRIPT=/docker-entrypoint.d/set-public-url.sh
-
-COPY --from=installer /app/apps/studio/build /usr/share/nginx/html/
-# Add an entrypoint script that replaces all occurrences of the
-# placeholder value by the configured base URL. If no base URL
-# is configured we assume the application is running at '/'.
-RUN echo "find /usr/share/nginx/html/ -type f -print0 | xargs -0 sed -i \"s|${BASE_URL_PLACEHOLDER}|\${BASE_URL}|g\"" > $ENTRYPOINT_SCRIPT && chmod +x $ENTRYPOINT_SCRIPT
-
-FROM runtime
diff --git a/apps/studio/README.md b/apps/studio/README.md
deleted file mode 100644
index d11a7fbb5..000000000
--- a/apps/studio/README.md
+++ /dev/null
@@ -1,117 +0,0 @@
-[![AsyncAPI Studio](../../assets/logo.png)](https://studio.asyncapi.com)
-
-One place that allows you to develop an AsyncAPI document, validate it, convert it to the latest version, preview the documentation and visualize the events flow.
-
-
-[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-)
-
-
----
-
-## :loudspeaker: ATTENTION:
-
-This project is still under development and has not reached version 1.0.0 yet. This means that its API/styling/features may contain breaking changes until we're able to deploy the first stable version and begin semantic versioning.
-
----
-
-
-
-
-
-- [Requirements](#requirements)
-- [Using it locally](#using-it-locally)
-- [Using it via Docker](#using-it-via-docker)
-- [Development](#development)
- * [Spin up Gitpod](#spin-up-gitpod)
-- [Contribution](#contribution)
-- [Contributors β¨](#contributors-%E2%9C%A8)
-
-
-
-## Requirements
-
-- [NodeJS](https://nodejs.org/en/) >= 14
-
-## Using it locally
-
-Run:
-
-```bash
-npm install
-npm start
-```
-
-and then go to [http://localhost:3000](http://localhost:3000).
-
-## Using it via Docker
-
-Run:
-
-```bash
-docker run -it -p 8000:80 asyncapi/studio
-```
-
-and then go to [http://localhost:8000](http://localhost:8000).
-
-The `asyncapi/studio` image is based on the official `nginx` image.
-Please refer to the [Nginx documentation](https://registry.hub.docker.com/_/nginx/) to learn how to e.g. pass a custom `nginx` configuration or plug in additional volumes.
-
-In some hosting scenarios (e.g. Docker Compose, Kubernetes) the container might not be exposed at the root path of the host.
-Set the environment variable `BASE_URL` to let AsyncAPI Studio know from where to resolve static assets:
-
-```bash
-docker run -it -p 8000:80 -e BASE_URL=/a/custom/path asyncapi/studio
-```
-
-Studio is also available as a Docker Desktop Extension. For more information, check [the related repository](https://github.com/thiyagu06/asyncapi-studio-docker-extension).
-
-## Development
-
-1. Setup project by installing dependencies `npm install`
-2. Write code and tests.
-3. Make sure all tests pass `npm test`
-
-### Spin up Gitpod
-In order to prepare and spin up a Gitpod dev environment for our project, we configured our workspace through a [.gitpod.yml](/.gitpod.yml) file.
-
-To spin up a Gitpod, go to http://gitpod.io/#https://github.com/asyncapi/studio.
-
-## Contribution
-
-Read [CONTRIBUTING](https://github.com/asyncapi/.github/blob/master/CONTRIBUTING.md) guide.
-
-## Contributors β¨
-
-Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
-
-
-
-
-
-
-
-
-
-
-
-This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
diff --git a/apps/studio/craco.config.js b/apps/studio/craco.config.js
deleted file mode 100644
index a2376cce8..000000000
--- a/apps/studio/craco.config.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* eslint-disable */
-const crypto = require('crypto');
-const webpack = require('webpack');
-
-function getFileLoaderRule(rules) {
- for (const rule of rules) {
- if ("oneOf" in rule) {
- const found = getFileLoaderRule(rule.oneOf);
- if (found) {
- return found;
- }
- } else if (rule.test === undefined && rule.type === 'asset/resource') {
- return rule;
- }
- }
- throw new Error("File loader not found");
-}
-
-function configureWebpack(webpackConfig) {
- // fallbacks
- const fallback = webpackConfig.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/'),
- fs: false,
- });
- webpackConfig.resolve.fallback = fallback;
-
- // aliases
- webpackConfig.resolve.alias = webpackConfig.resolve.alias || {};
- webpackConfig.resolve.alias['nimma/fallbacks'] = require.resolve('../../node_modules/nimma/dist/legacy/cjs/fallbacks/index.js');
- webpackConfig.resolve.alias['nimma/legacy'] = require.resolve('../../node_modules/nimma/dist/legacy/cjs/index.js');
-
- // plugins
- webpackConfig.plugins = (webpackConfig.plugins || []).concat([
- new webpack.ProvidePlugin({
- process: 'process/browser.js',
- Buffer: ['buffer', 'Buffer']
- })
- ]);
-
- // rules/loaders
- // workaround for https://github.com/facebook/create-react-app/issues/11889 issue
- const fileLoaderRule = getFileLoaderRule(webpackConfig.module.rules);
- fileLoaderRule.exclude.push(/\.cjs$/);
- webpackConfig.module.rules.push({
- test: /\.yml$/i,
- type: 'asset/source',
- });
-
- // ignore source-map warnings
- webpackConfig.ignoreWarnings = [...(webpackConfig.ignoreWarnings || []), /Failed to parse source map/];
-
- return webpackConfig;
-}
-
-// Force method use SHA-256 to address OpenSSL 3.0 deprecation of MD4 algorithm
-function configureCrypto() {
- const cryptCreateHashOrig = crypto.createHash;
- crypto.createHash = () => cryptCreateHashOrig('sha256');
-}
-
-function setEnvironments() {
- process.env.DISABLE_ESLINT_PLUGIN = true;
-}
-
-function configureCraco() {
- setEnvironments();
- configureCrypto();
-
- return {
- webpack: {
- configure: configureWebpack,
- }
- };
-}
-
-module.exports = configureCraco();
diff --git a/apps/studio/package.json b/apps/studio/package.json
deleted file mode 100644
index c72576910..000000000
--- a/apps/studio/package.json
+++ /dev/null
@@ -1,141 +0,0 @@
-{
- "name": "@asyncapi/studio",
- "version": "0.21.4",
- "description": "One place that allows you to develop an AsyncAPI document, validate it, convert it to the latest version, preview the documentation and visualize the events flow.",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/asyncapi/studio/issues"
- },
- "keywords": [
- "asyncapi",
- "documentation",
- "studio",
- "playground"
- ],
- "author": {
- "name": "The AsyncAPI maintainers"
- },
- "files": [
- "/build",
- "/assets/logo.png",
- "./README.md",
- "./LICENSE"
- ],
- "dependencies": {
- "@asyncapi/avro-schema-parser": "^3.0.22",
- "@asyncapi/converter": "1.5.0",
- "@asyncapi/openapi-schema-parser": "^3.0.22",
- "@asyncapi/parser": "^3.2.2",
- "@asyncapi/protobuf-schema-parser": "^3.2.11",
- "@asyncapi/react-component": "^1.4.10",
- "@asyncapi/specs": "^6.7.0",
- "@babel/preset-react": "^7.22.3",
- "@ebay/nice-modal-react": "^1.2.10",
- "@headlessui/react": "^1.7.4",
- "@hookstate/core": "^4.0.0-rc21",
- "@monaco-editor/react": "^4.4.6",
- "@stoplight/yaml": "^4.3.0",
- "@tippyjs/react": "^4.2.6",
- "js-base64": "^3.7.3",
- "js-file-download": "^0.4.12",
- "js-yaml": "^4.1.0",
- "monaco-editor": "0.34.1",
- "monaco-yaml": "4.0.2",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "react-hot-toast": "2.4.0",
- "react-icons": "^4.6.0",
- "reactflow": "^11.2.0",
- "tippy.js": "^6.3.7",
- "zustand": "^4.1.4"
- },
- "scripts": {
- "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
- "dev": "npm run start",
- "start": "craco start",
- "build": "npm run generate:template-parameters && craco build",
- "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf build",
- "test": "npm run test:unit",
- "test:unit": "craco test --watchAll=false --detectOpenHandles",
- "eject": "react-scripts eject",
- "generate:readme:toc": "markdown-toc -i README.md",
- "generate:assets": "npm run build && npm run generate:readme:toc",
- "generate:template-parameters": "ts-node ./scripts/template-parameters.ts",
- "prepublishOnly": "npm run build && npm run generate:readme:toc"
- },
- "browserslist": {
- "production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
- ],
- "development": [
- "last 1 chrome version",
- "last 1 firefox version",
- "last 1 safari version"
- ]
- },
- "devDependencies": {
- "@asyncapi/dotnet-nats-template": "^0.12.1",
- "@asyncapi/go-watermill-template": "^0.2.75",
- "@asyncapi/html-template": "^2.3.5",
- "@asyncapi/java-spring-cloud-stream-template": "^0.13.4",
- "@asyncapi/java-spring-template": "^1.5.1",
- "@asyncapi/java-template": "^0.2.1",
- "@asyncapi/markdown-template": "^1.6.1",
- "@asyncapi/nodejs-template": "^3.0.0",
- "@asyncapi/nodejs-ws-template": "^0.9.35",
- "@asyncapi/python-paho-template": "^0.2.13",
- "@asyncapi/ts-nats-template": "^0.10.3",
- "@babel/preset-env": "^7.24.4",
- "@babel/preset-typescript": "^7.24.1",
- "@craco/craco": "^7.1.0",
- "@craco/types": "^7.1.0",
- "@tailwindcss/typography": "^0.5.8",
- "@testing-library/jest-dom": "^5.16.5",
- "@testing-library/react": "^13.4.0",
- "@testing-library/user-event": "^14.4.3",
- "@types/jest": "^29.2.3",
- "@types/js-yaml": "^4.0.5",
- "@types/json-schema": "^7.0.11",
- "@types/node": "^18.19.31",
- "@types/react": "^18.0.25",
- "@types/react-dom": "^18.0.9",
- "assert": "^2.0.0",
- "autoprefixer": "^10.4.13",
- "browserify-zlib": "^0.2.0",
- "buffer": "^6.0.3",
- "conventional-changelog-conventionalcommits": "^5.0.0",
- "cross-env": "^7.0.3",
- "esbuild": "0.18.20",
- "https-browserify": "^1.0.0",
- "markdown-toc": "^1.2.0",
- "path-browserify": "^1.0.1",
- "postcss": "^8.4.31",
- "process": "^0.11.10",
- "raw-loader": "^4.0.2",
- "react-scripts": "5.0.1",
- "stream-browserify": "^3.0.0",
- "stream-http": "^3.2.0",
- "tailwindcss": "^3.2.4",
- "ts-node": "^10.9.1",
- "typescript": "^4.9.3",
- "url": "^0.11.0",
- "util": "^0.12.5",
- "web-vitals": "^3.1.0",
- "webpack": "^5.75.0",
- "eslint-config-custom": "workspace:*"
- },
- "jest": {
- "transformIgnorePatterns": [
- "node_modules/.pnpm/(?!monaco-editor|monaco-yaml|monaco-marker-data-provider|monaco-worker-manager)"
- ],
- "moduleNameMapper": {
- "^nimma/legacy$": "/../../node_modules/nimma/dist/legacy/cjs/index.js",
- "^nimma/(.*)": "/../../node_modules/nimma/dist/cjs/$1"
- }
- },
- "publishConfig": {
- "access": "public"
- }
-}
diff --git a/apps/studio/public/_redirects b/apps/studio/public/_redirects
deleted file mode 100644
index 9392728f9..000000000
--- a/apps/studio/public/_redirects
+++ /dev/null
@@ -1,19 +0,0 @@
-# Redirect editor.asyncapi.org to Studio
-
-http://editor.asyncapi.org/* https://studio.asyncapi.com 301!
-https://editor.asyncapi.org/* https://studio.asyncapi.com 301!
-
-# Redirect playground.asyncapi.io to Studio
-
-http://playground.asyncapi.io/* https://studio.asyncapi.com/?redirectedFrom=playground 301!
-https://playground.asyncapi.io/* https://studio.asyncapi.com/?redirectedFrom=playground 301!
-
-http://playground.asyncapi.io/* load=:load https://studio.asyncapi.com/?redirectedFrom=playground&load=:load 301!
-https://playground.asyncapi.io/* load=:load https://studio.asyncapi.com/?redirectedFrom=playground&load=:load 301!
-http://playground.asyncapi.io/* load=:load readOnly=:readOnly https://studio.asyncapi.com/?redirectedFrom=playground&load=:load&readOnly=true 301!
-https://playground.asyncapi.io/* load=:load readOnly=:readOnly https://studio.asyncapi.com/?redirectedFrom=playground&load=:load&readOnly=true 301!
-
-http://playground.asyncapi.io/* url=:url https://studio.asyncapi.com/?redirectedFrom=playground&url=:url 301!
-https://playground.asyncapi.io/* url=:url https://studio.asyncapi.com/?redirectedFrom=playground&url=:url 301!
-http://playground.asyncapi.io/* url=:url readOnly=:readOnly https://studio.asyncapi.com/?redirectedFrom=playground&url=:url&readOnly=true 301!
-https://playground.asyncapi.io/* url=:url readOnly=:readOnly https://studio.asyncapi.com/?redirectedFrom=playground&url=:url&readOnly=true 301!
diff --git a/apps/studio/public/favicon-16x16.png b/apps/studio/public/favicon-16x16.png
deleted file mode 100644
index f52b03ec9..000000000
Binary files a/apps/studio/public/favicon-16x16.png and /dev/null differ
diff --git a/apps/studio/public/favicon-194x194.png b/apps/studio/public/favicon-194x194.png
deleted file mode 100644
index 0d6bc7985..000000000
Binary files a/apps/studio/public/favicon-194x194.png and /dev/null differ
diff --git a/apps/studio/public/favicon-32x32.png b/apps/studio/public/favicon-32x32.png
deleted file mode 100644
index a65f8093c..000000000
Binary files a/apps/studio/public/favicon-32x32.png and /dev/null differ
diff --git a/apps/studio/public/favicon.ico b/apps/studio/public/favicon.ico
deleted file mode 100644
index 2597a4cf4..000000000
Binary files a/apps/studio/public/favicon.ico and /dev/null differ
diff --git a/apps/studio/public/img/logo-studio.svg b/apps/studio/public/img/logo-studio.svg
deleted file mode 100644
index e663e2b0e..000000000
--- a/apps/studio/public/img/logo-studio.svg
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/studio/public/img/meta-studio-og-image.jpeg b/apps/studio/public/img/meta-studio-og-image.jpeg
deleted file mode 100644
index 1a6b4b2de..000000000
Binary files a/apps/studio/public/img/meta-studio-og-image.jpeg and /dev/null differ
diff --git a/apps/studio/public/img/survey-illustration.svg b/apps/studio/public/img/survey-illustration.svg
deleted file mode 100644
index cd45a399d..000000000
--- a/apps/studio/public/img/survey-illustration.svg
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/studio/public/index.html b/apps/studio/public/index.html
deleted file mode 100644
index c0b25224b..000000000
--- a/apps/studio/public/index.html
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AsyncAPI Studio
-
-
- You need to enable JavaScript to run this app.
-
-
-
-
-
-
- beta
-
-
-
-
-
-
-
-
-
diff --git a/apps/studio/public/robots.txt b/apps/studio/public/robots.txt
deleted file mode 100644
index e9e57dc4d..000000000
--- a/apps/studio/public/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# https://www.robotstxt.org/robotstxt.html
-User-agent: *
-Disallow:
diff --git a/apps/studio/scripts/template-parameters.ts b/apps/studio/scripts/template-parameters.ts
deleted file mode 100644
index fbaf04a8f..000000000
--- a/apps/studio/scripts/template-parameters.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-/* eslint-disable security/detect-non-literal-fs-filename */
-import fs from 'fs';
-import path from 'path';
-import { JSONSchema7 } from 'json-schema';
-
-const DESTINATION_JSON = path.join(__dirname, '../src/components/Modals/Generator/template-parameters.json');
-const TEMPLATES: Record = {
- '@asyncapi/dotnet-nats-template': '.NET Nats Project',
- '@asyncapi/go-watermill-template': 'GO Lang Watermill Project',
- '@asyncapi/html-template': 'HTML website',
- '@asyncapi/java-spring-cloud-stream-template': 'Java Spring Cloud Stream Project',
- '@asyncapi/java-spring-template': 'Java Spring Project',
- '@asyncapi/java-template': 'Java Project',
- '@asyncapi/markdown-template': 'Markdown Documentation',
- '@asyncapi/nodejs-template': 'NodeJS Project',
- '@asyncapi/nodejs-ws-template': 'NodeJS WebSocket Project',
- '@asyncapi/python-paho-template': 'Python Paho Project',
- '@asyncapi/ts-nats-template': 'Typescript Nats Project',
-};
-const SUPPORTED_TEMPLATES = Object.keys(TEMPLATES);
-
-interface TemplateParameter {
- description?: string;
- default?: any;
- required?: boolean;
-}
-
-interface TemplateConfig {
- parameters: Record;
-}
-
-function serializeParam(configParam: TemplateParameter): JSONSchema7 {
- const param: JSONSchema7 = {
- description: configParam.description,
- };
-
- if (typeof configParam.default === 'boolean' || configParam.default === 'true' || configParam.default === 'false') {
- param.type = 'boolean';
- if (typeof configParam.default === 'boolean') {
- param.default = configParam.default;
- } else if (configParam.default === 'true') {
- param.default = true;
- } else if (configParam.default === 'false') {
- param.default = false;
- }
- } else if (typeof configParam.default === 'number') {
- param.type = 'number';
- param.default = Number(configParam.default);
- } else {
- param.type = 'string';
- param.default = configParam.default;
- }
-
- return param;
-}
-
-function serializeTemplateParameters(config: TemplateConfig): JSONSchema7 | undefined {
- if (!config || !config.parameters) {
- return;
- }
-
- const configParameters = config.parameters;
- const parameters: Record = {};
- const required: string[] = [];
- for (const parameter in configParameters) {
- const configParam = configParameters[String(parameter)];
-
- const param = serializeParam(configParam);
- if (configParam.required) {
- required.push(parameter);
- }
-
- parameters[String(parameter)] = param;
- }
-
- return {
- $schema: 'http://json-schema.org/draft-07/schema#',
- type: 'object',
- properties: parameters,
- required,
- // don't allow non supported properties
- additionalProperties: false,
- } as JSONSchema7;
-}
-
-async function main() {
- const schemas: Record = {};
- for (let i = 0, l = SUPPORTED_TEMPLATES.length; i < l; i++) {
- const templateName = SUPPORTED_TEMPLATES[Number(i)];
-
- console.info(`[INFO]: Prepare parameters for ${templateName}.`);
-
- const pathToPackageJSON = path.join(__dirname, `../../../node_modules/${templateName}/package.json`);
- const packageJSONContent = await fs.promises.readFile(pathToPackageJSON, 'utf-8');
- const packageJSON = JSON.parse(packageJSONContent);
- const generatorConfig = packageJSON.generator;
-
- const schema = serializeTemplateParameters(generatorConfig);
- if (schema) {
- schemas[String(templateName)] = {
- title: TEMPLATES[String(templateName)],
- schema,
- supportedProtocols: generatorConfig.supportedProtocols,
- };
- }
- }
-
- console.info(`[INFO]: Save template parameters schemas to ${DESTINATION_JSON}.`);
- await fs.promises.writeFile(DESTINATION_JSON, JSON.stringify(schemas), 'utf-8');
-}
-main();
diff --git a/apps/studio/src/App.tsx b/apps/studio/src/App.tsx
deleted file mode 100644
index bfb54b021..000000000
--- a/apps/studio/src/App.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { AsyncAPIStudio } from './studio';
-
-import type { FunctionComponent } from 'react';
-
-export const App: FunctionComponent = () => {
- return (
-
- );
-};
diff --git a/apps/studio/src/components/Content.tsx b/apps/studio/src/components/Content.tsx
deleted file mode 100644
index 1c147165f..000000000
--- a/apps/studio/src/components/Content.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import SplitPane from './SplitPane';
-import { Editor } from './Editor/Editor';
-import { Navigation } from './Navigation';
-import { Navigationv3 } from './Navigationv3';
-import { Template } from './Template';
-import { VisualiserTemplate } from './Visualiser';
-
-import { debounce } from '../helpers';
-import { usePanelsState, useDocumentsState } from '../state';
-
-import type { FunctionComponent } from 'react';
-
-interface ContentProps {}
-
-export const Content: FunctionComponent = () => { // eslint-disable-line sonarjs/cognitive-complexity
- const { show, secondaryPanelType } = usePanelsState();
- const document = useDocumentsState(state => state.documents['asyncapi']?.document) || null;
- const isV3 = document?.version() === '3.0.0';
- const navigationEnabled = show.primarySidebar;
- const editorEnabled = show.primaryPanel;
- const viewEnabled = show.secondaryPanel;
- const viewType = secondaryPanelType;
-
- const splitPosLeft = 'splitPos:left';
- const splitPosRight = 'splitPos:right';
-
- const localStorageLeftPaneSize = parseInt(localStorage.getItem(splitPosLeft) || '0', 10) || 220;
- const localStorageRightPaneSize = parseInt(localStorage.getItem(splitPosRight) || '0', 10) || '55%';
-
- const secondPaneSize = navigationEnabled && !editorEnabled ? localStorageLeftPaneSize : localStorageRightPaneSize;
- const secondPaneMaxSize = navigationEnabled && !editorEnabled ? 360 : '100%';
-
- const navigationAndEditor = (
- {
- localStorage.setItem(splitPosLeft, String(size));
- }, 100)}
- >
- {
- isV3 ? :
- }
-
-
- );
-
- return (
-
-
- {
- localStorage.setItem(splitPosRight, String(size));
- }, 100)}
- >
- {navigationAndEditor}
- {viewType === 'template' && }
- {viewType === 'visualiser' && }
-
-
-
- );
-};
\ No newline at end of file
diff --git a/apps/studio/src/components/Editor/Editor.tsx b/apps/studio/src/components/Editor/Editor.tsx
deleted file mode 100644
index 380c6607e..000000000
--- a/apps/studio/src/components/Editor/Editor.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from 'react';
-
-import SplitPane from '../SplitPane';
-import { EditorSidebar } from './EditorSidebar';
-import { MonacoWrapper } from './MonacoWrapper';
-import { Terminal } from '../Terminal/Terminal';
-
-import { useOtherState } from '../../state';
-
-export interface EditorProps {}
-
-export const Editor: React.FunctionComponent = () => {
- const editorHeight = useOtherState(state => state.editorHeight);
-
- return (
-
- );
-};
diff --git a/apps/studio/src/components/Editor/EditorDropdown.tsx b/apps/studio/src/components/Editor/EditorDropdown.tsx
deleted file mode 100644
index bc7456c90..000000000
--- a/apps/studio/src/components/Editor/EditorDropdown.tsx
+++ /dev/null
@@ -1,250 +0,0 @@
-import React from 'react';
-import toast from 'react-hot-toast';
-import { show } from '@ebay/nice-modal-react';
-import { FaEllipsisH } from 'react-icons/fa';
-
-import {
- ImportURLModal,
- ImportBase64Modal,
- GeneratorModal,
- ConvertModal,
-} from '../Modals';
-import { Dropdown } from '../common';
-
-import { useServices } from '../../services';
-import { useDocumentsState, useFilesState } from '../../state';
-
-interface EditorDropdownProps {}
-
-export const EditorDropdown: React.FunctionComponent = () => {
- const { editorSvc } = useServices();
- const isInvalidDocument = !useDocumentsState(state => state.documents['asyncapi'].valid);
- const language = useFilesState(state => state.files['asyncapi'].language);
-
- const importUrlButton = (
- show(ImportURLModal)}
- >
- Import from URL
-
- );
-
- const importFileButton = (
-
- {
- toast.promise(editorSvc.importFile(event.target.files), {
- loading: 'Importing...',
- success: (
-
-
- Document succesfully imported!
-
-
- ),
- error: (
-
-
- Failed to import document. Maybe the file type is invalid.
-
-
- ),
- });
- }}
- />
- Import File
-
- );
-
- const importBase64Button = (
- show(ImportBase64Modal)}
- >
- Import from Base64
-
- );
-
- const generateButton = (
- show(GeneratorModal)}
- >
- Generate code/docs
-
- );
-
- const saveFileButton = (
- {
- toast.promise(
- language === 'yaml'
- ? editorSvc.saveAsYaml()
- : editorSvc.saveAsJSON(),
- {
- loading: 'Saving...',
- success: (
-
-
- Document succesfully saved!
-
-
- ),
- error: (
-
-
- Failed to save document.
-
-
- ),
- },
- );
- }}
- disabled={isInvalidDocument}
- >
- Save as {language === 'yaml' ? 'YAML' : 'JSON'}
-
- );
-
- const convertLangAndSaveButton = (
- {
- toast.promise(
- language === 'yaml'
- ? editorSvc.saveAsJSON()
- : editorSvc.saveAsYaml(),
- {
- loading: 'Saving...',
- success: (
-
-
- Document succesfully converted and saved!
-
-
- ),
- error: (
-
-
- Failed to convert and save document.
-
-
- ),
- },
- );
- }}
- disabled={isInvalidDocument}
- >
- Convert and save as {language === 'yaml' ? 'JSON' : 'YAML'}
-
- );
-
- const convertLangButton = (
- {
- toast.promise(
- language === 'yaml'
- ? editorSvc.convertToJSON()
- : editorSvc.convertToYaml(),
- {
- loading: 'Saving...',
- success: (
-
-
- Document succesfully converted!
-
-
- ),
- error: (
-
-
- Failed to convert document.
-
-
- ),
- },
- );
- }}
- disabled={isInvalidDocument}
- >
- Convert to {language === 'yaml' ? 'JSON' : 'YAML'}
-
- );
-
- const convertButton = (
- show(ConvertModal)}
- >
- Convert document
-
- );
-
- return (
- }
- buttonHoverClassName="text-gray-500 hover:text-white"
- >
-
-
-
- {importUrlButton}
-
-
- {importFileButton}
-
-
- {importBase64Button}
-
-
-
-
- {generateButton}
-
-
-
-
- {saveFileButton}
-
-
- {convertLangAndSaveButton}
-
-
-
-
- {convertLangButton}
-
-
- {convertButton}
-
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Editor/EditorSidebar.tsx b/apps/studio/src/components/Editor/EditorSidebar.tsx
deleted file mode 100644
index c8e304796..000000000
--- a/apps/studio/src/components/Editor/EditorSidebar.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-
-import { EditorDropdown } from './EditorDropdown';
-
-import { useFilesState } from '../../state';
-import { ShareButton } from './ShareButton';
-
-interface EditorSidebarProps {}
-
-export const EditorSidebar: React.FunctionComponent<
- EditorSidebarProps
-> = () => {
- const { source, from } = useFilesState((state) => state.files['asyncapi']);
-
- let documentFromText = '';
- if (from === 'storage') {
- documentFromText = 'From localStorage';
- } else if (from === 'base64') {
- documentFromText = 'From Base64';
- } else {
- documentFromText = `From URL ${source}`;
- }
-
- return (
-
-
- {documentFromText}
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Editor/MonacoWrapper.tsx b/apps/studio/src/components/Editor/MonacoWrapper.tsx
deleted file mode 100644
index b34ea1116..000000000
--- a/apps/studio/src/components/Editor/MonacoWrapper.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { useMemo } from 'react';
-import MonacoEditor from '@monaco-editor/react';
-
-import { debounce } from '../../helpers';
-import { useServices } from '../../services';
-import { useFilesState, useSettingsState } from '../../state';
-
-import type { FunctionComponent } from 'react';
-import type { EditorProps as MonacoEditorProps } from '@monaco-editor/react';
-
-export const MonacoWrapper: FunctionComponent = ({
- ...props
-}) => {
- const { editorSvc, parserSvc } = useServices();
- const { autoSaving, savingDelay } = useSettingsState(state => state.editor);
- const file = useFilesState(state => state.files['asyncapi']);
-
- const onChange = useMemo(() => {
- return debounce((v: string) => {
- editorSvc.updateState({ content: v, file: { from: 'storage', source: undefined } });
- autoSaving && editorSvc.saveToLocalStorage(v, false);
- parserSvc.parse('asyncapi', v);
- }, savingDelay);
- }, [autoSaving, savingDelay]);
-
- return (
-
- );
-};
diff --git a/apps/studio/src/components/Editor/ShareButton.tsx b/apps/studio/src/components/Editor/ShareButton.tsx
deleted file mode 100644
index 96f4b9481..000000000
--- a/apps/studio/src/components/Editor/ShareButton.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import { FaShareAlt } from 'react-icons/fa';
-import { useServices } from '../../services';
-import { toast } from 'react-hot-toast';
-import { Tooltip } from '../common';
-
-interface ShareButtonProps {}
-
-export const ShareButton: React.FunctionComponent = () => {
- const { editorSvc } = useServices();
-
- const handleShare = () => {
- toast.promise(
- (async function () {
- const base64 = await editorSvc.exportAsBase64();
- const url = `${window.location.origin}/?base64=${encodeURIComponent(
- base64
- )}`;
- await navigator.clipboard.writeText(url);
- }()),
- {
- loading: 'Copying URL to clipboard...',
- success: 'URL copied to clipboard!',
- error: 'Failed to copy URL to clipboard.',
- }
- );
- };
-
- return (
-
-
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Editor/index.ts b/apps/studio/src/components/Editor/index.ts
deleted file mode 100644
index 427409686..000000000
--- a/apps/studio/src/components/Editor/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './Editor';
-export * from './MonacoWrapper';
diff --git a/apps/studio/src/components/Modals/ConfirmModal.tsx b/apps/studio/src/components/Modals/ConfirmModal.tsx
deleted file mode 100644
index 3d7bbf6e7..000000000
--- a/apps/studio/src/components/Modals/ConfirmModal.tsx
+++ /dev/null
@@ -1,150 +0,0 @@
-import { Fragment, useRef, useCallback } from 'react';
-import { Dialog, Transition } from '@headlessui/react';
-import { useModal } from '@ebay/nice-modal-react';
-
-import type { ReactNode, FunctionComponent, PropsWithChildren } from 'react';
-
-interface ConfirmModalProps {
- title: ReactNode;
- description?: ReactNode;
- warning?: ReactNode;
- link?: string;
- confirmText?: ReactNode;
- cancelText?: ReactNode;
- confirmDisabled?: boolean;
- cancelDisabled?: boolean;
- containerClassName?: string;
- closeAfterSumbit?: boolean;
- onSubmit?: () => void;
- onCancel?: () => void;
-}
-
-export const ConfirmModal: FunctionComponent> = ({
- title,
- description,
- warning,
- link,
- confirmText = 'Save',
- cancelText = 'Cancel',
- confirmDisabled = true,
- cancelDisabled = false,
- closeAfterSumbit = true,
- onSubmit,
- onCancel = () => {
- // This is intentional
- },
- containerClassName,
- children,
-}) => {
- const modal = useModal();
- const cancelButtonRef = useRef(null);
-
- const handleOnSubmit = () => {
- onSubmit && onSubmit();
- if (closeAfterSumbit) {
- modal.hide();
- }
- };
-
- const handleOnCancel = () => {
- onCancel();
- modal.hide();
- };
-
- const handleAfterLeave = useCallback(() => {
- modal.remove();
- }, []);
-
- return (
- <>
-
-
-
-
-
-
-
- {/* This element is to trick the browser into centering the modal contents. */}
-
-
-
-
-
-
-
-
- {title}
-
- {description && (
-
{description}
- )}
- {warning && (
-
- {warning}
-
- )}
-
{children}
-
-
-
- {onSubmit && (
-
- {confirmText}
-
- )}
-
- {cancelText}
-
-
-
-
-
-
-
- >
- );
-};
diff --git a/apps/studio/src/components/Modals/ConfirmNewFileModal.tsx b/apps/studio/src/components/Modals/ConfirmNewFileModal.tsx
deleted file mode 100644
index 2263632d3..000000000
--- a/apps/studio/src/components/Modals/ConfirmNewFileModal.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { create } from '@ebay/nice-modal-react';
-import { NewFileModal } from './NewFileModal';
-import { ConfirmModal } from './ConfirmModal';
-import { show as showModal } from '@ebay/nice-modal-react';
-
-export const ConfirmNewFileModal = create(() => {
- const onConfirm = () => {
- showModal(NewFileModal)
- };
-
- return (
-
-
-
-
- Would you like to create a new file?
-
- All the existing changes will be lost and overwritten.
-
-
-
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/ConvertModal.tsx b/apps/studio/src/components/Modals/ConvertModal.tsx
deleted file mode 100644
index 0d72a3bb0..000000000
--- a/apps/studio/src/components/Modals/ConvertModal.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { useState } from 'react';
-import toast from 'react-hot-toast';
-import { create } from '@ebay/nice-modal-react';
-
-import { ConfirmModal } from './index';
-
-import { useServices } from '../../services';
-import { useDocumentsState } from '../../state';
-
-import type { SpecVersions } from '../../types';
-
-export const ConvertModal = create(() => {
- const { editorSvc, specificationSvc } = useServices();
- const document = useDocumentsState(state => state.documents['asyncapi']?.document);
- const latestVersion = specificationSvc.latestVersion;
-
- const [version, setVersion] = useState(latestVersion);
- const actualVersion = document?.version();
- const allowedVersions = Object.keys(specificationSvc.specs);
- actualVersion && (allowedVersions.splice(0, allowedVersions.indexOf(actualVersion) + 1));
- const reservedAllowedVersions = [...allowedVersions].reverse();
-
- const onSubmit = () => {
- toast.promise(editorSvc.convertSpec(version), {
- loading: 'Converting...',
- success: (
-
-
- Document succesfully converted!
-
-
- ),
- error: (
-
-
- Failed to convert document.
-
-
- ),
- });
- };
-
- return (
-
-
- {allowedVersions.length > 0 ? (
-
-
- To version:
-
- setVersion(e.target.value as SpecVersions)}
- value={version}
- >
- Please Select
- {reservedAllowedVersions.map(v => (
-
- {v === latestVersion ? `${v} (latest)` : v}
-
- ))}
-
-
- ) : (
-
Uses the latest version.
- )}
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/ConvertToLatestModal.tsx b/apps/studio/src/components/Modals/ConvertToLatestModal.tsx
deleted file mode 100644
index fa4a270ec..000000000
--- a/apps/studio/src/components/Modals/ConvertToLatestModal.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import { useState } from 'react';
-import toast from 'react-hot-toast';
-import { create } from '@ebay/nice-modal-react';
-
-import { ConfirmModal } from './ConfirmModal';
-
-import { useServices } from '../../services';
-import { useDocumentsState } from '../../state';
-
-interface ConvertToLatestModal {
- convertOnlyToLatest: boolean
-}
-
-export const ConvertToLatestModal = create(({ convertOnlyToLatest = false }) => {
- const [version, setVersion] = useState('');
- const { editorSvc, specificationSvc } = useServices();
- const document = useDocumentsState(state => state.documents['asyncapi']?.document);
-
- const actualVersion = document?.version() || '2.0.0-rc2';
- const latestVersion = specificationSvc.latestVersion;
- const allowedVersions = Object.keys(specificationSvc.specs);
- actualVersion && (allowedVersions.splice(0, allowedVersions.indexOf(actualVersion) + 1));
- const reservedAllowedVersions = [...allowedVersions].reverse();
-
- function onSubmit() {
- async function convert() {
- try {
- await editorSvc.convertSpec(version);
- } catch (err: any) {
- // intentionally
- }
- }
-
- toast.promise(convert(), {
- loading: 'Converting...',
- success: (
-
-
- Document succesfully converted!
-
-
- ),
- error: (
-
-
- Failed to convert document.
-
-
- ),
- });
- }
-
- let content = '';
- if (convertOnlyToLatest) {
- content = `Your document is using not latest version of AsyncAPI. Convert your document to latest (${latestVersion}) version`;
- } else {
- content = 'There is a new version of AsyncAPI. Convert your document to newest version if you want.';
- }
-
- return (
-
-
-
- {content}
-
-
- {convertOnlyToLatest === false ? (
-
-
- To version:
-
- setVersion(e.target.value)}
- value={version}
- >
- {latestVersion} (latest)
- {reservedAllowedVersions.filter((v) => v !== latestVersion).map(v => (
-
- {v}
-
- ))}
-
-
- ) : null}
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/Generator/GeneratorModal.tsx b/apps/studio/src/components/Modals/Generator/GeneratorModal.tsx
deleted file mode 100644
index 5b9e15b10..000000000
--- a/apps/studio/src/components/Modals/Generator/GeneratorModal.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-import { useState, useRef, useEffect } from 'react';
-import toast from 'react-hot-toast';
-import { create, useModal } from '@ebay/nice-modal-react';
-
-import { ConfirmModal } from '../index';
-import { TemplateParameters, TemplateParametersHandle } from './TemplateParameters';
-
-import { useServices } from '../../../services';
-import { ServerAPIProblem } from '../../../services/server-api.service';
-
-import { filesState, useDocumentsState } from '../../../state';
-
-import templates from './template-parameters.json';
-
-const unsupportedGenerators = [
- '@asyncapi/dotnet-nats-template',
- '@asyncapi/ts-nats-template',
- '@asyncapi/python-paho-template',
- '@asyncapi/nodejs-ws-template',
- '@asyncapi/java-spring-cloud-stream-template',
- '@asyncapi/go-watermill-template',
- '@asyncapi/java-spring-template',
- '@asyncapi/nodejs-template',
- '@asyncapi/java-template',
- '@asyncapi/php-template'
-];
-
-const renderOptions = (actualVersion: string) => {
- return Object.keys(templates).map(templateItem => {
- const isSupported = actualVersion === '3.0.0' && !unsupportedGenerators.includes(templateItem);
- const disableOption = actualVersion === '3.0.0' ? !isSupported : false;
- return (
-
- {(templates as Record)[String(templateItem)]?.title}
-
- );
- });
-};
-
-export const GeneratorModal = create(() => {
- const modal = useModal();
- const [template, setTemplate] = useState('');
- const { serverAPISvc } = useServices();
- const [problem, setProblem] = useState(null);
- const [confirmDisabled, setConfirmDisabled] = useState(true);
- const templateParamsRef = useRef(null);
- const document = useDocumentsState(state => state.documents['asyncapi']?.document);
- const actualVersion = document?.version() || '';
-
- useEffect(() => {
- const required = template ? (templates as Record)[String(template)].schema.required : [];
- setConfirmDisabled(!template || required.length !== 0);
- setProblem(null);
- }, [template, setProblem]);
-
- const generateTemplate = async () => {
- setProblem(null);
- const response = await serverAPISvc.generate({
- asyncapi: filesState.getState().files['asyncapi'].content,
- template,
- parameters: templateParamsRef.current?.getValues(),
- });
-
- if (response.ok) {
- modal.hide();
- setTemplate('');
- } else {
- const responseProblem = await serverAPISvc.retrieveProblem<{ validationErrors: string[] }>(response);
- setProblem(responseProblem as ServerAPIProblem & { validationErrors: string[] });
- throw new Error(responseProblem?.title);
- }
- };
-
- const onSubmit = () => {
- toast.promise(generateTemplate(), {
- loading: 'Generating...',
- success: (
-
-
- Succesfully generated!
-
-
- ),
- error: (
-
-
- Failed to generate.
-
-
- ),
- });
- };
-
- const onCancel = () => {
- setTimeout(() => {
- setTemplate('');
- setProblem(null);
- setConfirmDisabled(true);
- modal.hide();
- }, 200);
- };
-
- return (
-
-
-
-
- Generate
-
- {
- setTemplate(e.target.value);
- }}
- value={template}
- >
- Please Select
- {renderOptions(actualVersion)}
-
-
- {template && (
-
- )}
-
- )[String(template)]?.schema : {}}
- supportedProtocols={template ? (templates as Record)[String(template)]?.supportedProtocols : []}
- setConfirmDisabled={setConfirmDisabled}
- />
-
- {problem && (
-
-
-
-
- {problem.title}
-
-
- {problem.validationErrors &&
- problem.validationErrors.length &&
- problem.validationErrors.filter(error => error.message).length
- ? (
-
- {problem.validationErrors.map(error => (
-
- {error.message}
-
- ))}
-
- ) : (
-
- {problem.detail}
-
- )
- }
-
- )}
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/Generator/TemplateParameters.tsx b/apps/studio/src/components/Modals/Generator/TemplateParameters.tsx
deleted file mode 100644
index 862f7e783..000000000
--- a/apps/studio/src/components/Modals/Generator/TemplateParameters.tsx
+++ /dev/null
@@ -1,236 +0,0 @@
-import { useState, useCallback, useImperativeHandle, forwardRef, useEffect, useMemo } from 'react';
-import { JSONSchema7 } from 'json-schema';
-
-import { Switch } from '../../common';
-
-import { useDocumentsState } from '../../../state';
-
-import type { FunctionComponent, ForwardRefRenderFunction, PropsWithChildren, Dispatch, SetStateAction } from 'react';
-
-interface TemplateParameterProps {
- propertyName: string;
- property: JSONSchema7;
- isRequired: boolean;
- setValue: (propertyName: string, value: any, isRequired: boolean) => void;
-}
-
-const StringParameter: FunctionComponent = ({
- propertyName,
- property,
- isRequired,
- setValue,
-}) => {
- if (property.enum) {
- return (
- setValue(propertyName, e.target.value, isRequired)}
- >
- Please select server
- {property.enum.map(serverName => (
-
- {serverName as string}
-
- ))}
-
- );
- }
-
- return (
- setValue(propertyName, e.target.value, isRequired)}
- />
- );
-};
-
-const NumberParameter = StringParameter;
-
-const BooleanParameter: FunctionComponent = ({
- propertyName,
- property,
- isRequired,
- setValue
-}) => {
- return (
- setValue(propertyName, v, isRequired)}
- />
- );
-};
-
-const ParameterItem: FunctionComponent = (props) => {
- switch (props.property.type) {
- case 'string': {
- return ;
- }
- case 'number': {
- return ;
- }
- case 'boolean': {
- return ;
- }
- default: return null;
- }
-};
-
-export interface TemplateParametersHandle {
- getValues(): any;
-}
-
-interface TemplateParametersProps {
- templateName: string;
- template: JSONSchema7;
- supportedProtocols: string[];
- setConfirmDisabled: Dispatch>;
-}
-
-export const TemplateParametersSans: ForwardRefRenderFunction> = ({
- templateName,
- template: { properties = {}, required = [] },
- supportedProtocols = [],
- setConfirmDisabled,
-}, templateParamsRef) => {
- const [values, setValues] = useState>({});
- const [showOptionals, setShowOptionals] = useState(false);
- const document = useDocumentsState(state => state.documents['asyncapi']?.document);
-
- const { requiredProps, optionalProps, hasSupportedProtocols } = useMemo(() => {
- const requiredProperties: Record = {};
- const optionalProperties: Record = {};
- let hasSupportedProto = true;
-
- const servers = document?.servers();
- const availableServers: string[] = [];
- Object.entries(servers || {}).forEach(([serverName, server]) => {
- if (server.protocol && supportedProtocols.includes(server.protocol())) availableServers.push(serverName);
- });
-
- if (supportedProtocols.length && availableServers.length === 0) {
- hasSupportedProto = false;
- setConfirmDisabled(true);
- } else {
- Object.keys(properties).forEach(propKey => {
- if (propKey === 'server') {
- // @ts-ignore
- const jsonProperty = { ...properties[String(propKey)] };
- jsonProperty.enum = availableServers;
- requiredProperties[String(propKey)] = jsonProperty;
- } else if (required.includes(propKey)) {
- // @ts-ignore
- requiredProperties[String(propKey)] = properties[String(propKey)];
- } else {
- // @ts-ignore
- optionalProperties[String(propKey)] = properties[String(propKey)];
- }
- });
- }
-
- return { requiredProps: requiredProperties, optionalProps: optionalProperties, hasSupportedProtocols: hasSupportedProto };
- }, [properties, required, document]);
-
- useEffect(() => {
- setValues({});
- setShowOptionals(false);
- }, [templateName, setValues, setShowOptionals]);
-
- useImperativeHandle(templateParamsRef, () => ({
- getValues() {
- return values;
- }
- }));
-
- const setValue = useCallback((propertyName: string, value: any, isRequired: boolean) => {
- setValues(oldValues => {
- oldValues[String(propertyName)] = String(value);
- if (isRequired) {
- const disableConfirm = required.some(r => !oldValues[String(r)]);
- setConfirmDisabled(disableConfirm);
- }
- return oldValues;
- });
- }, [required]);
-
- const renderFields = useCallback((propertyName: string, property: JSONSchema7, isRequired: boolean, isFirst: boolean) => {
- return (
-
-
-
-
- {propertyName}
-
-
-
-
-
- {property.description}
-
-
- );
- }, [templateName]);
-
- if (document === null) {
- return null;
- }
-
- if (!templateName) {
- return null;
- }
-
- if (!hasSupportedProtocols) {
- return (
-
- AsyncAPI document doesn't have at least one server with supported protocols. For the selected generation, these are supported: {supportedProtocols.join(', ')}
-
- );
- }
-
- if (!properties || !Object.keys(properties).length) {
- return (
-
- {'The given generation hasn\'t parameters to pass'}
-
- );
- }
-
- return (
-
- );
-};
-
-const TemplateParameters = forwardRef(TemplateParametersSans);
-export { TemplateParameters };
diff --git a/apps/studio/src/components/Modals/Generator/template-parameters.json b/apps/studio/src/components/Modals/Generator/template-parameters.json
deleted file mode 100644
index cd065e7eb..000000000
--- a/apps/studio/src/components/Modals/Generator/template-parameters.json
+++ /dev/null
@@ -1 +0,0 @@
-{"@asyncapi/dotnet-nats-template":{"title":".NET Nats Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"version":{"description":"Version of the generated library","type":"string","default":"0.0.1"},"projectName":{"description":"Name of the generated library","type":"string","default":"AsyncapiNatsClient"},"repositoryUrl":{"description":"Repository url for the project file, often needed for release pipelines","type":"string"},"targetFramework":{"description":"The project target framework","type":"string","default":"netstandard2.0;netstandard2.1"},"packageVersion":{"description":"PackageVersion of the generated library","type":"string"},"assemblyVersion":{"description":"AssemblyVersion of the generated library","type":"string"},"fileVersion":{"description":"FileVersion of the generated library","type":"string"},"serializationLibrary":{"description":"Which serialization library should the models use? `newtonsoft` or `json` (system.text.json)","type":"string","default":"json"}},"required":[],"additionalProperties":false},"supportedProtocols":["nats"]},"@asyncapi/go-watermill-template":{"title":"GO Lang Watermill Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"moduleName":{"description":"name of the go module to be generated","type":"string","default":"go-async-api"}},"required":[],"additionalProperties":false},"supportedProtocols":["amqp"]},"@asyncapi/html-template":{"title":"HTML website","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"sidebarOrganization":{"description":"Defines how the sidebar should be organized. 'byTags' to categorize operations by tags in the root of the document, `byTagsNoRoot` does the same but for pub/sub tags.","type":"string"},"baseHref":{"description":"Sets the base URL for links and forms.","type":"string"},"version":{"description":"Override the version of your application provided under `info.version` location in the specification file.","type":"string"},"singleFile":{"description":"If set this parameter to true generate single html file with scripts and styles inside","type":"boolean","default":false},"outFilename":{"description":"The name of the output HTML file","type":"string","default":"index.html"},"pdf":{"description":"Set to `true` to get index.pdf generated next to your index.html","type":"boolean","default":false},"pdfTimeout":{"description":"The timeout (in ms) used to generate the pdf","type":"number","default":30000},"favicon":{"description":"URL/Path of the favicon","type":"string","default":""},"config":{"description":"Stringified JSON or a path to a JSON file to override the default React component config. The config override is merged with the default config using the [JSON Merge Patch](https://tools.ietf.org/html/rfc7386) algorithm.","type":"string","default":""}},"required":[],"additionalProperties":false}},"@asyncapi/java-spring-cloud-stream-template":{"title":"Java Spring Cloud Stream Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"actuator":{"description":"If present, it adds the dependencies for spring-boot-starter-web, spring-boot-starter-actuator and micrometer-registry-prometheus.","type":"boolean","default":false},"artifactId":{"description":"The Maven artifact id. Alternatively you can set the specification extension info.x-artifact-id","type":"string","default":"project-name"},"artifactType":{"description":"The type of project to generate, application or library. The default is application. When generating an application, the pom.xml file will contain the complete set of dependencies required to run an app, and it will contain an Application class with a main function. Otherwise the pom file will include only the dependencies required to compile a library.","type":"string","default":"application"},"binder":{"description":"The name of the binder implementation, one of kafka, rabbit or solace. Default: kafka. If you need other binders to be supported, please let us know!","type":"string","default":"kafka"},"dynamicType":{"description":"When using channels with parameters, i.e. dynamic topics where the topic could be different for each message, this determines whether to use the StreamBridge or a message header. StreamBridge can be used with all binders, but some binders such as Solace can use the topic set in a header for better performance. Possible values are streamBridge and header. Default is streamBridge.","type":"string","default":"streamBridge"},"groupId":{"description":"The Maven group id. Alternatively you can set the specification extension info.x-group-id","type":"string","default":"com.company"},"host":{"description":"The host connection property. Currently this only works with the Solace binder. Example: tcp://myhost.com:55555.","type":"string","default":"tcp://localhost:55555"},"javaPackage":{"description":"The Java package of the generated classes. Alternatively you can set the specification extension info.x-java-package","type":"string"},"msgVpn":{"description":"The message vpn connection property. Currently this only works with the Solace binder.","type":"string","default":"default"},"parametersToHeaders":{"description":"If true, this will create headers on the incoming messages for each channel parameter. Currently this only works with messages originating from Solace (using the solace_destination header) and RabbitMQ (using the amqp_receivedRoutingKey header.)","type":"boolean","default":false},"password":{"description":"The client password connection property. Currently this only works with the Solace binder.","type":"string","default":"default"},"reactive":{"description":"If true, this will generate reactive style functions using the Flux class. Defalt: false.","type":"boolean","default":false},"solaceSpringCloudVersion":{"description":"The version of the solace-spring-cloud-bom dependency used when generating an application. Alternatively you can set the specification extension info.x-solace-spring-cloud-version.","type":"string","default":"2.1.0"},"springBootVersion":{"description":"The version of Spring Boot used when generating an application. Alternatively you can set the specification extension info.x-spring-booot-version. Example: 2.2.6.RELEASE.","type":"string","default":"2.4.7"},"springCloudVersion":{"description":"The version of the spring-cloud-dependencies BOM dependency used when generating an application. Alternatively you can set the specification extension info.x-spring-cloud-version. Example: Hoxton.RELEASE.","type":"string","default":"2020.0.3"},"springCloudStreamVersion":{"description":"The version of the spring-cloud-stream dependency specified in the Maven file, when generating a library. When generating an application, the spring-cloud-dependencies BOM is used instead. Example: 3.0.1.RELEASE","type":"string","default":"3.1.3"},"username":{"description":"The client username connection property. Currently this only works with the Solace binder","type":"string","default":"default"},"view":{"description":"The view that the template uses. By default it is the client view, which means that when the document says publish, we subscribe. In the case of the provider view, when the document says publish, we publish. Values are client or provider. The default is client.","type":"string","default":"client"},"useServers":{"description":"This option works when binder is kafka. By default it is set to false. When set to true, it will concatenate all the urls in the servers section as a list of brokers for kafka.","type":"string"}},"required":[],"additionalProperties":false}},"@asyncapi/java-spring-template":{"title":"Java Spring Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"inverseOperations":{"description":"Generate application that will publish messages to `publish` operation of channels and read messages from `subscribe` operation of channels. Literally this flag just swap `publish` and `subscribe` operations in channels.","type":"boolean","default":false},"disableEqualsHashCode":{"description":"Disable generation of equals and hashCode methods for model classes.","type":"boolean","default":false},"listenerPollTimeout":{"description":"Only for Kafka. Timeout to use when polling the consumer.","type":"number","default":3000},"listenerConcurrency":{"description":"Only for Kafka. Number of threads to run in the listener containers.","type":"number","default":3},"connectionTimeout":{"description":"Only for MQTT. This value, measured in seconds, defines the maximum time interval the client will wait for the network connection to the MQTT server to be established. The default timeout is 30 seconds. A value of 0 disables timeout processing meaning the client will wait until the network connection is made successfully or fails.","type":"number","default":30},"disconnectionTimeout":{"description":"Only for MQTT. The completion timeout in milliseconds when disconnecting. The default disconnect completion timeout is 5000 milliseconds.","type":"number","default":5000},"completionTimeout":{"description":"Only for MQTT. The completion timeout in milliseconds for operations. The default completion timeout is 30000 milliseconds.","type":"number","default":30000},"mqttClientId":{"description":"Only for MQTT. Provides the client identifier for the MQTT server. This parameter overrides the value of the clientId if it's set in the AsyncAPI file.","type":"string"},"asyncapiFileDir":{"description":"Parameter of @asyncapi/generator-hooks#createAsyncapiFile, allows to specify where original AsyncAPI file will be stored.","type":"string","default":"src/main/resources/api/"},"javaPackage":{"description":"The Java package of the generated classes. Alternatively you can set the specification extension info.x-java-package","type":"string","default":"com.asyncapi"},"addTypeInfoHeader":{"description":"Only for Kafka. Add type information to the message header","type":"boolean","default":true},"springBoot2":{"description":"Generate template files for the Spring Boot version 2. For kafka protocol it will also force to use spring-kafka 2.9.9","type":"boolean","default":false},"maven":{"description":"Generate pom.xml Maven build file instead of Gradle build","type":"boolean","default":false}},"required":[],"additionalProperties":false},"supportedProtocols":["kafka","amqp","mqtt"]},"@asyncapi/java-template":{"title":"Java Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"server":{"description":"The server you want to use in the code.","type":"string"},"asyncapiFileDir":{"description":"Custom location of the AsyncAPI file that you provided as an input in generation. By default it is located in the root of the output directory","type":"string"},"user":{"description":"Username for the server to generate code for","type":"string","default":"app"},"password":{"description":"Password for the server to generate code for","type":"string","default":"passw0rd"},"package":{"description":"Java package name for generated code","type":"string","default":"com.asyncapi"},"mqTopicPrefix":{"description":"MQ topic prefix. Used for ibmmq protocols. Default will work with dev MQ instance","type":"string","default":"dev//"}},"required":["server"],"additionalProperties":false},"supportedProtocols":["ibmmq","ibmmq-secure","kafka","kafka-secure"]},"@asyncapi/markdown-template":{"title":"Markdown Documentation","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"frontMatter":{"description":"The name of a JSON or YAML formatted file containing values to provide the YAML frontmatter for static-site or documentation generators. The file may contain {{title}} and {{version}} replaceable tags.","type":"string"},"outFilename":{"description":"The name of the output markdown file","type":"string","default":"asyncapi.md"},"toc":{"description":"Include a Table-of-Contents in the output markdown.","type":"boolean","default":true},"version":{"description":"Override the version of your application provided under `info.version` location in the specification file.","type":"string"}},"required":[],"additionalProperties":false}},"@asyncapi/nodejs-template":{"title":"NodeJS Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"server":{"description":"The server you want to use in the code.","type":"string"},"asyncapiFileDir":{"description":"Custom location of the AsyncAPI file that you provided as an input in generation. By default it is located in the root of the output directory","type":"string"},"securityScheme":{"description":"Name of the security scheme. Only scheme with X509 and Kafka protocol is supported for now.","type":"string"},"certFilesDir":{"description":"Directory where application certificates are located. This parameter is needed when you use X509 security scheme and your cert files are not located in the root of your application.","type":"string","default":"./"}},"required":["server"],"additionalProperties":false},"supportedProtocols":["amqp","mqtt","mqtts","kafka","kafka-secure","ws"]},"@asyncapi/nodejs-ws-template":{"title":"NodeJS WebSocket Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"server":{"description":"The server you want to use in the code.","type":"string"},"asyncapiFileDir":{"description":"Custom location of the AsyncAPI file that you provided as an input in generation. By default it is located in the root of the output directory","type":"string"}},"required":["server"],"additionalProperties":false},"supportedProtocols":["ws"]},"@asyncapi/python-paho-template":{"title":"Python Paho Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"view":{"description":"The view that the template uses. By default it is the client view, which means that when the document says publish, we subscribe. In the case of the provider view, when the document says publish, we publish. Values are client or provider. The default is client.","type":"string"}},"required":[],"additionalProperties":false}},"@asyncapi/ts-nats-template":{"title":"Typescript Nats Project","schema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{"generateTestClient":{"description":"Generate the test client","type":"boolean","default":false},"promisifyReplyCallback":{"description":"Use promises as callbacks for reply operation","type":"boolean","default":false}},"required":[],"additionalProperties":false},"supportedProtocols":["nats"]}}
\ No newline at end of file
diff --git a/apps/studio/src/components/Modals/ImportBase64Modal.tsx b/apps/studio/src/components/Modals/ImportBase64Modal.tsx
deleted file mode 100644
index 64ee1d22a..000000000
--- a/apps/studio/src/components/Modals/ImportBase64Modal.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import { useState } from 'react';
-import toast from 'react-hot-toast';
-import { create } from '@ebay/nice-modal-react';
-
-import { ConfirmModal } from './index';
-
-import { useServices } from '../../services';
-
-export const ImportBase64Modal = create(() => {
- const [base64, setBase64] = useState('');
- const { editorSvc } = useServices();
-
- const onSubmit = () => {
- toast.promise(editorSvc.importBase64(base64), {
- loading: 'Importing...',
- success: (
-
-
- Document succesfully imported!
-
-
- ),
- error: (
-
-
- Failed to import document.
-
-
- ),
- });
- };
-
- return (
-
-
-
- Base64 content
-
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/ImportURLModal.tsx b/apps/studio/src/components/Modals/ImportURLModal.tsx
deleted file mode 100644
index 3362e501e..000000000
--- a/apps/studio/src/components/Modals/ImportURLModal.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import { useState } from 'react';
-import toast from 'react-hot-toast';
-import { create } from '@ebay/nice-modal-react';
-
-import { ConfirmModal } from './index';
-
-import { useServices } from '../../services';
-
-export const ImportURLModal = create(() => {
- const [url, setUrl] = useState('');
- const { editorSvc } = useServices();
-
- const onSubmit = () => {
- toast.promise(editorSvc.importFromURL(url), {
- loading: 'Importing...',
- success: (
-
-
- Document succesfully imported!
-
-
- ),
- error: (
-
-
- Failed to import document.
-
-
- ),
- });
- };
-
- return (
-
-
-
- Document URL
-
- setUrl(e.target.value)}
- />
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/NewFileModal.tsx b/apps/studio/src/components/Modals/NewFileModal.tsx
deleted file mode 100644
index c2a8a1e68..000000000
--- a/apps/studio/src/components/Modals/NewFileModal.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import { useState } from 'react';
-import { BsFillCheckCircleFill } from 'react-icons/bs';
-import toast from 'react-hot-toast';
-import { create } from '@ebay/nice-modal-react';
-
-import examples from '../../examples';
-
-import { ConfirmModal } from './ConfirmModal';
-import { useServices } from '../../services';
-
-import type { ComponentType, MouseEventHandler, FunctionComponent } from 'react';
-
-interface TemplateListItemProps {
- title: string;
- description: ComponentType;
- isSelected: boolean;
- onClick: MouseEventHandler;
- key: string;
-}
-
-const TemplateListItem: FunctionComponent = ({ title, description: Description, onClick, isSelected }) => {
- const containerStyles = isSelected ? 'border-pink-500' : 'border-gray-200';
- const textStyles = isSelected ? 'text-pink-600' : 'text-gray-600';
-
- return (
-
-
- {title}
- {isSelected && }
-
-
-
-
-
- );
-};
-
-export const NewFileModal = create(() => {
- const { editorSvc } = useServices();
- const [selectedTemplate, setSelectedTemplate] = useState({ title: '', template: '' });
-
- const onSubmit = () => {
- editorSvc.updateState({ content: selectedTemplate.template, updateModel: true });
- setSelectedTemplate({ title: '', template: '' });
-
- toast.success(
-
- Successfully reused the {`"${selectedTemplate.title}"`} template.
-
- );
- };
-
- const realLifeExamples = examples.filter((template) => template.type === 'real-example');
- const templates = examples.filter((template) => template.type === 'protocol-example');
- const tutorials = examples.filter((template) => template.type === 'tutorial-example');
-
- return (
-
-
-
-
-
Templates
-
- {templates.map(({ title, description, template }) => {
- const isSelected = selectedTemplate.title === title;
- return setSelectedTemplate({ title, template })} />;
- })}
-
-
-
-
Real world Examples
-
- {realLifeExamples.map(({ title, description, template }) => {
- const isSelected = selectedTemplate.title === title;
- return setSelectedTemplate({ title, template })} />;
- })}
-
-
-
-
Tutorials
-
- {tutorials.map(({ title, description, template }) => {
- const isSelected = selectedTemplate.title === title;
- return setSelectedTemplate({ title, template })} />;
- })}
-
-
-
- Don't see what you're looking for?
-
- Request a template or add one to the list →
-
-
-
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/RedirectedModal.tsx b/apps/studio/src/components/Modals/RedirectedModal.tsx
deleted file mode 100644
index 6846d09a4..000000000
--- a/apps/studio/src/components/Modals/RedirectedModal.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import { useState } from 'react';
-import { create } from '@ebay/nice-modal-react';
-
-import { ConfirmModal } from './ConfirmModal';
-import { Markdown } from '../common';
-
-const CHANGES = `
-Below are the changes compared to the old AsyncAPI Playground:
-
-- There is no preview for markdown.
-- Studio supports the same query parameters except **template**.
-- To download an AsyncAPI document from an external source use the editor menu and select **Import from URL**. There is also an option to use a local file, base64 saved file, convert a given version of AsyncAPI document to a newer one as well as change the format from YAML to JSON and vice versa. There is also option to download AsyncAPI document as file.
-- To generate the template, please click on the **Generate code/docs** item in the menu at the top right corner of the editor, enter (needed) the parameters and click **Generate**.
-- The left navigation is used to open/close the panels.
-- Errors in the AsyncAPI document are shown in a panel at the bottom of the editor. The panel is expandable.
-- To see the data flow in AsyncAPI document click the 4th node in the left navigation.
-- To select a sample template file click on the 5th item in the left navigation.
-- Studio settings can be changed by clicking on the settings icon in the lower left corner.
-- Panels can be stretched.
-`;
-
-function onCancel() {
- if (typeof window.history.replaceState === 'function') {
- const url = new URL(window.location.href);
- url.searchParams.delete('redirectedFrom');
- window.history.replaceState({}, window.location.href, url.toString());
- }
-}
-
-export const RedirectedModal = create(() => {
- const [showMore, setShowMore] = useState(false);
-
- return (
-
-
-
-
- {CHANGES}
-
- {!showMore && (
- <>
-
-
- setShowMore(true)}
- >
- Show what's changed
-
-
- >
- )}
-
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/Settings/SettingsModal.tsx b/apps/studio/src/components/Modals/Settings/SettingsModal.tsx
deleted file mode 100644
index 8df9bd029..000000000
--- a/apps/studio/src/components/Modals/Settings/SettingsModal.tsx
+++ /dev/null
@@ -1,211 +0,0 @@
-import { useState, useEffect, useCallback } from 'react';
-import toast from 'react-hot-toast';
-import { create, useModal } from '@ebay/nice-modal-react';
-
-import { SettingsTabs, SettingTab } from './SettingsTabs';
-
-import { ConfirmModal } from '../index';
-import { Switch } from '../../common';
-
-import { useServices } from '../../../services';
-
-import type { Dispatch, SetStateAction, FunctionComponent } from 'react';
-import type { SettingsState } from '../../../state/settings.state';
-
-interface ShowGovernanceOptionProps {
- label: 'warning' | 'information' | 'hint';
- state: boolean;
- setState: Dispatch>;
-}
-
-const ShowGovernanceOption: FunctionComponent = ({
- label,
- state,
- setState
-}) => {
- return (
-
-
-
-
- Show {label} governance issues
-
-
-
-
- Show {label} governance issues in the editor's Diagnostics tab.
-
-
-
- );
-};
-
-interface SettingsModalProps {
- activeTab?: 'editor' | 'governance' | 'template';
-}
-
-export const SettingsModal = create(({ activeTab = 'editor' }) => {
- const { settingsSvc } = useServices();
- const settings = settingsSvc.get();
- const modal = useModal();
-
- const [autoSaving, setAutoSaving] = useState(settings.editor.autoSaving);
- const [savingDelay, setSavingDelay] = useState(settings.editor.savingDelay);
- const [governanceWarnings, setGovernanceWarnings] = useState(settings.governance.show.warnings);
- const [governanceInformations, setGovernanceInformations] = useState(settings.governance.show.informations);
- const [governanceHints, setGovernanceHints] = useState(settings.governance.show.hints);
- const [autoRendering, setAutoRendering] = useState(settings.templates.autoRendering);
- const [confirmDisabled, setConfirmDisabled] = useState(true);
-
- const createNewState = (): SettingsState => {
- return {
- editor: {
- autoSaving,
- savingDelay,
- },
- governance: {
- show: {
- warnings: governanceWarnings,
- informations: governanceInformations,
- hints: governanceHints,
- },
- },
- templates: {
- autoRendering,
- }
- };
- };
-
- useEffect(() => {
- const newState = createNewState();
- const isThisSameObjects = settingsSvc.isEqual(newState);
- setConfirmDisabled(isThisSameObjects);
- }, [autoSaving, savingDelay, autoRendering, governanceWarnings, governanceInformations, governanceHints]);
-
- const onCancel = useCallback(() => {
- modal.hide();
- }, []);
-
- const onSubmit = () => {
- const newState = createNewState();
- settingsSvc.set(newState);
-
- toast.success(
-
-
- Settings succesfully saved!
-
-
- );
- onCancel();
- };
-
- const tabs: Array = [
- {
- name: 'editor',
- tab: Editor ,
- content: (
-
-
-
-
- Auto saving
-
- setAutoSaving(v)}
- />
-
-
- Save automatically after each change in the document or manually.
-
-
-
-
-
- Delay (in miliseconds)
-
- setSavingDelay(JSON.parse(e.target.value))}
- value={autoSaving ? savingDelay : ''}
- disabled={!autoSaving}
- >
- Please Select
- {[250, 500, 625, 750, 875, 1000].map(v => (
-
- {v}
-
- ))}
-
-
-
- Delay in saving the modified document.
-
-
-
- ),
- },
- {
- name: 'governance',
- tab: Governance ,
- content: (
- <>
-
-
-
- >
- ),
- },
- {
- name: 'templates',
- tab: Templates ,
- content: (
-
-
-
-
- Auto rendering
-
- setAutoRendering(v)}
- />
-
-
-
- Automatic rendering after each change in the document or manually.
-
-
- ),
- },
- ];
-
- return (
-
-
-
- );
-});
diff --git a/apps/studio/src/components/Modals/Settings/SettingsTabs.tsx b/apps/studio/src/components/Modals/Settings/SettingsTabs.tsx
deleted file mode 100644
index c53bda074..000000000
--- a/apps/studio/src/components/Modals/Settings/SettingsTabs.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import { useState } from 'react';
-
-import type { ReactNode, FunctionComponent } from 'react';
-
-export interface SettingTab {
- name: string;
- tab: ReactNode;
- content: ReactNode;
-}
-
-interface SettingTabsProps {
- active: string;
- tabs: Array;
-}
-
-export const SettingsTabs: FunctionComponent = ({
- active,
- tabs = [],
-}) => {
- const [activeTab, setActiveTab] = useState(
- tabs.some(tab => tab.name === active) ? active : tabs[0]?.name
- );
-
- if (tabs.length === 0) {
- return null;
- }
-
- return (
-
-
-
- {tabs.map(tab => (
- setActiveTab(tab.name)}
- >
-
- {tab.tab}
-
-
- ))}
-
-
-
-
- {tabs.map(tab => (
-
- {tab.content}
-
- ))}
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Modals/index.tsx b/apps/studio/src/components/Modals/index.tsx
deleted file mode 100644
index b89162281..000000000
--- a/apps/studio/src/components/Modals/index.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-export * from './Generator/GeneratorModal';
-export * from './Settings/SettingsModal';
-
-export * from './ConfirmModal';
-export * from './ConvertModal';
-export * from './ConvertToLatestModal';
-export * from './ImportBase64Modal';
-export * from './ImportURLModal';
-export * from './NewFileModal';
-export * from './RedirectedModal';
-export * from './ConfirmNewFileModal';
\ No newline at end of file
diff --git a/apps/studio/src/components/Navigation.tsx b/apps/studio/src/components/Navigation.tsx
deleted file mode 100644
index 22ccb1beb..000000000
--- a/apps/studio/src/components/Navigation.tsx
+++ /dev/null
@@ -1,353 +0,0 @@
-/* eslint-disable sonarjs/no-nested-template-literals, sonarjs/no-duplicate-string */
-
-import React, { useEffect, useState } from 'react';
-
-import { useServices } from '../services';
-import { useDocumentsState, useFilesState } from '../state';
-
-import type { AsyncAPIDocumentInterface } from '@asyncapi/parser/cjs';
-
-interface NavigationProps {
- className?: string;
-}
-
-interface NavigationSectionProps {
- document: AsyncAPIDocumentInterface;
- rawSpec: string;
- hash: string;
-}
-
-const ServersNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- return (
- <>
-
- navigationSvc.scrollTo('/servers', 'servers')
- }
- >
- Servers
-
-
- {document.servers().all().map((server) => {
- const serverName = server.id();
- return
- navigationSvc.scrollTo(
- `/servers/${serverName.replace(/\//g, '~1')}`,
- `server-${serverName}`,
- )
- }
- >
-
-
-
- {server.protocolVersion()
- ? `${server.protocol()} ${server.protocolVersion()}`
- : server.protocol()}
-
-
-
{serverName}
-
-
- })}
-
- >
- );
-};
-
-const OperationsNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- const operations = document.operations().all().map(
- (operation) => {
- const channels: React.ReactNode[] = [];
- // only has one channel per operation
- let channelName = 'Unknown';
- if (!operation.channels().isEmpty()) {
- channelName = operation.channels().all()[0].address() ?? 'Unknown';
- }
- if (operation.isReceive()) {
- channels.push(
-
- navigationSvc.scrollTo(
- `/channels/${channelName.replace(/\//g, '~1')}`,
- `operation-publish-${channelName}`,
- )
- }
- >
-
-
-
- Pub
-
-
-
{channelName}
-
- ,
- );
- }
- if (operation.isSend()) {
- channels.push(
-
- navigationSvc.scrollTo(
- `/channels/${channelName.replace(/\//g, '~1')}`,
- `operation-subscribe-${channelName}`,
- )
- }
- >
-
-
-
- Sub
-
-
-
{channelName}
-
- ,
- );
- }
-
- return channels;
- },
- );
-
- return (
- <>
-
- navigationSvc.scrollTo(
- '/channels',
- 'operations',
- )
- }
- >
- Operations
-
-
- >
- );
-};
-
-const MessagesNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- const messages = document.components().messages().all().map(
- message => {
- const messageName = message.id();
- return
- navigationSvc.scrollTo(
- `/components/messages/${messageName.replace(/\//g, '~1')}`,
- `message-${messageName}`,
- )
- }
- >
- {messageName}
-
- },
- );
-
- return (
- <>
-
- navigationSvc.scrollTo(
- '/components/messages',
- 'messages',
- )
- }
- >
- Messages
-
-
- >
- );
-};
-
-const SchemasNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- const schemas = document.components().schemas().all().map(
- schema => {
- const schemaName = schema.id();
- return
- navigationSvc.scrollTo(
- `/components/schemas/${schemaName.replace(/\//g, '~1')}`,
- `schema-${schemaName}`,
- )
- }
- >
- {schemaName}
-
- }
- );
-
- return (
- <>
-
- navigationSvc.scrollTo(
- '/components/schemas',
- 'schemas',
- )
- }
- >
- Schemas
-
-
- >
- );
-};
-
-export const Navigation: React.FunctionComponent = ({
- className = '',
-}) => {
- const [hash, setHash] = useState(window.location.hash);
- const [loading, setloading] = useState(false);
-
- const { navigationSvc } = useServices();
- const rawSpec = useFilesState(state => state.files['asyncapi']?.content);
- const document = useDocumentsState(state => state.documents['asyncapi']?.document);
-
- useEffect(() => {
- const fn = () => {
- // remove `#` char
- const h = window.location.hash.startsWith('#') ? window.location.hash.substring(1) : window.location.hash;
- setHash(h);
- };
- fn();
- window.addEventListener('hashchange', fn);
- return () => {
- window.removeEventListener('hashchange', fn);
- };
- }, []);
-
- useEffect(() => {
- if (!document) {
- setloading(true);
- const timer = setTimeout(() => {
- setloading(false);
- }, 1000);
- return () => clearTimeout(timer);
- }
- },[document])
-
- if (!rawSpec || !document) {
- return (
-
- {loading ?(
-
- ) : (
-
Empty or invalid document. Please fix errors/define AsyncAPI document.
- )
- }
-
- );
- }
-
- const components = document.components();
- return (
-
- );
-};
diff --git a/apps/studio/src/components/Navigationv3.tsx b/apps/studio/src/components/Navigationv3.tsx
deleted file mode 100644
index 56d28aaff..000000000
--- a/apps/studio/src/components/Navigationv3.tsx
+++ /dev/null
@@ -1,391 +0,0 @@
-/* eslint-disable sonarjs/no-nested-template-literals, sonarjs/no-duplicate-string */
-
-import React, { useEffect, useState } from 'react';
-
-import { useServices } from '../services';
-import { useDocumentsState, useFilesState } from '../state';
-
-import type { AsyncAPIDocumentInterface } from '@asyncapi/parser/cjs';
-
-interface NavigationProps {
- className?: string;
-}
-
-interface NavigationSectionProps {
- document: AsyncAPIDocumentInterface;
- rawSpec: string;
- hash: string;
-}
-
-const ServersNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- return (
- <>
-
- navigationSvc.scrollTo('/servers', 'servers')
- }
- >
- Servers
-
-
- {document.servers().all().map((server) => {
- const serverName = server.id();
- return
- navigationSvc.scrollTo(
- `/servers/${serverName.replace(/\//g, '~1')}`,
- `server-${serverName}`,
- )
- }
- >
-
-
-
- {server.protocolVersion()
- ? `${server.protocol()} ${server.protocolVersion()}`
- : server.protocol()}
-
-
-
{serverName}
-
-
- })}
-
- >
- );
-};
-
-const ChannelsNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- const channels = document.channels().all().map(
- (channel) => {
- return
- navigationSvc.scrollTo(
- `/channels/${(channel.id() ?? '').replace(/\//g, '~1')}`,
- `channels-${channel.id()}`,
- )
- }
- >
-
-
-
- {channel.id()}
-
-
-
{channel.address()}
-
-
- },
- );
-
- return (
- <>
-
- navigationSvc.scrollTo(
- '/channels',
- 'channels',
- )
- }
- >
- Channels
-
-
- >
- );
-};
-
-const OperationsNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- const operations = document.operations().all().map(
- (operation) => {
- const operations: React.ReactNode[] = [];
- if (operation.isReceive()) {
- operations.push(
-
- navigationSvc.scrollTo(
- `/operations/${(operation.id() ?? '').replace(/\//g, '~1')}`,
- `operation-receive-${operation.id()}`,
- )
- }
- >
-
-
-
- Receive
-
-
-
{operation.id()}
-
-
- );
- }
- if (operation.isSend()) {
- operations.push(
-
- navigationSvc.scrollTo(
- `/operations/${(operation.id() ?? '').replace(/\//g, '~1')}`,
- `operation-send-${operation.id()}`,
- )
- }
- >
-
-
-
- Send
-
-
-
{operation.id()}
-
- ,
- );
- }
-
- return operations;
- },
- );
-
- return (
- <>
-
- navigationSvc.scrollTo(
- '/operations',
- 'operations',
- )
- }
- >
- Operations
-
-
- >
- );
-};
-
-const MessagesNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- const messages = document.components().messages().all().map(
- message => {
- const messageName = message.id();
- return
- navigationSvc.scrollTo(
- `/components/messages/${messageName.replace(/\//g, '~1')}`,
- `message-${messageName}`,
- )
- }
- >
- {messageName}
-
- },
- );
-
- return (
- <>
-
- navigationSvc.scrollTo(
- '/components/messages',
- 'messages',
- )
- }
- >
- Messages
-
-
- >
- );
-};
-
-const SchemasNavigation: React.FunctionComponent = ({
- document,
- hash,
-}) => {
- const { navigationSvc } = useServices();
-
- const schemas = document.components().schemas().all().map(
- schema => {
- const schemaName = schema.id();
- return
- navigationSvc.scrollTo(
- `/components/schemas/${schemaName.replace(/\//g, '~1')}`,
- `schema-${schemaName}`,
- )
- }
- >
- {schemaName}
-
- }
- );
-
- return (
- <>
-
- navigationSvc.scrollTo(
- '/components/schemas',
- 'schemas',
- )
- }
- >
- Schemas
-
-
- >
- );
-};
-
-export const Navigationv3: React.FunctionComponent = ({
- className = '',
-}) => {
- const [hash, setHash] = useState(window.location.hash);
-
- const { navigationSvc } = useServices();
- const rawSpec = useFilesState(state => state.files['asyncapi']?.content);
- const document = useDocumentsState(state => state.documents['asyncapi']?.document);
-
- useEffect(() => {
- const fn = () => {
- // remove `#` char
- const h = window.location.hash.startsWith('#') ? window.location.hash.substring(1) : window.location.hash;
- setHash(h);
- };
- fn();
- window.addEventListener('hashchange', fn);
- return () => {
- window.removeEventListener('hashchange', fn);
- };
- }, []);
-
- if (!rawSpec || !document) {
- return (
-
- Empty or invalid document. Please fix errors/define AsyncAPI document.
-
- );
- }
-
- const components = document.components();
- return (
-
- );
-};
\ No newline at end of file
diff --git a/apps/studio/src/components/Popovers/SurveyPopover.tsx b/apps/studio/src/components/Popovers/SurveyPopover.tsx
deleted file mode 100644
index 0e5fe76cb..000000000
--- a/apps/studio/src/components/Popovers/SurveyPopover.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import type { FunctionComponent } from 'react';
-
-interface SurveyPopoverProps {}
-
-export const SurveyPopover: FunctionComponent = () => {
- return null;
-
- // const editorState = state.useEditorState();
- // const editorLoaded = editorState.editorLoaded.get();
- // const [show, setShow] = useState(false);
-
- // useEffect(() => {
- // if (localStorage.getItem('show:survey') === 'false') return;
- // if (editorLoaded) {
- // setTimeout(() => {
- // setShow(true);
- // }, 3000);
- // }
- // }, [editorLoaded]);
-
- // const closePopover = () => {
- // localStorage.setItem('show:survey', 'false');
- // setShow(false);
- // };
-
- // return (
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
Help us improve AsyncAPI Studio
- //
We know that the best way to improve our tools is to understand our users better. Help us define your needs by completing this short survey!
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
- // );
-};
diff --git a/apps/studio/src/components/Popovers/index.ts b/apps/studio/src/components/Popovers/index.ts
deleted file mode 100644
index 61169847d..000000000
--- a/apps/studio/src/components/Popovers/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './SurveyPopover';
\ No newline at end of file
diff --git a/apps/studio/src/components/Sidebar.tsx b/apps/studio/src/components/Sidebar.tsx
deleted file mode 100644
index 2d6f32065..000000000
--- a/apps/studio/src/components/Sidebar.tsx
+++ /dev/null
@@ -1,149 +0,0 @@
-import { VscListSelection, VscCode, VscOpenPreview, VscGraph, VscNewFile, VscSettingsGear } from 'react-icons/vsc';
-import { show as showModal } from '@ebay/nice-modal-react';
-
-import { Tooltip } from './common';
-import { SettingsModal, ConfirmNewFileModal } from './Modals';
-
-import { usePanelsState, panelsState, useDocumentsState } from '../state';
-
-import type { FunctionComponent, ReactNode } from 'react';
-import type { PanelsState } from '../state/panels.state';
-
-function updateState(panelName: keyof PanelsState['show'], type?: PanelsState['secondaryPanelType']) {
- const settingsState = panelsState.getState();
- let secondaryPanelType = settingsState.secondaryPanelType;
- const newShow = { ...settingsState.show };
-
- if (type === 'template' || type === 'visualiser') {
- // on current type
- if (secondaryPanelType === type) {
- newShow[`${panelName}`] = !newShow[`${panelName}`];
- } else {
- secondaryPanelType = type;
- if (newShow[`${panelName}`] === false) {
- newShow[`${panelName}`] = true;
- }
- }
- } else {
- newShow[`${panelName}`] = !newShow[`${panelName}`];
- }
-
- if (!newShow.primaryPanel && !newShow.secondaryPanel) {
- newShow.secondaryPanel = true;
- }
-
- panelsState.setState({
- show: newShow,
- secondaryPanelType,
- });
-}
-
-interface NavItem {
- name: string;
- title: string;
- isActive: boolean;
- onClick: () => void;
- icon: ReactNode;
- tooltip: ReactNode;
- enabled: boolean;
-}
-
-interface SidebarProps {}
-
-export const Sidebar: FunctionComponent = () => {
- const { show, secondaryPanelType } = usePanelsState();
- const document = useDocumentsState(state => state.documents['asyncapi']?.document) || null;
- const isV3 = document?.version() === '3.0.0';
-
- if (show.activityBar === false) {
- return null;
- }
-
- let navigation: NavItem[] = [
- // navigation
- {
- name: 'primarySidebar',
- title: 'Navigation',
- isActive: show.primarySidebar,
- onClick: () => updateState('primarySidebar'),
- icon: ,
- tooltip: 'Navigation',
- enabled: true
- },
- // editor
- {
- name: 'primaryPanel',
- title: 'Editor',
- isActive: show.primaryPanel,
- onClick: () => updateState('primaryPanel'),
- icon: ,
- tooltip: 'Editor',
- enabled: true
- },
- // template
- {
- name: 'template',
- title: 'Template',
- isActive: show.secondaryPanel && secondaryPanelType === 'template',
- onClick: () => updateState('secondaryPanel', 'template'),
- icon: ,
- tooltip: 'HTML preview',
- enabled: true
- },
- // visuliser
- {
- name: 'visualiser',
- title: 'Visualiser',
- isActive: show.secondaryPanel && secondaryPanelType === 'visualiser',
- onClick: () => updateState('secondaryPanel', 'visualiser'),
- icon: ,
- tooltip: 'Blocks visualiser',
- enabled: !isV3
- },
- // newFile
- {
- name: 'newFile',
- title: 'New file',
- isActive: false,
- onClick: () => showModal(ConfirmNewFileModal),
- icon: ,
- tooltip: 'New file',
- enabled: true
- },
- ];
-
- navigation = navigation.filter(item => item.enabled);
-
- return (
-
-
- {navigation.map(item => (
-
- item.onClick()}
- className={'flex text-sm focus:outline-none border-box p-2'}
- type="button"
- >
-
- {item.icon}
-
-
-
- ))}
-
-
-
- showModal(SettingsModal)}
- >
-
-
-
-
-
- );
-};
\ No newline at end of file
diff --git a/apps/studio/src/components/SplitPane/Pane.tsx b/apps/studio/src/components/SplitPane/Pane.tsx
deleted file mode 100644
index 7b6bbf14e..000000000
--- a/apps/studio/src/components/SplitPane/Pane.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-/* eslint-disable */
-// @ts-nocheck
-
-function Pane(props) {
- const { children, className, split, style: styleProps, size, eleRef } = props;
-
- const classes = ['Pane', split, className];
-
- let style = {
- flex: 1,
- position: 'relative',
- outline: 'none',
- };
-
- if (size !== undefined) {
- if (split === 'vertical') {
- style.width = size;
- } else {
- style.height = size;
- style.display = 'flex';
- }
- style.flex = 'none';
- }
-
- style = Object.assign({}, style, styleProps || {});
-
- return (
-
- {children}
-
- );
-}
-
-export default Pane;
\ No newline at end of file
diff --git a/apps/studio/src/components/SplitPane/Readme.md b/apps/studio/src/components/SplitPane/Readme.md
deleted file mode 100644
index bef5d6984..000000000
--- a/apps/studio/src/components/SplitPane/Readme.md
+++ /dev/null
@@ -1,9 +0,0 @@
-MIT License
-
-Copyright (c) 2022 Jeremy Grieshop
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/apps/studio/src/components/SplitPane/Resizer.tsx b/apps/studio/src/components/SplitPane/Resizer.tsx
deleted file mode 100644
index 3a4f766aa..000000000
--- a/apps/studio/src/components/SplitPane/Resizer.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-/* eslint-disable */
-// @ts-nocheck
-
-export const RESIZER_DEFAULT_CLASSNAME = 'Resizer';
-
-function Resizer(props) {
- const {
- className,
- onClick,
- onDoubleClick,
- onMouseDown,
- onTouchEnd,
- onTouchStart,
- resizerClassName,
- split,
- style,
- } = props;
- const classes = [resizerClassName, split, className];
-
- return (
- onMouseDown(event)}
- onTouchStart={event => {
- event.preventDefault();
- onTouchStart(event);
- }}
- onTouchEnd={event => {
- event.preventDefault();
- onTouchEnd(event);
- }}
- onClick={event => {
- if (onClick) {
- event.preventDefault();
- onClick(event);
- }
- }}
- onDoubleClick={event => {
- if (onDoubleClick) {
- event.preventDefault();
- onDoubleClick(event);
- }
- }}
- />
- );
-}
-
-Resizer.defaultProps = {
- resizerClassName: RESIZER_DEFAULT_CLASSNAME,
-};
-
-export default Resizer;
\ No newline at end of file
diff --git a/apps/studio/src/components/SplitPane/SplitPane.tsx b/apps/studio/src/components/SplitPane/SplitPane.tsx
deleted file mode 100644
index 526a80686..000000000
--- a/apps/studio/src/components/SplitPane/SplitPane.tsx
+++ /dev/null
@@ -1,322 +0,0 @@
-/* eslint-disable */
-// @ts-nocheck
-
-import React, { useEffect, useState, useCallback, useRef } from 'react';
-
-import Pane from './Pane';
-import Resizer, { RESIZER_DEFAULT_CLASSNAME } from './Resizer';
-
-function unFocus(document, window) {
- if (document.selection) {
- document.selection.empty();
- } else {
- try {
- window.getSelection().removeAllRanges();
- // eslint-disable-next-line no-empty
- } catch (e) {}
- }
-}
-
-function getDefaultSize(defaultSize, minSize, maxSize, draggedSize) {
- if (typeof draggedSize === 'number') {
- const min = typeof minSize === 'number' ? minSize : 0;
- const max = typeof maxSize === 'number' && maxSize >= 0 ? maxSize : Infinity;
- return Math.max(min, Math.min(max, draggedSize));
- }
- if (defaultSize !== undefined) {
- return defaultSize;
- }
- return minSize;
-}
-
-function removeNullChildren(children) {
- return React.Children.toArray(children).filter(c => c);
-}
-
-function SplitPane(props) {
- const {
- allowResize = true,
- children,
- className,
- defaultSize,
- minSize = 50,
- maxSize,
- onChange,
- onDragFinished,
- onDragStarted,
- onResizerClick,
- onResizerDoubleClick,
- paneClassName = '',
- pane1ClassName = '',
- pane2ClassName = '',
- paneStyle,
- primary = 'first',
- pane1Style: pane1StyleProps,
- pane2Style: pane2StyleProps,
- resizerClassName,
- resizerStyle,
- size,
- split = 'vertical',
- step,
- style: styleProps,
- } = props;
-
- const initialSize =
- size !== undefined ? size : getDefaultSize(defaultSize, minSize, maxSize, null);
-
- const [active, setActive] = useState(false);
- const [, setResized] = useState(false);
- const [pane1Size, setPane1Size] = useState(primary === 'first' ? initialSize : undefined);
- const [pane2Size, setPane2Size] = useState(primary === 'second' ? initialSize : undefined);
- const [draggedSize, setDraggedSize] = useState();
- const [position, setPosition] = useState();
-
- const splitPane = useRef();
- const pane1 = useRef();
- const pane2 = useRef();
- const instanceProps = useRef({ size });
-
- const getSizeUpdate = useCallback(() => {
- if (instanceProps.current.size === size && size !== undefined) {
- return undefined;
- }
-
- const newSize =
- size !== undefined ? size : getDefaultSize(defaultSize, minSize, maxSize, draggedSize);
-
- if (size !== undefined) {
- setDraggedSize(newSize);
- }
-
- const isPanel1Primary = primary === 'first';
- if (isPanel1Primary) {
- setPane1Size(newSize);
- setPane2Size(undefined);
- } else {
- setPane2Size(newSize);
- setPane1Size(undefined);
- }
-
- instanceProps.current.size = newSize;
- }, [defaultSize, draggedSize, maxSize, minSize, primary, size]);
-
- const onMouseUp = useCallback(() => {
- if (allowResize && active) {
- if (typeof onDragFinished === 'function') {
- onDragFinished(draggedSize);
- }
- setActive(false);
- }
- }, [active, allowResize, draggedSize, onDragFinished]);
-
- const onTouchMove = useCallback(
- event => {
- if (allowResize && active) {
- unFocus(document, window);
- const isPrimaryFirst = primary === 'first';
- const ref = isPrimaryFirst ? pane1.current : pane2.current;
- const ref2 = isPrimaryFirst ? pane2.current : pane1.current;
- if (ref) {
- const node = ref;
- const node2 = ref2;
-
- if (node.getBoundingClientRect) {
- const width = node.getBoundingClientRect().width;
- const height = node.getBoundingClientRect().height;
- const current =
- split === 'vertical' ? event.touches[0].clientX : event.touches[0].clientY;
- const size = split === 'vertical' ? width : height;
- let positionDelta = position - current;
- if (step) {
- if (Math.abs(positionDelta) < step) {
- return;
- }
- // Integer division
- // eslint-disable-next-line no-bitwise
- positionDelta = ~~(positionDelta / step) * step;
- }
- let sizeDelta = isPrimaryFirst ? positionDelta : -positionDelta;
-
- const pane1Order = parseInt(window.getComputedStyle(node).order);
- const pane2Order = parseInt(window.getComputedStyle(node2).order);
- if (pane1Order > pane2Order) {
- sizeDelta = -sizeDelta;
- }
-
- let newMaxSize = maxSize;
- if (maxSize !== undefined && maxSize <= 0) {
- if (split === 'vertical') {
- newMaxSize = splitPane.current.getBoundingClientRect().width + maxSize;
- } else {
- newMaxSize = splitPane.current.getBoundingClientRect().height + maxSize;
- }
- }
-
- let newSize = size - sizeDelta;
- const newPosition = position - positionDelta;
-
- if (newSize < minSize) {
- newSize = minSize;
- } else if (maxSize !== undefined && newSize > newMaxSize) {
- newSize = newMaxSize;
- } else {
- setPosition(newPosition);
- setResized(true);
- }
-
- if (onChange) onChange(newSize);
-
- setDraggedSize(newSize);
- if (isPrimaryFirst) setPane1Size(newSize);
- else setPane2Size(newSize);
- }
- }
- }
- },
- [active, allowResize, maxSize, minSize, onChange, position, primary, split, step],
- );
-
- const onMouseMove = useCallback(
- event => {
- const eventWithTouches = Object.assign({}, event, {
- touches: [{ clientX: event.clientX, clientY: event.clientY }],
- });
- onTouchMove(eventWithTouches);
- },
- [onTouchMove],
- );
-
- const onTouchStart = useCallback(
- event => {
- if (allowResize) {
- unFocus(document, window);
- const position = split === 'vertical' ? event.touches[0].clientX : event.touches[0].clientY;
-
- if (typeof onDragStarted === 'function') {
- onDragStarted();
- }
- setActive(true);
- setPosition(position);
- }
- },
- [allowResize, onDragStarted, split],
- );
-
- const onMouseDown = useCallback(
- event => {
- const eventWithTouches = Object.assign({}, event, {
- touches: [{ clientX: event.clientX, clientY: event.clientY }],
- });
- onTouchStart(eventWithTouches);
- },
- [onTouchStart],
- );
-
- useEffect(() => {
- document.addEventListener('mouseup', onMouseUp);
- document.addEventListener('mousemove', onMouseMove);
- document.addEventListener('touchmove', onTouchMove);
-
- getSizeUpdate();
-
- return () => {
- document.removeEventListener('mouseup', onMouseUp);
- document.removeEventListener('mousemove', onMouseMove);
- document.removeEventListener('touchmove', onTouchMove);
- };
- }, [onMouseUp, onMouseMove, onTouchMove, getSizeUpdate]);
-
- const disabledClass = allowResize ? '' : 'disabled';
- const resizerClassNamesIncludingDefault = resizerClassName
- ? `${resizerClassName} ${RESIZER_DEFAULT_CLASSNAME}`
- : resizerClassName;
-
- const notNullChildren = removeNullChildren(children);
-
- const style = {
- display: 'flex',
- flex: 1,
- height: '100%',
- position: 'absolute',
- outline: 'none',
- overflow: 'hidden',
- MozUserSelect: 'text',
- WebkitUserSelect: 'text',
- msUserSelect: 'text',
- userSelect: 'text',
- ...styleProps,
- };
-
- if (split === 'vertical') {
- Object.assign(style, {
- flexDirection: 'row',
- left: 0,
- right: 0,
- });
- } else {
- Object.assign(style, {
- bottom: 0,
- flexDirection: 'column',
- minHeight: '100%',
- top: 0,
- width: '100%',
- });
- }
-
- const classes = ['SplitPane', className, split, disabledClass];
-
- const pane1Style = { ...paneStyle, ...pane1StyleProps };
- const pane2Style = { ...paneStyle, ...pane2StyleProps };
-
- const pane1Classes = ['Pane1', paneClassName, pane1ClassName].join(' ');
- const pane2Classes = ['Pane2', paneClassName, pane2ClassName].join(' ');
-
- return (
- {
- splitPane.current = node;
- }}
- style={style}
- >
-
{
- pane1.current = node;
- }}
- size={pane1Size}
- split={split}
- style={pane1Style}
- >
- {notNullChildren[0]}
-
-
-
{
- pane2.current = node;
- }}
- size={pane2Size}
- split={split}
- style={pane2Style}
- >
- {notNullChildren[1]}
-
-
- );
-}
-
-export default SplitPane;
\ No newline at end of file
diff --git a/apps/studio/src/components/SplitPane/index.tsx b/apps/studio/src/components/SplitPane/index.tsx
deleted file mode 100644
index 18bcb3786..000000000
--- a/apps/studio/src/components/SplitPane/index.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import ReactSplitPane from './SplitPane';
-import Pane from './Pane';
-/**
- * Implementation from https://github.com/JeremyGrieshop/react-split-pane/blob/main/SplitPane.js
- */
-export default ReactSplitPane;
-export { Pane };
\ No newline at end of file
diff --git a/apps/studio/src/components/Template/HTMLWrapper.tsx b/apps/studio/src/components/Template/HTMLWrapper.tsx
deleted file mode 100644
index c8b65d58b..000000000
--- a/apps/studio/src/components/Template/HTMLWrapper.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import { AsyncApiComponentWP } from '@asyncapi/react-component';
-
-import { useServices } from '../../services';
-import { appState, useDocumentsState, useSettingsState, useOtherState, otherState } from '../../state';
-
-import { AsyncAPIDocumentInterface } from '@asyncapi/parser/cjs';
-
-interface HTMLWrapperProps {}
-
-export const HTMLWrapper: React.FunctionComponent = () => {
- const [parsedSpec, setParsedSpec] = useState(null);
- const { navigationSvc } = useServices();
- const document = useDocumentsState(state => state.documents['asyncapi']?.document) || null;
- const [loading, setloading] = useState(false);
-
- const autoRendering = useSettingsState(state => state.templates.autoRendering);
- const templateRerender = useOtherState(state => state.templateRerender);
-
- useEffect(() => {
- navigationSvc.scrollToHash();
- }, []); // eslint-disable-line
-
- useEffect(() => {
- if (autoRendering || parsedSpec === null) {
- setParsedSpec(document);
- }
- }, [document]); // eslint-disable-line
-
- useEffect(() => {
- if (templateRerender) {
- setParsedSpec(document);
- otherState.setState({ templateRerender: false });
- }
- }, [templateRerender]); // eslint-disable-line
-
- useEffect(() => {
- if (!document) {
- setloading(true);
- const timer = setTimeout(() => {
- setloading(false);
- }, 1000);
- return () => clearTimeout(timer);
- }
- },[document])
- if (!document) {
- return (
-
- {loading ?(
-
- ) : (
-
Empty or invalid document. Please fix errors/define AsyncAPI document.
- )
- }
-
- );
- }
-
- return (
- parsedSpec && (
-
- )
- );
-};
diff --git a/apps/studio/src/components/Template/Template.tsx b/apps/studio/src/components/Template/Template.tsx
deleted file mode 100644
index 912a38527..000000000
--- a/apps/studio/src/components/Template/Template.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-
-import { TemplateSidebar } from './TemplateSidebar';
-import { HTMLWrapper } from './HTMLWrapper';
-
-import { appState } from '../../state';
-
-interface TemplateProps {}
-
-export const Template: React.FunctionComponent = () => {
- return (
-
- {!appState.getState().readOnly && }
-
-
- );
-};
diff --git a/apps/studio/src/components/Template/TemplateSidebar.tsx b/apps/studio/src/components/Template/TemplateSidebar.tsx
deleted file mode 100644
index bfd9a6e95..000000000
--- a/apps/studio/src/components/Template/TemplateSidebar.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from 'react';
-import { VscRefresh } from 'react-icons/vsc';
-
-import { useSettingsState, otherState } from '../../state';
-
-interface TemplateSidebarProps {}
-
-export const TemplateSidebar: React.FunctionComponent = () => {
- const autoRendering = useSettingsState(state => state.templates.autoRendering);
-
- return (
-
- {autoRendering ? (
-
- ) : (
-
-
otherState.setState({ templateRerender: true })}>
-
-
-
-
-
- Rerender
-
-
- )}
-
- );
-};
diff --git a/apps/studio/src/components/Template/index.ts b/apps/studio/src/components/Template/index.ts
deleted file mode 100644
index 1972b01e5..000000000
--- a/apps/studio/src/components/Template/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './Template';
-export * from './HTMLWrapper';
diff --git a/apps/studio/src/components/Terminal/ProblemsTab.tsx b/apps/studio/src/components/Terminal/ProblemsTab.tsx
deleted file mode 100644
index 9368cb840..000000000
--- a/apps/studio/src/components/Terminal/ProblemsTab.tsx
+++ /dev/null
@@ -1,306 +0,0 @@
-import React, { useCallback, useMemo, useRef, useState } from 'react';
-import { VscError, VscWarning, VscInfo, VscLightbulb, VscSearch, VscClose, VscSettingsGear } from 'react-icons/vsc';
-import { useModal } from '@ebay/nice-modal-react';
-import { DiagnosticSeverity } from '@asyncapi/parser/cjs';
-
-import { SettingsModal } from '../Modals/Settings/SettingsModal';
-
-import { Tooltip } from '../common';
-import { useServices } from '../../services';
-import { debounce } from '../../helpers';
-import { useDocumentsState, useSettingsState } from '../../state';
-
-import type { FunctionComponent } from 'react';
-import type { Diagnostic } from '@asyncapi/parser/cjs';
-
-interface ProblemsTabProps {}
-
-export const ProblemsTab: FunctionComponent = () => {
- const diagnostics = useDocumentsState(state => state.documents['asyncapi'].diagnostics);
-
- const errorDiagnosticsLength = diagnostics.errors.length;
- const warningDiagnosticsLength = diagnostics.warnings.length;
- const informationDiagnosticsLength = diagnostics.informations.length;
- const hintDiagnosticsLength = diagnostics.hints.length;
-
- return (
-
-
Diagnostics
-
- {errorDiagnosticsLength > 0 && (
-
-
- {errorDiagnosticsLength}
-
-
- )}
- {warningDiagnosticsLength > 0 && (
-
-
- {warningDiagnosticsLength}
-
-
- )}
- {informationDiagnosticsLength > 0 && (
-
-
- {informationDiagnosticsLength}
-
-
- )}
- {hintDiagnosticsLength > 0 && (
-
-
- {hintDiagnosticsLength}
-
-
- )}
-
-
- );
-};
-
-interface SeverityIconProps {
- severity: Diagnostic['severity']
-}
-
-const SeverityIcon: React.FunctionComponent = ({ severity }) => {
- switch (severity) {
- case 1: return (
-
-
-
- );
- case 2: return (
-
-
-
- );
- case 3: return (
-
-
-
- );
- default: return (
-
-
-
- );
- }
-};
-
-function createProperMessage(
- disabled: boolean,
- active: DiagnosticSeverity[],
- severity: DiagnosticSeverity,
- showMessage: string,
- hideMessage: string,
- firstMessage: string,
-) {
- if (disabled) {
- return 'Disabled. Enable it in the settings.';
- }
- if (active.some(s => s === severity)) {
- if (active.length === 1) {
- return 'Show all diagnostics';
- }
- return hideMessage;
- }
- if (active.length === 0) {
- return firstMessage;
- }
- return showMessage;
-}
-
-interface SeverityButtonsProps {
- active: DiagnosticSeverity[];
- setActive: (severity: DiagnosticSeverity) => void;
-}
-
-const SeverityButtons: FunctionComponent = ({ active, setActive }) => {
- const diagnostics = useDocumentsState(state => state.documents['asyncapi'].diagnostics);
- const governanceShowState = useSettingsState(state => state.governance.show);
-
- const errorDiagnostics = diagnostics.errors;
- const warningDiagnostics = diagnostics.warnings;
- const infoDiagnostics = diagnostics.informations;
- const hintDiagnostics = diagnostics.hints;
-
- const errorsTooltip = createProperMessage(false, active, DiagnosticSeverity.Error, 'Show errors', 'Hide errors', 'Show only errors');
- const warningsTooltip = createProperMessage(!governanceShowState.warnings, active, DiagnosticSeverity.Warning, 'Show warnings', 'Hide warnings', 'Show only warnings');
- const informationTooltip = createProperMessage(!governanceShowState.informations, active, DiagnosticSeverity.Information, 'Show information messages', 'Hide information messages', 'Show only information messages');
- const hintsTooltip = createProperMessage(!governanceShowState.hints, active, DiagnosticSeverity.Hint, 'Show hints', 'Hide hints', 'Show only hints');
-
- const activeBg = 'bg-gray-900';
- const notActiveBg = 'bg-gray-700';
-
- return (
-
-
-
- s === DiagnosticSeverity.Error) ? activeBg : notActiveBg} text-xs font-medium text-white hover:bg-gray-900 disabled:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-offset-1 focus:ring-gray-700`}
- onClick={() => setActive(DiagnosticSeverity.Error)}
- >
-
-
- {errorDiagnostics.length}
-
-
-
-
-
-
- s === DiagnosticSeverity.Warning) ? activeBg : notActiveBg} text-xs font-medium text-white hover:bg-gray-900 disabled:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-offset-1 focus:ring-gray-700`}
- onClick={() => setActive(DiagnosticSeverity.Warning)}
- disabled={!governanceShowState.warnings}
- >
-
-
- {warningDiagnostics.length}
-
-
-
-
-
-
- s === DiagnosticSeverity.Information) ? activeBg : notActiveBg} text-xs font-medium text-white hover:bg-gray-900 disabled:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-offset-1 focus:ring-gray-700`}
- onClick={() => setActive(DiagnosticSeverity.Information)}
- disabled={!governanceShowState.informations}
- >
-
-
- {infoDiagnostics.length}
-
-
-
-
-
-
- s === DiagnosticSeverity.Hint) ? activeBg : notActiveBg} text-xs font-medium text-white hover:bg-gray-900 disabled:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-offset-1 focus:ring-gray-700`}
- onClick={() => setActive(DiagnosticSeverity.Hint)}
- disabled={!governanceShowState.hints}
- >
-
-
- {hintDiagnostics.length}
-
-
-
-
-
- );
-};
-
-export const ProblemsTabContent: FunctionComponent = () => {
- const { navigationSvc } = useServices();
- const diagnostics = useDocumentsState(state => state.documents['asyncapi'].diagnostics);
- const modal = useModal(SettingsModal);
-
- const [active, setActive] = useState>([]);
- const [search, setSearch] = useState('');
- const inputRef = useRef(null);
-
- const setActiveFn = useCallback((severity: DiagnosticSeverity) => {
- setActive(acc => {
- if (acc.some(s => s === severity)) {
- return acc.filter(s => s !== severity);
- }
- return [...acc, severity];
- });
- }, [setActive]);
-
- const filteredDiagnostics = useMemo(() => {
- return diagnostics.filtered.filter(diagnostic => {
- const { severity, message } = diagnostic;
-
- if (active.length && !active.some(s => s === severity)) {
- return false;
- }
-
- const lowerCasingSearch = search.toLowerCase();
- return !(lowerCasingSearch && !message.toLowerCase().includes(lowerCasingSearch));
- });
- }, [diagnostics, search, active]);
-
- return (
-
-
-
-
-
-
- setSearch(e.target.value), 250)} />
- {
- if (inputRef.current) {
- inputRef.current.value = '';
- }
- setSearch('');
- }}>
-
-
-
-
- modal.show({ activeTab: 'governance' })}
- >
-
-
-
-
-
-
-
-
- Type
- Line
- Message
-
-
-
- {filteredDiagnostics.map((diagnostic, id) => {
- const { severity, message, range } = diagnostic;
-
- return (
-
-
-
- navigationSvc.scrollToEditorLine(
- range.start.line + 1,
- range.start.character + 1,
- )
- }
- >
- {range.start.line + 1}:{range.start.character + 1}
-
- {message}
-
- );
- })}
-
-
- {filteredDiagnostics.length === 0 && !search && (
-
- No issues.
-
- )}
- {filteredDiagnostics.length === 0 && search && (
-
- No results for "{search}".
-
- )}
-
-
- );
-};
diff --git a/apps/studio/src/components/Terminal/Terminal.tsx b/apps/studio/src/components/Terminal/Terminal.tsx
deleted file mode 100644
index beb0afa9f..000000000
--- a/apps/studio/src/components/Terminal/Terminal.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import React from 'react';
-
-import { TerminalTabs, TerminalTab } from './TerminalTabs';
-import { ProblemsTab, ProblemsTabContent } from './ProblemsTab';
-
-interface TerminalProps {}
-
-export const Terminal: React.FunctionComponent = () => {
- const tabs: Array = [
- {
- name: 'problems',
- tab: ,
- content: ,
- },
- ];
-
- return (
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Terminal/TerminalInfo.tsx b/apps/studio/src/components/Terminal/TerminalInfo.tsx
deleted file mode 100644
index 20bb74343..000000000
--- a/apps/studio/src/components/Terminal/TerminalInfo.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import { useCallback } from 'react';
-import { VscRadioTower } from 'react-icons/vsc';
-import { show } from '@ebay/nice-modal-react';
-
-import { ConvertToLatestModal } from '../Modals';
-
-import { useServices } from '../../services';
-import { useAppState, useDocumentsState, useFilesState, useSettingsState } from '../../state';
-
-import type { FunctionComponent, MouseEvent as ReactMouseEvent } from 'react';
-
-interface TerminalInfoProps {}
-
-export const TerminalInfo: FunctionComponent = () => {
- const { specificationSvc } = useServices();
- const file = useFilesState(state => state.files['asyncapi']);
- const document = useDocumentsState(state => state.documents['asyncapi']);
- const autoSaving = useSettingsState(state => state.editor.autoSaving);
-
- const liveServer = useAppState(state => state.liveServer);
- const actualVersion = document.document?.version() || '2.0.0';
- const latestVersion = specificationSvc.latestVersion;
-
- const onNonLatestClick = useCallback((e: ReactMouseEvent) => {
- e.stopPropagation();
- show(ConvertToLatestModal);
- }, []);
-
- return (
-
- {liveServer && (
-
-
-
-
- Live server
-
- )}
- {document.diagnostics.errors.length > 0 ? (
-
- ) : (
-
- )}
- {!autoSaving && file.modified && (
-
- )}
-
-
-
-
-
-
-
{autoSaving ? 'Autosave: On' : 'Autosave: Off'}
-
- {actualVersion !== latestVersion && document.valid === true && (
-
- )}
-
- {file.language}
-
-
- );
-};
diff --git a/apps/studio/src/components/Terminal/TerminalTabs.tsx b/apps/studio/src/components/Terminal/TerminalTabs.tsx
deleted file mode 100644
index 6130c91c1..000000000
--- a/apps/studio/src/components/Terminal/TerminalTabs.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import React, { useState } from 'react';
-
-import { TerminalInfo } from './TerminalInfo';
-import { otherState, useDocumentsState } from '../../state';
-
-export interface TerminalTab {
- name: string;
- tab: React.ReactNode;
- content: React.ReactNode;
-}
-
-interface TerminalTabsProps {
- tabs: Array;
- active?: string;
-}
-
-export const TerminalTabs: React.FunctionComponent = ({
- tabs = [],
- active = 0,
-}) => {
- const [activeTab, setActiveTab] = useState(active);
- const document = useDocumentsState(state => state.documents['asyncapi']?.document) || null;
- const isV3 = document?.version() === '3.0.0';
- if (tabs.length === 0) {
- return null;
- }
-
- return (
-
-
{
- const clientRects = e.currentTarget.parentElement?.parentElement?.getClientRects()[0];
- if (!clientRects) return;
-
- const height = clientRects.height;
- const calc160px = 'calc(100% - 160px)';
- const calc36px = 'calc(100% - 36px)';
-
- const prevHeight = otherState.getState().editorHeight;
- const newHeight =
- height < 50 ? calc160px : calc36px;
- if (
- prevHeight === calc160px &&
- newHeight === calc160px
- ) {
- return 'calc(100% - 161px)';
- }
- if (
- prevHeight === calc36px &&
- newHeight === calc36px
- ) {
- return 'calc(100% - 37px)';
- }
-
- otherState.setState({ editorHeight: newHeight });
- }}
- >
-
- {!isV3 && tabs.map(tab => (
- setActiveTab(tab.name)}
- >
-
- {tab.tab}
-
-
- ))}
-
-
-
-
-
- {tabs.map(tab => (
-
- {tab.content}
-
- ))}
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Terminal/index.ts b/apps/studio/src/components/Terminal/index.ts
deleted file mode 100644
index 39f1492ee..000000000
--- a/apps/studio/src/components/Terminal/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './Terminal';
diff --git a/apps/studio/src/components/Toolbar.tsx b/apps/studio/src/components/Toolbar.tsx
deleted file mode 100644
index 6568a8037..000000000
--- a/apps/studio/src/components/Toolbar.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from 'react';
-import { IoGlobeOutline, IoLogoGithub, IoLogoSlack } from 'react-icons/io5';
-
-interface ToolbarProps {}
-
-export const Toolbar: React.FunctionComponent = () => {
- return (
-
-
-
-
-
-
-
- beta
-
-
-
-
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Visualiser/Controls.tsx b/apps/studio/src/components/Visualiser/Controls.tsx
deleted file mode 100644
index 1e6d6f7c2..000000000
--- a/apps/studio/src/components/Visualiser/Controls.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { useState, useEffect } from 'react';
-import { useStore, useReactFlow, useNodes, useEdges } from 'reactflow';
-import { VscDebugStart, VscDebugPause, VscRefresh } from 'react-icons/vsc';
-
-import { calculateNodesForDynamicLayout } from './utils/node-calculator';
-
-import type { FunctionComponent } from 'react';
-
-interface ControlsProps {}
-
-export const Controls: FunctionComponent = () => {
- const [animateNodes, setAnimateNodes] = useState(false);
-
- const { fitView } = useReactFlow();
- const nodes = useNodes();
- const edges = useEdges();
- const setNodes = useStore(state => state.setNodes);
- const setEdges = useStore(state => state.setEdges);
-
- useEffect(() => {
- if (nodes.length > 0) {
- const newNodeEdges = edges.map(edge => ({ ...edge, animated: animateNodes }));
- setEdges([...newNodeEdges]);
- }
- }, [animateNodes]);
-
- const reloadInterface = () => {
- setNodes(calculateNodesForDynamicLayout(nodes));
- fitView();
- };
-
- return (
-
- setAnimateNodes(!animateNodes)}>
- {animateNodes && }
- {!animateNodes && }
-
-
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Visualiser/FlowDiagram.tsx b/apps/studio/src/components/Visualiser/FlowDiagram.tsx
deleted file mode 100644
index 28b214cef..000000000
--- a/apps/studio/src/components/Visualiser/FlowDiagram.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import { useEffect } from 'react';
-import ReactFlow, { Controls as FlowControls, Background, BackgroundVariant, useReactFlow, useStore, useNodesState, useEdgesState, useNodes } from 'reactflow';
-
-import NodeTypes from './Nodes';
-import { Controls } from './Controls';
-import { getElementsFromAsyncAPISpec } from './utils/node-factory';
-import { calculateNodesForDynamicLayout } from './utils/node-calculator';
-
-import type { OldAsyncAPIDocument as AsyncAPIDocument } from '@asyncapi/parser/cjs';
-import type { FunctionComponent } from 'react';
-
-interface FlowDiagramProps {
- parsedSpec: AsyncAPIDocument;
-}
-
-interface AutoLayoutProps {}
-
-const AutoLayout: FunctionComponent = () => {
- const { fitView } = useReactFlow();
- const nodes = useNodes();
- const setNodes = useStore(state => state.setNodes);
-
- useEffect(() => {
- if (nodes.length === 0 || !nodes[0].width) {
- return;
- }
-
- const nodesWithOrginalPosition = nodes.filter(node => node.position.x === 0 && node.position.y === 0);
- if (nodesWithOrginalPosition.length > 1) {
- const calculatedNodes = calculateNodesForDynamicLayout(nodes);
- setNodes(calculatedNodes);
- fitView();
- }
- }, [nodes]);
-
- return null;
-};
-
-export const FlowDiagram: FunctionComponent = ({ parsedSpec }) => {
- const [nodes, setNodes, onNodesChange] = useNodesState([]);
- const [edges, setEdges, onEdgesChange] = useEdgesState([]);
-
- useEffect(() => {
- const elements = getElementsFromAsyncAPISpec(parsedSpec);
- const newNodes = elements.map(el => el.node).filter(Boolean);
- const newEdges = elements.map(el => el.edge).filter(Boolean);
-
- setNodes(newNodes);
- setEdges(newEdges);
- }, [parsedSpec]);
-
- return (
-
-
-
-
-
-
-
-
-
-
- Event Visualiser
- |
- {parsedSpec.info().title()}
-
-
- );
-};
diff --git a/apps/studio/src/components/Visualiser/Nodes/ApplicationNode.tsx b/apps/studio/src/components/Visualiser/Nodes/ApplicationNode.tsx
deleted file mode 100644
index d6a380564..000000000
--- a/apps/studio/src/components/Visualiser/Nodes/ApplicationNode.tsx
+++ /dev/null
@@ -1,166 +0,0 @@
-import { useState, useEffect } from 'react';
-import { Handle, Position } from 'reactflow';
-import { OldAsyncAPIDocument as AsyncAPIDocument } from '@asyncapi/parser/cjs';
-
-import { useServices } from '../../../services';
-import { Markdown } from '../../common';
-
-import type { FunctionComponent } from 'react';
-
-interface IData {
- spec: AsyncAPIDocument
-}
-
-interface ApplicationNodeProps {
- data: IData
-}
-
-const buildNodeData = (spec: AsyncAPIDocument) => {
- const servers = spec.servers();
-
- const mappedServers = Object.keys(servers).reduce((newMappedServers: any[], serverKey) => {
- const server = servers[String(serverKey)];
-
- newMappedServers.push({
- name: serverKey,
- url: server.url(),
- description: server.description(),
- protocol: server.protocol(),
- protocolVersion: server.protocolVersion(),
- });
- return newMappedServers;
- }, []);
-
- const specInfo = spec.info();
-
- return {
- defaultContentType: spec.defaultContentType(),
- description: specInfo.description(),
- title: specInfo.title(),
- version: specInfo.version(),
- license: {
- name: specInfo.license() && specInfo.license()?.name(),
- url: specInfo.license() && specInfo.license()?.url(),
- },
- // @ts-ignore
- externalDocs: spec.externalDocs() && spec.externalDocs().url(),
- servers: mappedServers,
- };
-};
-
-export const ApplicationNode: FunctionComponent = ({
- data: { spec } = {},
-}) => {
- const { navigationSvc } = useServices();
- const [highlight, setHighlight] = useState(false);
- const { description, title, version, license, externalDocs, servers, defaultContentType } = buildNodeData(spec as AsyncAPIDocument);
-
- useEffect(() => {
- return navigationSvc.highlightVisualiserNode('#server', setHighlight);
- }, [navigationSvc, setHighlight]);
-
- return (
-
-
-
-
- In
-
-
-
-
-
-
- application
-
-
-
-
-
{title}
-
- v{version}
-
-
- {description && (
-
-
- {description}
-
-
- )}
- {defaultContentType && (
-
- Default ContentType:{' '}
-
- {defaultContentType}
-
-
- )}
-
-
- {servers.length > 0 && (
-
-
Servers
-
- {servers.map((server) => {
- return (
-
-
- {server.name}
-
- {server.protocolVersion
- ? `${server.protocol} ${server.protocolVersion}`
- : server.protocol}
-
-
-
-
- {server.description}
-
-
- url: {server.url}
-
- );
- })}
-
-
- )}
-
-
-
-
-
- Out
-
-
-
-
- );
-};
-
-export default ApplicationNode;
\ No newline at end of file
diff --git a/apps/studio/src/components/Visualiser/Nodes/PublishNode.tsx b/apps/studio/src/components/Visualiser/Nodes/PublishNode.tsx
deleted file mode 100644
index c9e729c3e..000000000
--- a/apps/studio/src/components/Visualiser/Nodes/PublishNode.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import { useState, useEffect } from 'react';
-import { Handle, Position } from 'reactflow';
-
-import { useServices } from '../../../services';
-import getBackgroundColor from '../utils/random-background-color';
-
-// @ts-ignore
-import { Markdown } from '@asyncapi/react-component/lib/esm/components/Markdown';
-
-import type React from 'react';
-
-interface IData {
- messages: any[];
- channel: string
- description: string
-}
-
-interface PublishNodeProps {
- data: IData
-}
-
-export const PublishNode: React.FunctionComponent = ({
- data: { messages = [], channel, description },
-}) => {
- const { navigationSvc } = useServices();
- const [highlight, setHighlight] = useState(false);
-
- useEffect(() => {
- return navigationSvc.highlightVisualiserNode(`#operation-publish-${channel}`, setHighlight);
- }, [navigationSvc, setHighlight]);
-
- return (
-
-
-
You can publish
-
-
{channel}
- {description && (
-
-
- {description}
-
-
- )}
-
-
-
-
- Messages
-
-
- Payloads you can publish using this channel
-
-
- {messages.map((message) => {
- const theme = getBackgroundColor(message.title);
-
- return (
-
- );
- })}
-
-
-
-
-
- );
-};
-
-export default PublishNode;
\ No newline at end of file
diff --git a/apps/studio/src/components/Visualiser/Nodes/SubscribeNode.tsx b/apps/studio/src/components/Visualiser/Nodes/SubscribeNode.tsx
deleted file mode 100644
index 85a2602ce..000000000
--- a/apps/studio/src/components/Visualiser/Nodes/SubscribeNode.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import { useState, useEffect } from 'react';
-import { Handle, Position } from 'reactflow';
-
-import { useServices } from '../../../services';
-import getBackgroundColor from '../utils/random-background-color';
-
-// @ts-ignore
-import { Markdown } from '@asyncapi/react-component/lib/esm/components/Markdown';
-
-import type { FunctionComponent } from 'react';
-
-interface IData {
- messages: any []
- channel: string
- description: string
-}
-
-interface PublishNodeProps {
- data: IData
-}
-
-export const SubscribeNode: FunctionComponent = ({ data: { channel, description, messages } }) => {
- const { navigationSvc } = useServices();
- const [highlight, setHighlight] = useState(false);
-
- useEffect(() => {
- return navigationSvc.highlightVisualiserNode(`#operation-subscribe-${channel}`, setHighlight);
- }, [navigationSvc, setHighlight]);
-
- return (
-
-
-
-
-
- You can subscribe
-
-
-
-
-
{channel}
- {description && (
-
-
- {description}
-
-
- )}
-
-
-
-
- Messages
-
-
- Payloads to expect from listening to this channel
-
-
- {messages.map((message) => {
- return (
-
-
-
-
- {message.title}
-
-
-
- );
- })}
-
-
-
-
-
- );
-};
-
-export default SubscribeNode;
\ No newline at end of file
diff --git a/apps/studio/src/components/Visualiser/Nodes/index.tsx b/apps/studio/src/components/Visualiser/Nodes/index.tsx
deleted file mode 100644
index 10475b57a..000000000
--- a/apps/studio/src/components/Visualiser/Nodes/index.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import PublishNode from './PublishNode';
-import ApplicationNode from './ApplicationNode';
-import SubscribeNode from './SubscribeNode';
-
-const nodeTypes = {
- publishNode: PublishNode,
- subscribeNode: SubscribeNode,
- applicationNode: ApplicationNode
-};
-
-export default nodeTypes;
\ No newline at end of file
diff --git a/apps/studio/src/components/Visualiser/Visualiser.tsx b/apps/studio/src/components/Visualiser/Visualiser.tsx
deleted file mode 100644
index 357d2c632..000000000
--- a/apps/studio/src/components/Visualiser/Visualiser.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { useState, useEffect } from 'react';
-
-import { FlowDiagram } from './FlowDiagram';
-
-import { useDocumentsState, useSettingsState, useOtherState, otherState } from '../../state';
-
-import { OldAsyncAPIDocument as AsyncAPIDocument, convertToOldAPI } from '@asyncapi/parser/cjs';
-import type { FunctionComponent } from 'react';
-
-interface VisualiserProps {}
-
-export const Visualiser: FunctionComponent = () => {
- const [parsedSpec, setParsedSpec] = useState(null);
- const document = useDocumentsState(state => state.documents['asyncapi']?.document) || null;
- const autoRendering = useSettingsState(state => state.templates.autoRendering);
- const templateRerender = useOtherState(state => state.templateRerender);
-
- useEffect(() => {
- if (autoRendering || parsedSpec === null) {
- const oldDocument = document !== null ? convertToOldAPI(document) : null;
- setParsedSpec(oldDocument);
- }
- }, [document]); // eslint-disable-line
-
- useEffect(() => {
- if (templateRerender) {
- const oldDocument = document !== null ? convertToOldAPI(document) : null;
- setParsedSpec(oldDocument);
- otherState.setState({ templateRerender: false });
- }
- }, [templateRerender]); // eslint-disable-line
-
- if (!document) {
- return (
-
-
Empty or invalid document. Please fix errors/define AsyncAPI document.
-
- );
- }
-
- return (
- parsedSpec && (
-
- )
- );
-};
diff --git a/apps/studio/src/components/Visualiser/VisualiserTemplate.tsx b/apps/studio/src/components/Visualiser/VisualiserTemplate.tsx
deleted file mode 100644
index c6440795b..000000000
--- a/apps/studio/src/components/Visualiser/VisualiserTemplate.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Visualiser } from './Visualiser';
-import { TemplateSidebar } from '../Template/TemplateSidebar';
-
-import type { FunctionComponent } from 'react';
-
-interface VisualiserTemplateProps {}
-
-export const VisualiserTemplate: FunctionComponent = () => {
- return (
-
-
-
-
- );
-};
diff --git a/apps/studio/src/components/Visualiser/index.ts b/apps/studio/src/components/Visualiser/index.ts
deleted file mode 100644
index 02d60e00d..000000000
--- a/apps/studio/src/components/Visualiser/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './Visualiser';
-export * from './VisualiserTemplate';
diff --git a/apps/studio/src/components/Visualiser/utils/node-calculator.ts b/apps/studio/src/components/Visualiser/utils/node-calculator.ts
deleted file mode 100644
index 96a7f8166..000000000
--- a/apps/studio/src/components/Visualiser/utils/node-calculator.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { isNode, Node } from 'reactflow';
-
-const groupNodesByColumn = (elements: Node[]) => {
- return elements.reduce((elementsGrouped: any, element: Node) => {
- if (isNode(element)) {
- if (elementsGrouped[element?.data.columnToRenderIn]) {
- return {
- ...elementsGrouped,
- [element.data.columnToRenderIn]: elementsGrouped[element?.data.columnToRenderIn].concat([element])};
- }
-
- return {
- ...elementsGrouped,
- [element.data.columnToRenderIn]: (elementsGrouped[element?.data.groupId] = [element]),
- };
- }
- return elementsGrouped;
- }, {});
-};
-
-export const calculateNodesForDynamicLayout = (elements: Node[]) => {
- const elementsGroupedByColumn = groupNodesByColumn(elements);
-
- const newElements: { nodes: Node[], currentXPosition: number } = Object.keys(elementsGroupedByColumn).reduce(
- (data: { nodes: Node[], currentXPosition: number }, group: string) => {
- const groupNodes = elementsGroupedByColumn[String(group)];
-
- // eslint-disable-next-line
- const maxWidthOfColumn = Math.max.apply(
- Math,
- groupNodes.map((o: Node) => {
- return o.width;
- })
- );
-
- // For each group (column), render the nodes based on height they require (with some padding)
- const { positionedNodes } = groupNodes.reduce(
- (groupedNodes: { positionedNodes: Node[], currentYPosition: number }, currentNode: Node) => {
- const verticalPadding = 40;
-
- currentNode.position.x = data.currentXPosition;
- currentNode.position.y = groupedNodes.currentYPosition;
-
- return {
- positionedNodes: groupedNodes.positionedNodes.concat([currentNode]),
- currentYPosition: groupedNodes.currentYPosition + (currentNode.height || 0) + verticalPadding,
- };
- },
- { positionedNodes: [], currentYPosition: 0 }
- );
-
- return {
- nodes: [...data.nodes, ...positionedNodes],
- currentXPosition: data.currentXPosition + maxWidthOfColumn + 100,
- };
- },
- { nodes: [], currentXPosition: 0 }
- );
-
- return newElements.nodes;
-};
diff --git a/apps/studio/src/components/Visualiser/utils/node-factory.ts b/apps/studio/src/components/Visualiser/utils/node-factory.ts
deleted file mode 100644
index 68de1f322..000000000
--- a/apps/studio/src/components/Visualiser/utils/node-factory.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import type { OldAsyncAPIDocument as AsyncAPIDocument, OldChannel, OldOperation, OldMessage } from '@asyncapi/parser/cjs';
-import type { Node, Edge } from 'reactflow';
-
-interface FileredChannel {
- channel: string;
- channelModel: OldChannel;
- operationModel: OldOperation;
- messagesModel: OldMessage[];
-}
-
-function getChannelsByOperation(operation: string, spec: AsyncAPIDocument) {
- const channels = spec.channels();
- return Object.keys(channels).reduce((filteredChannels: FileredChannel[], channel) => {
- const operationFn = operation === 'publish' ? 'hasPublish' : 'hasSubscribe';
- // eslint-disable-next-line
- if (channels[String(channel)][operationFn]()) {
- const operationModel = (channels as any)[String(channel)][String(operation)]() as OldOperation;
- filteredChannels.push({
- channel,
- channelModel: channels[String(channel)],
- operationModel,
- messagesModel: operationModel.messages(),
- });
- }
- return filteredChannels;
- }, []);
-}
-
-function buildFlowElementsForOperation({ operation, spec, applicationLinkType, data }: { operation: 'publish' | 'subscribe'; spec: AsyncAPIDocument; applicationLinkType: string, data: any }): Array<{ node: Node, edge: Edge }> {
- return getChannelsByOperation(operation, spec).reduce((nodes: any, channel) => {
- const { channelModel, operationModel, messagesModel } = channel;
-
- const node: Node = {
- id: `${operation}-${channel.channel}`,
- type: `${operation}Node`,
- data: {
- title: operationModel.id(),
- channel: channel.channel,
- tags: operationModel.tags(),
- messages: messagesModel.map((message) => ({
- title: message.uid(),
- description: message.description(),
- })),
-
- spec,
- description: channelModel.description(),
- operationId: operationModel.id(),
- elementType: operation,
- theme: operation === 'subscribe' ? 'green' : 'blue',
- ...data
- },
- position: { x: 0, y: 0 },
- };
-
- const edge: Edge = {
- id: `${operation}-${channel.channel}-to-application`,
- // type: 'smoothstep',
- // animated: true,
- // label: messagesModel.map(message => message.uid()).join(','),
- style: { stroke: applicationLinkType === 'target' ? '#00A5FA' : '#7ee3be', strokeWidth: 4 },
- source: applicationLinkType === 'target' ? `${operation}-${channel.channel}` : 'application',
- target: applicationLinkType === 'target' ? 'application' : `${operation}-${channel.channel}`,
- };
-
- return [...nodes, { node, edge }];
- }, []);
-}
-
-export function getElementsFromAsyncAPISpec(spec: AsyncAPIDocument): Array<{ node: Node, edge: Edge }> {
- const publishNodes = buildFlowElementsForOperation({
- operation: 'publish',
- spec,
- applicationLinkType: 'target',
- data: { columnToRenderIn: 'col-1' },
- });
- const subscribeNodes = buildFlowElementsForOperation({
- operation: 'subscribe',
- spec,
- applicationLinkType: 'source',
- data: { columnToRenderIn: 'col-3' },
- });
- const applicationNode = {
- id: 'application',
- type: 'applicationNode',
- data: { spec, elementType: 'application', theme: 'indigo', columnToRenderIn: 'col-2' },
- position: { x: 0, y: 0 },
- };
-
- return [
- ...publishNodes,
- { node: applicationNode } as { node: Node, edge: Edge },
- ...subscribeNodes
- ];
-}
diff --git a/apps/studio/src/components/Visualiser/utils/random-background-color.ts b/apps/studio/src/components/Visualiser/utils/random-background-color.ts
deleted file mode 100644
index cc6a8435a..000000000
--- a/apps/studio/src/components/Visualiser/utils/random-background-color.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export default (stringInput: string) => {
- //@ts-ignore
- const stringUniqueHash = [...stringInput].reduce((acc, char) => {
- return char.charCodeAt(0) + ((acc << 5) - acc);
- }, 0);
- return `hsla(${stringUniqueHash % 360}, 95%, 35%, 0.5)`;
-};
\ No newline at end of file
diff --git a/apps/studio/src/components/common/Dropdown.tsx b/apps/studio/src/components/common/Dropdown.tsx
deleted file mode 100644
index 88d5a83e6..000000000
--- a/apps/studio/src/components/common/Dropdown.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { useState, useRef } from 'react';
-
-import { useOutsideClickCallback } from '../../helpers';
-
-import type { FunctionComponent, PropsWithChildren, ReactNode } from 'react';
-
-interface DropdownProps extends PropsWithChildren {
- opener: ReactNode;
- className?: string;
- buttonHoverClassName?: string;
- align?: string;
-}
-
-export const Dropdown: FunctionComponent = ({
- opener,
- className = 'relative',
- buttonHoverClassName,
- align = 'right',
- children,
-}) => {
- const [open, setOpen] = useState(false);
- const dropdownRef = useRef(null);
-
- useOutsideClickCallback(dropdownRef, () => setOpen(false));
- buttonHoverClassName = buttonHoverClassName || 'hover:text-white';
-
- return (
-
-
setOpen(!open)}
- type="button"
- className={`flex p-2 text-sm rounded-md ${buttonHoverClassName} focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo transition ease-in-out duration-150`}
- >
- {opener}
-
-
setOpen(false)}
- className={`${
- open ? 'visible' : 'invisible'
- } origin-top-right absolute ${align === 'right' &&
- 'right-0'} ${align === 'left' &&
- 'left-0'} mt-1 mr-3 w-64 rounded-md shadow-lg z-50`}
- >
-
-
-
- );
-};
diff --git a/apps/studio/src/components/common/Markdown.tsx b/apps/studio/src/components/common/Markdown.tsx
deleted file mode 100644
index 9afa46b7f..000000000
--- a/apps/studio/src/components/common/Markdown.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-// @ts-ignore
-import { Markdown as MarkdownComponent } from '@asyncapi/react-component/lib/cjs/components/Markdown';
-
-import type { FunctionComponent, PropsWithChildren } from 'react';
-
-export const Markdown: FunctionComponent = ({
- children,
-}) => {
- return (
-
-
- {children}
-
-
- );
-};
diff --git a/apps/studio/src/components/common/Switch.tsx b/apps/studio/src/components/common/Switch.tsx
deleted file mode 100644
index eae99baee..000000000
--- a/apps/studio/src/components/common/Switch.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import React, { useState } from 'react';
-
-interface SwitchProps {
- toggle?: boolean;
- onChange: (toggle: boolean) => void;
-}
-
-export const Switch: React.FunctionComponent = ({
- toggle: initToggle = false,
- onChange,
-}) => {
- const [toggle, setToggle] = useState(initToggle);
-
- return (
- {
- const newValue = !toggle;
- setToggle(newValue);
- onChange(newValue);
- }}
- >
-
-
-
-
- );
-};
\ No newline at end of file
diff --git a/apps/studio/src/components/common/Tooltip.tsx b/apps/studio/src/components/common/Tooltip.tsx
deleted file mode 100644
index c17f3e59c..000000000
--- a/apps/studio/src/components/common/Tooltip.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import Tippy, { TippyProps } from '@tippyjs/react';
-
-export const Tooltip: React.FunctionComponent = ({
- placement = 'bottom',
- arrow = true,
- animation = 'shift-away',
- className = 'text-xs bg-gray-900 text-center',
- hideOnClick = false,
- children,
- ...rest
-}) => {
- return (
-
- {children}
-
- );
-};
diff --git a/apps/studio/src/components/common/index.ts b/apps/studio/src/components/common/index.ts
deleted file mode 100644
index aed0e9e6b..000000000
--- a/apps/studio/src/components/common/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from './Dropdown';
-export * from './Markdown';
-export * from './Switch';
-export * from './Tooltip';
diff --git a/apps/studio/src/components/index.ts b/apps/studio/src/components/index.ts
deleted file mode 100644
index c9e5082a4..000000000
--- a/apps/studio/src/components/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export * from './Editor';
-export * from './Content';
-export * from './Navigation';
-export * from './Sidebar';
-export * from './Template';
-export * from './Toolbar';
diff --git a/apps/studio/src/examples/ibmmq.yml b/apps/studio/src/examples/ibmmq.yml
deleted file mode 100644
index d9e8d09d2..000000000
--- a/apps/studio/src/examples/ibmmq.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-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
\ No newline at end of file
diff --git a/apps/studio/src/examples/index.tsx b/apps/studio/src/examples/index.tsx
deleted file mode 100644
index b166ad96d..000000000
--- a/apps/studio/src/examples/index.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-// @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
- }
-];
diff --git a/apps/studio/src/examples/real-world/gitter-streaming.yml b/apps/studio/src/examples/real-world/gitter-streaming.yml
deleted file mode 100644
index ec0cbd12c..000000000
--- a/apps/studio/src/examples/real-world/gitter-streaming.yml
+++ /dev/null
@@ -1,178 +0,0 @@
-asyncapi: 3.0.0
-id: 'tag:stream.gitter.im,2022:api'
-info:
- title: Gitter Streaming API
- version: 1.0.0
-servers:
- production:
- host: stream.gitter.im
- pathname: /v1
- protocol: https
- protocolVersion: '1.1'
- security:
- - $ref: '#/components/securitySchemes/httpBearerToken'
-channels:
- rooms:
- address: '/rooms/{roomId}/{resource}'
- messages:
- chatMessage:
- $ref: '#/components/messages/chatMessage'
- heartbeat:
- $ref: '#/components/messages/heartbeat'
- parameters:
- roomId:
- description: Id of the Gitter room.
- examples:
- - 53307860c3599d1de448e19d
- resource:
- enum:
- - chatMessages
- - events
- description: The resource to consume.
-operations:
- sendRoomInfo:
- action: send
- channel:
- $ref: '#/channels/rooms'
- bindings:
- http:
- method: POST
- messages:
- - $ref: '#/channels/rooms/messages/chatMessage'
- - $ref: '#/channels/rooms/messages/heartbeat'
-components:
- securitySchemes:
- httpBearerToken:
- type: http
- scheme: bearer
- messages:
- chatMessage:
- summary: >-
- A message represents an individual chat message sent to a room. They are
- a sub-resource of a room.
- payload:
- schemaFormat: application/schema+yaml;version=draft-07
- schema:
- type: object
- properties:
- id:
- type: string
- description: ID of the message.
- text:
- type: string
- description: Original message in plain-text/markdown.
- html:
- type: string
- description: HTML formatted message.
- sent:
- type: string
- format: date-time
- description: ISO formatted date of the message.
- fromUser:
- type: object
- description: User that sent the message.
- properties:
- id:
- type: string
- description: Gitter User ID.
- username:
- type: string
- description: Gitter/GitHub username.
- displayName:
- type: string
- description: Gitter/GitHub user real name.
- url:
- type: string
- description: Path to the user on Gitter.
- avatarUrl:
- type: string
- format: uri
- description: User avatar URI.
- avatarUrlSmall:
- type: string
- format: uri
- description: User avatar URI (small).
- avatarUrlMedium:
- type: string
- format: uri
- description: User avatar URI (medium).
- v:
- type: number
- description: Version.
- gv:
- type: string
- description: Stands for "Gravatar version" and is used for cache busting.
- unread:
- type: boolean
- description: Boolean that indicates if the current user has read the message.
- readBy:
- type: number
- description: Number of users that have read the message.
- urls:
- type: array
- description: List of URLs present in the message.
- items:
- type: string
- format: uri
- mentions:
- type: array
- description: List of @Mentions in the message.
- items:
- type: object
- properties:
- screenName:
- type: string
- userId:
- type: string
- userIds:
- type: array
- items:
- type: string
- issues:
- type: array
- description: 'List of #Issues referenced in the message.'
- items:
- type: object
- properties:
- number:
- type: string
- meta:
- type: array
- description: Metadata. This is currently not used for anything.
- items: {}
- v:
- type: number
- description: Version.
- gv:
- type: string
- description: Stands for "Gravatar version" and is used for cache busting.
- bindings:
- http:
- headers:
- type: object
- properties:
- Transfer-Encoding:
- type: string
- const: chunked
- Trailer:
- type: string
- const: \r\n
- heartbeat:
- summary: Its purpose is to keep the connection alive.
- payload:
- schemaFormat: application/schema+yaml;version=draft-07
- schema:
- type: string
- enum:
- - "\r\n"
- bindings:
- http:
- headers:
- type: object
- properties:
- Transfer-Encoding:
- type: string
- const: chunked
- Trailer:
- type: string
- const: \r\n
\ No newline at end of file
diff --git a/apps/studio/src/examples/real-world/kraken-api-request-reply-filter.yml b/apps/studio/src/examples/real-world/kraken-api-request-reply-filter.yml
deleted file mode 100644
index 9abb79398..000000000
--- a/apps/studio/src/examples/real-world/kraken-api-request-reply-filter.yml
+++ /dev/null
@@ -1,388 +0,0 @@
-asyncapi: 3.0.0
-
-info:
- title: Kraken Websockets API
- version: '1.8.0'
- description: |
- WebSockets API offers real-time market data updates. WebSockets is a bidirectional protocol offering fastest real-time data, helping you build real-time applications. The public message types presented below do not require authentication. Private-data messages can be subscribed on a separate authenticated endpoint.
-
- ### General Considerations
-
- - TLS with SNI (Server Name Indication) is required in order to establish a Kraken WebSockets API connection. See Cloudflare's [What is SNI?](https://www.cloudflare.com/learning/ssl/what-is-sni/) guide for more details.
- - All messages sent and received via WebSockets are encoded in JSON format
- - All decimal fields (including timestamps) are quoted to preserve precision.
- - Timestamps should not be considered unique and not be considered as aliases for transaction IDs. Also, the granularity of timestamps is not representative of transaction rates.
- - At least one private message should be subscribed to keep the authenticated client connection open.
- - Please use REST API endpoint [AssetPairs](https://www.kraken.com/features/api#get-tradable-pairs) to fetch the list of pairs which can be subscribed via WebSockets API. For example, field 'wsname' gives the supported pairs name which can be used to subscribe.
- - Cloudflare imposes a connection/re-connection rate limit (per IP address) of approximately 150 attempts per rolling 10 minutes. If this is exceeded, the IP is banned for 10 minutes.
- - Recommended reconnection behaviour is to (1) attempt reconnection instantly up to a handful of times if the websocket is dropped randomly during normal operation but (2) after maintenance or extended downtime, attempt to reconnect no more quickly than once every 5 seconds. There is no advantage to reconnecting more rapidly after maintenance during cancel_only mode.
-
-
-channels:
- currencyExchange:
- address: /
- messages:
- ping:
- $ref: '#/components/messages/ping'
- pong:
- $ref: '#/components/messages/pong'
- heartbeat:
- $ref: '#/components/messages/heartbeat'
- systemStatus:
- $ref: '#/components/messages/systemStatus'
- subscriptionStatus:
- $ref: '#/components/messages/subscriptionStatus'
- subscribe:
- $ref: '#/components/messages/subscribe'
- unsubscribe:
- $ref: '#/components/messages/unsubscribe'
- dummyCurrencyInfo:
- $ref: '#/components/messages/dummyCurrencyInfo'
-
-
-operations:
- receivePing:
- action: receive
- channel:
- $ref: '#/channels/currencyExchange'
- reply:
- channel:
- $ref: '#/channels/currencyExchange'
- messages:
- - $ref: '#/channels/currencyExchange/messages/pong'
- messages:
- - $ref: '#/channels/currencyExchange/messages/ping'
- sendHeartbeat:
- action: send
- channel:
- $ref: '#/channels/currencyExchange'
- messages:
- - $ref: '#/channels/currencyExchange/messages/heartbeat'
- systemStatus:
- action: send
- channel:
- $ref: '#/channels/currencyExchange'
- messages:
- - $ref: '#/channels/currencyExchange/messages/systemStatus'
- receiveSubscribeRequest:
- action: receive
- channel:
- $ref: '#/channels/currencyExchange'
- reply:
- channel:
- $ref: '#/channels/currencyExchange'
- messages:
- - $ref: '#/channels/currencyExchange/messages/subscriptionStatus'
- - $ref: '#/channels/currencyExchange/messages/dummyCurrencyInfo'
- messages:
- - $ref: '#/channels/currencyExchange/messages/subscribe'
- receiveUnsubscribeRequest:
- action: receive
- channel:
- $ref: '#/channels/currencyExchange'
- reply:
- channel:
- $ref: '#/channels/currencyExchange'
- messages:
- - $ref: '#/channels/currencyExchange/messages/subscriptionStatus'
- messages:
- - $ref: '#/channels/currencyExchange/messages/unsubscribe'
-
-
-components:
- messages:
- dummyCurrencyInfo:
- summary: Dummy message with no real life details
- description: It is here in this example to showcase that there is an additional message that normally is of a complex structure. It represents actually currency exchange value to show a reply to operation receiveSubscribeRequest with more than one possible message.
- payload:
- type: object
- properties:
- event:
- type: string
- const: currencyInfo
- reqid:
- $ref: '#/components/schemas/reqid'
- data:
- type: object
- required:
- - event
- correlationId:
- location: '$message.payload#/reqid'
-
- ping:
- summary: Ping server to determine whether connection is alive
- description: Client can ping server to determine whether connection is alive, server responds with pong. This is an application level ping as opposed to default ping in websockets standard which is server initiated
- payload:
- $ref: '#/components/schemas/ping'
- correlationId:
- location: '$message.payload#/reqid'
-
- pong:
- summary: Pong is a response to ping message
- description: Server pong response to a ping to determine whether connection is alive. This is an application level pong as opposed to default pong in websockets standard which is sent by client in response to a ping
- payload:
- $ref: '#/components/schemas/pong'
- correlationId:
- location: '$message.payload#/reqid'
-
- subscribe:
- description: Subscribe to a topic on a single or multiple currency pairs.
- payload:
- $ref: '#/components/schemas/subscribe'
- correlationId:
- location: '$message.payload#/reqid'
- unsubscribe:
- description: Unsubscribe, can specify a channelID or multiple currency pairs.
- payload:
- $ref: '#/components/schemas/unsubscribe'
- correlationId:
- location: '$message.payload#/reqid'
- subscriptionStatus:
- description: Subscription status response to subscribe, unsubscribe or exchange initiated unsubscribe.
- payload:
- $ref: '#/components/schemas/subscriptionStatus'
- examples:
- - payload:
- channelID: 10001
- channelName: ohlc-5
- event: subscriptionStatus
- pair: XBT/EUR
- reqid: 42
- status: unsubscribed
- subscription:
- interval: 5
- name: ohlc
- - payload:
- errorMessage: Subscription depth not supported
- event: subscriptionStatus
- pair: XBT/USD
- status: error
- subscription:
- depth: 42
- name: book
-
- systemStatus:
- description: Status sent on connection or system status changes.
- payload:
- $ref: '#/components/schemas/systemStatus'
-
- heartbeat:
- description: Server heartbeat sent if no subscription traffic within 1 second (approximately)
- payload:
- $ref: '#/components/schemas/heartbeat'
-
-
- schemas:
- ping:
- type: object
- properties:
- event:
- type: string
- const: ping
- reqid:
- $ref: '#/components/schemas/reqid'
- required:
- - event
- heartbeat:
- type: object
- properties:
- event:
- type: string
- const: heartbeat
- pong:
- type: object
- properties:
- event:
- type: string
- const: pong
- reqid:
- $ref: '#/components/schemas/reqid'
- systemStatus:
- type: object
- properties:
- event:
- type: string
- const: systemStatus
- connectionID:
- type: integer
- description: The ID of the connection
- status:
- $ref: '#/components/schemas/status'
- version:
- type: string
- status:
- type: string
- enum:
- - online
- - maintenance
- - cancel_only
- - limit_only
- - post_only
- subscribe:
- type: object
- properties:
- event:
- type: string
- const: subscribe
- reqid:
- $ref: '#/components/schemas/reqid'
- pair:
- $ref: '#/components/schemas/pair'
- subscription:
- type: object
- properties:
- depth:
- $ref: '#/components/schemas/depth'
- interval:
- $ref: '#/components/schemas/interval'
- name:
- $ref: '#/components/schemas/name'
- ratecounter:
- $ref: '#/components/schemas/ratecounter'
- snapshot:
- $ref: '#/components/schemas/snapshot'
- token:
- $ref: '#/components/schemas/token'
- required:
- - name
- required:
- - event
- unsubscribe:
- type: object
- properties:
- event:
- type: string
- const: unsubscribe
- reqid:
- $ref: '#/components/schemas/reqid'
- pair:
- $ref: '#/components/schemas/pair'
- subscription:
- type: object
- properties:
- depth:
- $ref: '#/components/schemas/depth'
- interval:
- $ref: '#/components/schemas/interval'
- name:
- $ref: '#/components/schemas/name'
- token:
- $ref: '#/components/schemas/token'
- required:
- - name
- required:
- - event
- subscriptionStatus:
- type: object
- oneOf:
- - $ref: '#/components/schemas/subscriptionStatusError'
- - $ref: '#/components/schemas/subscriptionStatusSuccess'
- subscriptionStatusError:
- allOf:
- - properties:
- errorMessage:
- type: string
- required:
- - errorMessage
- - $ref: '#/components/schemas/subscriptionStatusCommon'
- subscriptionStatusSuccess:
- allOf:
- - properties:
- channelID:
- type: integer
- description: ChannelID on successful subscription, applicable to public messages only.
- channelName:
- type: string
- description: Channel Name on successful subscription. For payloads 'ohlc' and 'book', respective interval or depth will be added as suffix.
- required:
- - channelID
- - channelName
- - $ref: '#/components/schemas/subscriptionStatusCommon'
- subscriptionStatusCommon:
- type: object
- required:
- - event
- properties:
- event:
- type: string
- const: subscriptionStatus
- reqid:
- $ref: '#/components/schemas/reqid'
- pair:
- $ref: '#/components/schemas/pair'
- status:
- $ref: '#/components/schemas/status'
- subscription:
- required:
- - name
- type: object
- properties:
- depth:
- $ref: '#/components/schemas/depth'
- interval:
- $ref: '#/components/schemas/interval'
- maxratecount:
- $ref: '#/components/schemas/maxratecount'
- name:
- $ref: '#/components/schemas/name'
- token:
- $ref: '#/components/schemas/token'
- interval:
- type: integer
- description: Time interval associated with ohlc subscription in minutes.
- default: 1
- enum:
- - 1
- - 5
- - 15
- - 30
- - 60
- - 240
- - 1440
- - 10080
- - 21600
- name:
- type: string
- description: The name of the channel you subscribe too.
- enum:
- - book
- - ohlc
- - openOrders
- - ownTrades
- - spread
- - ticker
- - trade
- token:
- type: string
- description: base64-encoded authentication token for private-data endpoints.
- depth:
- type: integer
- default: 10
- enum:
- - 10
- - 25
- - 100
- - 500
- - 1000
- description: Depth associated with book subscription in number of levels each side.
- maxratecount:
- type: integer
- description: Max rate-limit budget. Compare to the ratecounter field in the openOrders updates to check whether you are approaching the rate limit.
- ratecounter:
- type: boolean
- default: false
- description: Whether to send rate-limit counter in updates (supported only for openOrders subscriptions)
- snapshot:
- type: boolean
- default: true
- description: Whether to send historical feed data snapshot upon subscription (supported only for ownTrades subscriptions)
- reqid:
- type: integer
- description: client originated ID reflected in response message.
- pair:
- type: array
- description: Array of currency pairs.
- items:
- type: string
- description: Format of each pair is "A/B", where A and B are ISO 4217-A3 for standardized assets and popular unique symbol if not standardized.
- pattern: '[A-Z\s]+\/[A-Z\s]+'
\ No newline at end of file
diff --git a/apps/studio/src/examples/real-world/slack-rtm.yml b/apps/studio/src/examples/real-world/slack-rtm.yml
deleted file mode 100644
index 1973e3b99..000000000
--- a/apps/studio/src/examples/real-world/slack-rtm.yml
+++ /dev/null
@@ -1,982 +0,0 @@
-asyncapi: 3.0.0
-id: 'wss://wss-primary.slack.com/websocket'
-info:
- title: Slack Real Time Messaging API
- version: 1.0.0
-servers:
- production:
- host: slack.com
- pathname: /api/rtm.connect
- protocol: https
- protocolVersion: '1.1'
- security:
- - $ref: '#/components/securitySchemes/token'
-channels:
- root:
- address: /
- messages:
- outgoingMessage:
- $ref: '#/components/messages/outgoingMessage'
- hello:
- $ref: '#/components/messages/hello'
- connectionError:
- $ref: '#/components/messages/connectionError'
- accountsChanged:
- $ref: '#/components/messages/accountsChanged'
- botAdded:
- $ref: '#/components/messages/botAdded'
- botChanged:
- $ref: '#/components/messages/botChanged'
- channelArchive:
- $ref: '#/components/messages/channelArchive'
- channelCreated:
- $ref: '#/components/messages/channelCreated'
- channelDeleted:
- $ref: '#/components/messages/channelDeleted'
- channelHistoryChanged:
- $ref: '#/components/messages/channelHistoryChanged'
- channelJoined:
- $ref: '#/components/messages/channelJoined'
- channelLeft:
- $ref: '#/components/messages/channelLeft'
- channelMarked:
- $ref: '#/components/messages/channelMarked'
- channelRename:
- $ref: '#/components/messages/channelRename'
- channelUnarchive:
- $ref: '#/components/messages/channelUnarchive'
- commandsChanged:
- $ref: '#/components/messages/commandsChanged'
- dndUpdated:
- $ref: '#/components/messages/dndUpdated'
- dndUpdatedUser:
- $ref: '#/components/messages/dndUpdatedUser'
- emailDomainChanged:
- $ref: '#/components/messages/emailDomainChanged'
- emojiRemoved:
- $ref: '#/components/messages/emojiRemoved'
- emojiAdded:
- $ref: '#/components/messages/emojiAdded'
- fileChange:
- $ref: '#/components/messages/fileChange'
- fileCommentAdded:
- $ref: '#/components/messages/fileCommentAdded'
- fileCommentDeleted:
- $ref: '#/components/messages/fileCommentDeleted'
- fileCommentEdited:
- $ref: '#/components/messages/fileCommentEdited'
- fileCreated:
- $ref: '#/components/messages/fileCreated'
- fileDeleted:
- $ref: '#/components/messages/fileDeleted'
- filePublic:
- $ref: '#/components/messages/filePublic'
- fileShared:
- $ref: '#/components/messages/fileShared'
- fileUnshared:
- $ref: '#/components/messages/fileUnshared'
- goodbye:
- $ref: '#/components/messages/goodbye'
- groupArchive:
- $ref: '#/components/messages/groupArchive'
- groupClose:
- $ref: '#/components/messages/groupClose'
- groupHistoryChanged:
- $ref: '#/components/messages/groupHistoryChanged'
- groupJoined:
- $ref: '#/components/messages/groupJoined'
- groupLeft:
- $ref: '#/components/messages/groupLeft'
- groupMarked:
- $ref: '#/components/messages/groupMarked'
- groupOpen:
- $ref: '#/components/messages/groupOpen'
- groupRename:
- $ref: '#/components/messages/groupRename'
- groupUnarchive:
- $ref: '#/components/messages/groupUnarchive'
- imClose:
- $ref: '#/components/messages/imClose'
- imCreated:
- $ref: '#/components/messages/imCreated'
- imMarked:
- $ref: '#/components/messages/imMarked'
- imOpen:
- $ref: '#/components/messages/imOpen'
- manualPresenceChange:
- $ref: '#/components/messages/manualPresenceChange'
- memberJoinedChannel:
- $ref: '#/components/messages/memberJoinedChannel'
- message:
- $ref: '#/components/messages/message'
-operations:
- receiveOutgoingMessage:
- action: receive
- channel:
- $ref: '#/channels/root'
- messages:
- - $ref: '#/channels/root/messages/outgoingMessage'
- sendMessages:
- action: send
- channel:
- $ref: '#/channels/root'
- messages:
- - $ref: '#/channels/root/messages/hello'
- - $ref: '#/channels/root/messages/connectionError'
- - $ref: '#/channels/root/messages/accountsChanged'
- - $ref: '#/channels/root/messages/botAdded'
- - $ref: '#/channels/root/messages/botChanged'
- - $ref: '#/channels/root/messages/channelArchive'
- - $ref: '#/channels/root/messages/channelCreated'
- - $ref: '#/channels/root/messages/channelDeleted'
- - $ref: '#/channels/root/messages/channelHistoryChanged'
- - $ref: '#/channels/root/messages/channelJoined'
- - $ref: '#/channels/root/messages/channelLeft'
- - $ref: '#/channels/root/messages/channelMarked'
- - $ref: '#/channels/root/messages/channelRename'
- - $ref: '#/channels/root/messages/channelUnarchive'
- - $ref: '#/channels/root/messages/commandsChanged'
- - $ref: '#/channels/root/messages/dndUpdated'
- - $ref: '#/channels/root/messages/dndUpdatedUser'
- - $ref: '#/channels/root/messages/emailDomainChanged'
- - $ref: '#/channels/root/messages/emojiRemoved'
- - $ref: '#/channels/root/messages/emojiAdded'
- - $ref: '#/channels/root/messages/fileChange'
- - $ref: '#/channels/root/messages/fileCommentAdded'
- - $ref: '#/channels/root/messages/fileCommentDeleted'
- - $ref: '#/channels/root/messages/fileCommentEdited'
- - $ref: '#/channels/root/messages/fileCreated'
- - $ref: '#/channels/root/messages/fileDeleted'
- - $ref: '#/channels/root/messages/filePublic'
- - $ref: '#/channels/root/messages/fileShared'
- - $ref: '#/channels/root/messages/fileUnshared'
- - $ref: '#/channels/root/messages/goodbye'
- - $ref: '#/channels/root/messages/groupArchive'
- - $ref: '#/channels/root/messages/groupClose'
- - $ref: '#/channels/root/messages/groupHistoryChanged'
- - $ref: '#/channels/root/messages/groupJoined'
- - $ref: '#/channels/root/messages/groupLeft'
- - $ref: '#/channels/root/messages/groupMarked'
- - $ref: '#/channels/root/messages/groupOpen'
- - $ref: '#/channels/root/messages/groupRename'
- - $ref: '#/channels/root/messages/groupUnarchive'
- - $ref: '#/channels/root/messages/imClose'
- - $ref: '#/channels/root/messages/imCreated'
- - $ref: '#/channels/root/messages/imMarked'
- - $ref: '#/channels/root/messages/imOpen'
- - $ref: '#/channels/root/messages/manualPresenceChange'
- - $ref: '#/channels/root/messages/memberJoinedChannel'
- - $ref: '#/channels/root/messages/message'
-components:
- securitySchemes:
- token:
- type: httpApiKey
- name: token
- in: query
- schemas:
- attachment:
- type: object
- properties:
- fallback:
- type: string
- color:
- type: string
- pretext:
- type: string
- author_name:
- type: string
- author_link:
- type: string
- format: uri
- author_icon:
- type: string
- format: uri
- title:
- type: string
- title_link:
- type: string
- format: uri
- text:
- type: string
- fields:
- type: array
- items:
- type: object
- properties:
- title:
- type: string
- value:
- type: string
- short:
- type: boolean
- image_url:
- type: string
- format: uri
- thumb_url:
- type: string
- format: uri
- footer:
- type: string
- footer_icon:
- type: string
- format: uri
- ts:
- type: number
- messages:
- hello:
- summary: First event received upon connection.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - hello
- connectionError:
- summary: Event received when a connection error happens.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - error
- error:
- type: object
- properties:
- code:
- type: number
- msg:
- type: string
- accountsChanged:
- summary: The list of accounts a user is signed into has changed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - accounts_changed
- botAdded:
- summary: A bot user was added.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - bot_added
- bot:
- type: object
- properties:
- id:
- type: string
- app_id:
- type: string
- name:
- type: string
- icons:
- type: object
- additionalProperties:
- type: string
- botChanged:
- summary: A bot user was changed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - bot_added
- bot:
- type: object
- properties:
- id:
- type: string
- app_id:
- type: string
- name:
- type: string
- icons:
- type: object
- additionalProperties:
- type: string
- channelArchive:
- summary: A channel was archived.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_archive
- channel:
- type: string
- user:
- type: string
- channelCreated:
- summary: A channel was created.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_created
- channel:
- type: object
- properties:
- id:
- type: string
- name:
- type: string
- created:
- type: number
- creator:
- type: string
- channelDeleted:
- summary: A channel was deleted.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_deleted
- channel:
- type: string
- channelHistoryChanged:
- summary: Bulk updates were made to a channel's history.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_history_changed
- latest:
- type: string
- ts:
- type: string
- event_ts:
- type: string
- channelJoined:
- summary: You joined a channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_joined
- channel:
- type: object
- properties:
- id:
- type: string
- name:
- type: string
- created:
- type: number
- creator:
- type: string
- channelLeft:
- summary: You left a channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_left
- channel:
- type: string
- channelMarked:
- summary: Your channel read marker was updated.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_marked
- channel:
- type: string
- ts:
- type: string
- channelRename:
- summary: A channel was renamed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_rename
- channel:
- type: object
- properties:
- id:
- type: string
- name:
- type: string
- created:
- type: number
- channelUnarchive:
- summary: A channel was unarchived.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - channel_unarchive
- channel:
- type: string
- user:
- type: string
- commandsChanged:
- summary: A slash command has been added or changed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - commands_changed
- event_ts:
- type: string
- dndUpdated:
- summary: Do not Disturb settings changed for the current user.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - dnd_updated
- user:
- type: string
- dnd_status:
- type: object
- properties:
- dnd_enabled:
- type: boolean
- next_dnd_start_ts:
- type: number
- next_dnd_end_ts:
- type: number
- snooze_enabled:
- type: boolean
- snooze_endtime:
- type: number
- dndUpdatedUser:
- summary: Do not Disturb settings changed for a member.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - dnd_updated_user
- user:
- type: string
- dnd_status:
- type: object
- properties:
- dnd_enabled:
- type: boolean
- next_dnd_start_ts:
- type: number
- next_dnd_end_ts:
- type: number
- emailDomainChanged:
- summary: The workspace email domain has changed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - email_domain_changed
- email_domain:
- type: string
- event_ts:
- type: string
- emojiRemoved:
- summary: A custom emoji has been removed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - emoji_changed
- subtype:
- type: string
- enum:
- - remove
- names:
- type: array
- items:
- type: string
- event_ts:
- type: string
- emojiAdded:
- summary: A custom emoji has been added.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - emoji_changed
- subtype:
- type: string
- enum:
- - add
- name:
- type: string
- value:
- type: string
- format: uri
- event_ts:
- type: string
- fileChange:
- summary: A file was changed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_change
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- fileCommentAdded:
- summary: A file comment was added.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_comment_added
- comment: {}
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- fileCommentDeleted:
- summary: A file comment was deleted.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_comment_deleted
- comment:
- type: string
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- fileCommentEdited:
- summary: A file comment was edited.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_comment_edited
- comment: {}
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- fileCreated:
- summary: A file was created.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_created
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- fileDeleted:
- summary: A file was deleted.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_deleted
- file_id:
- type: string
- event_ts:
- type: string
- filePublic:
- summary: A file was made public.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_public
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- fileShared:
- summary: A file was shared.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_shared
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- fileUnshared:
- summary: A file was unshared.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - file_unshared
- file_id:
- type: string
- file:
- type: object
- properties:
- id:
- type: string
- goodbye:
- summary: The server intends to close the connection soon.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - goodbye
- groupArchive:
- summary: A private channel was archived.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_archive
- channel:
- type: string
- groupClose:
- summary: You closed a private channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_close
- user:
- type: string
- channel:
- type: string
- groupHistoryChanged:
- summary: Bulk updates were made to a private channel's history.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_history_changed
- latest:
- type: string
- ts:
- type: string
- event_ts:
- type: string
- groupJoined:
- summary: You joined a private channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_joined
- channel:
- type: object
- properties:
- id:
- type: string
- name:
- type: string
- created:
- type: number
- creator:
- type: string
- groupLeft:
- summary: You left a private channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_left
- channel:
- type: string
- groupMarked:
- summary: A private channel read marker was updated.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_marked
- channel:
- type: string
- ts:
- type: string
- groupOpen:
- summary: You opened a private channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_open
- user:
- type: string
- channel:
- type: string
- groupRename:
- summary: A private channel was renamed.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_rename
- channel:
- type: object
- properties:
- id:
- type: string
- name:
- type: string
- created:
- type: number
- groupUnarchive:
- summary: A private channel was unarchived.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - group_unarchive
- channel:
- type: string
- user:
- type: string
- imClose:
- summary: You closed a DM.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - im_close
- channel:
- type: string
- user:
- type: string
- imCreated:
- summary: A DM was created.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - im_created
- channel:
- type: object
- properties:
- id:
- type: string
- name:
- type: string
- created:
- type: number
- creator:
- type: string
- user:
- type: string
- imMarked:
- summary: A direct message read marker was updated.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - im_marked
- channel:
- type: string
- ts:
- type: string
- imOpen:
- summary: You opened a DM.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - im_open
- channel:
- type: string
- user:
- type: string
- manualPresenceChange:
- summary: You manually updated your presence.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - manual_presence_change
- presence:
- type: string
- memberJoinedChannel:
- summary: A user joined a public or private channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - member_joined_channel
- user:
- type: string
- channel:
- type: string
- channel_type:
- type: string
- enum:
- - C
- - G
- team:
- type: string
- inviter:
- type: string
- memberLeftChannel:
- summary: A user left a public or private channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - member_left_channel
- user:
- type: string
- channel:
- type: string
- channel_type:
- type: string
- enum:
- - C
- - G
- team:
- type: string
- message:
- summary: A message was sent to a channel.
- payload:
- type: object
- properties:
- type:
- type: string
- enum:
- - message
- user:
- type: string
- channel:
- type: string
- text:
- type: string
- ts:
- type: string
- attachments:
- type: array
- items:
- $ref: '#/components/schemas/attachment'
- edited:
- type: object
- properties:
- user:
- type: string
- ts:
- type: string
- outgoingMessage:
- summary: A message was sent to a channel.
- payload:
- type: object
- properties:
- id:
- type: number
- type:
- type: string
- enum:
- - message
- channel:
- type: string
- text:
- type: string
\ No newline at end of file
diff --git a/apps/studio/src/examples/simple.yml b/apps/studio/src/examples/simple.yml
deleted file mode 100644
index 75572baf4..000000000
--- a/apps/studio/src/examples/simple.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-asyncapi: 3.0.0
-info:
- title: Account Service
- version: 1.0.0
- description: This service is in charge of processing user signups
-channels:
- userSignedup:
- address: user/signedup
- messages:
- UserSignedUp:
- $ref: '#/components/messages/UserSignedUp'
-operations:
- sendUserSignedup:
- action: send
- channel:
- $ref: '#/channels/userSignedup'
- messages:
- - $ref: '#/channels/userSignedup/messages/UserSignedUp'
-components:
- messages:
- UserSignedUp:
- payload:
- type: object
- properties:
- displayName:
- type: string
- description: Name of the user
- email:
- type: string
- format: email
- description: Email of the user
\ No newline at end of file
diff --git a/apps/studio/src/examples/streetlights-kafka.yml b/apps/studio/src/examples/streetlights-kafka.yml
deleted file mode 100644
index 0cbdc195d..000000000
--- a/apps/studio/src/examples/streetlights-kafka.yml
+++ /dev/null
@@ -1,206 +0,0 @@
-asyncapi: 3.0.0
-info:
- title: Streetlights Kafka API
- version: 1.0.0
- description: |-
- The Smartylighting Streetlights API allows you to remotely manage the city
- lights.
- ### Check out its awesome features:
-
- * Turn a specific streetlight on/off π
- * Dim a specific streetlight π
- * Receive real-time information about environmental lighting conditions π
- license:
- name: Apache 2.0
- url: 'https://www.apache.org/licenses/LICENSE-2.0'
-defaultContentType: application/json
-servers:
- scram-connections:
- host: 'test.mykafkacluster.org:18092'
- protocol: kafka-secure
- description: Test broker secured with scramSha256
- security:
- - $ref: '#/components/securitySchemes/saslScram'
- tags:
- - name: 'env:test-scram'
- description: >-
- This environment is meant for running internal tests through
- scramSha256
- - name: 'kind:remote'
- description: This server is a remote server. Not exposed by the application
- - name: 'visibility:private'
- description: This resource is private and only available to certain users
- mtls-connections:
- host: 'test.mykafkacluster.org:28092'
- protocol: kafka-secure
- description: Test broker secured with X509
- security:
- - $ref: '#/components/securitySchemes/certs'
- tags:
- - name: 'env:test-mtls'
- description: This environment is meant for running internal tests through mtls
- - name: 'kind:remote'
- description: This server is a remote server. Not exposed by the application
- - name: 'visibility:private'
- description: This resource is private and only available to certain users
-channels:
- lightingMeasured:
- address: 'smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured'
- messages:
- lightMeasured:
- $ref: '#/components/messages/lightMeasured'
- description: The topic on which measured values may be produced and consumed.
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightTurnOn:
- address: 'smartylighting.streetlights.1.0.action.{streetlightId}.turn.on'
- messages:
- turnOn:
- $ref: '#/components/messages/turnOnOff'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightTurnOff:
- address: 'smartylighting.streetlights.1.0.action.{streetlightId}.turn.off'
- messages:
- turnOff:
- $ref: '#/components/messages/turnOnOff'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightsDim:
- address: 'smartylighting.streetlights.1.0.action.{streetlightId}.dim'
- messages:
- dimLight:
- $ref: '#/components/messages/dimLight'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
-operations:
- receiveLightMeasurement:
- action: receive
- channel:
- $ref: '#/channels/lightingMeasured'
- summary: >-
- Inform about environmental lighting conditions of a particular
- streetlight.
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightingMeasured/messages/lightMeasured'
- turnOn:
- action: send
- channel:
- $ref: '#/channels/lightTurnOn'
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightTurnOn/messages/turnOn'
- turnOff:
- action: send
- channel:
- $ref: '#/channels/lightTurnOff'
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightTurnOff/messages/turnOff'
- dimLight:
- action: send
- channel:
- $ref: '#/channels/lightsDim'
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightsDim/messages/dimLight'
-components:
- messages:
- lightMeasured:
- name: lightMeasured
- title: Light measured
- summary: >-
- Inform about environmental lighting conditions of a particular
- streetlight.
- contentType: application/json
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/lightMeasuredPayload'
- turnOnOff:
- name: turnOnOff
- title: Turn on/off
- summary: Command a particular streetlight to turn the lights on or off.
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/turnOnOffPayload'
- dimLight:
- name: dimLight
- title: Dim light
- summary: Command a particular streetlight to dim the lights.
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/dimLightPayload'
- schemas:
- lightMeasuredPayload:
- type: object
- properties:
- lumens:
- type: integer
- minimum: 0
- description: Light intensity measured in lumens.
- sentAt:
- $ref: '#/components/schemas/sentAt'
- turnOnOffPayload:
- type: object
- properties:
- command:
- type: string
- enum:
- - 'on'
- - 'off'
- description: Whether to turn on or off the light.
- sentAt:
- $ref: '#/components/schemas/sentAt'
- dimLightPayload:
- type: object
- properties:
- percentage:
- type: integer
- description: Percentage to which the light should be dimmed to.
- minimum: 0
- maximum: 100
- sentAt:
- $ref: '#/components/schemas/sentAt'
- sentAt:
- type: string
- format: date-time
- description: Date and time when the message was sent.
- securitySchemes:
- saslScram:
- type: scramSha256
- description: Provide your username and password for SASL/SCRAM authentication
- certs:
- type: X509
- description: Download the certificate files from service provider
- parameters:
- streetlightId:
- description: The ID of the streetlight.
- messageTraits:
- commonHeaders:
- headers:
- type: object
- properties:
- my-app-header:
- type: integer
- minimum: 0
- maximum: 100
- operationTraits:
- kafka:
- bindings:
- kafka:
- clientId:
- type: string
- enum:
- - my-app-id
diff --git a/apps/studio/src/examples/streetlights-mqtt.yml b/apps/studio/src/examples/streetlights-mqtt.yml
deleted file mode 100644
index d608968f8..000000000
--- a/apps/studio/src/examples/streetlights-mqtt.yml
+++ /dev/null
@@ -1,260 +0,0 @@
-asyncapi: 3.0.0
-info:
- title: Streetlights MQTT API
- version: 1.0.0
- description: |-
- The Smartylighting Streetlights API allows you to remotely manage the city
- lights.
- ### Check out its awesome features:
-
- * Turn a specific streetlight on/off π
- * Dim a specific streetlight π
- * Receive real-time information about environmental lighting conditions π
- license:
- name: Apache 2.0
- url: 'https://www.apache.org/licenses/LICENSE-2.0'
-defaultContentType: application/json
-servers:
- production:
- host: 'test.mosquitto.org:{port}'
- protocol: mqtt
- description: Test broker
- variables:
- port:
- description: Secure connection (TLS) is available through port 8883.
- default: '1883'
- enum:
- - '1883'
- - '8883'
- security:
- - $ref: '#/components/securitySchemes/apiKey'
- - type: oauth2
- description: Flows to support OAuth 2.0
- flows:
- implicit:
- authorizationUrl: 'https://authserver.example/auth'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- password:
- tokenUrl: 'https://authserver.example/token'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- clientCredentials:
- tokenUrl: 'https://authserver.example/token'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- authorizationCode:
- authorizationUrl: 'https://authserver.example/auth'
- tokenUrl: 'https://authserver.example/token'
- refreshUrl: 'https://authserver.example/refresh'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- scopes:
- - 'streetlights:on'
- - 'streetlights:off'
- - 'streetlights:dim'
- - $ref: '#/components/securitySchemes/openIdConnectWellKnown'
- tags:
- - name: 'env:production'
- description: This environment is meant for production use case
- - name: 'kind:remote'
- description: This server is a remote server. Not exposed by the application
- - name: 'visibility:public'
- description: This resource is public and available to everyone
-channels:
- lightingMeasured:
- address: 'smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured'
- messages:
- lightMeasured:
- $ref: '#/components/messages/lightMeasured'
- description: The topic on which measured values may be produced and consumed.
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightTurnOn:
- address: 'smartylighting/streetlights/1/0/action/{streetlightId}/turn/on'
- messages:
- turnOn:
- $ref: '#/components/messages/turnOnOff'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightTurnOff:
- address: 'smartylighting/streetlights/1/0/action/{streetlightId}/turn/off'
- messages:
- turnOff:
- $ref: '#/components/messages/turnOnOff'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightsDim:
- address: 'smartylighting/streetlights/1/0/action/{streetlightId}/dim'
- messages:
- dimLight:
- $ref: '#/components/messages/dimLight'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
-operations:
- receiveLightMeasurement:
- action: receive
- channel:
- $ref: '#/channels/lightingMeasured'
- summary: >-
- Inform about environmental lighting conditions of a particular
- streetlight.
- traits:
- - $ref: '#/components/operationTraits/mqtt'
- messages:
- - $ref: '#/channels/lightingMeasured/messages/lightMeasured'
- turnOn:
- action: send
- channel:
- $ref: '#/channels/lightTurnOn'
- traits:
- - $ref: '#/components/operationTraits/mqtt'
- messages:
- - $ref: '#/channels/lightTurnOn/messages/turnOn'
- turnOff:
- action: send
- channel:
- $ref: '#/channels/lightTurnOff'
- traits:
- - $ref: '#/components/operationTraits/mqtt'
- messages:
- - $ref: '#/channels/lightTurnOff/messages/turnOff'
- dimLight:
- action: send
- channel:
- $ref: '#/channels/lightsDim'
- traits:
- - $ref: '#/components/operationTraits/mqtt'
- messages:
- - $ref: '#/channels/lightsDim/messages/dimLight'
-components:
- messages:
- lightMeasured:
- name: lightMeasured
- title: Light measured
- summary: >-
- Inform about environmental lighting conditions of a particular
- streetlight.
- contentType: application/json
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/lightMeasuredPayload'
- turnOnOff:
- name: turnOnOff
- title: Turn on/off
- summary: Command a particular streetlight to turn the lights on or off.
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/turnOnOffPayload'
- dimLight:
- name: dimLight
- title: Dim light
- summary: Command a particular streetlight to dim the lights.
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/dimLightPayload'
- schemas:
- lightMeasuredPayload:
- type: object
- properties:
- lumens:
- type: integer
- minimum: 0
- description: Light intensity measured in lumens.
- sentAt:
- $ref: '#/components/schemas/sentAt'
- turnOnOffPayload:
- type: object
- properties:
- command:
- type: string
- enum:
- - 'on'
- - 'off'
- description: Whether to turn on or off the light.
- sentAt:
- $ref: '#/components/schemas/sentAt'
- dimLightPayload:
- type: object
- properties:
- percentage:
- type: integer
- description: Percentage to which the light should be dimmed to.
- minimum: 0
- maximum: 100
- sentAt:
- $ref: '#/components/schemas/sentAt'
- sentAt:
- type: string
- format: date-time
- description: Date and time when the message was sent.
- securitySchemes:
- apiKey:
- type: apiKey
- in: user
- description: Provide your API key as the user and leave the password empty.
- supportedOauthFlows:
- type: oauth2
- description: Flows to support OAuth 2.0
- flows:
- implicit:
- authorizationUrl: 'https://authserver.example/auth'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- password:
- tokenUrl: 'https://authserver.example/token'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- clientCredentials:
- tokenUrl: 'https://authserver.example/token'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- authorizationCode:
- authorizationUrl: 'https://authserver.example/auth'
- tokenUrl: 'https://authserver.example/token'
- refreshUrl: 'https://authserver.example/refresh'
- availableScopes:
- 'streetlights:on': Ability to switch lights on
- 'streetlights:off': Ability to switch lights off
- 'streetlights:dim': Ability to dim the lights
- openIdConnectWellKnown:
- type: openIdConnect
- openIdConnectUrl: 'https://authserver.example/.well-known'
- parameters:
- streetlightId:
- description: The ID of the streetlight.
- messageTraits:
- commonHeaders:
- headers:
- type: object
- properties:
- my-app-header:
- type: integer
- minimum: 0
- maximum: 100
- operationTraits:
- mqtt:
- bindings:
- mqtt:
- qos: 1
diff --git a/apps/studio/src/examples/tutorials/invalid.yml b/apps/studio/src/examples/tutorials/invalid.yml
deleted file mode 100644
index aa9921099..000000000
--- a/apps/studio/src/examples/tutorials/invalid.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-# This invalid file exists solely for educational purposes, and if you come across it, here is the tutorial: https://www.asyncapi.com/docs/tutorials/studio-document-validation
-
-asyncapi: 3.0.0
-info:
- title: Streetlights API
- version: '1.0.0'
- description: |
- The Smartylighting Streetlights API allows you
- to remotely manage the city lights.
- license:
- name: Apache 2.0
- url: 'https://www.apache.org/licenses/LICENSE-2.0'
-
-servers:
- mosquitto:
- url: test.mosquitto.org
- protocol: mqtt
-
-channels:
- lightMeasured:
- address: 'light/measured'
- messages:
- lightMeasuredMessage:
- name: LightMeasured
- payload:
- type: object
- properties:
- id:
- type: integer
- minimum: true
- description: Id of the streetlight.
- lumens:
- type: integer
- minimum: 0
- description: Light intensity measured in lumens.
- sentAt:
- type: string
- format: date-time
- description: Date and time when the message was sent.
-
-operations:
- onLightMeasured:
- action: 'receive'
- summary: Inform about environmental lighting conditions for a particular streetlight.
- channel:
- $ref: '#/channels/lightMeasured'
diff --git a/apps/studio/src/examples/websocket-gemini.yml b/apps/studio/src/examples/websocket-gemini.yml
deleted file mode 100644
index 0528487e1..000000000
--- a/apps/studio/src/examples/websocket-gemini.yml
+++ /dev/null
@@ -1,305 +0,0 @@
-asyncapi: 3.0.0
-info:
- title: Gemini Market Data Websocket API
- version: 1.0.0
- description: |-
- Market data is a public API that streams all the market data on a given
- symbol.
-
-
- You can quickly play with the API using
- [websocat](https://github.com/vi/websocat#installation) like this:
-
- ```bash
-
- websocat wss://api.gemini.com/v1/marketdata/btcusd?heartbeat=true -S
-
- ```
- contact:
- name: Gemini
- url: 'https://www.gemini.com/'
- externalDocs:
- url: 'https://docs.sandbox.gemini.com/websocket-api/#market-data'
-servers:
- public:
- host: api.gemini.com
- protocol: wss
-channels:
- marketDataV1:
- address: '/v1/marketdata/{symbol}'
- messages:
- marketData:
- $ref: '#/components/messages/marketData'
- parameters:
- symbol:
- enum:
- - btcusd
- - ethbtc
- - ethusd
- - zecusd
- - zecbtc
- - zeceth
- - zecbch
- - zecltc
- - bchusd
- - bchbtc
- - bcheth
- - ltcusd
- - ltcbtc
- - ltceth
- - ltcbch
- - batusd
- - daiusd
- - linkusd
- - oxtusd
- - batbtc
- - linkbtc
- - oxtbtc
- - bateth
- - linketh
- - oxteth
- - ampusd
- - compusd
- - paxgusd
- - mkrusd
- - zrxusd
- - kncusd
- - manausd
- - storjusd
- - snxusd
- - crvusd
- - balusd
- - uniusd
- - renusd
- - umausd
- - yfiusd
- - btcdai
- - ethdai
- - aaveusd
- - filusd
- - btceur
- - btcgbp
- - etheur
- - ethgbp
- - btcsgd
- - ethsgd
- - sklusd
- - grtusd
- - bntusd
- - 1inchusd
- - enjusd
- - lrcusd
- - sandusd
- - cubeusd
- - lptusd
- - bondusd
- - maticusd
- - injusd
- - sushiusd
- description: |-
- Symbols are formatted as CCY1CCY2 where prices are in CCY2 and
- quantities are in CCY1. To read more click
- [here](https://docs.sandbox.gemini.com/websocket-api/#symbols-and-minimums).
- bindings:
- ws:
- bindingVersion: 0.1.0
- query:
- type: object
- description: |-
- The semantics of entry type filtering is:
-
-
- If any entry type is specified as true or false, all of them must be
- explicitly flagged true to show up in the response
-
- If no entry types filtering parameters are included in the url, then
- all entry types will appear in the response
-
-
- NOTE: top_of_book has no meaning and initial book events are empty
- when only trades is specified
- properties:
- heartbeat:
- type: boolean
- default: false
- description: |-
- Optionally add this parameter and set to true to receive a
- heartbeat every 5 seconds
- top_of_book:
- type: boolean
- default: false
- description: |-
- If absent or false, receive full order book depth; if present
- and true, receive top of book only. Only applies to bids and
- offers.
- bids:
- type: boolean
- default: true
- description: Include bids in change events
- offers:
- type: boolean
- default: true
- description: Include asks in change events
- trades:
- type: boolean
- default: true
- description: Include trade events
- auctions:
- type: boolean
- default: true
- description: Include auction events
-operations:
- sendMarketData:
- action: send
- channel:
- $ref: '#/channels/marketDataV1'
- summary: Receive market updates on a given symbol
- messages:
- - $ref: '#/channels/marketDataV1/messages/marketData'
-components:
- messages:
- marketData:
- summary: Message with marked data information.
- description: |-
- The initial response message will show the existing state of the order
- book. Subsequent messages will show all executed trades, as well as all
- other changes to the order book from orders placed or canceled.
- payload:
- $ref: '#/components/schemas/market'
- examples:
- - name: updateMessage
- summary: >-
- Example of an update message that contains a change in price
- information.
- payload:
- type: update
- eventId: 36902233362
- timestamp: '1619769673'
- timestampms: '1619769673527'
- socket_sequence: 661
- events:
- - type: change
- side: bid
- price: '54350.40'
- remaining: '0.002'
- delta: '0.002'
- reason: place
- - name: heartbeatMessage
- summary: Example of additional heartbeat message when you enable them.
- payload:
- type: heartbeat
- socket_sequence: 1656
- schemas:
- market:
- type: object
- oneOf:
- - $ref: '#/components/schemas/heartbeat'
- - $ref: '#/components/schemas/update'
- heartbeat:
- allOf:
- - properties:
- type:
- type: string
- const: heartbeat
- required:
- - type
- - $ref: '#/components/schemas/default'
- update:
- allOf:
- - properties:
- type:
- type: string
- const: update
- eventId:
- type: integer
- description: |-
- A monotonically increasing sequence number indicating when this
- change occurred. These numbers are persistent and consistent
- between market data connections.
- events:
- $ref: '#/components/schemas/events'
- timestamp:
- type: string
- format: date-time
- description: |-
- The timestamp in seconds for this group of events (included for
- compatibility reasons). We recommend using the timestampms field
- instead.
- timestampms:
- type: string
- format: time
- description: The timestamp in milliseconds for this group of events.
- required:
- - type
- - eventId
- - events
- - timestamp
- - timestampms
- - $ref: '#/components/schemas/default'
- default:
- type: object
- description: |-
- This object is always part of the payload. In case of type=heartbeat,
- these are the only fields.
- required:
- - type
- - socket_sequence
- properties:
- socket_sequence:
- type: integer
- description: |-
- zero-indexed monotonic increasing sequence number attached to each
- message sent - if there is a gap in this sequence, you have missed a
- message. If you choose to enable heartbeats, then heartbeat and
- update messages will share a single increasing sequence. See
- [Sequence
- Numbers](https://docs.sandbox.gemini.com/websocket-api/#sequence-numbers)
- for more information.
- events:
- type: array
- description: |-
- Either a change to the order book, or the indication that a trade has
- occurred.
- items:
- type: object
- additionalProperties: false
- properties:
- type:
- type: string
- enum:
- - trade
- - change
- - 'auction, block_trade'
- price:
- type: number
- multipleOf: 1
- description: The price of this order book entry.
- side:
- type: string
- enum:
- - bid
- - side
- reason:
- type: string
- enum:
- - place
- - trade
- - cancel
- - initial
- description: |-
- Indicates why the change has occurred. initial is for the initial
- response message, which will show the entire existing state of the
- order book.
- remaining:
- type: number
- multipleOf: 1
- description: |-
- The quantity remaining at that price level after this change
- occurred. May be zero if all orders at this price level have been
- filled or canceled.
- delta:
- type: number
- multipleOf: 1
- description: |-
- The quantity changed. May be negative, if an order is filled or
- canceled. For initial messages, delta will equal remaining.
diff --git a/apps/studio/src/helpers/debounce.ts b/apps/studio/src/helpers/debounce.ts
deleted file mode 100644
index 964861b87..000000000
--- a/apps/studio/src/helpers/debounce.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-export function debounce(func: (...args: any[]) => any, wait: number, immediate?: boolean) {
- let timeout: number | null;
-
- return function executedFunction(...args: any[]) {
- // @ts-ignore
- const context = this;
-
- const later = function() {
- timeout = null;
- if (!immediate) {
- func.apply(context, args);
- }
- };
-
- const callNow = immediate && !timeout;
-
- timeout && clearTimeout(timeout);
- timeout = setTimeout(later, wait) as unknown as number;
-
- if (callNow) {
- func.apply(context, args);
- }
- };
-}
diff --git a/apps/studio/src/helpers/index.ts b/apps/studio/src/helpers/index.ts
deleted file mode 100644
index 29cd16b41..000000000
--- a/apps/studio/src/helpers/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './debounce';
-export * from './isDeepEqual';
-export * from './useOutsideClickCallback';
diff --git a/apps/studio/src/helpers/isDeepEqual.ts b/apps/studio/src/helpers/isDeepEqual.ts
deleted file mode 100644
index e9530573b..000000000
--- a/apps/studio/src/helpers/isDeepEqual.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-function isObject(object: Record) {
- return object && typeof object === 'object';
-}
-
-export function isDeepEqual(object1: Record, object2: Record) {
- const objKeys1 = Object.keys(object1);
- const objKeys2 = Object.keys(object2);
-
- if (objKeys1.length !== objKeys2.length) {
- return false;
- }
-
- for (const key of objKeys1) {
- const value1 = object1[String(key)];
- const value2 = object2[String(key)];
-
- const isObjects = isObject(value1) && isObject(value2);
-
- if ((isObjects && !isDeepEqual(value1, value2)) ||
- (!isObjects && value1 !== value2)
- ) {
- return false;
- }
- }
- return true;
-}
diff --git a/apps/studio/src/helpers/useOutsideClickCallback.ts b/apps/studio/src/helpers/useOutsideClickCallback.ts
deleted file mode 100644
index cd145e9d8..000000000
--- a/apps/studio/src/helpers/useOutsideClickCallback.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { useEffect } from 'react';
-
-import type { MutableRefObject } from 'react';
-
-export function useOutsideClickCallback(ref: MutableRefObject, callback: () => void) {
- useEffect(() => {
- function handleClickOutside(event: MouseEvent) {
- if (ref.current && !ref.current.contains(event.target as any)) {
- callback();
- }
- }
-
- document.addEventListener('mousedown', handleClickOutside);
- return () => {
- document.removeEventListener('mousedown', handleClickOutside);
- };
- }, [ref]);
-}
\ No newline at end of file
diff --git a/apps/studio/src/index.tsx b/apps/studio/src/index.tsx
deleted file mode 100644
index ecc596a34..000000000
--- a/apps/studio/src/index.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { StrictMode } from 'react';
-import { createRoot } from 'react-dom/client';
-import { Provider as ModalsProvider } from '@ebay/nice-modal-react';
-
-import { createServices, ServicesProvider } from './services';
-import { App } from './App';
-
-import 'tippy.js/dist/tippy.css';
-import 'tippy.js/animations/shift-away.css';
-import '@asyncapi/react-component/styles/default.min.css';
-import 'reactflow/dist/style.css';
-import './tailwind.css';
-import './main.css';
-
-function configureMonacoEnvironment() {
- window.MonacoEnvironment = {
- getWorker(_, label) {
- switch (label) {
- case 'editorWorkerService':
- return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url));
- case 'json':
- return new Worker(
- new URL('monaco-editor/esm/vs/language/json/json.worker', import.meta.url),
- );
- case 'yaml':
- case 'yml':
- return new Worker(new URL('monaco-yaml/yaml.worker', import.meta.url));
- default:
- throw new Error(`Unknown worker ${label}`);
- }
- },
- };
-}
-
-async function bootstrap() {
- configureMonacoEnvironment();
- const services = await createServices();
-
- const root = createRoot(
- document.getElementById('root') as HTMLElement,
- );
-
- root.render(
-
-
-
-
-
-
-
- );
-}
-
-bootstrap().catch(console.error);
diff --git a/apps/studio/src/main.css b/apps/studio/src/main.css
deleted file mode 100644
index 9dd4ac4f0..000000000
--- a/apps/studio/src/main.css
+++ /dev/null
@@ -1,115 +0,0 @@
-/** Preloader */
-#preloader {
- position: fixed;
- left: 0;
- top: 0;
- bottom: 0;
- right: 0;
- z-index: 10000;
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 20px;
- background: #1f2937;
- color: #ffffff;
- transition: .3s all ease;
-}
-
-#preloader.loaded {
- opacity: 0;
- visibility: hidden;
-}
-
-.rotating-wheel {
- width: 32px;
- height: 32px;
- margin: 0 auto;
- border: 3px solid #ec4899;
- border-radius: 50%;
- border-left-color: transparent;
- border-bottom-color: transparent;
- animation: rotating-spin .88s infinite linear;
-}
-
-@keyframes rotating-spin {
- 100% {
- transform: rotate(360deg);
- }
-}
-
-/** Resizer */
-.Resizer {
- background: #374251;
- z-index: 1;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- -moz-background-clip: padding;
- -webkit-background-clip: padding;
- background-clip: padding-box;
-}
-
-.Resizer:hover {
- -webkit-transition: all 2s ease;
- transition: all 2s ease;
-}
-
-.Resizer.horizontal {
- height: 11px;
- margin: -5px 0;
- border-top: 5px solid rgba(255, 255, 255, 0);
- border-bottom: 5px solid rgba(255, 255, 255, 0);
- cursor: row-resize;
- width: 100%;
-}
-
-.Resizer.horizontal:hover {
- border-top: 5px solid rgba(0, 0, 0, 0.5);
- border-bottom: 5px solid rgba(0, 0, 0, 0.5);
-}
-
-.Resizer.vertical {
- width: 11px;
- margin: 0 -5px;
- border-left: 5px solid rgba(255, 255, 255, 0);
- border-right: 5px solid rgba(255, 255, 255, 0);
- cursor: col-resize;
-}
-
-.Resizer.vertical:hover {
- border-left: 5px solid rgba(0, 0, 0, 0.5);
- border-right: 5px solid rgba(0, 0, 0, 0.5);
-}
-
-.Resizer.disabled {
- cursor: not-allowed;
-}
-
-.Resizer.disabled:hover {
- border-color: transparent;
-}
-
-/** Monaco editor */
-.diagnostic-warning {
- background: rgba(245, 158, 11);
- width: 3px !important;
-}
-
-.diagnostic-information {
- background: rgba(59, 130, 246);
- width: 3px !important;
-}
-
-.diagnostic-hint {
- background: rgba(16, 185, 129);
- width: 3px !important;
-}
-
-/** Tippy.js **/
-.tippy-box[data-placement^="bottom"] > .tippy-arrow:before {
- border-bottom-color: rgba(17, 24, 39) !important;
-}
-
-.tippy-box[data-placement^="right"] > .tippy-arrow:before {
- border-right-color: rgba(17, 24, 39) !important;
-}
\ No newline at end of file
diff --git a/apps/studio/src/react-app-env.d.ts b/apps/studio/src/react-app-env.d.ts
deleted file mode 100644
index f4ce82809..000000000
--- a/apps/studio/src/react-app-env.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-///
-
-import type * as monacoAPI from 'monaco-editor/esm/vs/editor/editor.api';
-import type { AsyncAPIDocumentInterface, ParseOutput } from '@asyncapi/parser/cjs';
-
-declare global {
- interface Window {
- // needed by monaco YAML plugin and Studio
- monaco: typeof monacoAPI;
- Editor: monacoAPI.editor.IStandaloneCodeEditor;
- MonacoEnvironment: monacoAPI.Environment | undefined;
- ParsedSpec?: AsyncAPIDocumentInterface;
- ParsedExtras?: ParseOutput['extras'];
- }
-}
diff --git a/apps/studio/src/services/abstract.service.ts b/apps/studio/src/services/abstract.service.ts
deleted file mode 100644
index 048194797..000000000
--- a/apps/studio/src/services/abstract.service.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { Services } from './index';
-
-export abstract class AbstractService {
- constructor(
- protected readonly svcs: Services = {} as Services,
- ) {}
-
- public onInit(): void | Promise {}
- public async afterAppInit(): Promise {}
-}
diff --git a/apps/studio/src/services/app.service.ts b/apps/studio/src/services/app.service.ts
deleted file mode 100644
index bc2dbd8b2..000000000
--- a/apps/studio/src/services/app.service.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import { show } from '@ebay/nice-modal-react';
-
-import { RedirectedModal } from '../components/Modals';
-
-import { appState, filesState } from '../state';
-
-export class ApplicationService extends AbstractService {
- override async onInit() {
- // subscribe to state to hide preloader
- this.hidePreloader();
-
- const { readOnly, url, base64 } =
- this.svcs.navigationSvc.getUrlParameters();
- // readOnly state should be only set to true when someone pass also url or base64 parameter
- const isStrictReadonly = Boolean(readOnly && (url || base64));
-
- let error: any;
- try {
- await this.fetchResource(url, base64);
- } catch (err) {
- error = err;
- console.error(err);
- }
-
- if (error) {
- appState.setState({ initErrors: [error] });
- }
-
- if (isStrictReadonly && !error) {
- appState.setState({
- readOnly,
- initialized: true,
- });
- }
- }
-
- public async afterAppInit() {
- const { readOnly, url, base64, redirectedFrom } =
- this.svcs.navigationSvc.getUrlParameters();
- const isStrictReadonly = Boolean(readOnly && (url || base64));
-
- // show RedirectedModal modal if the redirectedFrom is set (only when readOnly state is set to false)
- if (!isStrictReadonly && redirectedFrom) {
- show(RedirectedModal);
- }
- }
-
- private async fetchResource(url: string | null, base64: string | null) {
- if (!url && !base64) {
- return;
- }
-
- const { updateFile } = filesState.getState();
- let content = '';
- if (url) {
- content = await fetch(url).then((res) => res.text());
- } else if (base64) {
- content = this.svcs.formatSvc.decodeBase64(base64);
- }
-
- const language = this.svcs.formatSvc.retrieveLangauge(content);
- const source = url || undefined;
- updateFile('asyncapi', {
- content,
- language,
- source,
- from: url ? 'url' : 'base64',
- });
- await this.svcs.parserSvc.parse('asyncapi', content, { source });
- }
-
- private hidePreloader() {
- const unsunscribe = appState.subscribe((state, prevState) => {
- if (!prevState.initialized && state.initialized) {
- const preloader = document.getElementById('preloader');
- if (preloader) {
- preloader.classList.add('loaded');
- setTimeout(() => {
- preloader.remove();
- }, 350);
- unsunscribe();
- }
- }
- });
- }
-}
diff --git a/apps/studio/src/services/converter.service.ts b/apps/studio/src/services/converter.service.ts
deleted file mode 100644
index 5b9b5790a..000000000
--- a/apps/studio/src/services/converter.service.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import { convert } from '@asyncapi/converter';
-
-import type { AsyncAPIConvertVersion, ConvertOptions } from '@asyncapi/converter';
-
-export class ConverterService extends AbstractService {
- async convert(
- spec: string,
- version?: AsyncAPIConvertVersion,
- options?: ConvertOptions,
- ): Promise {
- version = version || this.svcs.specificationSvc.latestVersion;
-
- try {
- const converted = convert(spec, version, options);
- if (typeof converted === 'object') {
- return JSON.stringify(converted, undefined, 2);
- }
- return converted;
- } catch (err) {
- console.error(err);
- throw err;
- }
- }
-}
\ No newline at end of file
diff --git a/apps/studio/src/services/editor.service.tsx b/apps/studio/src/services/editor.service.tsx
deleted file mode 100644
index 6b46d896e..000000000
--- a/apps/studio/src/services/editor.service.tsx
+++ /dev/null
@@ -1,365 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import { KeyMod, KeyCode } from 'monaco-editor/esm/vs/editor/editor.api';
-import { DiagnosticSeverity } from '@asyncapi/parser/cjs';
-import { Range, MarkerSeverity } from 'monaco-editor/esm/vs/editor/editor.api';
-import toast from 'react-hot-toast';
-import fileDownload from 'js-file-download';
-
-import { appState, documentsState, filesState, settingsState } from '../state';
-
-import type * as monacoAPI from 'monaco-editor/esm/vs/editor/editor.api';
-import type { Diagnostic } from '@asyncapi/parser/cjs';
-import type { AsyncAPIConvertVersion } from '@asyncapi/converter';
-import type { File } from '../state/files.state';
-
-export interface UpdateState {
- content: string;
- updateModel?: boolean;
- sendToServer?: boolean;
- file?: Partial;
-}
-
-export class EditorService extends AbstractService {
- private created = false;
- private decorations: Map = new Map();
- private instance: monacoAPI.editor.IStandaloneCodeEditor | undefined;
-
- override onInit() {
- this.subcribeToDocuments();
- }
-
- async onDidCreate(editor: monacoAPI.editor.IStandaloneCodeEditor) {
- if (this.created) {
- return;
- }
- this.created = true;
- this.instance = editor;
-
- // parse on first run - only when document is undefined
- const document = documentsState.getState().documents.asyncapi;
- if (!document) {
- await this.svcs.parserSvc.parse('asyncapi', editor.getValue());
- } else {
- this.applyMarkersAndDecorations(document.diagnostics.filtered);
- }
-
- // apply save command
- editor.addCommand(
- KeyMod.CtrlCmd | KeyCode.KeyS,
- () => this.saveToLocalStorage(),
- );
-
- appState.setState({ initialized: true });
- }
-
- get editor(): monacoAPI.editor.IStandaloneCodeEditor | undefined {
- return this.instance;
- }
-
- get value(): string {
- return this.editor?.getModel()?.getValue() as string;
- }
-
- updateState({
- content,
- updateModel = false,
- sendToServer = true,
- file = {},
- }: UpdateState) {
- const currentContent = filesState.getState().files['asyncapi']?.content;
- if (currentContent === content || typeof content !== 'string') {
- return;
- }
-
- const language = file.language || this.svcs.formatSvc.retrieveLangauge(content);
- if (!language) {
- return;
- }
-
- if (sendToServer) {
- this.svcs.socketClientSvc.send('file:update', { code: content });
- }
-
- if (updateModel && this.editor) {
- const model = this.editor.getModel();
- if (model) {
- model.setValue(content);
- }
- }
-
- const { updateFile } = filesState.getState();
- updateFile('asyncapi', {
- language,
- content,
- modified: this.getFromLocalStorage() !== content,
- ...file,
- });
- }
-
- async convertSpec(version?: AsyncAPIConvertVersion | string) {
- const converted = await this.svcs.converterSvc.convert(this.value, version as AsyncAPIConvertVersion);
- this.updateState({ content: converted, updateModel: true });
- }
-
- async importFromURL(url: string): Promise {
- if (url) {
- return fetch(url)
- .then(res => res.text())
- .then(async text => {
- this.updateState({
- content: text,
- updateModel: true,
- file: {
- source: url,
- from: 'url'
- },
- });
- })
- .catch(err => {
- console.error(err);
- throw err;
- });
- }
- }
-
- async importFile(files: FileList | null) {
- if (files === null || files?.length !== 1) {
- return;
- }
- const file = files.item(0);
- if (!file) {
- return;
- }
-
- // Check if file is valid (only JSON and YAML are allowed currently) ----Change afterwards as per the requirement
- if (
- file.type !== 'application/json' &&
- file.type !== 'application/x-yaml' &&
- file.type !== 'application/yaml'
- ) {
- throw new Error('Invalid file type');
- }
-
- const fileReader = new FileReader();
- fileReader.onload = fileLoadedEvent => {
- const content = fileLoadedEvent.target?.result;
- this.updateState({ content: String(content), updateModel: true });
- };
- fileReader.readAsText(file, 'UTF-8');
- }
-
- async importBase64(content: string) {
- try {
- const decoded = this.svcs.formatSvc.decodeBase64(content);
- this.updateState({
- content: String(decoded),
- updateModel: true,
- file: {
- from: 'base64',
- source: undefined,
- },
- });
- } catch (err) {
- console.error(err);
- throw err;
- }
- }
-
- async exportAsBase64() {
- try {
- const file = filesState.getState().files['asyncapi'];
- return this.svcs.formatSvc.encodeBase64(file.content);
- } catch (err) {
- console.error(err);
- throw err;
- }
- }
-
- async convertToYaml() {
- try {
- const yamlContent = this.svcs.formatSvc.convertToYaml(this.value);
- if (yamlContent) {
- this.updateState({
- content: yamlContent,
- updateModel: true,
- file: {
- language: 'yaml',
- }
- });
- }
- } catch (err) {
- console.error(err);
- throw err;
- }
- }
-
- async convertToJSON() {
- try {
- const jsonContent = this.svcs.formatSvc.convertToJSON(this.value);
- if (jsonContent) {
- this.updateState({
- content: jsonContent,
- updateModel: true,
- file: {
- language: 'json',
- }
- });
- }
- } catch (err) {
- console.error(err);
- throw err;
- }
- }
-
- async saveAsYaml() {
- try {
- const yamlContent = this.svcs.formatSvc.convertToYaml(this.value);
- if (yamlContent) {
- this.downloadFile(yamlContent, `${this.fileName}.yaml`);
- }
- } catch (err) {
- console.error(err);
- throw err;
- }
- }
-
- async saveAsJSON() {
- try {
- const jsonContent = this.svcs.formatSvc.convertToJSON(this.value);
- if (jsonContent) {
- this.downloadFile(jsonContent, `${this.fileName}.json`);
- }
- } catch (err) {
- console.error(err);
- throw err;
- }
- }
-
- saveToLocalStorage(editorValue?: string, notify = true) {
- editorValue = editorValue || this.value;
- localStorage.setItem('document', editorValue);
-
- const { updateFile } = filesState.getState();
- updateFile('asyncapi', {
- from: 'storage',
- source: undefined,
- modified: false,
- });
-
- if (notify) {
- if (settingsState.getState().editor.autoSaving) {
- toast.success(
-
-
- Studio is currently saving your work automatically πͺ
-
-
,
- );
- } else {
- toast.success(
-
-
- Document succesfully saved to the local storage!
-
-
,
- );
- }
- }
- }
-
- getFromLocalStorage() {
- return localStorage.getItem('document');
- }
-
- private applyMarkersAndDecorations(diagnostics: Diagnostic[] = []) {
- const editor = this.editor;
- const model = editor?.getModel();
- const monaco = this.svcs.monacoSvc.monaco;
-
- if (!editor || !model || !monaco) {
- return;
- }
-
- const { markers, decorations } = this.createMarkersAndDecorations(diagnostics);
- monaco.editor.setModelMarkers(model, 'asyncapi', markers);
- let oldDecorations = this.decorations.get('asyncapi') || [];
- oldDecorations = editor.deltaDecorations(oldDecorations, decorations);
- this.decorations.set('asyncapi', oldDecorations);
- }
-
- createMarkersAndDecorations(diagnostics: Diagnostic[] = []) {
- const newDecorations: monacoAPI.editor.IModelDecoration[] = [];
- const newMarkers: monacoAPI.editor.IMarkerData[] = [];
-
- diagnostics.forEach(diagnostic => {
- const { message, range, severity } = diagnostic;
-
- if (severity !== DiagnosticSeverity.Error) {
- newDecorations.push({
- id: 'asyncapi',
- ownerId: 0,
- range: new Range(
- range.start.line + 1,
- range.start.character + 1,
- range.end.line + 1,
- range.end.character + 1
- ),
- options: {
- glyphMarginClassName: this.getSeverityClassName(severity),
- glyphMarginHoverMessage: { value: message },
- },
- });
- return;
- }
-
- newMarkers.push({
- startLineNumber: range.start.line + 1,
- startColumn: range.start.character + 1,
- endLineNumber: range.end.line + 1,
- endColumn: range.end.character + 1,
- severity: this.getSeverity(severity),
- message,
- });
- });
-
- return { decorations: newDecorations, markers: newMarkers };
- }
-
- private getSeverity(severity: DiagnosticSeverity): monacoAPI.MarkerSeverity {
- switch (severity) {
- case DiagnosticSeverity.Error: return MarkerSeverity.Error;
- case DiagnosticSeverity.Warning: return MarkerSeverity.Warning;
- case DiagnosticSeverity.Information: return MarkerSeverity.Info;
- case DiagnosticSeverity.Hint: return MarkerSeverity.Hint;
- default: return MarkerSeverity.Error;
- }
- }
-
- private getSeverityClassName(severity: DiagnosticSeverity): string {
- switch (severity) {
- case DiagnosticSeverity.Warning: return 'diagnostic-warning';
- case DiagnosticSeverity.Information: return 'diagnostic-information';
- case DiagnosticSeverity.Hint: return 'diagnostic-hint';
- default: return 'diagnostic-warning';
- }
- }
-
- private fileName = 'asyncapi';
- private downloadFile(content: string, fileName: string) {
- return fileDownload(content, fileName);
- }
-
- private subcribeToDocuments() {
- documentsState.subscribe((state, prevState) => {
- const newDocuments = state.documents;
- const oldDocuments = prevState.documents;
-
- Object.entries(newDocuments).forEach(([uri, document]) => {
- const oldDocument = oldDocuments[String(uri)];
- if (document === oldDocument) return;
- this.applyMarkersAndDecorations(document.diagnostics.filtered);
- });
- });
- }
-}
diff --git a/apps/studio/src/services/format.service.ts b/apps/studio/src/services/format.service.ts
deleted file mode 100644
index f0341e479..000000000
--- a/apps/studio/src/services/format.service.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import { encode, decode } from 'js-base64';
-import YAML from 'js-yaml';
-
-export class FormatService extends AbstractService {
- convertToYaml(spec: string) {
- try {
- // Editor content -> JS object -> YAML string
- const jsonContent = YAML.load(spec);
- return YAML.dump(jsonContent);
- } catch (err) {
- console.error(err);
- }
- }
-
- convertToJSON(spec: string) {
- try {
- // JSON or YAML String -> JS object
- const jsonContent = YAML.load(spec);
- // JS Object -> pretty JSON string
- return JSON.stringify(jsonContent, null, 2);
- } catch (err) {
- console.error(err);
- }
- }
-
- encodeBase64(content: string) {
- return encode(content);
- }
-
- decodeBase64(content: string) {
- return decode(content);
- }
-
- retrieveLangauge(content: string) {
- if (content.trimStart()[0] === '{') {
- return 'json';
- }
- return 'yaml';
- }
-}
diff --git a/apps/studio/src/services/index.ts b/apps/studio/src/services/index.ts
deleted file mode 100644
index 3b1cce9e4..000000000
--- a/apps/studio/src/services/index.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { createContext, useContext } from 'react';
-
-import { ApplicationService } from './app.service';
-import { ConverterService } from './converter.service';
-import { EditorService } from './editor.service';
-import { FormatService } from './format.service';
-import { MonacoService } from './monaco.service';
-import { NavigationService } from './navigation.service';
-import { ParserService } from './parser.service';
-import { ServerAPIService } from './server-api.service';
-import { SettingsService } from './settings.service';
-import { SocketClient } from './socket-client.service';
-import { SpecificationService } from './specification.service';
-
-export type Services = {
- appSvc: ApplicationService;
- converterSvc: ConverterService;
- editorSvc: EditorService;
- formatSvc: FormatService;
- monacoSvc: MonacoService;
- navigationSvc: NavigationService;
- parserSvc: ParserService;
- serverAPISvc: ServerAPIService;
- settingsSvc: SettingsService;
- socketClientSvc: SocketClient;
- specificationSvc: SpecificationService;
-}
-
-const servicesCtx = createContext({} as Services);
-
-export function useServices() {
- return useContext(servicesCtx);
-}
-
-export const ServicesProvider = servicesCtx.Provider;
-
-export async function createServices() {
- const services: Services = {} as Services;
-
- services.parserSvc = new ParserService(services);
- services.appSvc = new ApplicationService(services);
- services.converterSvc = new ConverterService(services);
- services.editorSvc = new EditorService(services);
- services.formatSvc = new FormatService(services);
- services.monacoSvc = new MonacoService(services);
- services.navigationSvc = new NavigationService(services);
- services.serverAPISvc = new ServerAPIService(services);
- services.settingsSvc = new SettingsService(services);
- services.socketClientSvc = new SocketClient(services);
- services.specificationSvc = new SpecificationService(services);
-
- for (const service in services) {
- await services[service as keyof Services].onInit();
- }
-
- return services;
-}
-
-export async function afterAppInit(services: Services) {
- for (const service in services) {
- await services[service as keyof Services].afterAppInit();
- }
-}
diff --git a/apps/studio/src/services/monaco.service.ts b/apps/studio/src/services/monaco.service.ts
deleted file mode 100644
index b83536fdf..000000000
--- a/apps/studio/src/services/monaco.service.ts
+++ /dev/null
@@ -1,186 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import { loader } from '@monaco-editor/react';
-import { setDiagnosticsOptions } from 'monaco-yaml';
-import YAML from 'js-yaml';
-
-import { documentsState, filesState } from '../state';
-
-import type * as monacoAPI from 'monaco-editor/esm/vs/editor/editor.api';
-import type { DiagnosticsOptions as YAMLDiagnosticsOptions } from 'monaco-yaml';
-import type { SpecVersions } from '../types';
-import type { JSONSchema7 } from 'json-schema';
-
-export class MonacoService extends AbstractService {
- private jsonSchemaSpecs: Map = new Map();
- private jsonSchemaDefinitions: monacoAPI.languages.json.DiagnosticsOptions['schemas'] = [];
- private actualVersion = 'X.X.X';
- private monacoInstance!: typeof monacoAPI;
-
- override async onInit() {
- // load monaco instance
- await this.loadMonaco();
- // set monaco theme
- this.setMonacoTheme();
- // prepare JSON Schema specs and definitions for JSON/YAML language config
- this.prepareJSONSchemas();
- // load initial language config (for json and yaml)
- this.setLanguageConfig(this.svcs.specificationSvc.latestVersion);
- // subscribe to document to update JSON/YAML language config
- this.subcribeToDocuments();
- }
-
- get monaco() {
- return this.monacoInstance;
- }
-
- updateLanguageConfig(version: SpecVersions = this.svcs.specificationSvc.latestVersion) {
- if (version === this.actualVersion) {
- return;
- }
- this.setLanguageConfig(version);
- this.actualVersion = version;
- }
-
- private setLanguageConfig(version: SpecVersions = this.svcs.specificationSvc.latestVersion) {
- if (!this.monaco) {
- return;
- }
- const options = this.prepareLanguageConfig(version);
-
- // json
- const json = this.monaco.languages.json;
- if (json && json.jsonDefaults) {
- json.jsonDefaults.setDiagnosticsOptions(options);
- }
-
- // yaml
- setDiagnosticsOptions(options as YAMLDiagnosticsOptions);
- }
-
- private prepareLanguageConfig(
- version: SpecVersions,
- ): monacoAPI.languages.json.DiagnosticsOptions {
- const spec = this.jsonSchemaSpecs.get(version);
-
- return {
- enableSchemaRequest: false,
- hover: true,
- completion: true,
- validate: true,
- format: true,
- schemas: [
- {
- uri: spec.$id, // id of the AsyncAPI spec schema
- fileMatch: ['*'], // associate with all models
- schema: spec,
- },
- ...(this.jsonSchemaDefinitions || []),
- ],
- } as any;
- }
-
- private async loadMonaco() {
- // in test environment we don't need monaco loaded
- if (process.env.NODE_ENV === 'test') {
- return;
- }
-
- const monaco = this.monacoInstance = await import('monaco-editor');
- loader.config({ monaco });
- }
-
- private setMonacoTheme() {
- if (!this.monaco) {
- return;
- }
-
- this.monaco.editor.defineTheme('asyncapi-theme', {
- base: 'vs-dark',
- inherit: true,
- colors: {
- 'editor.background': '#252f3f',
- 'editor.lineHighlightBackground': '#1f2a37',
- },
- rules: [{ token: '', background: '#252f3f' }],
- });
- }
-
- private prepareJSONSchemas() {
- const uris: string[] = [];
- Object.entries(this.svcs.specificationSvc.specs).forEach(([version, spec]) => {
- this.serializeSpec(spec, version, uris);
- });
- }
-
- private serializeSpec(spec: JSONSchema7, version: string, uris: string[]) {
- // copy whole spec
- const copiedSpec = this.copySpecification(spec);
-
- // serialize definitions
- const definitions = Object.entries(copiedSpec.definitions || {}).map(([uri, schema]) => {
- if (uri === 'http://json-schema.org/draft-07/schema') {
- uri = 'https://json-schema.org/draft-07/schema';
- }
-
- return {
- uri,
- schema,
- };
- });
- delete copiedSpec.definitions;
-
- // save spec to map
- this.jsonSchemaSpecs.set(version, copiedSpec);
-
- // save definitions
- definitions.forEach(definition => {
- if (uris.includes(definition.uri)) {
- return;
- }
-
- uris.push(definition.uri);
- if (Array.isArray(this.jsonSchemaDefinitions)) {
- this.jsonSchemaDefinitions.push(definition);
- }
- });
- }
-
- private copySpecification(spec: JSONSchema7): JSONSchema7 {
- return JSON.parse(JSON.stringify(spec, (_, value) => {
- if (
- value === 'http://json-schema.org/draft-07/schema#' ||
- value === 'http://json-schema.org/draft-07/schema'
- ) {
- return 'https://json-schema.org/draft-07/schema';
- }
- return value;
- })) as JSONSchema7;
- }
-
- private subcribeToDocuments() {
- documentsState.subscribe((state, prevState) => {
- const newDocuments = state.documents;
- const oldDocuments = prevState.documents;
-
- Object.entries(newDocuments).forEach(([uri, document]) => {
- const oldDocument = oldDocuments[String(uri)];
- if (document === oldDocument) return;
- const version = document.document?.version();
- if (version) {
- this.updateLanguageConfig(version as SpecVersions);
- } else {
- try {
- const file = filesState.getState().files['asyncapi'];
- if (file) {
- const version = (YAML.load(file.content) as { asyncapi: SpecVersions }).asyncapi;
- this.svcs.monacoSvc.updateLanguageConfig(version);
- }
- } catch (e: any) {
- // intentional
- }
- }
- });
- });
- }
-}
diff --git a/apps/studio/src/services/navigation.service.ts b/apps/studio/src/services/navigation.service.ts
deleted file mode 100644
index b0180e935..000000000
--- a/apps/studio/src/services/navigation.service.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import type React from 'react';
-
-export class NavigationService extends AbstractService {
- override async afterAppInit() {
- try {
- await this.scrollToHash();
- window.dispatchEvent(new HashChangeEvent('hashchange'));
- } catch (err: any) {
- console.error(err);
- }
- }
-
- getUrlParameters() {
- const urlParams = new URLSearchParams(window.location.search);
- return {
- url: urlParams.get('url') || urlParams.get('load'),
- base64: urlParams.get('base64'),
- readOnly: urlParams.get('readOnly') === 'true' || urlParams.get('readOnly') === '',
- liveServer: urlParams.get('liveServer'),
- redirectedFrom: urlParams.get('redirectedFrom'),
- };
- }
-
- async scrollTo(
- jsonPointer: string | Array,
- hash: string,
- ) {
- try {
- const doc = this.svcs.editorSvc;
- const methodType = doc.value.startsWith('asyncapi') ? 'getRangeForYamlPath' : 'getRangeForJsonPath';
- const range = this.svcs.parserSvc[methodType]('asyncapi', jsonPointer);
-
- if (range) {
- await this.scrollToEditorLine(range.start.line+1);
- }
-
- await this.scrollToHash(hash);
- this.emitHashChangeEvent(hash);
- } catch (e) {
- console.error(e);
- }
- }
-
- async scrollToHash(hash?: string) {
- try {
- const sanitizedHash = this.sanitizeHash(hash);
- if (!sanitizedHash) {
- return;
- }
-
- const items = document.querySelectorAll(`#${sanitizedHash}`);
- if (items.length) {
- const element = items[0];
- typeof element.scrollIntoView === 'function' &&
- element.scrollIntoView();
- }
- } catch (err) {
- console.error(err);
- }
- }
-
- async scrollToEditorLine(line: number, character = 1) {
- try {
- const editor = this.svcs.editorSvc.editor;
- if (editor) {
- editor.revealLineInCenter(line);
- editor.setPosition({ lineNumber: line, column: character });
- }
- } catch (err) {
- console.error(err);
- }
- }
-
- highlightVisualiserNode(nodeId: string, setState: React.Dispatch>) {
- function hashChanged() {
- if (location.hash.startsWith(nodeId)) {
- setState(true);
- setTimeout(() => {
- setState(false);
- }, 1000);
- }
- }
-
- window.addEventListener('hashchange', hashChanged);
- return () => {
- window.removeEventListener('hashchange', hashChanged);
- };
- }
-
- private sanitizeHash(hash?: string): string | undefined {
- hash = hash || window.location.hash.substring(1);
- try {
- const escapedHash = CSS.escape(hash);
- return escapedHash.startsWith('#') ? hash.substring(1) : escapedHash;
- } catch (err: any) {
- return;
- }
- }
-
- private emitHashChangeEvent(hash: string) {
- hash = hash.startsWith('#') ? hash : `#${hash}`;
- window.history.pushState({}, '', hash);
- window.dispatchEvent(new HashChangeEvent('hashchange'));
- }
-}
diff --git a/apps/studio/src/services/parser.service.ts b/apps/studio/src/services/parser.service.ts
deleted file mode 100644
index 4ade21f36..000000000
--- a/apps/studio/src/services/parser.service.ts
+++ /dev/null
@@ -1,196 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import { Parser, DiagnosticSeverity } from '@asyncapi/parser/cjs';
-import { OpenAPISchemaParser } from '@asyncapi/openapi-schema-parser';
-import { AvroSchemaParser } from '@asyncapi/avro-schema-parser';
-import { ProtoBuffSchemaParser } from '@asyncapi/protobuf-schema-parser';
-import { untilde } from '@asyncapi/parser/cjs/utils';
-
-import { isDeepEqual } from '../helpers';
-import { filesState, documentsState, settingsState } from '../state';
-
-import type { Diagnostic, ParseOptions } from '@asyncapi/parser/cjs';
-import type { DocumentDiagnostics } from '../state/documents.state';
-import { SchemaParser } from '@asyncapi/parser';
-import { getLocationForJsonPath, parseWithPointers } from '@stoplight/yaml';
-
-export class ParserService extends AbstractService {
- private parser!: Parser;
-
- override async onInit() {
- this.parser = new Parser({
- schemaParsers: [
- // Temporary fix for TS error
- OpenAPISchemaParser() as SchemaParser,
- AvroSchemaParser() as SchemaParser,
- ProtoBuffSchemaParser() as SchemaParser,
- ],
- __unstable: {
- resolver: {
- cache: false,
- }
- }
- });
-
- this.subscribeToFiles();
- this.subscribeToSettings();
- await this.parseSavedDocuments();
- }
-
- async parse(uri: string, spec: string, options: ParseOptions = {}): Promise {
- if (uri !== 'asyncapi' && !options.source) {
- options.source = uri;
- }
-
- let diagnostics: Diagnostic[] = [];
- try {
- const { document, diagnostics: _diagnostics, extras } = await this.parser.parse(spec, options);
- diagnostics = _diagnostics;
- if (document) {
- this.updateDocument(uri, {
- uri,
- document,
- diagnostics: this.createDiagnostics(diagnostics),
- extras,
- valid: true,
- });
- return;
- }
- } catch (err: unknown) {
- console.log(err);
- }
-
- this.updateDocument(uri, {
- uri,
- document: undefined,
- diagnostics: this.createDiagnostics(diagnostics),
- extras: undefined,
- valid: false,
- });
- }
-
- getRangeForJsonPath(uri: string, jsonPath: string | Array) {
- try {
- const { documents } = documentsState.getState();
-
- const extras = documents[String(uri)]?.extras;
-
- if (extras) {
- jsonPath = Array.isArray(jsonPath) ? jsonPath : jsonPath.split('/').map(untilde);
- if (jsonPath[0] === '') jsonPath.shift();
-
- return extras.document.getRangeForJsonPath(jsonPath);
- }
- } catch (err) {
- console.error(err);
- }
- }
-
- getRangeForYamlPath(uri: string, jsonPath: string | Array) {
- try {
- const { documents } = documentsState.getState();
-
- const extras = documents[String(uri)]?.extras;
-
- if (extras) {
- jsonPath = Array.isArray(jsonPath) ? jsonPath : jsonPath.split('/').map(untilde);
- if (jsonPath[0] === '') jsonPath.shift();
- const yamlDoc = parseWithPointers(this.svcs.editorSvc.value);
-
- const location = getLocationForJsonPath(yamlDoc, jsonPath, true);
- return location?.range || { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } };
- }
- } catch (err) {
- console.error(err);
- }
- }
-
- filterDiagnostics(diagnostics: Diagnostic[]) {
- const { governance: { show } } = settingsState.getState();
- return diagnostics.filter(({ severity }) => {
- return (
- severity === DiagnosticSeverity.Error ||
- (severity === DiagnosticSeverity.Warning && show.warnings) ||
- (severity === DiagnosticSeverity.Information && show.informations) ||
- (severity === DiagnosticSeverity.Hint && show.hints)
- );
- });
- }
-
- filterDiagnosticsBySeverity(diagnostics: Diagnostic[], severity: DiagnosticSeverity) {
- return diagnostics.filter(diagnostic => diagnostic.severity === severity);
- }
-
- private updateDocument = documentsState.getState().updateDocument;
-
- private createDiagnostics(diagnostics: Diagnostic[]) {
- // map messages of invalid ref to file
- diagnostics.forEach(diagnostic => {
- if (diagnostic.code === 'invalid-ref' && diagnostic.message.endsWith('readFile is not a function')) {
- diagnostic.message = 'File references are not yet supported in Studio';
- }
- });
-
- const collections: DocumentDiagnostics = {
- original: diagnostics,
- filtered: [],
- errors: [],
- warnings: [],
- informations: [],
- hints: [],
- };
-
- const { governance: { show } } = settingsState.getState();
- diagnostics.forEach(diagnostic => {
- const severity = diagnostic.severity;
- if (severity === DiagnosticSeverity.Error) {
- collections.filtered.push(diagnostic);
- collections.errors.push(diagnostic);
- } else if (severity === DiagnosticSeverity.Warning && show.warnings) {
- collections.filtered.push(diagnostic);
- collections.warnings.push(diagnostic);
- } else if (severity === DiagnosticSeverity.Information && show.informations) {
- collections.filtered.push(diagnostic);
- collections.informations.push(diagnostic);
- } else if (severity === DiagnosticSeverity.Hint && show.hints) {
- collections.filtered.push(diagnostic);
- collections.hints.push(diagnostic);
- }
- });
-
- return collections;
- }
-
- private subscribeToFiles() {
- filesState.subscribe((state, prevState) => {
- const newFiles = state.files;
- const oldFiles = prevState.files;
-
- Object.entries(newFiles).forEach(([uri, file]) => {
- const oldFile = oldFiles[String(uri)];
- if (file === oldFile) return;
- this.parse(uri, file.content, { source: file.source }).catch(console.error);
- });
- });
- }
-
- private subscribeToSettings() {
- settingsState.subscribe((state, prevState) => {
- if (isDeepEqual(state.governance, prevState.governance)) return;
-
- const { files } = filesState.getState();
- Object.entries(files).forEach(([uri, file]) => {
- this.parse(uri, file.content).catch(console.error);
- });
- });
- }
-
- private parseSavedDocuments() {
- const { files } = filesState.getState();
- return Promise.all(
- Object.entries(files).map(([uri, file]) => {
- return this.parse(uri, file.content);
- }),
- );
- }
-}
\ No newline at end of file
diff --git a/apps/studio/src/services/server-api.service.ts b/apps/studio/src/services/server-api.service.ts
deleted file mode 100644
index ce7c68094..000000000
--- a/apps/studio/src/services/server-api.service.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import fileDownload from 'js-file-download';
-
-export interface ServerAPIProblem {
- type: string;
- title: string;
- status: number;
- detail?: string;
- instance?: string;
- [key: string]: any;
-}
-
-export class ServerAPIService extends AbstractService {
- private serverPath = 'https://api.asyncapi.com/v1';
-
- async generate(data: {
- asyncapi: string | Record,
- template: string,
- parameters: Record,
- }): Promise {
- const response = await fetch(`${this.serverPath}/generate`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(data),
- });
-
- if (response.ok) {
- const zipFile = await response.blob();
- fileDownload(zipFile, 'asyncapi.zip');
- }
-
- return response;
- }
-
- async retrieveProblem = Record>(response: Response): Promise {
- if (response.ok || response.status < 400) return null;
- const responseBody = JSON.parse(await response.text());
- return responseBody as ServerAPIProblem & AP;
- }
-}
diff --git a/apps/studio/src/services/settings.service.ts b/apps/studio/src/services/settings.service.ts
deleted file mode 100644
index e47a2d764..000000000
--- a/apps/studio/src/services/settings.service.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import { isDeepEqual } from '../helpers';
-import { settingsState } from '../state';
-
-import type { SettingsState } from '../state/settings.state';
-
-export class SettingsService extends AbstractService {
- get(): SettingsState {
- return settingsState.getState();
- }
-
- set(state: Partial) {
- settingsState.setState(state);
- }
-
- isEqual(newState: Partial): boolean {
- return isDeepEqual(this.get(), newState);
- }
-}
\ No newline at end of file
diff --git a/apps/studio/src/services/socket-client.service.tsx b/apps/studio/src/services/socket-client.service.tsx
deleted file mode 100644
index 21118e89b..000000000
--- a/apps/studio/src/services/socket-client.service.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import toast from 'react-hot-toast';
-
-import { appState } from '../state';
-
-interface IncomingMessage {
- type: 'file:loaded' | 'file:changed' | 'file:deleted';
- code?: string;
-}
-
-export class SocketClient extends AbstractService {
- private ws!: WebSocket;
-
- public override onInit(): void {
- const { url, base64, readOnly, liveServer } = this.svcs.navigationSvc.getUrlParameters();
-
- const shouldConnect = !(base64 || url || readOnly);
- if (!shouldConnect) {
- return;
- }
-
- const liveServerPort = liveServer && Number(liveServer);
- if (typeof liveServerPort === 'number') {
- this.connect(window.location.hostname, liveServerPort);
- }
- }
-
- connect(hostname: string, port: string | number) {
- try {
- const ws = this.ws = new WebSocket(`ws://${hostname || 'localhost'}:${port}/live-server`);
-
- ws.onopen = this.onOpen.bind(this);
- ws.onmessage = this.onMessage.bind(this);
- ws.onerror = this.onError.bind(this);
- } catch (e) {
- console.error(e);
- this.onError();
- }
- }
-
- send(eventName: string, content: Record) {
- this.ws && this.ws.send(JSON.stringify({ type: eventName, ...content }));
- }
-
- private onMessage(event: MessageEvent) {
- try {
- const json: IncomingMessage = JSON.parse(event.data);
-
- switch (json.type) {
- case 'file:loaded':
- case 'file:changed':
- this.svcs.editorSvc.updateState({
- content: json.code as string,
- updateModel: true,
- sendToServer: false,
- });
- break;
- case 'file:deleted':
- console.warn('Live Server: The file has been deleted on the file system.');
- break;
- default:
- console.warn('Live Server: An unknown even has been received. See details:');
- console.log(json);
- }
- } catch (e) {
- console.error(`Live Server: An invalid event has been received. See details:\n${event.data}`);
- }
- }
-
- private onOpen() {
- toast.success(
-
-
- Correctly connected to the live server!
-
-
- );
- appState.setState({ liveServer: true });
- }
-
- private onError() {
- toast.error(
-
-
- Failed to connect to live server. Please check developer console for more information.
-
-
- );
- appState.setState({ liveServer: false });
- }
-}
diff --git a/apps/studio/src/services/specification.service.ts b/apps/studio/src/services/specification.service.ts
deleted file mode 100644
index bc675cf17..000000000
--- a/apps/studio/src/services/specification.service.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { AbstractService } from './abstract.service';
-
-import specs from '@asyncapi/specs';
-import { show } from '@ebay/nice-modal-react';
-
-import { ConvertToLatestModal } from '../components/Modals';
-
-import { documentsState, settingsState } from '../state';
-
-import type { SpecVersions } from '../types';
-
-export class SpecificationService extends AbstractService {
- private keySessionStorage = 'informed-about-latest';
- override onInit() {
- this.subcribeToDocuments();
- this.subscribeToSettings();
- }
-
- get specs() {
- return specs.schemas;
- }
-
- get latestVersion(): SpecVersions {
- return Object.keys(this.specs).pop() as SpecVersions;
- }
-
- getSpec(version: SpecVersions) {
- return this.specs[String(version) as SpecVersions];
- }
-
- private subcribeToDocuments() {
- documentsState.subscribe((state, prevState) => {
- const newDocuments = state.documents;
- const oldDocuments = prevState.documents;
-
- Object.entries(newDocuments).forEach(([uri, document]) => {
- const oldDocument = oldDocuments[String(uri)];
- if (document === oldDocument) return;
- const version = document.document?.version();
- if (version && this.tryInformAboutLatestVersion(version)) {
- show(ConvertToLatestModal);
- }
- });
- });
- }
-
- private subscribeToSettings() {
- settingsState.subscribe(() => {
- sessionStorage.removeItem(this.keySessionStorage);
- });
- }
-
- private tryInformAboutLatestVersion(
- version: string,
- ): boolean {
- const oneDay = 24 * 60 * 60 * 1000; /* ms */
-
- const nowDate = new Date();
- let dateOfLastQuestion = nowDate;
- const localStorageItem = sessionStorage.getItem(this.keySessionStorage);
- if (localStorageItem) {
- dateOfLastQuestion = new Date(localStorageItem);
- }
-
- const isOvertime =
- nowDate === dateOfLastQuestion ||
- nowDate.getTime() - dateOfLastQuestion.getTime() > oneDay;
- if (isOvertime && version !== this.latestVersion) {
- sessionStorage.setItem(this.keySessionStorage, nowDate.toString());
- return true;
- }
-
- return false;
- }
-}
\ No newline at end of file
diff --git a/apps/studio/src/services/tests/converter.service.test.ts b/apps/studio/src/services/tests/converter.service.test.ts
deleted file mode 100644
index 808054ecd..000000000
--- a/apps/studio/src/services/tests/converter.service.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { createServices } from '../';
-
-import type { ConverterService } from '../converter.service';
-
-describe('SpecificationService', () => {
- let converterSvc: ConverterService;
-
- beforeAll(async () => {
- const services = await createServices();
- converterSvc = services.converterSvc;
- });
-
- describe('.convertSpec', () => {
- test('should convert spec to the given (yaml case)', async () => {
- const result = await converterSvc.convert('asyncapi: 2.0.0', '2.1.0');
- expect(result).toEqual('asyncapi: 2.1.0\n');
- });
-
- test('should convert spec to the given (json case)', async () => {
- const result = await converterSvc.convert('{"asyncapi": "2.0.0"}', '2.1.0');
- expect(result).toEqual(JSON.stringify({ asyncapi: '2.1.0' }, undefined, 2));
- });
-
- test('should throw error if converter cannot convert spec - case with invalid version', async () => {
- try {
- await converterSvc.convert('asyncapi: 1.3.0', '2.1.0');
- } catch (e: any) {
- expect(e.message).toEqual('Cannot convert from 1.3.0 to 2.1.0.');
- }
- });
- });
-});
\ No newline at end of file
diff --git a/apps/studio/src/services/tests/editor.service.test.ts b/apps/studio/src/services/tests/editor.service.test.ts
deleted file mode 100644
index 808b62e0f..000000000
--- a/apps/studio/src/services/tests/editor.service.test.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-import * as monacoAPI from 'monaco-editor/esm/vs/editor/editor.api';
-import { DiagnosticSeverity } from '@asyncapi/parser/cjs';
-
-import { createServices } from '../';
-
-import type { EditorService } from '../editor.service';
-import type { Diagnostic } from '@asyncapi/parser/cjs';
-
-describe('EditorService', () => {
- let editorSvc: EditorService;
-
- beforeAll(async () => {
- const services = await createServices();
- editorSvc = services.editorSvc;
- });
-
- describe('.createMarkers', () => {
- test('should create markers with errors', () => {
- const errors: Diagnostic[] = [
- {
- message: 'some error 1',
- range: {
- start: {
- line: 2,
- character: 4,
- },
- end: {
- line: 9,
- character: 14,
- }
- },
- path: ['/'],
- code: '-',
- severity: DiagnosticSeverity.Error,
- },
- {
- message: 'some error 2',
- range: {
- start: {
- line: 0,
- character: 1,
- },
- end: {
- line: 1,
- character: 2,
- }
- },
- path: ['/'],
- code: '-',
- severity: DiagnosticSeverity.Error,
- }
- ];
-
- const { markers, decorations } = editorSvc.createMarkersAndDecorations(errors);
-
- // markers
- expect(markers).toHaveLength(2);
- expect(markers[0]).toEqual({
- endColumn: 15,
- endLineNumber: 10,
- startColumn: 5,
- startLineNumber: 3,
- message: 'some error 1',
- severity: monacoAPI.MarkerSeverity.Error
- });
- expect(markers[1]).toEqual({
- endColumn: 3,
- endLineNumber: 2,
- startColumn: 2,
- startLineNumber: 1,
- message: 'some error 2',
- severity: monacoAPI.MarkerSeverity.Error
- });
- // decorations
- expect(decorations).toHaveLength(0);
- });
-
- test('should create decorators with warnings', () => {
- const errors: Diagnostic[] = [
- {
- message: 'some warning 1',
- range: {
- start: {
- line: 2,
- character: 4,
- },
- end: {
- line: 9,
- character: 14,
- }
- },
- path: ['/'],
- code: '-',
- severity: DiagnosticSeverity.Warning,
- },
- {
- message: 'some warning 2',
- range: {
- start: {
- line: 0,
- character: 1,
- },
- end: {
- line: 1,
- character: 2,
- }
- },
- path: ['/'],
- code: '-',
- severity: DiagnosticSeverity.Warning,
- }
- ];
-
- const { markers, decorations } = editorSvc.createMarkersAndDecorations(errors);
-
- // markers
- expect(markers).toHaveLength(0);
- // decorations
- expect(decorations).toHaveLength(2);
- expect(decorations[0]).toEqual({
- id: 'asyncapi',
- options: {
- glyphMarginClassName: 'diagnostic-warning',
- glyphMarginHoverMessage: {
- value: 'some warning 1',
- },
- },
- ownerId: 0,
- range: new monacoAPI.Range(3, 5, 10, 15),
- });
- expect(decorations[1]).toEqual({
- id: 'asyncapi',
- options: {
- glyphMarginClassName: 'diagnostic-warning',
- glyphMarginHoverMessage: {
- value: 'some warning 2',
- },
- },
- ownerId: 0,
- range: new monacoAPI.Range(1, 2, 2, 3),
- });
- });
-
- test('should not create markers and decorators without errors', () => {
- const errors: any[] = [];
-
- const { markers, decorations } = editorSvc.createMarkersAndDecorations(errors);
- expect(markers.length).toEqual(0);
- expect(decorations.length).toEqual(0);
- });
- });
-});
diff --git a/apps/studio/src/services/tests/format.service.test.ts b/apps/studio/src/services/tests/format.service.test.ts
deleted file mode 100644
index c6a6fb861..000000000
--- a/apps/studio/src/services/tests/format.service.test.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { createServices } from '../';
-
-import type { FormatService } from '../format.service';
-
-describe('FormatService', () => {
- let formatSvc: FormatService;
-
- beforeAll(async () => {
- const services = await createServices();
- formatSvc = services.formatSvc;
- });
-
- describe('.convertToYaml', () => {
- const validYAML = 'asyncapi: 2.2.0\nfoobar: barfoo\n';
-
- test('should work with valid yaml', () => {
- const result = formatSvc.convertToYaml(validYAML);
- expect(result).toEqual(validYAML);
- });
-
- test('should work with valid stringified JSON', () => {
- const json = '{"asyncapi": "2.2.0", "foobar": "barfoo"}';
- const result = formatSvc.convertToYaml(json);
- expect(result).toEqual(validYAML);
- });
- });
-
- describe('.convertToJson', () => {
- const validJSON = JSON.stringify({ asyncapi: '2.2.0', foobar: 'barfoo' }, undefined, 2);
-
- test('should work with valid yaml', () => {
- const result = formatSvc.convertToJSON('asyncapi: 2.2.0\nfoobar: barfoo\n');
- expect(result).toEqual(validJSON);
- });
-
- test('should work with valid stringified JSON', () => {
- const result = formatSvc.convertToJSON(validJSON);
- expect(result).toEqual(validJSON);
- });
- });
-
- describe('.encodeBase64', () => {
- test('should properly encode content to base64', () => {
- const result = formatSvc.encodeBase64('hello world!');
- expect(result).toEqual('aGVsbG8gd29ybGQh');
- });
- });
-
- describe('.decodeBase64', () => {
- test('should properly decode content from base64', () => {
- const result = formatSvc.decodeBase64('aGVsbG8gd29ybGQh');
- expect(result).toEqual('hello world!');
- });
- });
-
- describe('.retrieveLangauge', () => {
- test('should check that content is yaml', () => {
- const result = formatSvc.retrieveLangauge('asyncapi: 2.2.0\nfoobar: barfoo\n');
- expect(result).toEqual('yaml');
- });
-
- test('should check that content is json', () => {
- const result = formatSvc.retrieveLangauge('{"asyncapi": "2.2.0", "foobar": "barfoo"}');
- expect(result).toEqual('json');
- });
-
- test('should check that content is yaml - fallback for non json content', () => {
- const result = formatSvc.retrieveLangauge('');
- expect(result).toEqual('yaml');
- });
- });
-});
\ No newline at end of file
diff --git a/apps/studio/src/services/tests/navigation.service.test.ts b/apps/studio/src/services/tests/navigation.service.test.ts
deleted file mode 100644
index 9078a211c..000000000
--- a/apps/studio/src/services/tests/navigation.service.test.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { createServices } from '../';
-
-import type { NavigationService } from '../navigation.service';
-
-describe('NavigationService', () => {
- let navigationSvc: NavigationService;
-
- beforeAll(async () => {
- const services = await createServices();
- navigationSvc = services.navigationSvc;
- });
-
- function updateLocation(search: string) {
- const location = {
- ...window.location,
- search,
- };
- Object.defineProperty(window, 'location', {
- writable: true,
- value: location,
- });
- }
-
- describe('.getUrlParameters() - checking readOnly parameter', () => {
- test('should return false if reaOnly flag is not defined', () => {
- updateLocation('?url=some-url.json');
- const result = navigationSvc.getUrlParameters();
- expect(result.readOnly).toEqual(false);
- });
-
- test('should return true if reaOnly flag is defined - empty value case', () => {
- updateLocation('?readOnly');
- const result = navigationSvc.getUrlParameters();
- expect(result.readOnly).toEqual(true);
- });
-
- test('should return true if reaOnly flag is defined - true value case', () => {
- updateLocation('?readOnly=true');
- const result = navigationSvc.getUrlParameters();
- expect(result.readOnly).toEqual(true);
- });
-
- test('should return false if reaOnly flag is not defined - non empty/true value case', () => {
- updateLocation('?readOnly=false');
- const result = navigationSvc.getUrlParameters();
- expect(result.readOnly).toEqual(false);
- });
- });
-});
diff --git a/apps/studio/src/setupTests.ts b/apps/studio/src/setupTests.ts
deleted file mode 100644
index 8f2609b7b..000000000
--- a/apps/studio/src/setupTests.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// jest-dom adds custom jest matchers for asserting on DOM nodes.
-// allows you to do things like:
-// expect(element).toHaveTextContent(/react/i)
-// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
diff --git a/apps/studio/src/state/app.state.ts b/apps/studio/src/state/app.state.ts
deleted file mode 100644
index 8a062ec91..000000000
--- a/apps/studio/src/state/app.state.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { create } from 'zustand';
-
-export type AppState = {
- initialized: boolean;
- readOnly: boolean;
- liveServer: boolean;
- initErrors: any[],
-}
-
-export const appState = create(() => ({
- initialized: false,
- readOnly: false,
- liveServer: false,
- initErrors: [],
-}));
-
-export const useAppState = appState;
diff --git a/apps/studio/src/state/documents.state.ts b/apps/studio/src/state/documents.state.ts
deleted file mode 100644
index 8e518317e..000000000
--- a/apps/studio/src/state/documents.state.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { create } from 'zustand';
-
-import type { AsyncAPIDocumentInterface, Diagnostic, ParseOutput } from '@asyncapi/parser/cjs';
-
-export type DocumentDiagnostics = {
- original: Diagnostic[];
- filtered: Diagnostic[];
- errors: Diagnostic[];
- warnings: Diagnostic[];
- informations: Diagnostic[];
- hints: Diagnostic[];
-}
-
-export type Document = {
- uri: string;
- document?: AsyncAPIDocumentInterface;
- extras?: ParseOutput['extras'];
- diagnostics: DocumentDiagnostics;
- valid?: boolean;
-}
-
-export type DocumentsState = {
- documents: Record;
-}
-
-export type DocumentsActions = {
- updateDocument: (uri: string, document: Partial) => void;
-}
-
-export const documentsState = create(set => ({
- documents: {},
- updateDocument(uri: string, document: Partial) {
- set(state => ({ documents: { ...state.documents, [String(uri)]: { ...state.documents[String(uri)] || {}, ...document } } }));
- },
-}));
-
-export const useDocumentsState = documentsState;
diff --git a/apps/studio/src/state/files.state.ts b/apps/studio/src/state/files.state.ts
deleted file mode 100644
index 569103ff1..000000000
--- a/apps/studio/src/state/files.state.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-import { create } from 'zustand';
-
-const schema =
- localStorage.getItem('document') || `asyncapi: 3.0.0
-info:
- title: Streetlights Kafka API
- version: 1.0.0
- description: |-
- The Smartylighting Streetlights API allows you to remotely manage the city
- lights.
- ### Check out its awesome features:
-
- * Turn a specific streetlight on/off π
- * Dim a specific streetlight π
- * Receive real-time information about environmental lighting conditions π
- license:
- name: Apache 2.0
- url: https://www.apache.org/licenses/LICENSE-2.0
-defaultContentType: application/json
-servers:
- scram-connections:
- host: test.mykafkacluster.org:18092
- protocol: kafka-secure
- description: Test broker secured with scramSha256
- security:
- - $ref: '#/components/securitySchemes/saslScram'
- tags:
- - name: env:test-scram
- description: >-
- This environment is meant for running internal tests through
- scramSha256
- - name: kind:remote
- description: This server is a remote server. Not exposed by the application
- - name: visibility:private
- description: This resource is private and only available to certain users
- mtls-connections:
- host: test.mykafkacluster.org:28092
- protocol: kafka-secure
- description: Test broker secured with X509
- security:
- - $ref: '#/components/securitySchemes/certs'
- tags:
- - name: env:test-mtls
- description: This environment is meant for running internal tests through mtls
- - name: kind:remote
- description: This server is a remote server. Not exposed by the application
- - name: visibility:private
- description: This resource is private and only available to certain users
-channels:
- lightingMeasured:
- address: smartylighting.streetlights.1.0.event.{streetlightId}.lighting.measured
- messages:
- lightMeasured:
- $ref: '#/components/messages/lightMeasured'
- description: The topic on which measured values may be produced and consumed.
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightTurnOn:
- address: smartylighting.streetlights.1.0.action.{streetlightId}.turn.on
- messages:
- turnOn:
- $ref: '#/components/messages/turnOnOff'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightTurnOff:
- address: smartylighting.streetlights.1.0.action.{streetlightId}.turn.off
- messages:
- turnOff:
- $ref: '#/components/messages/turnOnOff'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
- lightsDim:
- address: smartylighting.streetlights.1.0.action.{streetlightId}.dim
- messages:
- dimLight:
- $ref: '#/components/messages/dimLight'
- parameters:
- streetlightId:
- $ref: '#/components/parameters/streetlightId'
-operations:
- receiveLightMeasurement:
- action: receive
- channel:
- $ref: '#/channels/lightingMeasured'
- summary: >-
- Inform about environmental lighting conditions of a particular
- streetlight.
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightingMeasured/messages/lightMeasured'
- turnOn:
- action: send
- channel:
- $ref: '#/channels/lightTurnOn'
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightTurnOn/messages/turnOn'
- turnOff:
- action: send
- channel:
- $ref: '#/channels/lightTurnOff'
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightTurnOff/messages/turnOff'
- dimLight:
- action: send
- channel:
- $ref: '#/channels/lightsDim'
- traits:
- - $ref: '#/components/operationTraits/kafka'
- messages:
- - $ref: '#/channels/lightsDim/messages/dimLight'
-components:
- messages:
- lightMeasured:
- name: lightMeasured
- title: Light measured
- summary: >-
- Inform about environmental lighting conditions of a particular
- streetlight.
- contentType: application/json
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/lightMeasuredPayload'
- turnOnOff:
- name: turnOnOff
- title: Turn on/off
- summary: Command a particular streetlight to turn the lights on or off.
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/turnOnOffPayload'
- dimLight:
- name: dimLight
- title: Dim light
- summary: Command a particular streetlight to dim the lights.
- traits:
- - $ref: '#/components/messageTraits/commonHeaders'
- payload:
- $ref: '#/components/schemas/dimLightPayload'
- schemas:
- lightMeasuredPayload:
- type: object
- properties:
- lumens:
- type: integer
- minimum: 0
- description: Light intensity measured in lumens.
- sentAt:
- $ref: '#/components/schemas/sentAt'
- turnOnOffPayload:
- type: object
- properties:
- command:
- type: string
- enum:
- - 'on'
- - 'off'
- description: Whether to turn on or off the light.
- sentAt:
- $ref: '#/components/schemas/sentAt'
- dimLightPayload:
- type: object
- properties:
- percentage:
- type: integer
- description: Percentage to which the light should be dimmed to.
- minimum: 0
- maximum: 100
- sentAt:
- $ref: '#/components/schemas/sentAt'
- sentAt:
- type: string
- format: date-time
- description: Date and time when the message was sent.
- securitySchemes:
- saslScram:
- type: scramSha256
- description: Provide your username and password for SASL/SCRAM authentication
- certs:
- type: X509
- description: Download the certificate files from service provider
- parameters:
- streetlightId:
- description: The ID of the streetlight.
- messageTraits:
- commonHeaders:
- headers:
- type: object
- properties:
- my-app-header:
- type: integer
- minimum: 0
- maximum: 100
- operationTraits:
- kafka:
- bindings:
- kafka:
- clientId:
- type: string
- enum:
- - my-app-id
-`;
-
-export interface FileStat {
- mtime: number;
-}
-
-export type File = {
- uri: string;
- name: string;
- content: string;
- from: 'storage' | 'url' | 'base64';
- source?: string;
- language: 'json' | 'yaml';
- modified: boolean;
- stat?: FileStat;
-}
-
-export type FilesState = {
- files: Record;
-}
-
-export type FilesActions = {
- updateFile: (uri: string, file: Partial) => void;
-}
-
-export const filesState = create(set => ({
- files: {
- asyncapi: {
- uri: 'asyncapi',
- name: 'asyncapi',
- content: schema,
- from: 'storage',
- source: undefined,
- language: schema.trimStart()[0] === '{' ? 'json' : 'yaml',
- modified: false,
- stat: {
- mtime: (new Date()).getTime(),
- }
- }
- },
- updateFile(uri: string, file: Partial) {
- set(state => ({ files: { ...state.files, [String(uri)]: { ...state.files[String(uri)] || {}, ...file } } }));
- }
-}));
-
-export const useFilesState = filesState;
diff --git a/apps/studio/src/state/index.ts b/apps/studio/src/state/index.ts
deleted file mode 100644
index 84a191f99..000000000
--- a/apps/studio/src/state/index.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { appState, useAppState } from './app.state';
-import { documentsState, useDocumentsState } from './documents.state';
-import { filesState, useFilesState } from './files.state';
-import { otherState, useOtherState } from './other.state';
-import { panelsState, usePanelsState } from './panels.state';
-import { settingsState, useSettingsState } from './settings.state';
-
-export {
- appState, useAppState,
- documentsState, useDocumentsState,
- filesState, useFilesState,
- otherState, useOtherState,
- panelsState, usePanelsState,
- settingsState, useSettingsState,
-};
-
-const state = {
- // app
- app: appState,
- useAppState,
-
- // documents
- documents: documentsState,
- useDocumentsState,
-
- // file-system
- files: filesState,
- useFilesState,
-
- // other
- other: otherState,
- useOtherState,
-
- // panels
- panels: panelsState,
- usePanelsState,
-
- // settings
- settings: settingsState,
- useSettingsState,
-};
-
-export default state;
\ No newline at end of file
diff --git a/apps/studio/src/state/other.state.ts b/apps/studio/src/state/other.state.ts
deleted file mode 100644
index 453485e61..000000000
--- a/apps/studio/src/state/other.state.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { create } from 'zustand';
-
-export type OtherState = {
- editorHeight: string;
- templateRerender: boolean;
-}
-
-export const otherState = create(() => ({
- editorHeight: 'calc(100% - 36px)',
- templateRerender: false,
-}));
-
-export const useOtherState = otherState;
diff --git a/apps/studio/src/state/panels.state.ts b/apps/studio/src/state/panels.state.ts
deleted file mode 100644
index d920f56a1..000000000
--- a/apps/studio/src/state/panels.state.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { create } from 'zustand';
-import { persist } from 'zustand/middleware';
-
-export type PanelsState = {
- show: {
- activityBar: boolean;
- statusBar: boolean;
- primarySidebar: boolean;
- secondarySidebar: boolean;
- primaryPanel: boolean;
- secondaryPanel: boolean;
- contextPanel: boolean;
- };
- // TODO: remove when panels tabs will be introduced
- secondaryPanelType: 'template' | 'visualiser';
-}
-
-export const panelsState = create(
- persist(() =>
- ({
- show: {
- activityBar: true,
- statusBar: true,
- primarySidebar: true,
- secondarySidebar: true,
- primaryPanel: true,
- secondaryPanel: true,
- contextPanel: true,
- },
- secondaryPanelType: 'template',
- }),
- {
- name: 'studio-panels',
- getStorage: () => localStorage,
- }
- ),
-);
-
-export const usePanelsState = panelsState;
diff --git a/apps/studio/src/state/settings.state.ts b/apps/studio/src/state/settings.state.ts
deleted file mode 100644
index 1b4fbd10b..000000000
--- a/apps/studio/src/state/settings.state.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { create } from 'zustand';
-import { persist } from 'zustand/middleware';
-
-export type SettingsState = {
- editor: {
- autoSaving: boolean;
- savingDelay: number;
- };
- governance: {
- show: {
- warnings: boolean;
- informations: boolean;
- hints: boolean;
- }
- };
- templates: {
- autoRendering: boolean;
- };
-}
-
-export const settingsState = create(
- persist(() =>
- ({
- editor: {
- autoSaving: true,
- savingDelay: 625,
- },
- governance: {
- show: {
- warnings: true,
- informations: true,
- hints: true,
- },
- },
- templates: {
- autoRendering: true,
- },
- }),
- {
- name: 'studio-settings',
- getStorage: () => localStorage,
- }
- ),
-);
-
-export const useSettingsState = settingsState;
\ No newline at end of file
diff --git a/apps/studio/src/studio.tsx b/apps/studio/src/studio.tsx
deleted file mode 100644
index ba60207fc..000000000
--- a/apps/studio/src/studio.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React, { useEffect } from 'react';
-import toast, { Toaster } from 'react-hot-toast';
-
-import { Content, Sidebar, Template, Toolbar } from './components';
-
-import { afterAppInit, useServices } from './services';
-import { appState } from './state';
-
-export interface AsyncAPIStudioProps {}
-
-export const AsyncAPIStudio: React.FunctionComponent<
- AsyncAPIStudioProps
-> = () => {
- const services = useServices();
-
- useEffect(() => {
- setTimeout(() => {
- afterAppInit(services).catch(console.error);
- }, 250);
- }, []);
-
- if (appState.getState().readOnly) {
- return (
-
-
-
- );
- }
- const unsubscribe = appState.subscribe((state) => {
- state.initErrors.forEach((e) => {
- toast.error(e.message);
- });
- unsubscribe();
- appState.setState({ initErrors: [] });
- });
-
- return (
-
- );
-};
diff --git a/apps/studio/src/tailwind.css b/apps/studio/src/tailwind.css
deleted file mode 100644
index b5c61c956..000000000
--- a/apps/studio/src/tailwind.css
+++ /dev/null
@@ -1,3 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
diff --git a/apps/studio/src/types.ts b/apps/studio/src/types.ts
deleted file mode 100644
index 221ecc3d5..000000000
--- a/apps/studio/src/types.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import type specs from '@asyncapi/specs';
-
-export type SpecVersions = keyof typeof specs.schemas;
diff --git a/apps/studio/tailwind.config.js b/apps/studio/tailwind.config.js
deleted file mode 100644
index c9634805b..000000000
--- a/apps/studio/tailwind.config.js
+++ /dev/null
@@ -1,39 +0,0 @@
-module.exports = {
- content: [
- './src/**/*.{js,jsx,ts,tsx}',
- './public/index.html',
- ],
- theme: {
- extend: {
- colors: {
- teal: {
- 100: '#e6fffa',
- 200: '#b2f5ea',
- 300: '#81e6d9',
- 400: '#4fd1c5',
- 500: '#38b2ac',
- 600: '#319795',
- 700: '#2c7a7b',
- 800: '#285e61',
- 900: '#234e52',
- },
- },
- typography: theme => ({
- DEFAULT: {
- css: {
- pre: {
- backgroundColor: theme('colors.gray.900'),
- },
- },
- },
- }),
- },
- },
- variants: {
- extend: {
- cursor: ['disabled'],
- backgroundColor: ['disabled'],
- },
- },
- plugins: [require('@tailwindcss/typography')],
-};
\ No newline at end of file
diff --git a/apps/studio/tsconfig.json b/apps/studio/tsconfig.json
deleted file mode 100644
index 8c5c6f5bb..000000000
--- a/apps/studio/tsconfig.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "ts-node": {
- // these options are overrides used only by ts-node
- // same as our --compilerOptions flag and our TS_NODE_COMPILER_OPTIONS environment variable
- "compilerOptions": {
- "module": "commonjs"
- }
- },
- "compilerOptions": {
- "target": "es5",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
- "allowJs": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "noFallthroughCasesInSwitch": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx",
- },
- "include": [
- "src"
- ]
-}