diff --git a/.all-contributorsrc b/.all-contributorsrc index 6a753d77281..64e7fe6bdf7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -537,6 +537,24 @@ "contributions": [ "code" ] + }, + { + "login": "Shiva953", + "name": "Neutron", + "avatar_url": "https://avatars.githubusercontent.com/u/120790871?v=4", + "profile": "https://github.com/Shiva953", + "contributions": [ + "code" + ] + }, + { + "login": "sagarkori143", + "name": "Sagar Kori", + "avatar_url": "https://avatars.githubusercontent.com/u/129517558?v=4", + "profile": "https://github.com/sagarkori143", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000000..763c421c133 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +node_modules +.next +.github \ No newline at end of file diff --git a/.github/workflows/if-nodejs-pr-testing.yml b/.github/workflows/if-nodejs-pr-testing.yml new file mode 100644 index 00000000000..9ce9f9a19cf --- /dev/null +++ b/.github/workflows/if-nodejs-pr-testing.yml @@ -0,0 +1,78 @@ +# This action is centrally managed in https://github.com/asyncapi/.github/ +# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo + +# It does magic only if there is package.json file in the root of the project +name: PR testing - if Node project + +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + +jobs: + test-nodejs-pr: + name: Test NodeJS PR - ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + steps: + - if: > + !github.event.pull_request.draft && !( + (github.actor == 'asyncapi-bot' && ( + startsWith(github.event.pull_request.title, 'ci: update of files from global .github repo') || + startsWith(github.event.pull_request.title, 'chore(release):') + )) || + (github.actor == 'asyncapi-bot-eve' && ( + startsWith(github.event.pull_request.title, 'ci: update of files from global .github repo') || + startsWith(github.event.pull_request.title, 'chore(release):') + )) || + (github.actor == 'allcontributors[bot]' && + startsWith(github.event.pull_request.title, 'docs: add') + ) + ) + id: should_run + name: Should Run + run: echo "shouldrun=true" >> $GITHUB_OUTPUT + - if: steps.should_run.outputs.shouldrun == 'true' + name: Set git to use LF #to once and for all finish neverending fight between Unix and Windows + run: | + git config --global core.autocrlf false + git config --global core.eol lf + - if: steps.should_run.outputs.shouldrun == 'true' + name: Checkout repository + uses: actions/checkout@v3 + - if: steps.should_run.outputs.shouldrun == 'true' + name: Check if Node.js project and has package.json + id: packagejson + run: test -e ./package.json && echo "exists=true" >> $GITHUB_OUTPUT || echo "exists=false" >> $GITHUB_OUTPUT + shell: bash + - if: steps.packagejson.outputs.exists == 'true' + name: Check package-lock version + uses: asyncapi/.github/.github/actions/get-node-version-from-package-lock@master + id: lockversion + - if: steps.packagejson.outputs.exists == 'true' + name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "${{ steps.lockversion.outputs.version }}" + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + - if: steps.packagejson.outputs.exists == 'true' + name: Install dependencies + id: first-installation + run: npm install --loglevel verbose + continue-on-error: true + - if: steps.first-installation.outputs.status == 'failure' && steps.packagejson.outputs.exists == 'true' + name: Clear NPM cache and install deps again + run: | + npm cache clean --force + npm install --loglevel verbose + - if: steps.packagejson.outputs.exists == 'true' + name: Test + run: npm test --if-present + - if: steps.packagejson.outputs.exists == 'true' + name: Run linter + run: npm run lint --if-present + - if: steps.packagejson.outputs.exists == 'true' + name: Run release assets generation to make sure PR does not break it + run: npm run generate:assets --if-present diff --git a/.gitignore b/.gitignore index 97f8c203803..8a6940cc810 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ node_modules out config/posts.json config/case-studies.json +config/adopters.json public/rss.xml .env.local yarn.lock @@ -14,4 +15,5 @@ meetings.json .netlify .env cypress/screenshots -cypress/videos \ No newline at end of file +cypress/videos +/config/finance/json-data/* \ No newline at end of file diff --git a/ADDING_TRANSLATIONS.md b/ADDING_TRANSLATIONS.md new file mode 100644 index 00000000000..e4a26f9fefb --- /dev/null +++ b/ADDING_TRANSLATIONS.md @@ -0,0 +1,314 @@ +# Adding Translations to AsyncAPI Website + +We appreciate your valuable contributions to the AsyncAPI website, whether it's adding or improving existing translations. + +## Table of contents +- [Improving existing translations:](#improving-existing-translations) +- [Adding translations to a partially localized page:](#adding-translations-to-a-partially-localized-page) +- [Adding translations to a new page:](#adding-translations-to-a-new-page) +- [Adding a new locale:](#adding-a-new-locale) + +## Improving existing translations + +To modify or improve existing translations, simply navigate to the `locales` folder and edit the appropriate `JSON` files for your preferred language. + +Here is an example directory structure for the `locales` folder. It contains sub-folders named after different languages, each of which contains `JSON` files with key-value pairs for translations. + +The file `common.json` contains common translation keys such as buttons and CTAs. The other JSON files are specific to certain pages on the website. For instance, `tools.json` includes translations for all the tools-related pages on the website. + +``` +πŸ“¦locales + ┣ πŸ“‚de + ┃ ┣ πŸ“œcommon.json + ┃ ┣ πŸ“œlanding-page.json + ┃ β”— πŸ“œtools.json + ┃ β”— πŸ“œ....json + β”— πŸ“‚en + ┃ ┣ πŸ“œcommon.json + ┃ ┣ πŸ“œlanding-page.json + ┃ β”— πŸ“œtools.json + ┃ β”— πŸ“œ....json +``` + +To modify a `Landing Page`'s heading: +- Navigate to the `locales` folder. +- Select a language, e.g. `de` (German) - go to the `de` folder. +- Open `landing-page.json`. +- Change the values according to your needs. +- Create a pull request with the changes. + +## Adding translations to a partially localized page + +The text on any given page may not have a translation available in your language. + +Use the translation hook with the key specified in the `locales` folder. + +Suppose the Landing Page has a button that is still in English when the language is set to German: +- Navigate to the file where the component is defined. +- Import the `useTranslation` hook from `lib/i18n`. +- Extract the translation function from the hook `const { t } = useTranslation();`. +- Use it to pass the key of the required translation value. Make sure to add the required key to the `locales` folder according to the page's scope. In this example, we are adding translation for a button, since all translation keys related to buttons need to be specified in `common.json`. + +Example: + +`ICSFileButton.js` +```diff +... ++ import { useTranslation } from '../../lib/i18n'; + +export default function ICSFButton({ +- text = 'Download ICS File', ++ text = 'icsFileBtn', + ... +}) { + ++ const { t } = useTranslation('common'); + + return ( + )} diff --git a/components/campaigns/AnnoucementHero.js b/components/campaigns/AnnoucementHero.js index 94d67320996..26e227297ed 100644 --- a/components/campaigns/AnnoucementHero.js +++ b/components/campaigns/AnnoucementHero.js @@ -109,49 +109,50 @@ export default function AnnouncementHero({ className = '', small = false, hideVi }; }, [activeIndex]); - return ( - -
-
- -
-
-
- {banners.map((banner, index) => ( - banner.show && ( - - ) - ))} -
-
- {banners.map((banner, index) => ( -
goToIndex(index)} - /> - ))} -
-
-
- -
-
- - ); + return '' + // return ( + // + //
+ //
+ // + //
+ //
+ //
+ // {banners.map((banner, index) => ( + // banner.show && ( + // + // ) + // ))} + //
+ //
+ // {banners.map((banner, index) => ( + //
goToIndex(index)} + // /> + // ))} + //
+ //
+ //
+ // + //
+ //
+ // + // ); } diff --git a/components/campaigns/Banner.js b/components/campaigns/Banner.js index 28e309ce9ef..4c4e07e7e6c 100644 --- a/components/campaigns/Banner.js +++ b/components/campaigns/Banner.js @@ -12,9 +12,8 @@ export default function Banner({}) { const day = new Date().getUTCDate(); const month = new Date().getUTCMonth(); const year = new Date().getUTCFullYear(); - - // month=10 is November. Show only between 6-30 November. - if (year > 2022 || month !== 10 || day < 6) { + // month=11 is December. Show only between 6-31 December. + if (year > 2023 || month > 11 || day < 6) { return null; } @@ -22,27 +21,27 @@ export default function Banner({}) {
- diff --git a/components/dashboard/table/Table.js b/components/dashboard/table/Table.js index d41156cea0a..9d6e7626ab3 100644 --- a/components/dashboard/table/Table.js +++ b/components/dashboard/table/Table.js @@ -14,6 +14,17 @@ export default function Table({

{title}

+ {data.length===0 && ( +
+

There aren't any good first issues open for the given repository and area at the moment.

+
    +
  • Join our Slack to seek help.
  • +
  • In the #11_contributing channel, call out the maintainers that you want to work with. Ask them if there are any issues you could solve. You know who these people are from CODEOWNERS file in each repo.
  • +
  • If there is no response, you need to look for a different issue from different repository.
  • +
+
+ ) + }
    {data.map((item) => ( diff --git a/components/data/buckets.js b/components/data/buckets.js index a171d271885..8ecab700fa1 100644 --- a/components/data/buckets.js +++ b/components/data/buckets.js @@ -4,6 +4,7 @@ import IconUseCases from '../icons/UseCases' import IconGuide from '../icons/Guide' import IconSpec from '../icons/Spec' import IconUsers from '../icons/Users' +import IconMigration from '../icons/Migration' export const buckets = [ { @@ -51,7 +52,16 @@ export const buckets = [ borderClassName: 'border-yellow-200', Icon: IconSpec, }, - { + { + name: 'migration', + title: 'Migration', + description: 'Our migration guides on how to upgrade to newer AsyncAPI versions.', + link: '/docs/migration', + className: 'bg-blue-400', + borderClassName: 'border-blue-400', + Icon: IconMigration, + }, + { name: 'community', title: 'Community', description: 'Our Community section documents the community guidelines and resources.', @@ -61,7 +71,7 @@ export const buckets = [ Icon: IconUsers, }, ].map(bucket => { - // we need such a mapping for some parts of website, e.g navigation blocks use the `icon` property, not `Icon` etc. + // we need such a mapping for some parts of website, e.g navigation blocks use the `icon` property, not `Icon` etc. return { ...bucket, href: bucket.link, diff --git a/components/features/FeatureList.js b/components/features/FeatureList.js index 7ad58d9ed6e..d09ebb08eb1 100644 --- a/components/features/FeatureList.js +++ b/components/features/FeatureList.js @@ -1,7 +1,7 @@ export const features = [ { id: "specification", - links: [{ label: "Documentation", href: "docs/specifications/latest", id: 'whyasyncapi-spec-documentation-link' }], + links: [{ label: "Documentation", href: "docs/reference/specification/latest", id: 'whyasyncapi-spec-documentation-link' }], }, { id: 'document-apis', diff --git a/components/footer/FooterList.js b/components/footer/FooterList.js index b2161199a7b..ff5b394e972 100644 --- a/components/footer/FooterList.js +++ b/components/footer/FooterList.js @@ -49,7 +49,7 @@ export const initiativeLinks = [ }, { label: "Shop", - url: "https://asyncapi.threadless.com", + url: "https://www.store.asyncapi.com/", }, { label: "Jobs", @@ -59,6 +59,10 @@ export const initiativeLinks = [ label: "Brand", url: "https://github.com/asyncapi/brand/blob/master/brand-guidelines/README.md", }, + { + label:"Finance", + url:"/finance" + }, { label: "FAQs", url: "/about#faqs", diff --git a/components/helpers/useHeadingsObserver.js b/components/helpers/useHeadingsObserver.js new file mode 100644 index 00000000000..56de62808c8 --- /dev/null +++ b/components/helpers/useHeadingsObserver.js @@ -0,0 +1,36 @@ +import { useEffect, useRef, useState } from "react"; + +/** + * @description Custom hook to observe headings and set the current active heading + * @example const { currActive } = useHeadingsObserver(); + * @returns {object} currActive - current active heading + */ +export function useHeadingsObserver() { + const observer = useRef(null); + const headingsRef = useRef([]); + const [currActive, setCurrActive] = useState(null); + + useEffect(() => { + const callback = (entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + setCurrActive(entry.target.id); + } + }) + } + + // The heading in from top 20% of the viewport to top 30% of the viewport will be considered as active + observer.current = new IntersectionObserver(callback, { + rootMargin: '-20% 0px -70% 0px', + }); + + headingsRef.current = document.querySelectorAll('h2, h3'); + headingsRef.current.forEach(heading => { + observer.current.observe(heading); + }) + + return () => observer.current.disconnect(); + }, []); + + return { currActive } +} diff --git a/components/icons/DocsArrow.js b/components/icons/DocsArrow.js new file mode 100644 index 00000000000..a9307b921aa --- /dev/null +++ b/components/icons/DocsArrow.js @@ -0,0 +1,7 @@ +export default function DocsArrow({ isDropDown, activeDropDownItem, onClick, className }) { + return ( +
    { }}> + {isDropDown && } +
    + ); +} diff --git a/components/icons/Migration.js b/components/icons/Migration.js new file mode 100644 index 00000000000..77180efeba8 --- /dev/null +++ b/components/icons/Migration.js @@ -0,0 +1,15 @@ +export default function IconUsers({ ...rest }) { + // + return ( + + + + ); +} diff --git a/components/icons/Twitter.js b/components/icons/Twitter.js index 15d860ef101..4d5239856ea 100644 --- a/components/icons/Twitter.js +++ b/components/icons/Twitter.js @@ -5,7 +5,7 @@ export default function IconTwitter({ className }) { fillRule="evenodd" d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" fill="currentColor" - clip-fillRule="evenodd" > + clip-fillrule="evenodd" > ) diff --git a/components/icons/Users.js b/components/icons/Users.js index c46a89deb77..9f43fdcb633 100644 --- a/components/icons/Users.js +++ b/components/icons/Users.js @@ -1,14 +1,14 @@ export default function IconUsers({ ...rest }) { return ( - diff --git a/components/languageSelector/LanguageSelect.js b/components/languageSelector/LanguageSelect.js index b8d931a7d6f..99d8a68baba 100644 --- a/components/languageSelector/LanguageSelect.js +++ b/components/languageSelector/LanguageSelect.js @@ -8,11 +8,11 @@ export default function LanguageSelect({ return (
    {showMenu && ( -
    +
    - - -
    @@ -18,9 +16,6 @@ export default function GenericPostLayout({ post, children }) { return ( - - -
    -
    - -
    {children} diff --git a/components/layout/JobsLayout.js b/components/layout/JobsLayout.js index a0578fba4dd..176bd075fad 100644 --- a/components/layout/JobsLayout.js +++ b/components/layout/JobsLayout.js @@ -2,11 +2,9 @@ import { useRouter } from 'next/router' import ErrorPage from 'next/error' import Head from '../Head' import JobsContext from '../../context/JobsContext' -import NavBar from '../navigation/NavBar' import Container from './Container' import JobSummary from '../JobSummary' import ApplyJobButton from '../buttons/ApplyJob' -import StickyNavbar from '../navigation/StickyNavbar' export default function JobsLayout({ post, children }) { if (!post) return ; @@ -19,10 +17,6 @@ export default function JobsLayout({ post, children }) { return ( - - - -
    { const router = useRouter(); + + // If there is no router available (e.g., during server-side rendering & cypress tests), render a standard Link + if (!router) { + return ( + + {children} + + ); + } + const { pathname, query, asPath } = router; - // Detect current language + // Detect current language based on the path or query parameter const slug = asPath.split("/")[1]; const langSlug = languages.includes(slug) && slug; const language = query.lang || langSlug || defaultLanguage; let href = props.href || pathname; + /* + If explicit href is provided, and the language-specific paths for the current language do not include the href, or if the href starts with "http", render a standard Link + */ + if ((props.href && i18nPaths[language] && !i18nPaths[language].includes(href)) || href.includes("http", 0)) { + return ( + + {children} + + ); + } + + // If a locale is provided, update the href with the locale if (locale) { if (props.href) { href = `/${locale}${href}`; } else { + // If the current path starts with "/404", update href to be the root path with the locale + // Otherwise, replace "[lang]" placeholder with the locale if (pathname.startsWith("/404")) { href = `/${locale}`; } else { @@ -24,6 +49,7 @@ const LinkComponent = ({ children, locale, ...props }) => { } } } else { + // If no locale is provided, update the href with the current language or keep it as is if (language) { href = `/${language}${href}`; } else { diff --git a/components/navigation/DocsNav.js b/components/navigation/DocsNav.js index d06a2f99bd4..acaf3132c9a 100644 --- a/components/navigation/DocsNav.js +++ b/components/navigation/DocsNav.js @@ -1,8 +1,12 @@ +import React, { useState, useEffect } from 'react'; import DocsNavItem from './DocsNavItem'; import IconHome from '../icons/Home'; +import SubCategoryDocsNav from './SubCategoryDocsNav'; +import DocsArrow from '../icons/DocsArrow'; import { buckets } from '../data/buckets'; + const serializedBuckets = buckets.reduce((acc, bucket) => { acc[bucket.name] = { ...bucket, @@ -19,28 +23,35 @@ const serializedBuckets = buckets.reduce((acc, bucket) => { export default function DocsNav({ item, active, - onClick = () => {}, + onClick = () => { }, }) { const subCategories = item.children; const bucket = serializedBuckets[item.item.rootSectionId]; + const [openSubCategory, setOpenSubCategory] = useState(active.startsWith(item.item.slug)); + + const onClickHandler = () => { + setOpenSubCategory(!openSubCategory); + onClick(); + } + + useEffect(() => { + setOpenSubCategory(active.startsWith(item.item.slug)); + }, [active]) + return (
  • - -
      - {Object.values(subCategories).map((subCategory) => ( -
    • - -
        - {subCategory.children && subCategory.children.map(subItem => ( -
      • - -
      • - ))} -
      -
    • - ))} -
    +
    + 0} activeDropDownItem={openSubCategory} onClick={() => setOpenSubCategory(!openSubCategory)} /> + +
    + {openSubCategory && ( +
      + {Object.values(subCategories).map((subCategory) => ( + + ))} +
    + )}
  • ); } diff --git a/components/navigation/MenuBlocks.js b/components/navigation/MenuBlocks.js index ae9d9ff7049..f9caa326820 100644 --- a/components/navigation/MenuBlocks.js +++ b/components/navigation/MenuBlocks.js @@ -1,19 +1,22 @@ +import LinkComponent from '../link'; import Paragraph from '../typography/Paragraph'; import Label from './Label' -import Link from 'next/link' +import { useRouter } from 'next/router'; + export default function MenuBlocks ({ items = [], }) { + const router = useRouter() return ( <> { items.map((item, index) => { const isExternalHref = item.href && item.href.startsWith('http'); return ( - + @@ -29,7 +32,7 @@ export default function MenuBlocks ({
    - + ) }) } diff --git a/components/navigation/MobileNavMenu.js b/components/navigation/MobileNavMenu.js index adcfe3424e5..a7f88fb4eb2 100644 --- a/components/navigation/MobileNavMenu.js +++ b/components/navigation/MobileNavMenu.js @@ -6,10 +6,20 @@ import toolingItems from './toolingItems'; import communityItems from './communityItems'; import otherItems from './otherItems'; import Link from 'next/link'; +import NavItemDropdown from '../icons/NavItemDropdown'; +import { useState } from 'react'; export default function MobileNavMenu({ onClickClose = () => {} }) { + const [open, setOpen] = useState(); + function showMenu(menu) { + if (open === menu) { + setOpen(null) + return; + } + setOpen(menu); + } return ( -
    +
    @@ -60,37 +70,30 @@ export default function MobileNavMenu({ onClickClose = () => {} }) {
    -
    - -

    - Docs -

    - - -
    -
    - -

    Tools

    - - +
    showMenu('learning')} data-testid="MobileNav-docs"> +

    Docs

    + {open === 'learning' && } +
    +
    showMenu('tooling')} data-testid="MobileNav-tools"> +

    Tools

    + {open === 'tooling' && } +
    +
    showMenu('community')} data-testid="MobileNav-community"> +

    Community

    + {open === 'community' && }
    -
    - -

    Community

    - - +
    showMenu('others')} data-testid="MobileNav-others">
    -

    Others

    - {otherItems.map((item, index) => ( +

    Others

    + {open === 'others' && otherItems.map((item, index) => ( {item.text} diff --git a/components/navigation/NavBar.js b/components/navigation/NavBar.js index 630e74aadf6..235df1c8a8c 100644 --- a/components/navigation/NavBar.js +++ b/components/navigation/NavBar.js @@ -9,7 +9,6 @@ import LearningPanel from './LearningPanel' import CommunityPanel from "./CommunityPanel" import MobileNavMenu from './MobileNavMenu' import otherItems from './otherItems' - import GithubButton from "../buttons/GithubButton" import { SearchButton } from '../AlgoliaSearch'; import IconLoupe from '../icons/Loupe'; @@ -21,12 +20,9 @@ import { useTranslation, } from "../../lib/i18n"; import browserLanguageDetector from "../../lib/browserLanguageDetector"; +import i18nPaths from "../../lib/i18nPaths"; const isMobile = isMobileDevice(); -const uniqueLangs = [...new Set(["EN", "DE"])].map((repo) => ({ - key: repo, - text: repo, -})); export default function NavBar({ className = '', @@ -38,10 +34,46 @@ export default function NavBar({ const [mobileMenuOpen, setMobileMenuOpen] = useState(); const { i18n } = useTranslation(); + /** + * Retrieves unique language options based on the current path and i18nPaths configuration. + * + * @returns {string[]} - An array of unique language options in uppercase. + */ + const getUniqueLangs = () => { + let pathnameWithoutLocale = pathname; + + // Check if the pathname includes "/[lang]", if so, replace it with an empty string + if (pathname && pathname.includes("/[lang]")) { + pathnameWithoutLocale = pathname.replace("/[lang]", ""); + } + + // Filter unique languages based on i18nPaths that include the modified pathnameWithoutLocale + let uniqueLangs = Object.keys(i18nPaths).filter(lang => i18nPaths[lang].includes(pathnameWithoutLocale)).map(lang => lang.toUpperCase()); + + // If no unique languages are found, default to ["EN"] + return uniqueLangs.length === 0 ? ["EN"] : uniqueLangs; + } + + const uniqueLangs = getUniqueLangs().map((lang) => ({ + key: lang, + text: lang, + value: lang + })); + + /** + * Changes the language and updates the URL accordingly. + * + * @async + * @param {string} locale - The new locale/language to set. + * @param {boolean} langPicker - Indicates whether the change is from the language picker. + * If true, stores the language in local storage. + * @returns {Promise} - A promise representing the completion of the language change. + * @throws {Error} - If an error occurs during the language change process. + */ const changeLanguage = async (locale, langPicker) => { // Verifies if the language change is from langPicker or the browser-api - if(langPicker){ + if (langPicker) { localStorage.setItem('i18nLang', locale); } @@ -72,11 +104,6 @@ export default function NavBar({ router.push(href); }; - // To be enabled on the last PR - // useEffect(() => { - // changeLanguage(browserLanguageDetector(), false); - // }, []); - function outsideClick(menu) { if (open !== menu) return; setOpen(null); @@ -100,12 +127,12 @@ export default function NavBar({ useEffect(() => { setMobileMenuOpen(false); setOpen(null); - }, [asPath]) + }, [asPath]); return (
    - Skip to main content -
    + {/* Skip to main content */} +
    {!hideLogo && (
    @@ -173,21 +200,21 @@ export default function NavBar({
    {/* // Language Picker Component */} - {/* { changeLanguage(value.toLowerCase(), true); }} className="" - selected={i18n.language.toLocaleUpperCase()} - /> */} + selected={i18n.language ? i18n.language.toUpperCase() : "EN"} + />
    diff --git a/components/navigation/SubCategoryDocsNav.js b/components/navigation/SubCategoryDocsNav.js new file mode 100644 index 00000000000..87cac1852e1 --- /dev/null +++ b/components/navigation/SubCategoryDocsNav.js @@ -0,0 +1,34 @@ +import { useState, useEffect } from "react"; +import DocsNavItem from "./DocsNavItem"; +import DocsArrow from "../icons/DocsArrow"; + +export default function SubCategoryDocsNav({ subCategory, activeItem, onClick }) { + const [openSubCategoryChildren, setOpenSubCategoryChildren] = useState(activeItem.startsWith(subCategory.item.slug)); + + const onClickHandler = () => { + setOpenSubCategoryChildren(!openSubCategoryChildren); + onClick(); + } + + useEffect(() => { + setOpenSubCategoryChildren(activeItem.startsWith(subCategory.item.slug)); + }, [activeItem]) + + return ( +
  • +
    + setOpenSubCategoryChildren(!openSubCategoryChildren)} /> + +
    + {openSubCategoryChildren && ( +
      + {subCategory.children && subCategory.children.map(subItem => ( +
    • + +
    • + ))} +
    + )} +
  • + ) +} diff --git a/components/navigation/learningItems.js b/components/navigation/learningItems.js index 65ba491f9a9..f04382b44ae 100644 --- a/components/navigation/learningItems.js +++ b/components/navigation/learningItems.js @@ -4,6 +4,7 @@ import IconPlant from '../icons/Plant' import IconGuide from '../icons/Guide' import IconPaper from '../icons/Paper' import IconUsers from '../icons/Users' +import IconMigration from '../icons/Migration' export default [ { href: '/docs/concepts', icon: IconRocket, className: 'bg-secondary-200', title: 'Concepts', description: 'Our Concepts section defines the concepts of AsyncAPI features and capabilities.' }, @@ -11,5 +12,6 @@ export default [ { href: '/docs/tools', icon: IconPlant, className: 'bg-green-200', title: 'Tools', description: 'Our Tools section documents the AsyncAPI tools ecosystem.' }, { href: '/docs/guides', icon: IconGuide, className: 'bg-primary-200', title: 'Guides', description: `Our Guides section teaches AsyncAPI's capabilities at a high level.` }, { href: '/docs/reference', icon: IconPaper, className: 'bg-yellow-200', title: 'Reference', description: `Our Reference section documents the AsyncAPI specification.` }, + { href: '/docs/migration', icon: IconMigration, className: 'bg-blue-400', title: 'Migrations', description: `Our migration guides on how to upgrade to newer AsyncAPI versions.` }, { href: '/docs/community', icon: IconUsers, className: 'bg-red-200', title: 'Community', description: `Our Community section documents the community guidelines and resources.` }, ] diff --git a/components/sponsors/GoldSponsors.js b/components/sponsors/GoldSponsors.js index d8d73bc34bd..af9cf2ed8f8 100644 --- a/components/sponsors/GoldSponsors.js +++ b/components/sponsors/GoldSponsors.js @@ -13,7 +13,7 @@ export default function GoldSponsors({ className = '', showSupportBanner = true data-testid="GoldSponsors-link" > {sponsor.name} + {children} ) diff --git a/config/AMBASSADORS_MEMBERS.json b/config/AMBASSADORS_MEMBERS.json index b953354ef4c..6022f962f20 100644 --- a/config/AMBASSADORS_MEMBERS.json +++ b/config/AMBASSADORS_MEMBERS.json @@ -154,6 +154,90 @@ } ] }, + { + "name": "Ivan Garcia Sainz-Aja", + "github": "ivangsa", + "twitter": "ivangsa", + "bio": "Java Architect with a deep understanding of Java, Spring-Boot, Spring-Cloud technologies, specializing in Domain-Driven Design (DDD) and Event-Driven Architectures creating Software Easy to Understand. Building ZenWave 360ΒΊ. ZenWave 360ΒΊ is a set of tools built on the foundations of Domain Driven Design and API-First principles for Event-Driven Architectures, to help you create software easy to understand. https://www.zenwave360.io/", + "linkedin": "ivangarciasainzaja", + "company": "SNGULAR", + "title": "Java Architect. Speaker. Building ZenWave 360Β°.", + "img": "https://avatars.githubusercontent.com/u/1246876?v=4", + "contributions": [ + { + "type": "iniciative_driver", + "title": "AsyncAPI Conference On Tour 2023 - Madrid", + "date": { + "year": 2023, + "month": "October" + }, + "link": "https://www.youtube.com/playlist?list=PLbi1gRlP7pihD-7XYb6c9wcTdkavDzF3_" + }, + { + "type": "iniciative_driver", + "title": "ZenWave SDK - Code Generator for AsyncAPI with Spring Cloud Streams", + "date": { + "year": 2024, + "month": "2022" + }, + "link": "https://www.zenwave360.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/" + }, + { + "type": "article", + "title": "API-First with AsyncAPI", + "date": { + "year": 2023, + "month": "March" + }, + "link": "https://www.zenwave360.io/posts/API-First-with-AsyncAPI-And-ZenWave-SDK/" + }, + { + "type": "article", + "title": "ZenWave AsyncAPI Code Generator", + "date": { + "year": 2023, + "month": "March" + }, + "link": "https://www.zenwave360.io/posts/ZenWave-AsyncAPI-Code-Generator/" + }, + { + "type": "article", + "title": "Generating AsyncAPI definition files from JDL with ZenWaveSDK", + "date": { + "year": 2023, + "month": "April" + }, + "link": "https://www.zenwave360.io/posts/JHipster-As-IDL-for-AsyncAPIv2/" + }, + { + "type": "presentation", + "title": "KIT - API-First with AsyncAPI for Event Driven Architectures", + "date": { + "year": 2023, + "month": "May" + }, + "link": "https://www.youtube.com/watch?v=EoWFZfmspFM" + }, + { + "type": "presentation", + "title": "Practical Event Storming with AsyncAPI v3 and ZenWave SDK", + "date": { + "year": 2023, + "month": "October" + }, + "link": "https://www.youtube.com/watch?v=-uHONzz-a6U" + }, + { + "type": "presentation", + "title": "Code Generation For Enterprise Integration Patterns w/ AsyncAPI & ZenWave SDK", + "date": { + "year": 2023, + "month": "October" + }, + "link": "https://www.youtube.com/watch?v=gUsoD8RaCuw" + } + ] + }, { "name": "Jesse Menning", "github": "jessemenning", @@ -225,10 +309,10 @@ "github": "M3lkior", "twitter": "ldussart", "country": "πŸ‡«πŸ‡·", - "bio": "Ludovic has been working for Ineat for the last 10 years. Starting as a java developer, he is now a Solutions Architect, working with his customers to build EDA-oriented digital products wherever possible. His first contributions to AsyncAPI date back to 2020 around the kafka and avro specifications. Since then, Ludovic has been spreading the word about AsyncAPI to companies in Northern France, to accelerate adoption of the initiative.", + "bio": "Ludovic is a Solutions Architect, working with his customers to build EDA-oriented digital products wherever possible. His first contributions to AsyncAPI date back to 2020 around the kafka and avro specifications. Since then, Ludovic has been spreading the word about AsyncAPI to companies in Northern France, to accelerate adoption of the initiative.", "linkedin": "ludovic-dussart-846a8063", - "company": "Ineat", - "title": "Solutions Architect", + "company": "zatsit", + "title": "Solutions Architect / DevRel", "img": "https://avatars.githubusercontent.com/u/5501911?s=400&u=d3f33c22f67788aba810ba8e910452aff62ad7c9&v=4", "contributions": [ { @@ -309,7 +393,7 @@ "date": { "year": 2023 }, - "link": "" + "link": "https://www.asyncapi.com/casestudies/adeogroup" }, { "type": "presentation", @@ -327,7 +411,25 @@ "year": 2023, "month": "October" }, + "link": "https://www.youtube.com/watch?v=pFMmQVppV6s" + }, + { + "type": "special contribution", + "title": "Stay at API Days AsyncAPI Booth to share with attendees.", + "date": { + "year": 2023, + "month": "December" + }, "link": "" + }, + { + "type": "presentation", + "title": "Quoi de neuf dans AsyncAPI v3 ? DΓ©couvrez le en live avec la migration du use-case Adeo", + "date": { + "year": 2023, + "month": "December" + }, + "link": "https://www.youtube.com/watch?v=WCK9_ZDv6K4" } ] }, diff --git a/config/MAINTAINERS.json b/config/MAINTAINERS.json index 672d3db2e88..2cc5a6e9f65 100644 --- a/config/MAINTAINERS.json +++ b/config/MAINTAINERS.json @@ -70,6 +70,18 @@ "cupid" ] }, + { + "name": "Ashish Padhy", + "github": "Shurtu-gal", + "linkedin": "ashish-padhy3023", + "slack": "U0572R8J927", + "twitter": "Shurtu_Gal", + "availableForHire": true, + "isTscMember": true, + "repos": [ + "github-action-for-cli" + ] + }, { "name": "Cameron Rushton", "github": "cameronrushton", @@ -338,6 +350,18 @@ "jasyncapi-idea-plugin" ] }, + { + "name": "Prince Rajpoot", + "github": "princerajpoot20", + "linkedin": "princerajpoot", + "slack": "U04STTQHV18", + "twitter": "iamPrince_2003", + "availableForHire": true, + "isTscMember": true, + "repos": [ + "studio" + ] + }, { "name": "Richard Coppen", "github": "rcoppen", @@ -350,6 +374,19 @@ "bindings" ] }, + { + "name": "Samir AMZANI", + "github": "Amzani", + "slack": "U01N6AW5V5G", + "twitter": "amzani", + "linkedin": "amzani", + "availableForHire": false, + "company": "Postman", + "isTscMember": true, + "repos": [ + "studio" + ] + }, { "name": "Sergio Moya", "github": "smoya", @@ -648,5 +685,39 @@ "website", "community" ] + }, + { + "name": "Ashmit JaiSarita Gupta", + "github": "devilkiller-ag", + "linkedin": "jaisarita", + "twitter": "jaisarita", + "slack": "U062LA14E58", + "availableForHire": true, + "isTscMember": true, + "repos": [ + "modelina" + ] + }, + { + "name": "Sambhav Gupta", + "github": "sambhavgupta0705", + "linkedin": "sambhavgupta0705", + "twitter": "sambhavgupta75", + "slack": "U04630DU3N3", + "availableForHire": true, + "isTscMember": true, + "repos": [ + "website" + ] + }, + { + "name": "Viacheslav Turovskyi", + "github": "aeworxet", + "slack": "U01G3U01SVC", + "availableForHire": false, + "isTscMember": false, + "repos": [ + "bundler" + ] } ] \ No newline at end of file diff --git a/config/adopters.json b/config/adopters.json new file mode 100644 index 00000000000..e92e3ed5865 --- /dev/null +++ b/config/adopters.json @@ -0,0 +1 @@ +[{"companyName":"Reiffeisen Bank","useCase":"Continuous Integration and Continuous Delivery (CI/CD) pipeline based on GitOps to deploy a topology built on Async API definitions using a Kubernetes operator to an Apache Pulsar cluster.","resources":[{"title":"Video - From an AsyncAPI Definition to a Deployed Pulsar Topology Via GitOps","link":"https://www.youtube.com/watch?v=_MwzLZMwFN8"}]},{"companyName":"LEGO Group","useCase":"Broker management, where developers do not access the management console themselves, but rely on uploading AsyncAPI documents to a self service API that provisions access and topics specified in documents.","resources":[{"title":"Video - Documentation as Configuration for Management of Apache Pulsar","link":"https://www.youtube.com/watch?v=m8I0fYjx6Cc"}]},{"companyName":"LEGO Group","useCase":"Define, document and distribute event-driven APIs. Ensuring consistency and governance","resources":[{"title":"Video - Cross-Domain Events with AsyncAPI and AWS","link":"https://www.youtube.com/watch?v=qjarcJQVLOg"}]},{"companyName":"Bank of New Zealand","useCase":"Decentralized company-wide governance strategy for API. A self service for publishing APIs and docs.","resources":[{"title":"Video - Self-service Events & Decentralised Governance with AsyncAPI: A Real World Example","link":"https://www.confluent.io/events/kafka-summit-apac-2021/self-service-events-and-decentralised-governance-with-asyncapi-a-real-world/"}]},{"companyName":"Zora Robotics","useCase":"Documenting lot products public MQTT API and building a developers portal.","resources":[{"title":"Video - Buliding and managing an extensive API for Robotics and loT","link":"https://www.youtube.com/watch?v=yjHgT0n2BtA"},{"title":"Docs - Buliding and managing an extensive API for Robotics and loT","link":"https://docs.zorabots.be/dev-mqtt-docs/latest/index.html"}]},{"companyName":"Walmart","useCase":"Managing a central API Hub for internal teams. Using AsyncAPI for events discoverability an visibility in a single place. AsyncAPI also enabled company-wide governance on asynchronous APIs.","resources":[{"title":"Video - Time For AsyncAPI Specification","link":"https://www.youtube.com/watch?v=SxTpGRaNIPo"}]},{"companyName":"eBay","useCase":"Enabling partners to build with eBay through asynchronous communication. Public AsyncAPI documents enable code generation and faster integration. It also enables governance and standardisation.","resources":[{"title":"Video - AsyncAPI 2.0: Enabling the Event-Driven World","link":"https://www.youtube.com/watch?v=SxTpGRaNIPo"},{"title":"Article - AsyncAPI 2.0: Enabling the Event-Driven World","link":"https://innovation.ebayinc.com/tech/engineering/asyncapi-2-0-enabling-the-event-driven-world/"},{"title":"Docs - Overview of Notification API with public AsyncAPI documents","link":"https://developer.ebay.com/api-docs/commerce/notification/overview.html"}]}] \ No newline at end of file diff --git a/config/adopters.yml b/config/adopters.yml new file mode 100644 index 00000000000..0ffaba4966c --- /dev/null +++ b/config/adopters.yml @@ -0,0 +1,83 @@ +- companyName: Reiffeisen Bank + useCase: Implementing a Continuous Integration and Continuous Delivery (CI/CD) pipeline utilizing GitOps principles to deploy a topology constructed on AsyncAPI definitions using a Kubernetes operator to an Apache Pulsar cluster. + resources: + - title: "Video: From an AsyncAPI Definition to a Deployed Pulsar Topology Via GitOps" + link: https://www.youtube.com/watch?v=_MwzLZMwFN8 + +- companyName: LEGO Group + useCase: Managing brokers, where developers abstain from direct access to the management console and instead upload AsyncAPI documents to a self-service API, which provisions access and topics specified in the documents. + resources: + - title: "Video: Documentation as Configuration for Management of Apache Pulsar" + link: https://www.youtube.com/watch?v=m8I0fYjx6Cc + +- companyName: LEGO Group + useCase: Defining, documenting, and distributing event-driven APIs while ensuring consistency and governance. + resources: + - title: "Video: Cross-Domain Events with AsyncAPI and AWS" + link: https://www.youtube.com/watch?v=qjarcJQVLOg + +- companyName: Bank of New Zealand + useCase: Establishing a decentralized company-wide governance strategy for APIs, providing a self-service platform for publishing APIs and documentation. + resources: + - title: "Video: Self-service Events & Decentralised Governance with AsyncAPI: A Real World Example" + link: https://www.confluent.io/events/kafka-summit-apac-2021/self-service-events-and-decentralised-governance-with-asyncapi-a-real-world/ + +- companyName: Zora Robotics + useCase: Documenting public MQTT APIs for IoT products and constructing a developer portal. + resources: + - title: "Video: Building and managing an extensive API for Robotics and IoT" + link: https://www.youtube.com/watch?v=yjHgT0n2BtA + - title: "Docs: Building and managing an extensive API for Robotics and IoT" + link: https://docs.zorabots.be/dev-mqtt-docs/latest/index.html + +- companyName: Walmart + useCase: Managing a centralized API Hub for internal teams, enhancing event discoverability and visibility using AsyncAPI. AsyncAPI facilitates company-wide governance on asynchronous APIs. + resources: + - title: "Video: Time For AsyncAPI Specification" + link: https://www.youtube.com/watch?v=SxTpGRaNIPo + +- companyName: eBay + useCase: Facilitating partner integration with eBay through asynchronous communication, leveraging public AsyncAPI documents for code generation and rapid integration, while ensuring governance and standardization. + resources: + - title: "Video: AsyncAPI 2.0: Enabling the Event-Driven World" + link: https://www.youtube.com/watch?v=SxTpGRaNIPo + - title: "Article: AsyncAPI 2.0: Enabling the Event-Driven World" + link: https://innovation.ebayinc.com/tech/engineering/asyncapi-2-0-enabling-the-event-driven-world/ + - title: "Docs: Overview of Notification API with public AsyncAPI documents" + link: https://developer.ebay.com/api-docs/commerce/notification/overview.html + +- companyName: Postman + useCase: Enhancing discoverability of information about system events by building a tool called Synapse for provisioning entire event-based infrastructure, with AsyncAPI documents as the source of truth. + resources: + - title: "Video: Turbocharging your Developer Ecosystem with Events Powered by SNS/SQS, Serverless, and AsyncAPI" + link: https://www.youtube.com/watch?v=0_7QZyKLPoE + +- companyName: Adobe + useCase: Providing event documentation to expedite development by generating classes based on message payload information from AsyncAPI documents. + resources: + - title: "Slides: AsyncAPI and Modelina" + link: https://drive.google.com/file/d/1AVCG9_fFtuOtrvZVZWENmU2aDT7C51Jr/view?usp=sharing + +- companyName: Open University of Catalonia and Prodevelop + useCase: Enabling monitoring of ports through a design-first approach, utilizing UML class diagrams to design the entire infrastructure. UML diagrams are source of truth for generated AsyncAPI documents that later are used for models and clients generation. These documents are extended with additional SLA properties to specify runtime quality of service requirements, facilitating real-time monitoring. + resources: + - title: "Video: Leveraging AsyncAPI To Detect Anomalies in Smart Ports Platforms" + link: https://www.youtube.com/watch?v=m4KS6FSeTT4 + +- companyName: Oracle + useCase: Documenting data streaming APIs with AsyncAPI documents for client library generation in various programming languages, reducing development time for applications consuming data. + resources: + - title: "Video: Productizing AsyncAPI for Data Replication" + link: https://www.youtube.com/watch?v=CGLlxYy66LY + +- companyName: TransferGo + useCase: Enhancing discoverability of information about event-driven systems by documenting services with AsyncAPI, rendering documentation, and creating catalogs of events. Legacy services utilize a special library to generate AsyncAPI documents, while new services require AsyncAPI documents for generating PHP classes. + resources: + - title: "Slides: How TransferGo Uses AsyncAPI To Improve Developer Experience" + link: https://drive.google.com/file/d/1t7tYMr8FMRInaZV0lWod1QfDuhhSjwBJ/view?usp=sharing + +- companyName: Kuehne+Nagel + useCase: Implementing a GitOps-based pipeline to enable self-service management of Kafka infrastructure, including access control management. Automation of AsyncAPI document governance ensures consistency in the infrastructure at the pull request level. + resources: + - title: "Slides: AsyncAPI For Platform Self-Service: A GitOps Tale" + link: https://drive.google.com/file/d/1y67PI8NaITPPwZAiDF2Zs7ISfcIpqMV8/view?usp=sharing \ No newline at end of file diff --git a/config/all-tags.json b/config/all-tags.json index d9fbea47635..005cc3399f1 100644 --- a/config/all-tags.json +++ b/config/all-tags.json @@ -1 +1 @@ -{"languages":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"},{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"},{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"},{"name":"HTML","color":"bg-[#E2A291]","borderColor":"border-[#E44D26]"},{"name":"C/C++","color":"bg-[#93CDEF]","borderColor":"border-[#0080CC]"},{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"},{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"},{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"},{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"},{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"},{"name":"Markdown","color":"bg-[#BABEBF]","borderColor":"border-[#445B64]"},{"name":"YAML","color":"bg-[#FFB764]","borderColor":"border-[#F1901F]"},{"name":"R","color":"bg-[#84B5ED]","borderColor":"border-[#246BBE]"},{"name":"Ruby","color":"bg-[#FF8289]","borderColor":"border-[#FF000F]"},{"name":"Rust","color":"bg-[#FFB8AA]","borderColor":"border-[#E43716]"},{"name":"Shell","color":"bg-[#87D4FF]","borderColor":"border-[#389ED7]"},{"name":"Groovy","color":"bg-[#B6D5E5]","borderColor":"border-[#609DBC]"}],"technologies":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Hermes","color":"bg-[#8AEEBD]","borderColor":"border-[#2AB672]"},{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"AWS","color":"bg-[#FF9F59]","borderColor":"border-[#EF6703]"},{"name":"Docker","color":"bg-[#B8E0FF]","borderColor":"border-[#2596ED]"},{"name":"Node-RED","color":"bg-[#FF7474]","borderColor":"border-[#8F0101]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Saas","color":"bg-[#6AB8EC]","borderColor":"border-[#2275AD]"},{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Scala","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Azure","color":"bg-[#4B93FF]","borderColor":"border-[#015ADF]"},{"name":"Jenkins","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Nest Js","color":"bg-[#E1224E]","borderColor":"border-[#B9012b]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Kotlin","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Groovy","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Markdown","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Shell","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"WebComponents","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Babel","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Storybook","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JetBrains","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"IntelliJ IDEA","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"HTML","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}]} \ No newline at end of file +{"languages":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"},{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"},{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"},{"name":"HTML","color":"bg-[#E2A291]","borderColor":"border-[#E44D26]"},{"name":"C/C++","color":"bg-[#93CDEF]","borderColor":"border-[#0080CC]"},{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"},{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"},{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"},{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"},{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"},{"name":"Markdown","color":"bg-[#BABEBF]","borderColor":"border-[#445B64]"},{"name":"YAML","color":"bg-[#FFB764]","borderColor":"border-[#F1901F]"},{"name":"R","color":"bg-[#84B5ED]","borderColor":"border-[#246BBE]"},{"name":"Ruby","color":"bg-[#FF8289]","borderColor":"border-[#FF000F]"},{"name":"Rust","color":"bg-[#FFB8AA]","borderColor":"border-[#E43716]"},{"name":"Shell","color":"bg-[#87D4FF]","borderColor":"border-[#389ED7]"},{"name":"Groovy","color":"bg-[#B6D5E5]","borderColor":"border-[#609DBC]"}],"technologies":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Hermes","color":"bg-[#8AEEBD]","borderColor":"border-[#2AB672]"},{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"AWS","color":"bg-[#FF9F59]","borderColor":"border-[#EF6703]"},{"name":"Docker","color":"bg-[#B8E0FF]","borderColor":"border-[#2596ED]"},{"name":"Node-RED","color":"bg-[#FF7474]","borderColor":"border-[#8F0101]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Saas","color":"bg-[#6AB8EC]","borderColor":"border-[#2275AD]"},{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Scala","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Azure","color":"bg-[#4B93FF]","borderColor":"border-[#015ADF]"},{"name":"Jenkins","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Nest Js","color":"bg-[#E1224E]","borderColor":"border-[#B9012b]"},{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Kotlin","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Groovy","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Markdown","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Shell","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"WebComponents","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Babel","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Storybook","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JetBrains","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"IntelliJ IDEA","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"HTML","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Java","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}]} \ No newline at end of file diff --git a/config/finance/2023/Expenses.yml b/config/finance/2023/Expenses.yml new file mode 100644 index 00000000000..f3810dc4d70 --- /dev/null +++ b/config/finance/2023/Expenses.yml @@ -0,0 +1,107 @@ +January: + - Category: Ambassador Program + Amount: '68.95' + - Category: Google Season of Docs 2022 + Amount: '35.62' + - Category: Google Season of Docs 2022 + Amount: '1666.67' + - Category: AsyncAPI Mentorship 2022 + Amount: '1500' + - Category: AsyncAPI Mentorship 2022 + Amount: '1500' + - Category: AsyncAPI Mentorship 2022 + Amount: '1500' + +February: + - Category: Community Manager + Amount: '1000.39' + - Category: AsyncAPI Mentorship 2022 + Amount: '1500' + +March: + - Category: Community Manager + Amount: '2000.39' + - Category: AsyncAPI Mentorship 2022 + Amount: '1500' + - Category: AsyncAPI Mentorship 2022 + Amount: '1500' + +April: + - Category: Community Manager + Amount: '2000.39' + +May: + - Category: Community Manager + Amount: '2000.39' + - Category: Swag Store + Amount: '75.11' + - Category: Bounty Program + Amount: '400' + +June: + - Category: Community Manager + Amount: '2000.39' + - Category: Bounty Program + Amount: '200' + - Category: 3rd Party Services + Amount: '28.31' + - Category: Bounty Program + Amount: '200' + - Category: Bounty Program + Amount: '200' + - Category: Bounty Program + Amount: '200' + +July: + - Category: Community Manager + Amount: '2000.39' + - Category: Bounty Program + Amount: '400' + +August: + - Category: 3rd Party Services + Amount: '1093.92' + - Category: Swag Store + Amount: '15672.02' + - Category: Bounty Program + Amount: '800.78' + - Category: Community Manager + Amount: '2000.39' + +September: + - Category: Ambassador Program + Amount: '139.10' + - Category: Community Manager + Amount: '2000.39' + +October: + - Category: Mentorship Program 2023 + Amount: '5277.78' + - Category: Community Manager + Amount: '2000.39' + - Category: AsyncAPI Conf on Tour 2023 + Amount: '943.07' + - Category: Swag Store + Amount: '7893.72' + - Category: 3rd Party Services + Amount: '247.04' + +November: + - Category: Mentorship Program 2023 + Amount: '1363.50' + - Category: Community Manager + Amount: '2000.39' + - Category: Swag Store + Amount: '873.87' + +December: + - Category: Mentorship Program 2023 + Amount: '675.39' + - Category: Community Manager + Amount: '2000.39' + - Category: AsyncAPI Conf on Tour 2023 + Amount: '1356.34' + - Category: Swag Store + Amount: '1415.90' + - Category: Bounty Program + Amount: '813.10' \ No newline at end of file diff --git a/config/finance/2023/ExpensesLink.yml b/config/finance/2023/ExpensesLink.yml new file mode 100644 index 00000000000..dfbbc3e5d8f --- /dev/null +++ b/config/finance/2023/ExpensesLink.yml @@ -0,0 +1,27 @@ +- category: "Ambassador Program" + link: "https://github.com/orgs/asyncapi/discussions/425" + +- category: "Google Season of Docs 2022" + link: "https://github.com/orgs/asyncapi/discussions/303" + +- category: "AsyncAPI Mentorship 2022" + link: "https://github.com/orgs/asyncapi/discussions/284" + +- category: "Swag Store" + link: "https://github.com/orgs/asyncapi/discussions/710" + +- category: "Bounty Program" + link: "https://github.com/orgs/asyncapi/discussions/541" + +- category: "3rd Party Services" + link: "https://github.com/orgs/asyncapi/discussions/295" + +- category: "Community Manager" + link: "https://github.com/orgs/asyncapi/discussions/515" + +- category: "AsyncAPI Conf on Tour 2023" + link: "https://github.com/orgs/asyncapi/discussions/598" + +- category: "Mentorship Program 2023" + link: "https://github.com/orgs/asyncapi/discussions/689" + \ No newline at end of file diff --git a/config/finance/2024/Expenses.yml b/config/finance/2024/Expenses.yml new file mode 100644 index 00000000000..ee2c9f5d49e --- /dev/null +++ b/config/finance/2024/Expenses.yml @@ -0,0 +1,14 @@ +January: + - Category: JSON Schema Sponsorship + Amount: '250.00' + - Category: Swag Store + Amount: '678.26' + - Category: Bounty Program + Amount: '1800.00' + - Category: Community Manager + Amount: '2000.00' + - Category: AsyncAPI Conf on Tour 2023 + Amount: '318.98' +February: + - Category: JSON Schema Sponsorship + Amount: '250.00' \ No newline at end of file diff --git a/config/finance/2024/ExpensesLink.yml b/config/finance/2024/ExpensesLink.yml new file mode 100644 index 00000000000..449c60ded4b --- /dev/null +++ b/config/finance/2024/ExpensesLink.yml @@ -0,0 +1,29 @@ +- category: "Ambassador Program" + link: "https://github.com/orgs/asyncapi/discussions/425" + +- category: "Google Season of Docs 2023" + link: "https://github.com/orgs/asyncapi/discussions/961" + +- category: "Swag Store" + link: "https://github.com/orgs/asyncapi/discussions/710" + +- category: "Bounty Program" + link: "https://github.com/orgs/asyncapi/discussions/541" + +- category: "3rd Party Services" + link: "https://github.com/orgs/asyncapi/discussions/295" + +- category: "Community Manager" + link: "https://github.com/orgs/asyncapi/discussions/515" + +- category: "AsyncAPI Conf on Tour 2023" + link: "https://github.com/orgs/asyncapi/discussions/598" + +- category: "AsyncAPI Conf on Tour 2024" + link: "https://github.com/orgs/asyncapi/discussions/1018" + +- category: "Mentorship Program 2023" + link: "https://github.com/orgs/asyncapi/discussions/689" + +- category: "JSON Schema Sponsorship" + link: "https://github.com/orgs/asyncapi/discussions/1017" \ No newline at end of file diff --git a/config/mailchimp-config.json b/config/mailchimp-config.json new file mode 100644 index 00000000000..5f423956d39 --- /dev/null +++ b/config/mailchimp-config.json @@ -0,0 +1,8 @@ +{ + "listId": "6e3e437abe", + "interests" : { + "Newsletter": "a7d6314955", + "Meetings": "3505cd49d1", + "TSC Voting": "f7204f9b90" + } +} \ No newline at end of file diff --git a/config/meetings.json b/config/meetings.json index bc62c60adf3..22e635f2fbd 100644 --- a/config/meetings.json +++ b/config/meetings.json @@ -1,114 +1,98 @@ [ - { - "title": "Spec 3.0 Docs Meeting", - "calLink": "https://www.google.com/calendar/event?eid=aHJwdnA1bzI1ajVjNzliZ2h2bm1nZnI3b3MgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/793", - "banner": "", - "date": "2023-08-31T14:30:00.000Z" - }, { "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=Z3YzNDRwamprYzMwNTluYTdtNG1iaHA5NjggY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/845", - "banner": "https://user-images.githubusercontent.com/40604284/260686941-20c44493-65de-4a09-9dac-a8f7d1f0fcaf.png", - "date": "2023-08-22T08:00:00.000Z" + "calLink": "https://www.google.com/calendar/event?eid=ODNjM2h0bGQ4dGhwcWd2Mmw2MWhkcGcycGcgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/918", + "banner": "https://user-images.githubusercontent.com/40604284/277314435-ec985247-c575-4449-9f79-442b3077541a.png", + "date": "2023-11-28T16:00:00.000Z" }, { - "title": "Spec 3.0 Meeting", - "calLink": "https://www.google.com/calendar/event?eid=Y281MHE2dGo1ZmE1cmtobmtyOGYzb3VsazAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/847", - "banner": "", - "date": "2023-08-23T16:00:00.000Z" + "title": "Community Meeting", + "calLink": "https://www.google.com/calendar/event?eid=M2I4MXRidmpqb2ZyZTUyajhsZm41ZjN0bTggY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/979", + "banner": "https://user-images.githubusercontent.com/40604284/288050762-4d064212-22ea-4af0-9d1a-b23c8fd70d6b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDE3ODI2MDUsIm5iZiI6MTcwMTc4MjMwNSwicGF0aCI6Ii80MDYwNDI4NC8yODgwNTA3NjItNGQwNjQyMTItMjJlYS00YWYwLTlkMWEtYjIzYzhmZDcwZDZiLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjA1VDEzMTgyNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWYzOGFhZmI5NzAxODljZDQ4NTFhNDc0NGIxNGQzZDZlZmU3ZjhhYTExOGU1YTRkN2FjODU1MzgzZGU0M2UzNmMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.-FT5AFf2Np1cFxMyXVga0zAfLjFc9fspwL-BJ_t7KLg", + "date": "2023-12-12T08:00:00.000Z" }, { - "title": "Spec 3.0 Meeting", - "calLink": "https://www.google.com/calendar/event?eid=NDEzM2E1ZGE5YWttYXVpYW9zbTl1cWM1YWMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/857", - "banner": "", - "date": "2023-09-06T16:00:00.000Z" + "title": "Overview of AyncAPI v3", + "calLink": "https://www.google.com/calendar/event?eid=c3E0Ym1qMTFnMDY5ODljdGk1ajh2anRrdjAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/981", + "banner": "https://user-images.githubusercontent.com/40604284/285945520-e06ff77c-0e37-432e-964d-b4d47167cc18.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDE3ODI1NzUsIm5iZiI6MTcwMTc4MjI3NSwicGF0aCI6Ii80MDYwNDI4NC8yODU5NDU1MjAtZTA2ZmY3N2MtMGUzNy00MzJlLTk2NGQtYjRkNDcxNjdjYzE4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDUlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjA1VDEzMTc1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWY5MjBhNTEwMjIwNDQxNzczY2EyMDI1YjQzOWIwYzRhY2MxNTU3ZDYyMGY2NzMxYjVkYzYyNmViZTM5Yjg4ZTEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.Dm-WJy2AQO2xUMAJ1nO6ADZuBFYXKj0NEFgdcDd44Fg", + "date": "2023-12-19T13:00:00.000Z" }, { - "title": "AsyncAPI spec v3 support in Diff", - "calLink": "https://www.google.com/calendar/event?eid=YnVvZWt1azlwcTQxNzZnNzNpZ2c3cjdmbzAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/858", - "banner": "", - "date": "2023-08-29T13:30:00.000Z" + "title": "AsyncAPI v3 announcement", + "calLink": "https://www.google.com/calendar/event?eid=NmhzMGZnNTRnZHNnZTFtbnRjbmhpZnJzbjAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "date": "2023-12-06T15:00:00.000Z" }, { - "title": "Brainstorm on AsyncAPI Cheat Sheet Poster", - "calLink": "https://www.google.com/calendar/event?eid=bGx1dXBuc2x1a29mN3RzMmQzcGFjaWM4anMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/862", - "banner": "", - "date": "2023-09-06T09:00:00.000Z" + "title": "3 Request/Reply Use Cases", + "calLink": "https://www.google.com/calendar/event?eid=b3NvM2c0dW9tcTk1djRiMDJmbWU4dG9odGcgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/985", + "banner": "https://user-images.githubusercontent.com/40604284/288488243-e274e624-c5b3-4bff-b0ec-8c1929a24aae.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDE4ODI2MTUsIm5iZiI6MTcwMTg4MjMxNSwicGF0aCI6Ii80MDYwNDI4NC8yODg0ODgyNDMtZTI3NGU2MjQtYzViMy00YmZmLWIwZWMtOGMxOTI5YTI0YWFlLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjA2VDE3MDUxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWUyMGYyNDE3Nzg4OGUyZGVmYjNlMDkxYzVkOWFkNjEwYjM4ZDI2YzZjZmUyYjRjMDliMDQ3YWJiNTVlNDI1MmQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.jYmY72ZRresQv1lMFeKwA49Wi6VkAozRpIHH4uE0J8g", + "date": "2023-12-14T18:00:00.000Z" }, { - "title": "Generator and new parser discussion", - "calLink": "https://www.google.com/calendar/event?eid=bnI2ZHBsa2ZxMDM3bmw5anFtY21pbjF0amMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/865", - "banner": "", - "date": "2023-09-06T15:00:00.000Z" + "title": "Quoi de neuf dans AsyncAPI v3 ? DΓ©couvrez le en live avec la migration du use-case Adeo", + "calLink": "https://www.google.com/calendar/event?eid=Nmk1dm8yZm10dWc0ZXI3MTNtczRhbWkzdTAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/988", + "banner": "https://user-images.githubusercontent.com/40604284/289498866-12bffa57-7db8-491f-917e-8e4f8f5b20a7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTEiLCJleHAiOjE3MDIyODk0MDMsIm5iZiI6MTcwMjI4OTEwMywicGF0aCI6Ii80MDYwNDI4NC8yODk0OTg4NjYtMTJiZmZhNTctN2RiOC00OTFmLTkxN2UtOGU0ZjhmNWIyMGE3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFJV05KWUFYNENTVkVINTNBJTJGMjAyMzEyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjMxMjExVDEwMDUwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTA4ZmVlODI0YzY4OTEwMTVkMWMxNzA3MzE5NGNkZDE4N2RmOTIzMWIwMTExNmQ2YzNiNjRhZGMwYWI5YmU2NjImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.4vALVenjnYGjuQYn4FAT5X3yYBJHi8-bKVpGMriehJc", + "date": "2023-12-14T10:00:00.000Z" }, { "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=aTNsZXN2YzkwbWdyanBxdDgwY2RrbGxnMTggY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/868", - "banner": "https://user-images.githubusercontent.com/40604284/264583319-519e721e-3112-43ca-adab-d68bac288666.png", - "date": "2023-09-05T16:00:00.000Z" + "calLink": "https://www.google.com/calendar/event?eid=dDhmcGZna2lhZmtpZHJhNW4yZ2NjaTVzNmMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1016", + "banner": "https://user-images.githubusercontent.com/40604284/297103292-e05b8e50-1203-4452-8b2d-0983a48a7925.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDU0MTkwMzksIm5iZiI6MTcwNTQxODczOSwicGF0aCI6Ii80MDYwNDI4NC8yOTcxMDMyOTItZTA1YjhlNTAtMTIwMy00NDUyLThiMmQtMDk4M2E0OGE3OTI1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAxMTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMTE2VDE1MjUzOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWFjY2EzYzg2NjNmNTQxOWQxODUxYWMxODlhZWVjNzkwYWRlOWQ5ODkxOTQ4NDhkYWFjNjZjOGU1YTcwMzhhMDYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.hs63wNh2t8iH1xayTqIFvprHHa2Z--RfIA9k3q2lD4Y", + "date": "2024-01-23T16:00:00.000Z" }, { - "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=b3MydnJrN2VuMjNjY3J1Z2IycW9qMDFmZTQgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/874", - "banner": "https://user-images.githubusercontent.com/40604284/266744714-511aeade-19df-4714-bb4e-980af5423171.png", - "date": "2023-09-19T08:00:00.000Z" - }, - { - "title": "Spec 3.0 Docs Meeting", - "calLink": "https://www.google.com/calendar/event?eid=N3VtcTEycDhncjdndWI1cHFvYzRwaG1kYjAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/885", + "title": "AsyncAPI v3 retrospective", + "calLink": "https://www.google.com/calendar/event?eid=ZnNjNTllMW9ydGIwOHEzZTYxY3NncHRyZzQgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1019", "banner": "", - "date": "2023-09-28T14:30:00.000Z" + "date": "2024-02-08T15:00:00.000Z" }, { - "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=MmlicWJyZ2puMzB2c3B1ZmJzdXUxMWFtanMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/894", - "banner": "https://user-images.githubusercontent.com/40604284/271795752-eda6bcf3-4d74-47f0-9061-b2610e710ab2.png", - "date": "2023-10-03T16:00:00.000Z" + "title": "AACoT'24 Community Meeting", + "calLink": "https://www.google.com/calendar/event?eid=YjY3Z3BxdGMzdmRlZmxmNzJpMmQ3MzQwMm8gY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1041", + "banner": "https://user-images.githubusercontent.com/66913810/300802575-5ace2c11-9b6d-4904-b22a-5507ee381360.png", + "date": "2024-02-07T14:00:00.000Z" }, { - "title": "Let's talk about contributing Hacktoberfest 2023", - "calLink": "https://www.google.com/calendar/event?eid=aDRpaTZsbmIyOWIyNnJmZmc0dDRlNXVjN3MgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/895", - "banner": "https://user-images.githubusercontent.com/40604284/271795643-615174df-3bc0-4e7f-b615-cabb6e701234.png", - "date": "2023-10-05T13:00:00.000Z" + "title": "Community Meeting", + "calLink": "https://www.google.com/calendar/event?eid=YnMwYjNoaDVpamYwdjlpcTkwOXRjcmxqODggY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1042", + "banner": "https://github.com/asyncapi/community/assets/40604284/01c2b8de-fa5c-44dd-81a5-70cb96df4813", + "date": "2024-02-06T08:00:00.000Z" }, { "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=Y3FhbWh0bzA5cTc5MnVscTJuZjIzMWg2MmsgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/912", - "banner": "https://user-images.githubusercontent.com/40604284/275363125-696a5c41-81b2-4e0b-a485-f108a7f525f0.png", - "date": "2023-10-17T08:00:00.000Z" + "calLink": "https://www.google.com/calendar/event?eid=ZzZ0OG1iNmkyZW5lbnF2bnE5ZnY5ZW9ua28gY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1067", + "banner": "https://github.com/asyncapi/community/assets/40604284/897e0278-8da4-41dc-b2b2-b5add9370d6f", + "date": "2024-02-20T16:00:00.000Z" }, { "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=ZGk3ZHJybXZhNmM3aWJzNWdzZWdtNTZjMHMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/916", - "banner": "https://user-images.githubusercontent.com/40604284/277314120-f03a06ea-0820-462a-85af-18b1706ea5c6.png", - "date": "2023-10-31T16:00:00.000Z" + "calLink": "https://www.google.com/calendar/event?eid=dHJ1dGxncm81b3VvZjI0ZjE1MDkxY25lcjggY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1068", + "banner": "https://github.com/asyncapi/community/assets/40604284/70eff71e-5de5-4c99-bc89-86a1b9b81e81", + "date": "2024-03-05T08:00:00.000Z" }, { - "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=b3BvZGhqN2xwZXFiMmtvOTQ1M2cwNGRlZTAgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/917", - "banner": "https://user-images.githubusercontent.com/40604284/277314352-f62224d8-03a9-46b2-94bf-13bfae6f973b.png", - "date": "2023-11-14T08:00:00.000Z" + "title": "Essential building blocks for AsyncAPI", + "calLink": "https://www.google.com/calendar/event?eid=dmoyY2ZjNXZ1cDh2cGRiZzFnNG92YzQzZHMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1084", + "banner": "", + "date": "2024-03-12T20:00:00.000Z" }, { - "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=ODNjM2h0bGQ4dGhwcWd2Mmw2MWhkcGcycGcgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/918", - "banner": "https://user-images.githubusercontent.com/40604284/277314435-ec985247-c575-4449-9f79-442b3077541a.png", - "date": "2023-11-28T16:00:00.000Z" + "title": "AACoT'24 Community Meeting", + "calLink": "https://www.google.com/calendar/event?eid=aG9xMzUyam82cDluaDNpY2c2aDBlb25pdDggY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1087", + "banner": "https://github.com/asyncapi/community/assets/66913810/43114d9e-ee7f-4479-8714-475d67a374aa", + "date": "2024-03-13T14:00:00.000Z" } ] \ No newline at end of file diff --git a/config/newsroom_videos.json b/config/newsroom_videos.json index 86f29445b5c..981d1abb3f1 100644 --- a/config/newsroom_videos.json +++ b/config/newsroom_videos.json @@ -1,32 +1,32 @@ [ { - "image_url": "https://i.ytimg.com/vi/KDort611FNg/hqdefault.jpg", - "title": "Community Meeting(November 14th, 2023)", - "description": "https://github.com/asyncapi/community/issues/917.", - "videoId": "KDort611FNg" + "image_url": "https://i.ytimg.com/vi/jO4PwdmKGNw/hqdefault.jpg", + "title": "Community Meeting(5th of March, 2024)", + "description": "https://github.com/asyncapi/community/issues/1068.", + "videoId": "jO4PwdmKGNw" }, { - "image_url": "https://i.ytimg.com/vi/Vm4ZKFb2PVE/hqdefault.jpg", - "title": "Community Meeting(October 31th, 2023)", - "description": "Powered by Restream https://restream.io https://github.com/asyncapi/community/issues/916.", - "videoId": "Vm4ZKFb2PVE" + "image_url": "https://i.ytimg.com/vi/4t4nAmDekDA/hqdefault.jpg", + "title": "AACoT'24 Community Meeting, Wednesday February 7th 2024", + "description": "https://github.com/asyncapi/community/issues/1041.", + "videoId": "4t4nAmDekDA" }, { - "image_url": "https://i.ytimg.com/vi/FN5eR1Zqh9c/hqdefault.jpg", - "title": "AsyncAPI Conf on Tour 2023 in Madrid", - "description": "AACoT'23 Madrid Edition streamed live from StageOne at SNGULAR. 00:00 Waiting 57:12 Opening 1:26:07 Everything You Wish ...", - "videoId": "FN5eR1Zqh9c" + "image_url": "https://i.ytimg.com/vi/8xiLLyIpFpw/hqdefault.jpg", + "title": "Community Meeting, February 6th 2024", + "description": "https://github.com/asyncapi/community/issues/1042.", + "videoId": "8xiLLyIpFpw" }, { - "image_url": "https://i.ytimg.com/vi/zSbv4ibqYds/hqdefault.jpg", - "title": "Community Meeting(October 17th, 2023)", - "description": "https://github.com/asyncapi/community/issues/912.", - "videoId": "zSbv4ibqYds" + "image_url": "https://i.ytimg.com/vi/cb7lrq5hxuE/hqdefault.jpg", + "title": "Community Meeting, January 23rd 2024", + "description": "", + "videoId": "cb7lrq5hxuE" }, { - "image_url": "https://i.ytimg.com/vi/KTnFoXY_evs/hqdefault.jpg", - "title": "Hacktoberfest (October 6th, 2023)", - "description": "https://github.com/asyncapi/community/issues/894.", - "videoId": "KTnFoXY_evs" + "image_url": "https://i.ytimg.com/vi/prFgD14u7T0/hqdefault.jpg", + "title": "Overview of AsyncAPI v3", + "description": "Join us for an insightful stream diving deep into the latest advancements of AsyncAPI v3! We'll explore this cutting-edge ...", + "videoId": "prFgD14u7T0" } ] \ No newline at end of file diff --git a/config/tools-automated.json b/config/tools-automated.json index e4d8bdb7790..11bb2acfecd 100644 --- a/config/tools-automated.json +++ b/config/tools-automated.json @@ -3,45 +3,45 @@ "description": "The following is a list of APIs that expose functionality related to AsyncAPI.", "toolsList": [ { - "title": "AsyncAPI Server API", - "description": "Server API providing official AsyncAPI tools", + "title": "SIO-AsyncAPI", + "description": "This is code-first approach to generate AsyncAPI specification from Socket.IO server.", "links": { - "websiteUrl": "https://api.asyncapi.com/v1", - "docsUrl": "https://api.asyncapi.com/v1/docs", - "repoUrl": "https://github.com/asyncapi/server-api" + "websiteUrl": "https://github.com/daler-rahimov/sio-asyncapi", + "docsUrl": "https://github.com/daler-rahimov/sio-asyncapi", + "repoUrl": "https://github.com/daler-rahimov/sio-asyncapi" }, "filters": { + "language": "Python", "technology": [ - "Node.js", - "TypeScript" + "Socket.IO", + "Flask" ], "categories": [ + "code-first", "api" ], "hasCommercial": false, - "isAsyncAPIOwner": true + "isAsyncAPIOwner": false } }, { - "title": "SIO-AsyncAPI", - "description": "This is code-first approach to generate AsyncAPI specification from Socket.IO server.", + "title": "AsyncAPI Server API", + "description": "Server API providing official AsyncAPI tools", "links": { - "websiteUrl": "https://github.com/daler-rahimov/sio-asyncapi", - "docsUrl": "https://github.com/daler-rahimov/sio-asyncapi", - "repoUrl": "https://github.com/daler-rahimov/sio-asyncapi" + "websiteUrl": "https://api.asyncapi.com/v1", + "docsUrl": "https://api.asyncapi.com/v1/docs", + "repoUrl": "https://github.com/asyncapi/server-api" }, "filters": { - "language": "Python", "technology": [ - "Socket.IO", - "Flask" + "Node.js", + "TypeScript" ], "categories": [ - "code-first", "api" ], "hasCommercial": false, - "isAsyncAPIOwner": false + "isAsyncAPIOwner": true } } ] @@ -117,6 +117,21 @@ "Code Generators": { "description": "The following is a list of tools that generate code from an AsyncAPI document; not the other way around.", "toolsList": [ + { + "title": "Golang AsyncAPI Code Generator", + "description": "Generate Go user and application boilerplate from AsyncAPI specifications. Can be called from `go generate` without requirements.\n", + "links": { + "repoUrl": "https://github.com/lerenn/asyncapi-codegen" + }, + "filters": { + "language": "golang", + "categories": [ + "code-generator" + ], + "hasCommercial": false, + "isAsyncAPIOwner": false + } + }, { "title": "ZenWave SDK", "description": "DDD and API-First for Event-Driven Microservices", @@ -143,21 +158,6 @@ "isAsyncAPIOwner": false } }, - { - "title": "Golang AsyncAPI Code Generator", - "description": "Generate Go user and application boilerplate from AsyncAPI specifications. Can be called from `go generate` without requirements.\n", - "links": { - "repoUrl": "https://github.com/lerenn/asyncapi-codegen" - }, - "filters": { - "language": "golang", - "categories": [ - "code-generator" - ], - "hasCommercial": false, - "isAsyncAPIOwner": false - } - }, { "title": "AsyncAPI Modelina", "description": "Generate payload models into Java, TypeScript, Go, etc, you name it, from AsyncAPI documents. This tool gives you full control over the models through high customization", @@ -304,9 +304,9 @@ "toolsList": [ { "title": "GitHub Action for Generator", - "description": "GitHub Action to generate all the things from your AsyncAPI document using the AsyncAPI generator", + "description": null, "links": { - "repoUrl": "https://github.com/asyncapi/github-action-for-generator" + "repoUrl": "https://github.com/actions-marketplace-validations/asyncapi_github-action-for-generator" }, "filters": { "technology": [ @@ -316,24 +316,24 @@ "github-action" ], "hasCommercial": false, - "isAsyncAPIOwner": true + "isAsyncAPIOwner": false } }, { - "title": "GitHub Action for Generator", - "description": null, + "title": "GitHub Action for CLI", + "description": "GitHub Action with generator, validator, converter and others - all in one for your AsyncAPI documents with AsyncAPI CLI as backbone", "links": { - "repoUrl": "https://github.com/actions-marketplace-validations/asyncapi_github-action-for-generator" + "repoUrl": "https://github.com/asyncapi/github-action-for-cli" }, "filters": { "technology": [ - "AsyncAPI Generator" + "AsyncAPI CLI" ], "categories": [ "github-action" ], "hasCommercial": false, - "isAsyncAPIOwner": false + "isAsyncAPIOwner": true } } ] @@ -413,30 +413,30 @@ "hasCommercial": false, "isAsyncAPIOwner": false } - } - ] - }, - "Compare tools": { - "description": "The following is a list of tools that compare AsyncAPI documents.", - "toolsList": [ + }, { - "title": "AsyncAPI Diff", - "description": "Diff is a library that compares two AsyncAPI Documents and provides information about the differences by pointing out explicitly information like breaking changes.", + "title": "AsyncAPI Validation", + "description": "Message validation package for YAML and JSON AsyncAPI documents.", "links": { - "repoUrl": "https://github.com/asyncapi/diff" + "repoUrl": "https://github.com/Elhebert/asyncapi-validation" }, "filters": { "language": "TypeScript", "technology": [ - "TypeScript" + "Node.js" ], "categories": [ - "compare-tool" + "validator" ], "hasCommercial": false, - "isAsyncAPIOwner": true + "isAsyncAPIOwner": false } - }, + } + ] + }, + "Compare tools": { + "description": "The following is a list of tools that compare AsyncAPI documents.", + "toolsList": [ { "title": "jasyncapicmp", "description": "Tool for comparing two AsyncAPI versions and evaluating compatibility.", @@ -456,6 +456,24 @@ "hasCommercial": false, "isAsyncAPIOwner": false } + }, + { + "title": "AsyncAPI Diff", + "description": "Diff is a library that compares two AsyncAPI Documents and provides information about the differences by pointing out explicitly information like breaking changes.", + "links": { + "repoUrl": "https://github.com/asyncapi/diff" + }, + "filters": { + "language": "TypeScript", + "technology": [ + "TypeScript" + ], + "categories": [ + "compare-tool" + ], + "hasCommercial": false, + "isAsyncAPIOwner": true + } } ] }, @@ -555,15 +573,18 @@ "description": "The following is a list of extensions for different IDEs like VSCode, IntelliJ IDEA and others", "toolsList": [ { - "title": "asyncapi-preview", - "description": "VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n", + "title": "jAsyncAPI - IDEA plugin", + "description": "Idea plugin for the java-asyncapi - Helps to edit and validate AsyncAPI schemas.", "links": { - "repoUrl": "https://github.com/asyncapi/vs-asyncapi-preview" + "websiteUrl": "https://plugins.jetbrains.com/plugin/15673-asyncapi", + "docsUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin#usage", + "repoUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin" }, "filters": { + "language": "Kotlin", "technology": [ - "VSCode", - "SmartPaste" + "JetBrains", + "IntelliJ IDEA" ], "categories": [ "ide-extension" @@ -573,18 +594,15 @@ } }, { - "title": "jAsyncAPI - IDEA plugin", - "description": "Idea plugin for the java-asyncapi - Helps to edit and validate AsyncAPI schemas.", + "title": "asyncapi-preview", + "description": "VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n", "links": { - "websiteUrl": "https://plugins.jetbrains.com/plugin/15673-asyncapi", - "docsUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin#usage", - "repoUrl": "https://github.com/asyncapi/jasyncapi-idea-plugin" + "repoUrl": "https://github.com/asyncapi/vs-asyncapi-preview" }, "filters": { - "language": "Kotlin", "technology": [ - "JetBrains", - "IntelliJ IDEA" + "VSCode", + "SmartPaste" ], "categories": [ "ide-extension" @@ -691,6 +709,26 @@ "hasCommercial": false, "isAsyncAPIOwner": true } + }, + { + "title": "Java Template", + "description": "Java template for the AsyncAPI Generator", + "links": { + "repoUrl": "https://github.com/asyncapi/java-template" + }, + "filters": { + "language": [ + "javascript" + ], + "technology": [ + "Java" + ], + "categories": [ + "generator-template" + ], + "hasCommercial": false, + "isAsyncAPIOwner": true + } } ] }, diff --git a/config/tools.json b/config/tools.json index 9c2ddb1b4e2..2c23899a693 100644 --- a/config/tools.json +++ b/config/tools.json @@ -1 +1 @@ -{"APIs":{"description":"The following is a list of APIs that expose functionality related to AsyncAPI.","toolsList":[{"title":"API Tracker - AsyncAPI specs","description":"Explore APIs and companies with public AsyncAPI specifications.","links":{"websiteUrl":"https://apitracker.io/specifications/asyncapi","repoUrl":""},"filters":{"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI Server API","description":"Server API providing official AsyncAPI tools","links":{"websiteUrl":"https://api.asyncapi.com/v1","docsUrl":"https://api.asyncapi.com/v1/docs","repoUrl":"https://github.com/asyncapi/server-api"},"filters":{"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["api"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI-Directory by APIs.guru","description":"Directory of asynchronous API specifications in AsyncAPI format.","links":{"websiteUrl":"https://apis.guru/asyncapi-directory/","repoUrl":"https://github.com/APIs-guru/asyncapi-directory"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"SIO-AsyncAPI","description":"This is code-first approach to generate AsyncAPI specification from Socket.IO server.","links":{"websiteUrl":"https://github.com/daler-rahimov/sio-asyncapi","docsUrl":"https://github.com/daler-rahimov/sio-asyncapi","repoUrl":"https://github.com/daler-rahimov/sio-asyncapi"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"technology":[{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["code-first","api"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Code-first tools":{"description":"The following is a list of tools that generate AsyncAPI documents from your code.","toolsList":[{"title":"AsyncAPI.Net","description":"The AsyncAPI.NET SDK contains a useful object model for AsyncAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.","links":{"websiteUrl":"https://github.com/LEGO/AsyncAPI.NET/","repoUrl":"https://github.com/LEGO/AsyncAPI.NET"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["converters","code-first","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"EventBridge Atlas","description":"Tool that translates your AWS EventBridge Schemas into an AsyncAPI document and a web UI.","links":{"websiteUrl":"https://eventbridge-atlas.netlify.app/","repoUrl":"https://github.com/boyney123/eventbridge-atlas"},"filters":{"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"FastStream","description":"A powerful and easy-to-use Python framework for building asynchronous services interacting with event streams such as Apache Kafka, RabbitMQ and NATS.","links":{"websiteUrl":"https://faststream.airt.ai","repoUrl":"https://github.com/airtai/FastStream"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"categories":["code-first","framework"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"Go AsyncAPI","description":"This library helps to create AsyncAPI spec from your Go message structures. It uses reflection to translate Go structures in JSON Schema definitions and arrange them in AsyncAPI schema.","links":{"repoUrl":"https://github.com/swaggest/go-asyncapi"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"Java AsyncAPI","description":"This tool stores modules, which simplifies interacting with AsyncAPI in jvm ecosystem.","links":{"repoUrl":"https://github.com/asyncapi/jasyncapi"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Kotlin","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"KnstEventBus","description":"AsyncApi code-first tools for c#. Generates document and view.","links":{"repoUrl":"https://github.com/d0972058277/KnstEventBus"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Kotlin AsyncAPI","description":"The Kotlin AsyncAPI project aims to provide convenience tools for generating and serving AsyncAPI documentation. The core of this project is a Kotlin DSL for building the specification in a typesafe way.","links":{"repoUrl":"https://github.com/OpenFolder/kotlin-asyncapi"},"filters":{"language":[{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"nestjs-asyncapi","description":"Utilize decorators to generate AsyncAPI document utilizing DTOs (similar to @nestjs/swagger) and a web UI.","links":{"repoUrl":"https://github.com/flamewow/nestjs-asyncapi"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Nest Js","color":"bg-[#E1224E]","borderColor":"border-[#B9012b]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Neuroglia AsyncAPI","description":"A .NET SDK for the Async API specification. Automatically generates and serves AsyncAPI documents based on your code. Includes fluent-builders to create AsyncAPI documents from scratch, and provides a web-based GUI to browse generated documents.","links":{"repoUrl":"https://github.com/neuroglia-io/AsyncApi"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Saunter","description":"Saunter is an AsyncAPI documentation generator for dotnet. Generates (and hosts) an AsyncAPI schema document from your code.","links":{"repoUrl":"https://github.com/tehmantra/saunter"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"SIO-AsyncAPI","description":"This is code-first approach to generate AsyncAPI specification from Socket.IO server.","links":{"websiteUrl":"https://github.com/daler-rahimov/sio-asyncapi","docsUrl":"https://github.com/daler-rahimov/sio-asyncapi","repoUrl":"https://github.com/daler-rahimov/sio-asyncapi"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"technology":[{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["code-first","api"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Springwolf","description":"Automated documentation for async APIs built with Spring Boot. Like Springfox for AsyncAPI. Auto-generates an AsyncAPI document and a web UI.","links":{"websiteUrl":"https://www.springwolf.dev","repoUrl":"https://github.com/springwolf/springwolf-core"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"sttp tapir","description":"Library for describing HTTP endpoints, and then interpreting them as a server, client, or documentation","links":{"websiteUrl":"https://tapir.softwaremill.com/","repoUrl":"https://github.com/softwaremill/tapir"},"filters":{"language":[{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}}]},"Code Generators":{"description":"The following is a list of tools that generate code from an AsyncAPI document; not the other way around.","toolsList":[{"title":"AsyncAPI Generator","description":"Generator is a tool that you can use to generate whatever you want basing on the AsyncAPI specification file as an input.","links":{"docsUrl":"https://www.asyncapi.com/docs/tools/generator","repoUrl":"https://github.com/asyncapi/generator"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["code-generator","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI Modelina","description":"Generate payload models into Java, TypeScript, Go, etc, you name it, from AsyncAPI documents. This tool gives you full control over the models through high customization","links":{"websiteUrl":"https://modelina.org","docsUrl":"https://github.com/asyncapi/modelina/tree/master/docs","repoUrl":"https://github.com/asyncapi/modelina"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"Docker","color":"bg-[#B8E0FF]","borderColor":"border-[#2596ED]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Golang AsyncAPI Code Generator","description":"Generate Go user and application boilerplate from AsyncAPI specifications. Can be called from `go generate` without requirements.\n","links":{"repoUrl":"https://github.com/lerenn/asyncapi-codegen"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"MultiAPI Generator","description":"This is a plugin designed to help developers automatizing the creation of code classes from YML files based on AsyncApi and OpenAPI. It is presented in 2 flavours Maven and Gradle","links":{"repoUrl":"https://github.com/sngular/scs-multiapi-plugin"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Groovy","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Node-RED AsyncAPI plugin","description":"A plugin for generating and configuring nodes for Kafka, MQTT, AMQP, etc. automatically from an AsyncAPI specification.","links":{"repoUrl":"https://github.com/dalelane/node-red-contrib-plugin-asyncapi"},"filters":{"technology":[{"name":"Node-RED","color":"bg-[#FF7474]","borderColor":"border-[#8F0101]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Converters":{"description":"The following is a list of tools that do not yet belong to any specific category but are also useful for the community.","toolsList":[{"title":"AsyncAPI-format","description":"Format an AsyncAPI document by ordering, casing, formatting, and filtering fields.","links":{"repoUrl":"https://github.com/thim81/asyncapi-format"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["converter","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI.Net","description":"The AsyncAPI.NET SDK contains a useful object model for AsyncAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.","links":{"websiteUrl":"https://github.com/LEGO/AsyncAPI.NET/","repoUrl":"https://github.com/LEGO/AsyncAPI.NET"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["converters","code-first","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Converter","description":"Converts old versions of AsyncAPI files into the latest version.","links":{"repoUrl":"https://github.com/asyncapi/converter-js"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["converter"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Converter-Go","description":"The AsyncAPI Converter converts AsyncAPI documents from versions 1.0.0, 1.1.0 and 1.2.0 to version 2.0.0. It supports both json and yaml formats on input and output. By default, the AsyncAPI Converter converts a document into the json format.","links":{"repoUrl":"https://github.com/asyncapi/converter-go"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["converter"],"hasCommercial":false,"isAsyncAPIOwner":true,"technology":[]}}]},"Directories":{"description":"The following is a list of directories that index public AsyncAPI documents.","toolsList":[{"title":"API Tracker - AsyncAPI specs","description":"Explore APIs and companies with public AsyncAPI specifications.","links":{"websiteUrl":"https://apitracker.io/specifications/asyncapi","repoUrl":""},"filters":{"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI-Directory by APIs.guru","description":"Directory of asynchronous API specifications in AsyncAPI format.","links":{"websiteUrl":"https://apis.guru/asyncapi-directory/","repoUrl":"https://github.com/APIs-guru/asyncapi-directory"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Documentation Generators":{"description":"The following is a list of tools that generate human-readable documentation from an AsyncAPI document.","toolsList":[{"title":"AsyncAPI Generator","description":"Generator is a tool that you can use to generate whatever you want basing on the AsyncAPI specification file as an input.","links":{"docsUrl":"https://www.asyncapi.com/docs/tools/generator","repoUrl":"https://github.com/asyncapi/generator"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Markdown","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"asyncapi-asciidoc-template","description":"Asciidoc template for the asyncapi generator","links":{"repoUrl":"https://gitlab.com/djencks/asyncapi-asciidoc-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"}],"categories":["documentation-generator","generator-template"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Bump.sh","description":"OpenAPI 2 & 3 / AsyncAPI 2 documentation generator, with automatic changelog and visual diff.","links":{"websiteUrl":"https://bump.sh/","repoUrl":""},"filters":{"categories":["documentation-generator"],"hasCommercial":true,"isAsyncAPIOwner":false,"technology":[]}},{"title":"Cupid","description":"A library that focuses on finding and analyzing the relationships between AsyncAPI documents. It outputs a map of the system architecture.","links":{"repoUrl":"https://github.com/asyncapi/cupid"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"KnstEventBus","description":"AsyncApi code-first tools for c#. Generates document and view.","links":{"repoUrl":"https://github.com/d0972058277/KnstEventBus"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Springwolf","description":"Automated documentation for async APIs built with Spring Boot. Like Springfox for AsyncAPI. Auto-generates an AsyncAPI document and a web UI.","links":{"websiteUrl":"https://www.springwolf.dev","repoUrl":"https://github.com/springwolf/springwolf-core"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Widdershins","description":"OpenAPI 3.0 / Swagger 2.0 / AsyncAPI 1.0 definition to Slate / Shins compatible markdown.","links":{"websiteUrl":"https://mermade.github.io/reslate/","repoUrl":"https://github.com/Mermade/widdershins"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Shell","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Editors":{"description":"The following is a list of editors or related tools that allow editing of AsyncAPI document.","toolsList":[{"title":"AsyncAPI Studio","description":"Visually design your AsyncAPI files and event-driven architecture.","links":{"websiteUrl":"https://studio.asyncapi.com","repoUrl":"https://github.com/asyncapi/studio"},"filters":{"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["editor"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"UI components":{"description":"The following is a list of UI components to view AsyncAPI documents.","toolsList":[{"title":"Api-Diff-Viewer","description":"React component to view the difference between two Json based API documents. Supported specifications: JsonSchema, OpenAPI 3.x, AsyncAPI 2.x.","links":{"repoUrl":"https://github.com/udamir/api-diff-viewer","websiteUrl":"https://api-diff-viewer.vercel.app/"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"Babel","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Storybook","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ui-component"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI React component","description":"React component for rendering documentation from your specification in real-time in the browser. It also provides a WebComponent and bundle for Angular and Vue","links":{"repoUrl":"https://github.com/asyncapi/asyncapi-react"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"WebComponents","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ui-component"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"DSL":{"description":"Writing YAML by hand is no fun, and maybe you don't want a GUI, so use a Domain Specific Language to write AsyncAPI in your language of choice.","toolsList":[{"title":"BOATS","description":"Compile your single AsyncAPI file from multiple YAML files with BOATS and with the help of the template engine Nunjucks, plus a many extra helpers to automate much of the donkey work.","links":{"repoUrl":"https://github.com/j-d-carmichael/boats"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["dsl"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Frameworks":{"description":"The following is a list of API/application frameworks that make use of AsyncAPI.","toolsList":[{"title":"Asynction","description":"SocketIO server framework driven by the AsyncAPI specification. Asynction guarantees that your API will work in accordance with its AsyncAPI documentation. Built on top of Flask-SocketIO.","links":{"websiteUrl":"https://pypi.org/project/asynction/","repoUrl":"https://github.com/dedoussis/asynction"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"technology":[{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["framework"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"FastStream","description":"A powerful and easy-to-use Python framework for building asynchronous services interacting with event streams such as Apache Kafka, RabbitMQ and NATS.","links":{"websiteUrl":"https://faststream.airt.ai","repoUrl":"https://github.com/airtai/FastStream"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"categories":["code-first","framework"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}}]},"GitHub Actions":{"description":"The following is a list of GitHub Actions that you can use in your workflows","toolsList":[{"title":"API documentation generation on Bump.sh","description":"With this GitHub Action you can automatically generate your API reference (with the changelog and diff) on Bump.sh from any AsyncAPI file.","links":{"websiteUrl":"https://github.com/marketplace/actions/api-documentation-on-bump","repoUrl":"https://github.com/bump-sh/github-action"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI GitHub Action","description":"This action validates if the AsyncAPI schema file is valid or not.","links":{"websiteUrl":"https://github.com/marketplace/actions/asyncapi-github-action","repoUrl":"https://github.com/WaleedAshraf/asyncapi-github-action"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["github-action","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Automated version bump for AsyncAPI documents","description":"With this GitHub Action, you can automatically bump the version based on commit messages, which is similar to what semantic-release is for NPM.","links":{"websiteUrl":"https://github.com/marketplace/actions/automated-version-bump-for-asyncapi","repoUrl":"https://github.com/bump-sh/github-action"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"GitHub Action for Generator","description":"GitHub Action to generate all the things from your AsyncAPI document using the AsyncAPI generator","links":{"repoUrl":"https://github.com/asyncapi/github-action-for-generator"},"filters":{"technology":[{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"GitHub Action for Generator","description":null,"links":{"repoUrl":"https://github.com/actions-marketplace-validations/asyncapi_github-action-for-generator"},"filters":{"technology":[{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Mocking and Testing":{"description":"The tools below take specification documents as input, then publish fake messages to broker destinations for simulation purposes. They may also check that publisher messages are compliant with schemas.","toolsList":[{"title":"Microcks","description":"Mocking and testing platform for API and microservices. Turn your AsyncAPI, OpenAPI contract examples, or Postman collections into ready-to-use mocks. Use examples to simulate and validate received messages according to schema elements.","links":{"websiteUrl":"https://microcks.io/","repoUrl":"https://github.com/microcks/microcks"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Saas","color":"bg-[#6AB8EC]","borderColor":"border-[#2275AD]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"MultiAPI Converter","description":"Use AsyncAPI definition, to generate Spring Cloud Contract producer validation or consumer stubs, using maven.","links":{"repoUrl":"https://github.com/sngular/scc-multiapi-converter"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Specmatic","description":"An API contract testing tool that helps ensure the correctness APIs by automatically generating test cases and verifying them against the API spec. It simplifies the process of testing APIs and reduces the likelihood of bugs and compatibility issues.","links":{"websiteUrl":"https://specmatic.in","docsUrl":"https://specmatic.in/documentation/","repoUrl":"https://github.com/znsio/specmatic"},"filters":{"language":[{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Virtualan","description":"Mocking and testing platform for API and microservices. Allows you to create and setup mocks for OpenAPI and AsyncAPI contracts. Shows how to setup and create AsyncAPI GitHub Reference Examples and OpenAPI GitHub Reference Examples.","links":{"websiteUrl":"https://www.virtualan.io/index.html","repoUrl":"https://github.com/virtualansoftware"},"filters":{"technology":[{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Validators":{"description":"The following is a list of tools that validate AsyncAPI documents.","toolsList":[{"title":"AMF","description":"AMF (AML Modeling Framework) is an open-source library capable of parsing and validating AML metadata documents.","links":{"docsUrl":"https://a.ml/docs/","repoUrl":"https://github.com/aml-org/amf"},"filters":{"language":[{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI GitHub Action","description":"This action validates if the AsyncAPI schema file is valid or not.","links":{"websiteUrl":"https://github.com/marketplace/actions/asyncapi-github-action","repoUrl":"https://github.com/WaleedAshraf/asyncapi-github-action"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["github-action","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI Parser","description":"Use this package to parse and validate AsyncAPI documents β€”either YAML or JSONβ€” in your Node.js or browser application. Updated bundle for the browser is always attached to the GitHub Release.","links":{"repoUrl":"https://github.com/asyncapi/parser-js"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI Parser","description":"The AsyncAPI Parser validates AsyncAPI documents according to dedicated schemas.","links":{"repoUrl":"https://github.com/asyncapi/parser-go"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":true,"technology":[]}},{"title":"AsyncAPI Parser Wrapper","description":"Use this library to parse and validate AsyncAPI documents β€” either YAML or JSON β€” in your Java application. It is a Java wrapper over JavaScript Parser implemented using J2V8.","links":{"repoUrl":"https://github.com/AsyncAPITools/parser-java-wrapper"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"asyncapi-validator","description":"It allows you to validate the schema of your messages against your AsyncAPI schema definition. You can use it with Kafka, RabbitMQ or any other messaging/queue.","links":{"repoUrl":"https://github.com/WaleedAshraf/asyncapi-validator"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI.Net","description":"The AsyncAPI.NET SDK contains a useful object model for AsyncAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.","links":{"websiteUrl":"https://github.com/LEGO/AsyncAPI.NET/","repoUrl":"https://github.com/LEGO/AsyncAPI.NET"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["converters","code-first","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Spectral","description":"A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI v3.1, v3.0, and v2.0 as well as AsyncAPI v2.x.","links":{"repoUrl":"https://github.com/stoplightio/spectral"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Compare tools":{"description":"The following is a list of tools that compare AsyncAPI documents.","toolsList":[{"title":"Api-Smart-Diff","description":"It allows you to compare two API documents and classify changes. Supported API specifications: OpenAPI, AsyncAPI, JsonSchema.","links":{"repoUrl":"https://github.com/udamir/api-smart-diff"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI Diff","description":"Diff is a library that compares two AsyncAPI Documents and provides information about the differences by pointing out explicitly information like breaking changes.","links":{"repoUrl":"https://github.com/asyncapi/diff"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"jasyncapicmp","description":"Tool for comparing two AsyncAPI versions and evaluating compatibility.","links":{"websiteUrl":"https://siom79.github.io/jasyncapicmp/","docsUrl":"https://github.com/siom79/jasyncapicmp","repoUrl":"https://github.com/siom79/jasyncapicmp"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"jasyncapicmp","description":"Tool/library/maven-plugin for comparing two AsyncAPI versions and evaluating compatibility.","links":{"websiteUrl":"https://siom79.github.io/jasyncapicmp/","repoUrl":"https://github.com/siom79/jasyncapicmp"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"CLIs":{"description":"The following is a list of tools that you can work with in terminal or do some CI/CD automation.","toolsList":[{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/asyncapi/cli"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/hkirat/asyncapi-fork"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI-format","description":"Format an AsyncAPI document by ordering, casing, formatting, and filtering fields.","links":{"repoUrl":"https://github.com/asyncapi/converter-go"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["converter","cli"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Bundlers":{"description":"The following is a list of tools that you can work with to bundle AsyncAPI documents.","toolsList":[{"title":"Api-ref-bundler","description":"It allows you bundle/dereference external/internal $refs in Json based API document. Supported specifications: OpenAPI, AsyncAPI, JsonSchema.","links":{"repoUrl":"https://github.com/udamir/api-ref-bundler"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["bundler"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI Bundler","description":"Combine multiple AsyncAPI specification files into one.","links":{"repoUrl":"https://github.com/asyncapi/bundler"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["bundler"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"IDE Extensions":{"description":"The following is a list of extensions for different IDEs like VSCode, IntelliJ IDEA and others","toolsList":[{"title":"asyncapi-preview","description":"VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n","links":{"repoUrl":"https://github.com/asyncapi/vs-asyncapi-preview"},"filters":{"technology":[{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ide-extension"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"asyncapi-preview","description":"VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n","links":{"repoUrl":"https://github.com/Savio629/testing2"},"filters":{"technology":[{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ide-extension"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"jAsyncAPI - IDEA plugin","description":"Idea plugin for the java-asyncapi - Helps to edit and validate AsyncAPI schemas.","links":{"websiteUrl":"https://plugins.jetbrains.com/plugin/15673-asyncapi","docsUrl":"https://github.com/asyncapi/jasyncapi-idea-plugin#usage","repoUrl":"https://github.com/asyncapi/jasyncapi-idea-plugin"},"filters":{"language":[{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"}],"technology":[{"name":"JetBrains","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"IntelliJ IDEA","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ide-extension"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"AsyncAPI Generator Templates":{"description":"The following is a list of templates compatible with AsyncAPI Generator. You can use them to generate apps, clients or documentation from your AsyncAPI documents.","toolsList":[{"title":"HTML Template","description":"HTML template for AsyncAPI Generator. Use it to generate a static docs. It is using AsyncAPI React component under the hood.","links":{"repoUrl":"https://github.com/asyncapi/html-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"HTML","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Java Spring Template","description":"Java Spring template for the AsyncAPI Generator","links":{"repoUrl":"https://github.com/asyncapi/java-spring-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Node.js Multiprotocol Template","description":"This template generates a server using your AsyncAPI document. It supports multiple different protocols, like Kafka or MQTT. It is designed in the way that generated code is a library and with it's API you can start the server, send messages or register a middleware for listening incoming messages. Runtime message validation included.","links":{"repoUrl":"https://github.com/asyncapi/nodejs-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Node.js Websockets Template","description":"Node.js WebSockets template for the AsyncAPI Generator. It showcases how from a single AsyncAPI document you can generate a server and a client at the same time.","links":{"repoUrl":"https://github.com/asyncapi/nodejs-ws-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"Others":{"description":"The following is a list of tools that comes under Other category.","toolsList":[{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/asyncapi/cli"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/hkirat/asyncapi-fork"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]}} \ No newline at end of file +{"APIs":{"description":"The following is a list of APIs that expose functionality related to AsyncAPI.","toolsList":[{"title":"API Tracker - AsyncAPI specs","description":"Explore APIs and companies with public AsyncAPI specifications.","links":{"websiteUrl":"https://apitracker.io/specifications/asyncapi","repoUrl":""},"filters":{"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI Server API","description":"Server API providing official AsyncAPI tools","links":{"websiteUrl":"https://api.asyncapi.com/v1","docsUrl":"https://api.asyncapi.com/v1/docs","repoUrl":"https://github.com/asyncapi/server-api"},"filters":{"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["api"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI-Directory by APIs.guru","description":"Directory of asynchronous API specifications in AsyncAPI format.","links":{"websiteUrl":"https://apis.guru/asyncapi-directory/","repoUrl":"https://github.com/APIs-guru/asyncapi-directory"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"SIO-AsyncAPI","description":"This is code-first approach to generate AsyncAPI specification from Socket.IO server.","links":{"websiteUrl":"https://github.com/daler-rahimov/sio-asyncapi","docsUrl":"https://github.com/daler-rahimov/sio-asyncapi","repoUrl":"https://github.com/daler-rahimov/sio-asyncapi"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"technology":[{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["code-first","api"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Code-first tools":{"description":"The following is a list of tools that generate AsyncAPI documents from your code.","toolsList":[{"title":"AsyncAPI.Net","description":"The AsyncAPI.NET SDK contains a useful object model for AsyncAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.","links":{"websiteUrl":"https://github.com/LEGO/AsyncAPI.NET/","repoUrl":"https://github.com/LEGO/AsyncAPI.NET"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["converters","code-first","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"EventBridge Atlas","description":"Tool that translates your AWS EventBridge Schemas into an AsyncAPI document and a web UI.","links":{"websiteUrl":"https://eventbridge-atlas.netlify.app/","repoUrl":"https://github.com/boyney123/eventbridge-atlas"},"filters":{"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"FastStream","description":"A powerful and easy-to-use Python framework for building asynchronous services interacting with event streams such as Apache Kafka, RabbitMQ and NATS.","links":{"websiteUrl":"https://faststream.airt.ai","repoUrl":"https://github.com/airtai/FastStream"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"categories":["code-first","framework"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"Go AsyncAPI","description":"This library helps to create AsyncAPI spec from your Go message structures. It uses reflection to translate Go structures in JSON Schema definitions and arrange them in AsyncAPI schema.","links":{"repoUrl":"https://github.com/swaggest/go-asyncapi"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"Java AsyncAPI","description":"This tool stores modules, which simplifies interacting with AsyncAPI in jvm ecosystem.","links":{"repoUrl":"https://github.com/asyncapi/jasyncapi"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Kotlin","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"KnstEventBus","description":"AsyncApi code-first tools for c#. Generates document and view.","links":{"repoUrl":"https://github.com/d0972058277/KnstEventBus"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Kotlin AsyncAPI","description":"The Kotlin AsyncAPI project aims to provide convenience tools for generating and serving AsyncAPI documentation. The core of this project is a Kotlin DSL for building the specification in a typesafe way.","links":{"repoUrl":"https://github.com/OpenFolder/kotlin-asyncapi"},"filters":{"language":[{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"nestjs-asyncapi","description":"Utilize decorators to generate AsyncAPI document utilizing DTOs (similar to @nestjs/swagger) and a web UI.","links":{"repoUrl":"https://github.com/flamewow/nestjs-asyncapi"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Nest Js","color":"bg-[#E1224E]","borderColor":"border-[#B9012b]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Neuroglia AsyncAPI","description":"A .NET SDK for the Async API specification. Automatically generates and serves AsyncAPI documents based on your code. Includes fluent-builders to create AsyncAPI documents from scratch, and provides a web-based GUI to browse generated documents.","links":{"repoUrl":"https://github.com/neuroglia-io/AsyncApi"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Saunter","description":"Saunter is an AsyncAPI documentation generator for dotnet. Generates (and hosts) an AsyncAPI schema document from your code.","links":{"repoUrl":"https://github.com/tehmantra/saunter"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"SIO-AsyncAPI","description":"This is code-first approach to generate AsyncAPI specification from Socket.IO server.","links":{"websiteUrl":"https://github.com/daler-rahimov/sio-asyncapi","docsUrl":"https://github.com/daler-rahimov/sio-asyncapi","repoUrl":"https://github.com/daler-rahimov/sio-asyncapi"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"technology":[{"name":"Socket.IO","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["code-first","api"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Springwolf","description":"Automated documentation for async APIs built with Spring Boot. Like Springfox for AsyncAPI. Auto-generates an AsyncAPI document and a web UI.","links":{"websiteUrl":"https://www.springwolf.dev","repoUrl":"https://github.com/springwolf/springwolf-core"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"sttp tapir","description":"Library for describing HTTP endpoints, and then interpreting them as a server, client, or documentation","links":{"websiteUrl":"https://tapir.softwaremill.com/","repoUrl":"https://github.com/softwaremill/tapir"},"filters":{"language":[{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"}],"categories":["code-first"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}}]},"Code Generators":{"description":"The following is a list of tools that generate code from an AsyncAPI document; not the other way around.","toolsList":[{"title":"AsyncAPI Generator","description":"Generator is a tool that you can use to generate whatever you want basing on the AsyncAPI specification file as an input.","links":{"docsUrl":"https://www.asyncapi.com/docs/tools/generator","repoUrl":"https://github.com/asyncapi/generator"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["code-generator","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI Modelina","description":"Generate payload models into Java, TypeScript, Go, etc, you name it, from AsyncAPI documents. This tool gives you full control over the models through high customization","links":{"websiteUrl":"https://modelina.org","docsUrl":"https://github.com/asyncapi/modelina/tree/master/docs","repoUrl":"https://github.com/asyncapi/modelina"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"Docker","color":"bg-[#B8E0FF]","borderColor":"border-[#2596ED]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Golang AsyncAPI Code Generator","description":"Generate Go user and application boilerplate from AsyncAPI specifications. Can be called from `go generate` without requirements.\n","links":{"repoUrl":"https://github.com/lerenn/asyncapi-codegen"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"MultiAPI Generator","description":"This is a plugin designed to help developers automatizing the creation of code classes from YML files based on AsyncApi and OpenAPI. It is presented in 2 flavours Maven and Gradle","links":{"repoUrl":"https://github.com/sngular/scs-multiapi-plugin"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Groovy","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Node-RED AsyncAPI plugin","description":"A plugin for generating and configuring nodes for Kafka, MQTT, AMQP, etc. automatically from an AsyncAPI specification.","links":{"repoUrl":"https://github.com/dalelane/node-red-contrib-plugin-asyncapi"},"filters":{"technology":[{"name":"Node-RED","color":"bg-[#FF7474]","borderColor":"border-[#8F0101]"}],"categories":["code-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Converters":{"description":"The following is a list of tools that do not yet belong to any specific category but are also useful for the community.","toolsList":[{"title":"AsyncAPI-format","description":"Format an AsyncAPI document by ordering, casing, formatting, and filtering fields.","links":{"repoUrl":"https://github.com/thim81/asyncapi-format"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["converter","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI.Net","description":"The AsyncAPI.NET SDK contains a useful object model for AsyncAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.","links":{"websiteUrl":"https://github.com/LEGO/AsyncAPI.NET/","repoUrl":"https://github.com/LEGO/AsyncAPI.NET"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["converters","code-first","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Converter","description":"Converts old versions of AsyncAPI files into the latest version.","links":{"repoUrl":"https://github.com/asyncapi/converter-js"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["converter"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Converter-Go","description":"The AsyncAPI Converter converts AsyncAPI documents from versions 1.0.0, 1.1.0 and 1.2.0 to version 2.0.0. It supports both json and yaml formats on input and output. By default, the AsyncAPI Converter converts a document into the json format.","links":{"repoUrl":"https://github.com/asyncapi/converter-go"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["converter"],"hasCommercial":false,"isAsyncAPIOwner":true,"technology":[]}}]},"Directories":{"description":"The following is a list of directories that index public AsyncAPI documents.","toolsList":[{"title":"API Tracker - AsyncAPI specs","description":"Explore APIs and companies with public AsyncAPI specifications.","links":{"websiteUrl":"https://apitracker.io/specifications/asyncapi","repoUrl":""},"filters":{"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI-Directory by APIs.guru","description":"Directory of asynchronous API specifications in AsyncAPI format.","links":{"websiteUrl":"https://apis.guru/asyncapi-directory/","repoUrl":"https://github.com/APIs-guru/asyncapi-directory"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["api","directory"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Documentation Generators":{"description":"The following is a list of tools that generate human-readable documentation from an AsyncAPI document.","toolsList":[{"title":"AsyncAPI Generator","description":"Generator is a tool that you can use to generate whatever you want basing on the AsyncAPI specification file as an input.","links":{"docsUrl":"https://www.asyncapi.com/docs/tools/generator","repoUrl":"https://github.com/asyncapi/generator"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Markdown","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"asyncapi-asciidoc-template","description":"Asciidoc template for the asyncapi generator","links":{"repoUrl":"https://gitlab.com/djencks/asyncapi-asciidoc-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"}],"categories":["documentation-generator","generator-template"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Bump.sh","description":"OpenAPI 2 & 3 / AsyncAPI 2 documentation generator, with automatic changelog and visual diff.","links":{"websiteUrl":"https://bump.sh/","repoUrl":""},"filters":{"categories":["documentation-generator"],"hasCommercial":true,"isAsyncAPIOwner":false,"technology":[]}},{"title":"Cupid","description":"A library that focuses on finding and analyzing the relationships between AsyncAPI documents. It outputs a map of the system architecture.","links":{"repoUrl":"https://github.com/asyncapi/cupid"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"KnstEventBus","description":"AsyncApi code-first tools for c#. Generates document and view.","links":{"repoUrl":"https://github.com/d0972058277/KnstEventBus"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"},{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Springwolf","description":"Automated documentation for async APIs built with Spring Boot. Like Springfox for AsyncAPI. Auto-generates an AsyncAPI document and a web UI.","links":{"websiteUrl":"https://www.springwolf.dev","repoUrl":"https://github.com/springwolf/springwolf-core"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Widdershins","description":"OpenAPI 3.0 / Swagger 2.0 / AsyncAPI 1.0 definition to Slate / Shins compatible markdown.","links":{"websiteUrl":"https://mermade.github.io/reslate/","repoUrl":"https://github.com/Mermade/widdershins"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"Shell","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["documentation-generator"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Editors":{"description":"The following is a list of editors or related tools that allow editing of AsyncAPI document.","toolsList":[{"title":"AsyncAPI Studio","description":"Visually design your AsyncAPI files and event-driven architecture.","links":{"websiteUrl":"https://studio.asyncapi.com","repoUrl":"https://github.com/asyncapi/studio"},"filters":{"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["editor"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"UI components":{"description":"The following is a list of UI components to view AsyncAPI documents.","toolsList":[{"title":"Api-Diff-Viewer","description":"React component to view the difference between two Json based API documents. Supported specifications: JsonSchema, OpenAPI 3.x, AsyncAPI 2.x.","links":{"repoUrl":"https://github.com/udamir/api-diff-viewer","websiteUrl":"https://api-diff-viewer.vercel.app/"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"Babel","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Storybook","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ui-component"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI React component","description":"React component for rendering documentation from your specification in real-time in the browser. It also provides a WebComponent and bundle for Angular and Vue","links":{"repoUrl":"https://github.com/asyncapi/asyncapi-react"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"React JS","color":"bg-[#9FECFA]","borderColor":"border-[#08D8FE]"},{"name":"WebComponents","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ui-component"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"DSL":{"description":"Writing YAML by hand is no fun, and maybe you don't want a GUI, so use a Domain Specific Language to write AsyncAPI in your language of choice.","toolsList":[{"title":"BOATS","description":"Compile your single AsyncAPI file from multiple YAML files with BOATS and with the help of the template engine Nunjucks, plus a many extra helpers to automate much of the donkey work.","links":{"repoUrl":"https://github.com/j-d-carmichael/boats"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["dsl"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Frameworks":{"description":"The following is a list of API/application frameworks that make use of AsyncAPI.","toolsList":[{"title":"Asynction","description":"SocketIO server framework driven by the AsyncAPI specification. Asynction guarantees that your API will work in accordance with its AsyncAPI documentation. Built on top of Flask-SocketIO.","links":{"websiteUrl":"https://pypi.org/project/asynction/","repoUrl":"https://github.com/dedoussis/asynction"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"technology":[{"name":"Flask","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["framework"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"FastStream","description":"A powerful and easy-to-use Python framework for building asynchronous services interacting with event streams such as Apache Kafka, RabbitMQ and NATS.","links":{"websiteUrl":"https://faststream.airt.ai","repoUrl":"https://github.com/airtai/FastStream"},"filters":{"language":[{"name":"Python","color":"bg-[#A8D0EF]","borderColor":"border-[#3878AB]"}],"categories":["code-first","framework"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}}]},"GitHub Actions":{"description":"The following is a list of GitHub Actions that you can use in your workflows","toolsList":[{"title":"API documentation generation on Bump.sh","description":"With this GitHub Action you can automatically generate your API reference (with the changelog and diff) on Bump.sh from any AsyncAPI file.","links":{"websiteUrl":"https://github.com/marketplace/actions/api-documentation-on-bump","repoUrl":"https://github.com/bump-sh/github-action"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI GitHub Action","description":"This action validates if the AsyncAPI schema file is valid or not.","links":{"websiteUrl":"https://github.com/marketplace/actions/asyncapi-github-action","repoUrl":"https://github.com/WaleedAshraf/asyncapi-github-action"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["github-action","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Automated version bump for AsyncAPI documents","description":"With this GitHub Action, you can automatically bump the version based on commit messages, which is similar to what semantic-release is for NPM.","links":{"websiteUrl":"https://github.com/marketplace/actions/automated-version-bump-for-asyncapi","repoUrl":"https://github.com/bump-sh/github-action"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"GitHub Action for CLI","description":"GitHub Action with generator, validator, converter and others - all in one for your AsyncAPI documents with AsyncAPI CLI as backbone","links":{"repoUrl":"https://github.com/asyncapi/github-action-for-cli"},"filters":{"technology":[{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"GitHub Action for Generator","description":null,"links":{"repoUrl":"https://github.com/actions-marketplace-validations/asyncapi_github-action-for-generator"},"filters":{"technology":[{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Mocking and Testing":{"description":"The tools below take specification documents as input, then publish fake messages to broker destinations for simulation purposes. They may also check that publisher messages are compliant with schemas.","toolsList":[{"title":"Microcks","description":"Mocking and testing platform for API and microservices. Turn your AsyncAPI, OpenAPI contract examples, or Postman collections into ready-to-use mocks. Use examples to simulate and validate received messages according to schema elements.","links":{"websiteUrl":"https://microcks.io/","repoUrl":"https://github.com/microcks/microcks"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"},{"name":"Saas","color":"bg-[#6AB8EC]","borderColor":"border-[#2275AD]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"MultiAPI Converter","description":"Use AsyncAPI definition, to generate Spring Cloud Contract producer validation or consumer stubs, using maven.","links":{"repoUrl":"https://github.com/sngular/scc-multiapi-converter"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Specmatic","description":"An API contract testing tool that helps ensure the correctness APIs by automatically generating test cases and verifying them against the API spec. It simplifies the process of testing APIs and reduces the likelihood of bugs and compatibility issues.","links":{"websiteUrl":"https://specmatic.in","docsUrl":"https://specmatic.in/documentation/","repoUrl":"https://github.com/znsio/specmatic"},"filters":{"language":[{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Virtualan","description":"Mocking and testing platform for API and microservices. Allows you to create and setup mocks for OpenAPI and AsyncAPI contracts. Shows how to setup and create AsyncAPI GitHub Reference Examples and OpenAPI GitHub Reference Examples.","links":{"websiteUrl":"https://www.virtualan.io/index.html","repoUrl":"https://github.com/virtualansoftware"},"filters":{"technology":[{"name":"Kubernetes-native","color":"bg-[#D7C7F2]","borderColor":"border-[#A387D2]"}],"categories":["mocking-and-testing"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Validators":{"description":"The following is a list of tools that validate AsyncAPI documents.","toolsList":[{"title":"AMF","description":"AMF (AML Modeling Framework) is an open-source library capable of parsing and validating AML metadata documents.","links":{"docsUrl":"https://a.ml/docs/","repoUrl":"https://github.com/aml-org/amf"},"filters":{"language":[{"name":"Scala","color":"bg-[#FFA299]","borderColor":"border-[#DF301F]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI GitHub Action","description":"This action validates if the AsyncAPI schema file is valid or not.","links":{"websiteUrl":"https://github.com/marketplace/actions/asyncapi-github-action","repoUrl":"https://github.com/WaleedAshraf/asyncapi-github-action"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["github-action","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI Parser","description":"Use this package to parse and validate AsyncAPI documents β€”either YAML or JSONβ€” in your Node.js or browser application. Updated bundle for the browser is always attached to the GitHub Release.","links":{"repoUrl":"https://github.com/asyncapi/parser-js"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI Parser","description":"The AsyncAPI Parser validates AsyncAPI documents according to dedicated schemas.","links":{"repoUrl":"https://github.com/asyncapi/parser-go"},"filters":{"language":[{"name":"Go/Golang","color":"bg-[#8ECFDF]","borderColor":"border-[#00AFD9]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":true,"technology":[]}},{"title":"AsyncAPI Parser Wrapper","description":"Use this library to parse and validate AsyncAPI documents β€” either YAML or JSON β€” in your Java application. It is a Java wrapper over JavaScript Parser implemented using J2V8.","links":{"repoUrl":"https://github.com/AsyncAPITools/parser-java-wrapper"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI Validation","description":"Message validation package for YAML and JSON AsyncAPI documents.","links":{"repoUrl":"https://github.com/Elhebert/asyncapi-validation"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"asyncapi-validator","description":"It allows you to validate the schema of your messages against your AsyncAPI schema definition. You can use it with Kafka, RabbitMQ or any other messaging/queue.","links":{"repoUrl":"https://github.com/WaleedAshraf/asyncapi-validator"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI.Net","description":"The AsyncAPI.NET SDK contains a useful object model for AsyncAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.","links":{"websiteUrl":"https://github.com/LEGO/AsyncAPI.NET/","repoUrl":"https://github.com/LEGO/AsyncAPI.NET"},"filters":{"language":[{"name":"C#","color":"bg-[#E3AFE0]","borderColor":"border-[#9B4F96]"}],"technology":[{"name":".NET","color":"bg-[#A184FF]","borderColor":"border-[#5026D4]"},{"name":"ASP.NET","color":"bg-[#71C2FB]","borderColor":"border-[#1577BC]"}],"categories":["converters","code-first","validator"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"Spectral","description":"A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI v3.1, v3.0, and v2.0 as well as AsyncAPI v2.x.","links":{"repoUrl":"https://github.com/stoplightio/spectral"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["validator"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Compare tools":{"description":"The following is a list of tools that compare AsyncAPI documents.","toolsList":[{"title":"Api-Smart-Diff","description":"It allows you to compare two API documents and classify changes. Supported API specifications: OpenAPI, AsyncAPI, JsonSchema.","links":{"repoUrl":"https://github.com/udamir/api-smart-diff"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":false,"technology":[]}},{"title":"AsyncAPI Diff","description":"Diff is a library that compares two AsyncAPI Documents and provides information about the differences by pointing out explicitly information like breaking changes.","links":{"repoUrl":"https://github.com/asyncapi/diff"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"jasyncapicmp","description":"Tool for comparing two AsyncAPI versions and evaluating compatibility.","links":{"websiteUrl":"https://siom79.github.io/jasyncapicmp/","docsUrl":"https://github.com/siom79/jasyncapicmp","repoUrl":"https://github.com/siom79/jasyncapicmp"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"jasyncapicmp","description":"Tool/library/maven-plugin for comparing two AsyncAPI versions and evaluating compatibility.","links":{"websiteUrl":"https://siom79.github.io/jasyncapicmp/","repoUrl":"https://github.com/siom79/jasyncapicmp"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"categories":["compare-tool"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"CLIs":{"description":"The following is a list of tools that you can work with in terminal or do some CI/CD automation.","toolsList":[{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/asyncapi/cli"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/hkirat/asyncapi-fork"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI-format","description":"Format an AsyncAPI document by ordering, casing, formatting, and filtering fields.","links":{"repoUrl":"https://github.com/asyncapi/converter-go"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["converter","cli"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"ZenWave SDK","description":"DDD and API-First for Event-Driven Microservices","links":{"websiteUrl":"https://zenwave360.github.io/","docsUrl":"https://zenwave360.github.io/zenwave-sdk/plugins/asyncapi-spring-cloud-streams3/","repoUrl":"https://github.com/zenwave360/zenwave-sdk"},"filters":{"language":[{"name":"Java","color":"bg-[#ECA2A4]","borderColor":"border-[#EC2125]"}],"technology":[{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Liquid","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"JHipster JDL","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-generator","dsl","mocking-and-testing","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"Bundlers":{"description":"The following is a list of tools that you can work with to bundle AsyncAPI documents.","toolsList":[{"title":"Api-ref-bundler","description":"It allows you bundle/dereference external/internal $refs in Json based API document. Supported specifications: OpenAPI, AsyncAPI, JsonSchema.","links":{"repoUrl":"https://github.com/udamir/api-ref-bundler"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["bundler"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"AsyncAPI Bundler","description":"Combine multiple AsyncAPI specification files into one.","links":{"repoUrl":"https://github.com/asyncapi/bundler"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["bundler"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"IDE Extensions":{"description":"The following is a list of extensions for different IDEs like VSCode, IntelliJ IDEA and others","toolsList":[{"title":"asyncapi-preview","description":"VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n","links":{"repoUrl":"https://github.com/asyncapi/vs-asyncapi-preview"},"filters":{"technology":[{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ide-extension"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"asyncapi-preview","description":"VSCode extension that enables you to:\n - Preview documentation generated using you AsyncAPI document. It uses AsyncAPI React component under the hood,\n - Create AsyncAPI documents faster using SmartPaste functionality\n","links":{"repoUrl":"https://github.com/Savio629/testing2"},"filters":{"technology":[{"name":"VSCode","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"SmartPaste","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ide-extension"],"hasCommercial":false,"isAsyncAPIOwner":false}},{"title":"jAsyncAPI - IDEA plugin","description":"Idea plugin for the java-asyncapi - Helps to edit and validate AsyncAPI schemas.","links":{"websiteUrl":"https://plugins.jetbrains.com/plugin/15673-asyncapi","docsUrl":"https://github.com/asyncapi/jasyncapi-idea-plugin#usage","repoUrl":"https://github.com/asyncapi/jasyncapi-idea-plugin"},"filters":{"language":[{"name":"Kotlin","color":"bg-[#B1ACDF]","borderColor":"border-[#756BD9]"}],"technology":[{"name":"JetBrains","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"IntelliJ IDEA","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["ide-extension"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"AsyncAPI Generator Templates":{"description":"The following is a list of templates compatible with AsyncAPI Generator. You can use them to generate apps, clients or documentation from your AsyncAPI documents.","toolsList":[{"title":"HTML Template","description":"HTML template for AsyncAPI Generator. Use it to generate a static docs. It is using AsyncAPI React component under the hood.","links":{"repoUrl":"https://github.com/asyncapi/html-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"HTML","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Java Spring Template","description":"Java Spring template for the AsyncAPI Generator","links":{"repoUrl":"https://github.com/asyncapi/java-spring-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Springboot","color":"bg-[#98E279]","borderColor":"border-[#68BC44]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"},{"name":"Gradle","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Java Template","description":"Java template for the AsyncAPI Generator","links":{"repoUrl":"https://github.com/asyncapi/java-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Java","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Node.js Multiprotocol Template","description":"This template generates a server using your AsyncAPI document. It supports multiple different protocols, like Kafka or MQTT. It is designed in the way that generated code is a library and with it's API you can start the server, send messages or register a middleware for listening incoming messages. Runtime message validation included.","links":{"repoUrl":"https://github.com/asyncapi/nodejs-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Node.js Websockets Template","description":"Node.js WebSockets template for the AsyncAPI Generator. It showcases how from a single AsyncAPI document you can generate a server and a client at the same time.","links":{"repoUrl":"https://github.com/asyncapi/nodejs-ws-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"}],"categories":["generator-template"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"Others":{"description":"The following is a list of tools that comes under Other category.","toolsList":[{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/asyncapi/cli"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"AsyncAPI CLI","description":"One CLI to rule them all. \nThis is a CLI that aims to integrate all AsyncAPI tools that you need while AsyncAPI document development and maintainance. \nYou can use it to generate docs or code, validate AsyncAPI document and event create new documents.\n","links":{"websiteUrl":"https://www.asyncapi.com/tools/cli","repoUrl":"https://github.com/hkirat/asyncapi-fork"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["others","cli"],"hasCommercial":false,"isAsyncAPIOwner":false}}]}} \ No newline at end of file diff --git a/cypress/test/Asyncapi3Comparison.cy.js b/cypress/test/Asyncapi3Comparison.cy.js new file mode 100644 index 00000000000..15893bfd5f9 --- /dev/null +++ b/cypress/test/Asyncapi3Comparison.cy.js @@ -0,0 +1,40 @@ +import { mount } from '@cypress/react' +import {Asyncapi3Comparison, Asyncapi3ChannelComparison, Asyncapi3IdAndAddressComparison, Asyncapi3MetaComparison, Asyncapi3OperationComparison, Asyncapi3SchemaFormatComparison, Asyncapi3ServerComparison} from '../../components/Asyncapi3Comparison' + +describe('Asyncapi3Comparison.cy', () => { + describe('Asyncapi3Comparison', () => { + it('renders without errors', () => { + mount(); + }); + }); + describe('Asyncapi3ChannelComparison', () => { + it('renders without errors', () => { + mount(); + }); + }); + describe('Asyncapi3IdAndAddressComparison', () => { + it('renders without errors', () => { + mount(); + }); + }); + describe('Asyncapi3MetaComparison', () => { + it('renders without errors', () => { + mount(); + }); + }); + describe('Asyncapi3OperationComparison', () => { + it('renders without errors', () => { + mount(); + }); + }); + describe('Asyncapi3SchemaFormatComparison', () => { + it('renders without errors', () => { + mount(); + }); + }); + describe('Asyncapi3ServerComparison', () => { + it('renders without errors', () => { + mount(); + }); + }); +}); diff --git a/cypress/test/components/CaseStudyCard.cy.js b/cypress/test/components/CaseStudyCard.cy.js index 2e14e4b176f..d0809517f0f 100644 --- a/cypress/test/components/CaseStudyCard.cy.js +++ b/cypress/test/components/CaseStudyCard.cy.js @@ -1,7 +1,8 @@ import React from 'react'; import { mount } from 'cypress/react'; import CaseStudyCard from '../../../components/CaseStudyCard'; -import CaseStudiesList from "../../../config/case-studies.json"; +import CaseStudiesList from '../../../config/case-studies.json'; + describe('CaseStudyCard Component', () => { it('renders the CaseStudyCard component with study data', () => { diff --git a/cypress/test/components/NewsletterSubscribe.cy.js b/cypress/test/components/NewsletterSubscribe.cy.js index d6f07fed824..0870489d019 100644 --- a/cypress/test/components/NewsletterSubscribe.cy.js +++ b/cypress/test/components/NewsletterSubscribe.cy.js @@ -9,8 +9,6 @@ describe('NewsletterSubscribe Component', () => { cy.get('[data-testid="NewsletterSubscribe-main"]').should('exist'); cy.get('[data-testid="NewsletterSubscribe-text-input"]').type("name"); cy.get('[data-testid="NewsletterSubscribe-email-input"]').type("test@gmail.com") - cy.get('form[name="form 1"]').should('exist'); - cy.get('input[name="type"]').should('exist'); cy.get('input[name="name"]').should('exist'); cy.get('input[name="email"]').should('exist'); diff --git a/cypress/test/components/campaignTests/AnnouncementHero.cy.js b/cypress/test/components/campaignTests/AnnouncementHero.cy.js index 3d5444d9b20..a2dc55b29bc 100644 --- a/cypress/test/components/campaignTests/AnnouncementHero.cy.js +++ b/cypress/test/components/campaignTests/AnnouncementHero.cy.js @@ -7,26 +7,28 @@ beforeEach(() => { mount(); }); +// .skip should be removed once the AnnouncementHero component is rendered in the website describe('AnnouncementHero Component', () => { - it('should render the component when the date is within the valid range', () => { + it.skip('should render the component when the date is within the valid range', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); cy.get('[data-testid="AnnouncementHero-main-div"]').should('exist'); }); //check if announcement rendered is small or large . - it('should render a small announcement when "small" prop is true', () => { + it.skip('should render a small announcement when "small" prop is true', () => { mount(); cy.get('[data-testid="AnnouncementHero-main-div"]').should('have.class', 'mb-4'); }); - it('should display the correct event information', () => { + it.skip('should display the correct event information', () => { // Assert the event details cy.get('[data-testid="Paragraph-test"]').should('exist'); cy.get('h2').should('exist'); }); - it('should have a link and text for the button', () => { + + it.skip('should have a link and text for the button', () => { mount(); cy.get('[data-testid="Button-link"]') .should('have.attr', 'target', '_blank') @@ -38,7 +40,7 @@ describe('AnnouncementHero Component', () => { }); //check if announcement rendered is small or large . - it('should render a small announcement when "small" prop is true', () => { + it.skip('should render a small announcement when "small" prop is true', () => { const mockDate = new Date('2023-05-01T00:00:00Z'); cy.clock(mockDate.getTime()); @@ -47,7 +49,7 @@ describe('AnnouncementHero Component', () => { cy.get('[data-testid="AnnouncementHero-main-div"]').should('have.class', 'mb-4'); }); - it('should render a large announcement when "small" prop is false', () => { + it.skip('should render a large announcement when "small" prop is false', () => { const mockDate = new Date('2023-05-01T00:00:00Z'); cy.clock(mockDate.getTime()); diff --git a/cypress/test/components/campaignTests/Banner.cy.js b/cypress/test/components/campaignTests/Banner.cy.js index 5ec6e4a1b47..fb196376002 100644 --- a/cypress/test/components/campaignTests/Banner.cy.js +++ b/cypress/test/components/campaignTests/Banner.cy.js @@ -2,8 +2,9 @@ import React from 'react'; import { mount } from '@cypress/react'; import Banner from '../../../../components/campaigns/Banner'; +// .skip should be removed once the Banner component is rendered in the website with default functionalities describe('Banner Component', () => { - it('should not render the banner when the date is not within the valid range', () => { + it.skip('should not render the banner when the date is not within the valid range', () => { const today = new Date(); const [day, month, year] = [today.getUTCDate(), today.getUTCMonth(), today.getUTCFullYear()]; if (year > 2022 || month !== 10 || day < 6) { @@ -17,21 +18,21 @@ describe('Banner Component', () => { } }); - it('should render the banner when the date is within the valid range', () => { + it.skip('should render the banner when the date is within the valid range', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); cy.get('[data-testid="Banner-main-div"]').should('be.visible'); }); - it('should display the correct message when the date is within the valid range', () => { + it.skip('should display the correct message when the date is within the valid range', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); cy.contains('.font-medium', 'AsyncAPI Conference 2022 has ended').should('be.visible'); }); - it('should have a link to the recordings playlist', () => { + it.skip('should have a link to the recordings playlist', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); @@ -41,7 +42,7 @@ describe('Banner Component', () => { .should('have.attr', 'rel', 'noopener noreferrer'); }); - it('should have the max-w-screen-xl class in the div element', () => { + it.skip('should have the max-w-screen-xl class in the div element', () => { const mockDate = new Date(2021, 10, 12).getTime(); cy.clock(mockDate); mount(); diff --git a/cypress/test/components/navigation/MobileNavMenu.cy.js b/cypress/test/components/navigation/MobileNavMenu.cy.js index c16542fd044..f160acf1d6d 100644 --- a/cypress/test/components/navigation/MobileNavMenu.cy.js +++ b/cypress/test/components/navigation/MobileNavMenu.cy.js @@ -13,5 +13,6 @@ describe('MobileNavMenu', () => { cy.get('[data-testid="MobileNav-docs"]').should('exist') cy.get('[data-testid="MobileNav-tools"]').should('exist') cy.get('[data-testid="MobileNav-others"]').should('exist') + cy.get('[data-testid="MobileNav-community"]').should('exist') }); }); diff --git a/cypress/test/pages/casestudies/index.cy.js b/cypress/test/pages/casestudies/index.cy.js index e8907f6baad..282ae639e05 100644 --- a/cypress/test/pages/casestudies/index.cy.js +++ b/cypress/test/pages/casestudies/index.cy.js @@ -1,6 +1,8 @@ import Casestudies from "../../../../pages/casestudies"; import MockApp from "../../../utils/MockApp"; -import {mount} from 'cypress/react'; +import { mount } from 'cypress/react'; +import AdoptersList from "../../../../config/adopters.json" + describe('Test for Case Study Pages', () => { it('renders correctly', () => { mount( @@ -8,7 +10,32 @@ describe('Test for Case Study Pages', () => { ); - cy.get('[data-testid="CaseStudy-main"]').should('exist'); - cy.get('[data-testid="CaseStudy-card"]').should('exist'); + cy.get('[data-testid="CaseStudy-main"]').should('exist'); + cy.get('[data-testid="CaseStudy-card"]').should('exist'); }); + + it('Adopters section renders correctly', () => { + mount( + + + + ); + cy.get('[data-testid="Adopters"]').should('have.length', AdoptersList.length); + + cy.get('table') + .should('exist') + .within(() => { + // Check table headers + cy.get('th').eq(0).should('have.text', 'Company name'); + cy.get('th').eq(1).should('have.text', 'Use Case'); + cy.get('th').eq(2).should('have.text', 'Resources'); + + // Check table data + cy.get('tbody tr').should('have.length', AdoptersList.length); + AdoptersList.forEach((entry, index) => { + cy.get('tbody tr').eq(index).find('td').eq(0).should('have.text', entry.companyName); + cy.get('tbody tr').eq(index).find('td').eq(1).should('have.text', entry.useCase); + }); + }); + }) }); \ No newline at end of file diff --git a/cypress/test/pages/community/dashboard.cy.js b/cypress/test/pages/community/dashboard.cy.js index da33c1cc006..610155d4631 100644 --- a/cypress/test/pages/community/dashboard.cy.js +++ b/cypress/test/pages/community/dashboard.cy.js @@ -22,7 +22,7 @@ describe('Integration Test for Dashboard ', () => { cy.contains('asyncapi/generator'); cy.contains('docs') //check if this is not selected options are not displayed - cy.should('not.contain', 'asyncapi/community'); - cy.should('not.contain', 'javascript'); + // cy.should('not.contain', 'asyncapi/community'); + // cy.should('not.contain', 'javascript'); }); }); \ No newline at end of file diff --git a/cypress/test/pages/community/index.cy.js b/cypress/test/pages/community/index.cy.js index 7eb0b28b3ff..c5a3e5ecd58 100644 --- a/cypress/test/pages/community/index.cy.js +++ b/cypress/test/pages/community/index.cy.js @@ -44,9 +44,7 @@ describe('CommunityIndexPage', () => { it('should display other cards correctly', () => { cy.get('[data-testid="CommunityCards-Goals"]').should('exist'); - cy.get('[href="https://github.com/asyncapi/community/discussions/513"]').should('exist'); - cy.get('[data-testid="CommunityCards-Contributors"]').should('exist'); - cy.get('[href="https://github.com/orgs/asyncapi/discussions/593"]').should('exist'); + cy.get('[href="https://github.com/orgs/asyncapi/discussions/948"]').should('exist'); cy.get('[data-testid="CommunityCards-TSC"]').should('exist'); cy.get('[href="/community/tsc"]').should('exist'); }); diff --git a/cypress/test/scripts/dashboard/build-dashboard.cy.js b/cypress/test/scripts/dashboard/build-dashboard.cy.js index cbcee3e09da..9b5487069bb 100644 --- a/cypress/test/scripts/dashboard/build-dashboard.cy.js +++ b/cypress/test/scripts/dashboard/build-dashboard.cy.js @@ -17,9 +17,13 @@ describe('getLabel function', () => { describe('monthsSince function', () => { // Define some sample dates and expected results const today = new Date(); - const oneMonthAgo = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate()); - const twoMonthsAgo = new Date(today.getFullYear(), today.getMonth() - 2, today.getDate()); - const threeMonthsAgo = new Date(today.getFullYear(), today.getMonth() - 3, today.getDate()); + + // number of miliseconds in a month + const month = 30 * 24 * 60 * 60 * 1000; + + const oneMonthAgo = today - month; + const twoMonthsAgo = today - 2 * month; + const threeMonthsAgo = today - 3 * month; // Write the test cases it('should return 0 for the same date', () => { diff --git a/dashboard.json b/dashboard.json index 95da8b15dc9..0a2a2f90832 100644 --- a/dashboard.json +++ b/dashboard.json @@ -1,123 +1,120 @@ { "hotDiscussions": [ { - "id": "MDU6SXNzdWU5ODkyOTg0MzY=", - "isPR": false, - "isAssigned": true, - "title": "Proposal to solve publish/subscribe confusion", - "author": "fmvilas", - "resourcePath": "/asyncapi/spec/issues/618", - "repo": "asyncapi/spec", - "labels": [ - { - "name": "πŸ’­ Strawman (RFC 0)", - "color": "C2E0C6" - } - ], - "score": 54.2759972736099 + "id": "PR_kwDOBW5R_c5f0CJh", + "isPR": true, + "isAssigned": false, + "title": "docs: tutorial for managing schemas with Schema Registry", + "author": "Arya-Gupta", + "resourcePath": "/asyncapi/website/pull/2331", + "repo": "asyncapi/website", + "labels": [], + "score": 27.56876051992884 }, { - "id": "PR_kwDOBW5R_c5Xb72L", + "id": "PR_kwDOBW5R_c5fbyLb", "isPR": true, "isAssigned": false, - "title": "feat: implement the asyncapi financial summary page", - "author": "vishvamsinh28", - "resourcePath": "/asyncapi/website/pull/2038", + "title": "docs: tutorial for bindings with Kafka", + "author": "CynthiaPeter", + "resourcePath": "/asyncapi/website/pull/2318", "repo": "asyncapi/website", "labels": [], - "score": 41.065966191144 + "score": 22.9739670999407 }, { - "id": "I_kwDOFLhIt84-OUI3", - "isPR": false, + "id": "PR_kwDOFLhIt85bqKL8", + "isPR": true, "isAssigned": false, - "title": "Create educational & technical video explaining AsyncAPI's main features", - "author": "alequetzalli", - "resourcePath": "/asyncapi/community/issues/155", + "title": "docs: add Bounty Program Rules", + "author": "aeworxet", + "resourcePath": "/asyncapi/community/pull/897", "repo": "asyncapi/community", - "labels": [ - { - "name": "enhancement", - "color": "a2eeef" - } - ], - "score": 33.31225229491402 + "labels": [], + "score": 21.538094156194408 }, { - "id": "MDU6SXNzdWU5OTMxODc5ODM=", + "id": "I_kwDOBW5R_c5J6qNe", "isPR": false, "isAssigned": false, - "title": "Proposal to allow defining schema format other than default one (AsyncAPI Schema)", - "author": "magicmatatjahu", - "resourcePath": "/asyncapi/spec/issues/622", - "repo": "asyncapi/spec", + "title": "Measuring AsyncAPI spec adoption", + "author": "derberg", + "resourcePath": "/asyncapi/website/issues/780", + "repo": "asyncapi/website", "labels": [ { - "name": "stale", - "color": "819cd3" + "name": "enhancement", + "color": "84b6eb" }, { - "name": "πŸ’­ Strawman (RFC 0)", - "color": "C2E0C6" + "name": "stale", + "color": "ededed" } ], - "score": 23.26114168868996 + "score": 20.102221212448114 }, { - "id": "I_kwDOBGu-184_rP6l", + "id": "I_kwDODou01c5AqLB8", "isPR": false, "isAssigned": false, - "title": "Let channels be identified by an ID rather than their address.", + "title": "\"Open with Studio\" button for Markdown files.", "author": "smoya", - "resourcePath": "/asyncapi/spec/issues/663", - "repo": "asyncapi/spec", + "resourcePath": "/asyncapi/studio/issues/218", + "repo": "asyncapi/studio", "labels": [ { - "name": "πŸ’­ Strawman (RFC 0)", - "color": "C2E0C6" + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "keep-open", + "color": "f9dd4b" } ], - "score": 21.825268744943667 + "score": 19.527872034949596 }, { - "id": "I_kwDOGJ23c85V9C3c", + "id": "I_kwDOFDnrNc51TZDT", "isPR": false, - "isAssigned": false, - "title": "Support `referenceIntoComponents` for other components than `message`", - "author": "thake", - "resourcePath": "/asyncapi/bundler/issues/97", - "repo": "asyncapi/bundler", + "isAssigned": true, + "title": "Improve CLI UI and UX", + "author": "fmvilas", + "resourcePath": "/asyncapi/cli/issues/872", + "repo": "asyncapi/cli", "labels": [ { "name": "enhancement", "color": "a2eeef" + }, + { + "name": "bounty", + "color": "0e8a16" + }, + { + "name": "level/medium", + "color": "0e8a16" } ], - "score": 20.102221212448114 + "score": 18.091999091203302 }, { - "id": "MDU6SXNzdWUzNjkwNDExMDc=", - "isPR": false, + "id": "PR_kwDOFLhIt85js7KX", + "isPR": true, "isAssigned": false, - "title": "Support request/reply pattern", - "author": "adrianhopebailie", - "resourcePath": "/asyncapi/spec/issues/94", - "repo": "asyncapi/spec", - "labels": [ - { - "name": "keep-open", - "color": "fce250" - } - ], - "score": 20.070109582694446 + "title": "chore: add documents CoC Committee and Incident Resolution Procedures", + "author": "Barbanio", + "resourcePath": "/asyncapi/community/pull/1013", + "repo": "asyncapi/community", + "labels": [], + "score": 18.091999091203302 }, { - "id": "I_kwDOBW5R_c5BIl5P", + "id": "I_kwDOBW5R_c580Z0o", "isPR": false, - "isAssigned": true, - "title": "Add new page for collecting user testing participants", - "author": "mcturco", - "resourcePath": "/asyncapi/website/issues/529", + "isAssigned": false, + "title": "New Contributor Guide and Maintenance Setup", + "author": "derberg", + "resourcePath": "/asyncapi/website/issues/2586", "repo": "asyncapi/website", "labels": [ { @@ -125,109 +122,125 @@ "color": "84b6eb" } ], - "score": 19.527872034949596 + "score": 16.65612614745701 }, { - "id": "I_kwDOE8Qh385nTCST", + "id": "I_kwDODou01c5E_LV0", "isPR": false, "isAssigned": false, - "title": "Improve layout of playground", - "author": "jonaslagoni", - "resourcePath": "/asyncapi/modelina/issues/1346", - "repo": "asyncapi/modelina", + "title": "Create onboarding for features of Studio", + "author": "mcturco", + "resourcePath": "/asyncapi/studio/issues/284", + "repo": "asyncapi/studio", "labels": [ { "name": "enhancement", "color": "a2eeef" - }, - { - "name": "good first issue", - "color": "7057ff" - }, - { - "name": "area/design", - "color": "0d67d3" - }, - { - "name": "website", - "color": "57A793" } ], - "score": 18.37917367995256 + "score": 16.36895155870775 }, { - "id": "PR_kwDOFLhIt85bqKL8", + "id": "PR_kwDOKp3ICM5g9w8f", "isPR": true, "isAssigned": false, - "title": "docs: add Bounty Program Rules", - "author": "aeworxet", - "resourcePath": "/asyncapi/community/pull/897", - "repo": "asyncapi/community", + "title": "docs: adding content for module 3", + "author": "TRohit20", + "resourcePath": "/asyncapi/learning-paths/pull/9", + "repo": "asyncapi/learning-paths", "labels": [], - "score": 16.65612614745701 + "score": 15.220253203710714 }, { - "id": "MDU6SXNzdWUxMjMwODQwMDM4", - "isPR": false, + "id": "PR_kwDODou01c5Iv4zR", + "isPR": true, "isAssigned": false, - "title": "Usages of allOf within message payload could be flattened", - "author": "jamescrowley", - "resourcePath": "/asyncapi/asyncapi-react/issues/596", - "repo": "asyncapi/asyncapi-react", + "title": "docs: added table of contents and introduction document for Studio tool", + "author": "Jagrutiti", + "resourcePath": "/asyncapi/studio/pull/553", + "repo": "asyncapi/studio", "labels": [], "score": 14.933078614961456 }, { - "id": "PR_kwDOBW5R_c5QjwOq", - "isPR": true, + "id": "I_kwDODou01c5BZZv-", + "isPR": false, "isAssigned": false, - "title": "feat: add table of contents in case study", - "author": "Shurtu-gal", - "resourcePath": "/asyncapi/website/pull/1673", - "repo": "asyncapi/website", - "labels": [], + "title": "Open Graph link preview image according to the document to open", + "author": "smoya", + "resourcePath": "/asyncapi/studio/issues/224", + "repo": "asyncapi/studio", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "keep-open", + "color": "f9dd4b" + } + ], "score": 14.645904026212197 } ], "goodFirstIssues": [ { - "id": "I_kwDOBGu-1853mU6h", - "title": "Fix description of Operation Trait object", + "id": "I_kwDODou01c6Aib3a", + "title": "Disable the generators that are not yet supported in V3", + "isAssigned": true, + "resourcePath": "/asyncapi/studio/issues/979", + "repo": "asyncapi/studio", + "author": "Amzani", + "area": "Unknown", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + } + ] + }, + { + "id": "I_kwDOE8Qh385_rNaC", + "title": "Create a one for all input document for runtime to test all functionality", "isAssigned": false, - "resourcePath": "/asyncapi/spec/issues/994", - "repo": "asyncapi/spec", - "author": "smoya", + "resourcePath": "/asyncapi/modelina/issues/1825", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", "area": "Unknown", "labels": [ { - "name": "πŸ€·β€β™€οΈ Ambiguity", - "color": "286AFC" + "name": "enhancement", + "color": "a2eeef" } ] }, { - "id": "I_kwDODCuNRs51jd3x", - "title": "Implement GitHub Action to Validate examples Field in Schemas", + "id": "I_kwDOE8Qh385-gvCP", + "title": "Add \"generated-code\" XmlDoc and `[GeneratedCode]` attribute to C# models.", "isAssigned": false, - "resourcePath": "/asyncapi/bindings/issues/217", - "repo": "asyncapi/bindings", - "author": "KhudaDad414", - "area": "ci-cd", + "resourcePath": "/asyncapi/modelina/issues/1784", + "repo": "asyncapi/modelina", + "author": "RowlandBanks", + "area": "typescript", "labels": [ { "name": "enhancement", "color": "a2eeef" + }, + { + "name": "C# generator", + "color": "c5def5" } ] }, { - "id": "I_kwDOCoBobc5zovn3", - "title": "Parser do not validate if channel that is referenced in reply with location has `null` in address", + "id": "I_kwDOCVQpZM58chHc", + "title": "Workflows failing because of some leftovers scripts", "isAssigned": false, - "resourcePath": "/asyncapi/parser-js/issues/876", - "repo": "asyncapi/parser-js", + "resourcePath": "/asyncapi/asyncapi-react/issues/888", + "repo": "asyncapi/asyncapi-react", "author": "derberg", - "area": "typescript", + "area": "Unknown", "labels": [ { "name": "bug", @@ -236,108 +249,258 @@ ] }, { - "id": "I_kwDOCoBobc5zosuk", - "title": "Parser do not validate and throw error when `parameters` are provided but address is null", + "id": "I_kwDOCHlHJM58YMi8", + "title": "Improve arborist (npm installation) to have no hacks", "isAssigned": false, - "resourcePath": "/asyncapi/parser-js/issues/875", - "repo": "asyncapi/parser-js", + "resourcePath": "/asyncapi/generator/issues/1102", + "repo": "asyncapi/generator", "author": "derberg", - "area": "typescript", + "area": "javascript", "labels": [ { - "name": "bug", - "color": "d73a4a" + "name": "enhancement", + "color": "a2eeef" } ] }, { - "id": "I_kwDOFDnrNc5yy6e0", - "title": "The new glee command is generating a 2.1.0 document", + "id": "I_kwDOE8Qh38572qE9", + "title": "Add runtime tests for Python", "isAssigned": false, - "resourcePath": "/asyncapi/cli/issues/829", - "repo": "asyncapi/cli", - "author": "fmvilas", + "resourcePath": "/asyncapi/modelina/issues/1745", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", "area": "Unknown", "labels": [ { - "name": "bug", - "color": "d73a4a" + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "Python generator", + "color": "5319e7" } ] }, { - "id": "I_kwDOFLhIt85yyn4B", - "title": "Update tooling doc with info about new category", + "id": "I_kwDOE8Qh38572pxu", + "title": "Add runtime tests for Dart", "isAssigned": false, - "resourcePath": "/asyncapi/community/issues/899", - "repo": "asyncapi/community", - "author": "derberg", - "area": "docs", + "resourcePath": "/asyncapi/modelina/issues/1744", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", + "area": "Unknown", "labels": [ { - "name": "Hacktoberfest", - "color": "FF8AE2" + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "Dart generator", + "color": "296FBA" } ] }, { - "id": "I_kwDODwv8N85yh95N", - "title": "would be nice if venue from past events is grayed out", + "id": "I_kwDOE8Qh38572gDd", + "title": "Add XSD support ", "isAssigned": false, - "resourcePath": "/asyncapi/conference-website/issues/208", - "repo": "asyncapi/conference-website", - "author": "derberg", - "area": "javascript", + "resourcePath": "/asyncapi/modelina/issues/1742", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + } + ] + }, + { + "id": "I_kwDOE8Qh38572csq", + "title": "Add Avro support", + "isAssigned": false, + "resourcePath": "/asyncapi/modelina/issues/1741", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + } + ] + }, + { + "id": "I_kwDOE8Qh38572bME", + "title": "Add JSON Type definition support ", + "isAssigned": false, + "resourcePath": "/asyncapi/modelina/issues/1740", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + } + ] + }, + { + "id": "I_kwDOE8Qh3857Kllp", + "title": "Add loading animation for when playground generate models ", + "isAssigned": false, + "resourcePath": "/asyncapi/modelina/issues/1725", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", + "area": "Unknown", "labels": [ { "name": "enhancement", "color": "a2eeef" }, { - "name": "Hacktoberfest", - "color": "FF8AE2" + "name": "website", + "color": "57A793" + } + ] + }, + { + "id": "I_kwDOE8Qh3857KkLT", + "title": "Introduce Modelina CLI that can be extended by AsyncAPI CLI", + "isAssigned": true, + "resourcePath": "/asyncapi/modelina/issues/1724", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" } ] }, { - "id": "I_kwDOIUldZc5ydvrx", - "title": "Remove this commented out code.", + "id": "I_kwDOE8Qh3857KYj1", + "title": "Add input document for OpenAPI", "isAssigned": false, - "resourcePath": "/asyncapi/EDAVisualiser/issues/35", - "repo": "asyncapi/EDAVisualiser", - "author": "AceTheCreator", + "resourcePath": "/asyncapi/modelina/issues/1723", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", "area": "Unknown", "labels": [ { - "name": "Hacktoberfest", - "color": "FF8AE2" + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "πŸ“‘ docs", + "color": "E50E99" } ] }, { - "id": "I_kwDOIUldZc5ydvh1", - "title": "Consider using \"forEach\" instead of \"map\" as its return value is not being used here.", + "id": "I_kwDOE8Qh3857KYQc", + "title": "Add input document for AsyncAPI", "isAssigned": false, - "resourcePath": "/asyncapi/EDAVisualiser/issues/32", - "repo": "asyncapi/EDAVisualiser", - "author": "AceTheCreator", + "resourcePath": "/asyncapi/modelina/issues/1722", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", "area": "Unknown", "labels": [ { - "name": "Hacktoberfest", - "color": "FF8AE2" + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "πŸ“‘ docs", + "color": "E50E99" } ] }, { - "id": "I_kwDOFDnrNc5ydvaR", - "title": "Nested block is redundant.", + "id": "I_kwDODyzcIc54mr9C", + "title": "Fix wrong format for Co-authored automerged commits + pagination", "isAssigned": false, - "resourcePath": "/asyncapi/cli/issues/822", - "repo": "asyncapi/cli", - "author": "AceTheCreator", + "resourcePath": "/asyncapi/.github/issues/263", + "repo": "asyncapi/.github", + "author": "smoya", + "area": "ci-cd", + "labels": [ + { + "name": "bug", + "color": "d73a4a" + } + ] + }, + { + "id": "I_kwDOB5hCo854UrcU", + "title": "We probably need `stableSchemas` in npm package", + "isAssigned": false, + "resourcePath": "/asyncapi/spec-json-schemas/issues/459", + "repo": "asyncapi/spec-json-schemas", + "author": "derberg", "area": "Unknown", "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + } + ] + }, + { + "id": "I_kwDODou01c531nlO", + "title": "Misalignment of Code Editor Highlight Box", + "isAssigned": true, + "resourcePath": "/asyncapi/studio/issues/861", + "repo": "asyncapi/studio", + "author": "princerajpoot20", + "area": "typescript", + "labels": [] + }, + { + "id": "I_kwDOCoBobc5zovn3", + "title": "Parser do not validate if channel that is referenced in reply with location has `null` in address", + "isAssigned": false, + "resourcePath": "/asyncapi/parser-js/issues/876", + "repo": "asyncapi/parser-js", + "author": "derberg", + "area": "typescript", + "labels": [ + { + "name": "bug", + "color": "d73a4a" + } + ] + }, + { + "id": "I_kwDOCoBobc5zosuk", + "title": "Parser do not validate and throw error when `parameters` are provided but address is null", + "isAssigned": false, + "resourcePath": "/asyncapi/parser-js/issues/875", + "repo": "asyncapi/parser-js", + "author": "derberg", + "area": "typescript", + "labels": [ + { + "name": "bug", + "color": "d73a4a" + } + ] + }, + { + "id": "I_kwDODwv8N85yh95N", + "title": "would be nice if venue from past events is grayed out", + "isAssigned": false, + "resourcePath": "/asyncapi/conference-website/issues/208", + "repo": "asyncapi/conference-website", + "author": "derberg", + "area": "javascript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + }, { "name": "Hacktoberfest", "color": "FF8AE2" @@ -345,18 +508,14 @@ ] }, { - "id": "I_kwDOBW5R_c5yduk_", - "title": "Single backtick is recognised as Codeblock", + "id": "I_kwDOFDnrNc5ydvaR", + "title": "Nested block is redundant.", "isAssigned": false, - "resourcePath": "/asyncapi/website/issues/2188", - "repo": "asyncapi/website", - "author": "akshatnema", + "resourcePath": "/asyncapi/cli/issues/822", + "repo": "asyncapi/cli", + "author": "AceTheCreator", "area": "Unknown", "labels": [ - { - "name": "bug", - "color": "ee0701" - }, { "name": "Hacktoberfest", "color": "FF8AE2" @@ -379,6 +538,10 @@ { "name": "Hacktoberfest", "color": "FF8AE2" + }, + { + "name": "stale", + "color": "ededed" } ] }, @@ -389,7 +552,7 @@ "resourcePath": "/asyncapi/java-spring-template/issues/326", "repo": "asyncapi/java-spring-template", "author": "Tenischev", - "area": "Unknown", + "area": "java", "labels": [ { "name": "bug", @@ -397,21 +560,6 @@ } ] }, - { - "id": "I_kwDOBW5R_c5sqLtN", - "title": "[πŸ“‘ Docs]: import Glee docs under tools folder", - "isAssigned": false, - "resourcePath": "/asyncapi/website/issues/2003", - "repo": "asyncapi/website", - "author": "AnimeshKumar923", - "area": "docs", - "labels": [ - { - "name": "πŸ“‘ docs", - "color": "E50E99" - } - ] - }, { "id": "I_kwDOBW5R_c5soAAM", "title": "Create a research page to have participants sign up for the research study", @@ -476,44 +624,6 @@ } ] }, - { - "id": "I_kwDOBW5R_c5qGUNf", - "title": "docs: validate messages (interactive version) - adapt for v3", - "isAssigned": true, - "resourcePath": "/asyncapi/website/issues/1872", - "repo": "asyncapi/website", - "author": "alequetzalli", - "area": "docs", - "labels": [ - { - "name": "stale", - "color": "ededed" - }, - { - "name": "πŸ“‘ docs", - "color": "E50E99" - } - ] - }, - { - "id": "I_kwDOBW5R_c5qGUND", - "title": "docs: validate document with studio (interactive version) - adapt for v3", - "isAssigned": true, - "resourcePath": "/asyncapi/website/issues/1871", - "repo": "asyncapi/website", - "author": "alequetzalli", - "area": "docs", - "labels": [ - { - "name": "stale", - "color": "ededed" - }, - { - "name": "πŸ“‘ docs", - "color": "E50E99" - } - ] - }, { "id": "I_kwDOBW5R_c5qGUMg", "title": "docs: generate code (interactive version) - adapt for v3", @@ -523,10 +633,6 @@ "author": "alequetzalli", "area": "docs", "labels": [ - { - "name": "stale", - "color": "ededed" - }, { "name": "πŸ“‘ docs", "color": "E50E99" @@ -541,44 +647,6 @@ "repo": "asyncapi/website", "author": "alequetzalli", "area": "docs", - "labels": [ - { - "name": "stale", - "color": "ededed" - }, - { - "name": "πŸ“‘ docs", - "color": "E50E99" - } - ] - }, - { - "id": "I_kwDOBW5R_c5qCdE5", - "title": "[πŸ“‘ Docs]: Adapt Streetlights - Interactive tutorial for v3", - "isAssigned": true, - "resourcePath": "/asyncapi/website/issues/1863", - "repo": "asyncapi/website", - "author": "jonaslagoni", - "area": "docs", - "labels": [ - { - "name": "stale", - "color": "ededed" - }, - { - "name": "πŸ“‘ docs", - "color": "E50E99" - } - ] - }, - { - "id": "I_kwDOBW5R_c5qCLdo", - "title": "[πŸ“‘ Docs]: Adapt coming from OpenAPI tutorial for v3", - "isAssigned": true, - "resourcePath": "/asyncapi/website/issues/1856", - "repo": "asyncapi/website", - "author": "jonaslagoni", - "area": "docs", "labels": [ { "name": "πŸ“‘ docs", @@ -587,31 +655,21 @@ ] }, { - "id": "I_kwDOFLhIt85o9dDJ", - "title": "Add 2023 mentorship directory", - "isAssigned": false, - "resourcePath": "/asyncapi/community/issues/753", - "repo": "asyncapi/community", - "author": "AceTheCreator", - "area": "Unknown", - "labels": [] - }, - { - "id": "I_kwDOE8Qh385nTCST", - "title": "Improve layout of playground", + "id": "I_kwDOE8Qh385m4AtC", + "title": "C# generator add xml docs from the async api description", "isAssigned": false, - "resourcePath": "/asyncapi/modelina/issues/1346", + "resourcePath": "/asyncapi/modelina/issues/1330", "repo": "asyncapi/modelina", - "author": "jonaslagoni", - "area": "design", + "author": "diogonborges", + "area": "typescript", "labels": [ { "name": "enhancement", "color": "a2eeef" }, { - "name": "website", - "color": "57A793" + "name": "C# generator", + "color": "c5def5" } ] }, @@ -630,63 +688,6 @@ } ] }, - { - "id": "I_kwDOBW5R_c5lGICH", - "title": "Make group dropdown for each section in Navbar", - "isAssigned": false, - "resourcePath": "/asyncapi/website/issues/1625", - "repo": "asyncapi/website", - "author": "akshatnema", - "area": "Unknown", - "labels": [ - { - "name": "enhancement", - "color": "84b6eb" - }, - { - "name": "Hacktoberfest", - "color": "FF8AE2" - } - ] - }, - { - "id": "I_kwDOBW5R_c5jJLzD", - "title": "[πŸ“‘ Docs]: new fragment for contributor questions section", - "isAssigned": true, - "resourcePath": "/asyncapi/website/issues/1555", - "repo": "asyncapi/website", - "author": "alequetzalli", - "area": "docs", - "labels": [ - { - "name": "stale", - "color": "ededed" - }, - { - "name": "πŸ“‘ docs", - "color": "E50E99" - } - ] - }, - { - "id": "I_kwDOE8Qh385iZlgl", - "title": "TypeScript uses Location as reserved keyword", - "isAssigned": false, - "resourcePath": "/asyncapi/modelina/issues/1206", - "repo": "asyncapi/modelina", - "author": "jonaslagoni", - "area": "typescript", - "labels": [ - { - "name": "bug", - "color": "d73a4a" - }, - { - "name": "TS generator", - "color": "33943E" - } - ] - }, { "id": "I_kwDOFi_gUM5hpuWl", "title": "Improve kafka adapter", @@ -702,36 +703,6 @@ } ] }, - { - "id": "I_kwDOB5hCo85hBDME", - "title": "Enable reusability of schemas between versions", - "isAssigned": false, - "resourcePath": "/asyncapi/spec-json-schemas/issues/364", - "repo": "asyncapi/spec-json-schemas", - "author": "jonaslagoni", - "area": "javascript", - "labels": [ - { - "name": "enhancement", - "color": "a2eeef" - } - ] - }, - { - "id": "I_kwDODCuNRs5e58gr", - "title": "MQTT `retain` flag should be applied only to `publish` operations", - "isAssigned": false, - "resourcePath": "/asyncapi/bindings/issues/187", - "repo": "asyncapi/bindings", - "author": "KhudaDad414", - "area": "docs", - "labels": [ - { - "name": "enhancement", - "color": "a2eeef" - } - ] - }, { "id": "I_kwDOBW5R_c5eFaBF", "title": "Add proper dropdowns to the Filters Select Menu", @@ -754,15 +725,30 @@ "resourcePath": "/asyncapi/modelina/issues/1128", "repo": "asyncapi/modelina", "author": "LouisXhaferi", - "area": "Unknown", + "area": "typescript", "labels": [ { "name": "enhancement", "color": "a2eeef" }, { - "name": "stale", - "color": "ededed" + "name": "Kotlin generator", + "color": "61A95C" + } + ] + }, + { + "id": "I_kwDOE8Qh385dmVp_", + "title": "Render Unions as custom type in Kotlin Generator", + "isAssigned": false, + "resourcePath": "/asyncapi/modelina/issues/1127", + "repo": "asyncapi/modelina", + "author": "LouisXhaferi", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" }, { "name": "Kotlin generator", @@ -770,6 +756,21 @@ } ] }, + { + "id": "I_kwDOE8Qh385dfoKl", + "title": "JSON Schema enum pattern to define enum key and value with oneOf", + "isAssigned": false, + "resourcePath": "/asyncapi/modelina/issues/1121", + "repo": "asyncapi/modelina", + "author": "jonaslagoni", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + } + ] + }, { "id": "I_kwDOBW5R_c5dfidP", "title": "docs: new style guide - Glossary", @@ -785,6 +786,25 @@ } ] }, + { + "id": "I_kwDOE8Qh385XYlR7", + "title": "Support JSONSchema draft 2020-12 in the input processing", + "isAssigned": false, + "resourcePath": "/asyncapi/modelina/issues/1016", + "repo": "asyncapi/modelina", + "author": "kennethaasan", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "keep", + "color": "FBCA04" + } + ] + }, { "id": "I_kwDOIUldZc5XXsGH", "title": "Filter out application which are not in use", @@ -804,6 +824,25 @@ } ] }, + { + "id": "I_kwDOE8Qh385WoDaU", + "title": "Add attrs and/or dataclasses presets to Python generator", + "isAssigned": false, + "resourcePath": "/asyncapi/modelina/issues/999", + "repo": "asyncapi/modelina", + "author": "tokarenko", + "area": "typescript", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "Python generator", + "color": "5319e7" + } + ] + }, { "id": "I_kwDODyzcIc5Uso2Q", "title": "Add support for minimum amount of approvals before merge", @@ -914,29 +953,6 @@ } ] }, - { - "id": "MDU6SXNzdWUxMDA4MjQ5Nzg4", - "title": "Set the left menu collapsable", - "isAssigned": false, - "resourcePath": "/asyncapi/asyncapi-react/issues/441", - "repo": "asyncapi/asyncapi-react", - "author": "M3lkior", - "area": "library", - "labels": [ - { - "name": "enhancement", - "color": "a2eeef" - }, - { - "name": "stale", - "color": "ededed" - }, - { - "name": "Hacktoberfest", - "color": "FF8AE2" - } - ] - }, { "id": "MDU6SXNzdWU4MDU4MDM5Njg=", "title": "Enhance API docs with information about results of code generation with generateFromString using entrypoint", @@ -949,10 +965,6 @@ { "name": "enhancement", "color": "a2eeef" - }, - { - "name": "stale", - "color": "ededed" } ] } diff --git a/lib/getUniqueCategories.js b/lib/getUniqueCategories.js new file mode 100644 index 00000000000..2c6e9500c7b --- /dev/null +++ b/lib/getUniqueCategories.js @@ -0,0 +1,20 @@ +/** + * Retrieves unique expense categories from the Expenses data. + * + * @param {Object} expenses - The expenses data. + * @returns {string[]} An array of unique expense categories. + */ + +import Expenses from '../config/finance/json-data/2024/Expenses.json'; + +export const getUniqueCategories = () => { + const allCategories = []; + for (const month in Expenses) { + Expenses[month].forEach(entry => { + if (!allCategories.includes(entry.Category)) { + allCategories.push(entry.Category); + } + }); + } + return allCategories; +}; \ No newline at end of file diff --git a/lib/i18nPaths.js b/lib/i18nPaths.js new file mode 100644 index 00000000000..138b598cea6 --- /dev/null +++ b/lib/i18nPaths.js @@ -0,0 +1,12 @@ +const i18nPaths = { + en: [ + "", //Homepage Route + "/tools/cli" + ], + de: [ + "", //Homepage Route + "/tools/cli" + ] +}; + +export default i18nPaths; \ No newline at end of file diff --git a/lib/staticHelpers.js b/lib/staticHelpers.js index a78f1045abd..7ae955c9901 100644 --- a/lib/staticHelpers.js +++ b/lib/staticHelpers.js @@ -97,3 +97,109 @@ export function getEvents(events, size) { return meetingsWithDates; } + +export const generateCaseStudyContent = (data) => { + const { challenges, solution, usecase, architecture, testing, codegen, schemaStorage, registry, versioning, validation, asyncapiStorage, asyncapiEditing, asyncapiExtensions, asyncapiDocumentation, asyncapiBindings, asyncapiTools, additionalResources, casestudy } = data; + const languages= casestudy.technical.languages + const frameworks=casestudy.technical.frameworks + const protocols=casestudy.technical.protocols + const versions=casestudy.asyncapi.versions + + return [ + { + title: "Challenges", + content: challenges, + }, + { + title: "Solution", + content: solution, + }, + { + title: "Use Case", + content: usecase, + }, + { + title: "More Details", + items: [ + `Languages: ${languages.join(", ")}`, + `Frameworks: ${frameworks.join(", ")}`, + `Protocols: ${protocols.join(", ")}`, + ], + children: [ + { + title: "Testing strategy", + content: testing, + }, + { + title: "Approach to code generation", + content: codegen, + }, + { + title: "Architecture", + content: architecture, + }, + { + title: "More Details about AsyncAPI", + items: [ + `Version: ${versions.join(", ")}`, + `Who maintains documents: ${casestudy.asyncapi.maintainers}}`, + `Internal users: ${casestudy.asyncapi.audience.internal.toString()}`, + `External users: ${casestudy.asyncapi.audience.external.toString()}`, + ], + children: [ + { + title: "How AsyncAPI documents are stored", + content: asyncapiStorage, + }, + { + title: "Where maintainers edit AsyncAPI documents", + content: asyncapiEditing, + }, + { + title: "What extensions are used", + content: asyncapiExtensions, + }, + { + title: "How documentation is generated", + content: asyncapiDocumentation, + }, + { + title: "What bindings are used", + content: asyncapiBindings, + }, + { + title: "What tools are used", + content: asyncapiTools, + }, + ], + }, + { + title: "Schemas", + items: [`Spec: ${casestudy.schemas.description}`], + children: [ + { + title: "Storage strategy", + content: schemaStorage, + }, + { + title: "Schema Registry", + content: registry, + }, + { + title: "Versioning of schemas", + content: versioning, + }, + { + title: "Validation of message schemas", + content: validation, + }, + { + title: "Additional Resources", + content: additionalResources, + }, + ], + }, + ], + }, + ]; +} \ No newline at end of file diff --git a/locales/de/common.json b/locales/de/common.json index 61ee0a72562..04d3c5c5398 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -4,7 +4,11 @@ "subtitle": "Wir respektieren Ihren Posteingang. Kein Spam, versprochen ✌️", "nameInput": "Ihr Name", "emailInput": "Deine E-Mail", - "subscribeBtn": "Abonnieren" + "subscribeBtn": "Abonnieren", + "successTitle": "Vielen Dank fΓΌr Ihr Abonnement!", + "errorTitle": "Etwas ist schief gelaufen", + "errorSubtitle": "Das Abonnement ist fehlgeschlagen, bitte informieren Sie uns darΓΌber, indem Sie einen Fehler melden", + "errorLinkText": "hier" }, "newsroomSection": { "title": "Aktuelle Nachrichten und Blogs", diff --git a/locales/en/common.json b/locales/en/common.json index 500a90540e2..28fc28df539 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -4,7 +4,11 @@ "subtitle": "We respect your inbox. No spam, promise ✌️", "nameInput": "Your name", "emailInput": "Your email", - "subscribeBtn": "Subscribe" + "subscribeBtn": "Subscribe", + "successTitle": "Thank you for subscribing!", + "errorTitle": "Something went wrong", + "errorSubtitle": "Subscription failed, please let us know about it by submitting a bug", + "errorLinkText": "here" }, "newsroomSection": { "title": "Latest news and blogs", diff --git a/netlify.toml b/netlify.toml index 3f3d2beb535..e199d8974c2 100644 --- a/netlify.toml +++ b/netlify.toml @@ -11,8 +11,8 @@ [build.environment] NETLIFY_NEXT_PLUGIN_SKIP = "true" - NODE_VERSION = "16.15.0" - NPM_VERSION = "8.5.5" + NODE_VERSION = "16.16.0" + NPM_VERSION = "8.11.0" # Used by JSON Schema definitions fetched directly from AsyncAPI website [[redirects]] diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 3197f584478..77c3141ee86 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -7,28 +7,27 @@ const NR_METRICS_ENDPOINT = Deno.env.get("NR_METRICS_ENDPOINT") || "https://metr const URL_DEST_SCHEMAS = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas"; const URL_DEST_DEFINITIONS = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/definitions"; -// Legitimate request: +// Schemas-related request: // Patterns: / OR // OR /// // Examples: /definitions OR /schema-store/2.5.0-without-$id.json OR /definitions/2.4.0/info.json -// Non-legitimate request: +// Schemas-unrelated request: // Patterns: ///* // Examples: /definitions/asyncapi.yaml OR /schema-store/2.4.0.JSON (uppercase) // -// Non-legitimate requests should not use our GitHub Token and affect the rate limit. Those shouldn't send metrics to NR either as they just add noise. -const legitimateRequestRegex = /^\/[\w\-]*\/?(?:([\w\-\.]*\/)?([\w\-$%\.]*\.json))?$/ +// Schemas-unrelated requests should not use our GitHub Token and affect the rate limit. Those shouldn't send metrics to NR either as they just add noise. +const SchemasRelatedRequestRegex = /^\/[\w\-]*\/?(?:([\w\-\.]*\/)?([\w\-$%\.]*\.json))?$/ export default async (request: Request, context: Context) => { let rewriteRequest = buildRewrite(request); let response: Response; if (rewriteRequest === null) { - rewriteRequest = request; - - response = await context.next(); - } else { - // Fetching the definition file - response = await fetch(rewriteRequest); + // This is a Schema-unrelated request. Let it go through and do not intercept it. + return await context.next(); } + // Fetching the definition file + response = await fetch(rewriteRequest); + const isRequestingAFile = request.url.endsWith('.json'); if (isRequestingAFile) { var metricName: string @@ -56,6 +55,7 @@ export default async (request: Request, context: Context) => { default: // Notifying NR of the error. metricName = "asyncapi.jsonschema.download.error"; + console.log("Error downloading JSON Schema file: " + response.status + " " + response.statusText); break; } } @@ -68,7 +68,7 @@ export default async (request: Request, context: Context) => { }; function buildRewrite(originalRequest: Request): (Request | null) { - const extractResult = legitimateRequestRegex.exec(new URL(originalRequest.url).pathname); + const extractResult = SchemasRelatedRequestRegex.exec(new URL(originalRequest.url).pathname); if (extractResult === null) { return null; } diff --git a/netlify/functions/newsletter_subscription.js b/netlify/functions/newsletter_subscription.js new file mode 100644 index 00000000000..56a16ece709 --- /dev/null +++ b/netlify/functions/newsletter_subscription.js @@ -0,0 +1,48 @@ +const mailchimp = require("@mailchimp/mailchimp_marketing"); +const md5 = require("md5"); +const config = require("../../config/mailchimp-config.json"); + + +exports.handler = async function (event) { + if (event.httpMethod == 'POST') { + const listId = config.listId; + const { email, name, interest } = JSON.parse(event.body) + + const subscriberHash = md5(email.toLowerCase()); + try { + mailchimp.setConfig({ + apiKey: process.env.MAILCHIMP_API_KEY, + server: 'us12' + }); + + const response = await mailchimp.lists.setListMember(listId, subscriberHash, { + email_address: email, + merge_fields: { + FNAME: name + }, + status: "subscribed", + interests: { + [config.interests[interest]]: true + } + }); + + return { + statusCode: 200, + body: JSON.stringify(response) + } + } catch (err) { + console.log(err); + return { + statusCode: err.status, + body: JSON.stringify(err) + } + } + } else { + return { + statusCode: 500, + body: JSON.stringify({ + message: "The specified HTTP method is not allowed." + }) + } + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b1873089983..ca186ad48fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@floating-ui/react-dom-interactions": "^0.1.1", "@fullhuman/postcss-purgecss": "^2.2.0", "@heroicons/react": "^1.0.5", + "@mailchimp/mailchimp_marketing": "^3.0.80", "@mdx-js/loader": "1.6.4", "@mdx-js/react": "^1.6.4", "@next/mdx": "^9.4.2", @@ -40,6 +41,7 @@ "lodash": "^4.17.21", "markdown-to-txt": "^2.0.1", "markdown-toc": "1.2.0", + "md5": "^2.3.0", "mermaid": "9.3.0", "moment": "^2.29.4", "next": "^12.0.0", @@ -58,6 +60,7 @@ "react-typing-animation": "^1.6.2", "react-youtube-embed": "^1.0.3", "reading-time": "^1.2.0", + "recharts": "^2.10.1", "remark-frontmatter": "^2.0.0", "remark-gemoji-to-emoji": "^1.1.0", "remark-heading-id": "^1.0.0", @@ -72,7 +75,7 @@ "@anshgoyalevil/eslint-config": "^1.0.3", "@cypress/react": "^7.0.3", "@netlify/functions": "^1.4.0", - "@netlify/plugin-nextjs": "^4.37.2", + "@netlify/plugin-nextjs": "^4.40.2", "cypress": "^10.11.0", "dedent": "^0.7.0", "inquirer": "^8.2.0", @@ -827,6 +830,18 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@mailchimp/mailchimp_marketing": { + "version": "3.0.80", + "resolved": "https://registry.npmjs.org/@mailchimp/mailchimp_marketing/-/mailchimp_marketing-3.0.80.tgz", + "integrity": "sha512-Cgz0xPb+1DUjmrl5whAsmqfAChBko+Wf4/PLQE4RvwfPlcq2agfHr1QFiXEhZ8e+GQwQ3hZQn9iLGXwIXwxUCg==", + "dependencies": { + "dotenv": "^8.2.0", + "superagent": "3.8.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@mdx-js/loader": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.4.tgz", @@ -1181,6 +1196,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/@netlify/blobs": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@netlify/blobs/-/blobs-2.2.0.tgz", + "integrity": "sha512-j2C0+IvWj9CLNGPoiA7ETquMFDExZTrv4CarjfE6Au0eY3zlinnnTVae7DE+VQFK+U0CDM/O0VvelNy1QbsdwQ==", + "dev": true, + "engines": { + "node": "^14.16.0 || >=16.0.0" + } + }, "node_modules/@netlify/esbuild": { "version": "0.14.39", "resolved": "https://registry.npmjs.org/@netlify/esbuild/-/esbuild-0.14.39.tgz", @@ -1603,14 +1627,15 @@ } }, "node_modules/@netlify/plugin-nextjs": { - "version": "4.37.2", - "resolved": "https://registry.npmjs.org/@netlify/plugin-nextjs/-/plugin-nextjs-4.37.2.tgz", - "integrity": "sha512-XDkSMIfz/MHVTXr08JMsirwUrpWEgZZC2qLFQh2IVp6Xb5rT8zlq4HBjxx2AbTyLJUsn3m7LB0uabuyln7XoMg==", + "version": "4.41.2", + "resolved": "https://registry.npmjs.org/@netlify/plugin-nextjs/-/plugin-nextjs-4.41.2.tgz", + "integrity": "sha512-+XByVkr9sRszq7xnsZ52EGi5xeTdAtj5PRxvP//xVywlGAi1jYintizdd6PCbI6Ty0Kegwgb0O6FgRKceyUIwA==", "dev": true, "dependencies": { + "@netlify/blobs": "^2.2.0", "@netlify/esbuild": "0.14.39", "@netlify/functions": "^1.6.0", - "@netlify/ipx": "^1.4.0", + "@netlify/ipx": "^1.4.6", "@vercel/node-bridge": "^2.1.0", "chalk": "^4.1.2", "chokidar": "^3.5.3", @@ -1625,7 +1650,7 @@ "node-stream-zip": "^1.15.0", "outdent": "^0.8.0", "p-limit": "^3.1.0", - "pathe": "^0.2.0", + "pathe": "^0.3.0", "pretty-bytes": "^5.6.0", "regexp-tree": "^0.1.24", "semver": "^7.3.5", @@ -2526,6 +2551,60 @@ "@types/estree": "*" } }, + "node_modules/@types/d3-array": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.5.tgz", + "integrity": "sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.3.tgz", + "integrity": "sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.1.tgz", + "integrity": "sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, "node_modules/@types/debug": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", @@ -3470,6 +3549,14 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, "node_modules/check-more-types": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", @@ -3867,6 +3954,11 @@ "node": ">=4.0.0" } }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3916,6 +4008,11 @@ "integrity": "sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==", "dev": true }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, "node_modules/core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", @@ -3962,6 +4059,14 @@ "which": "^2.0.1" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, "node_modules/css-color-list": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/css-color-list/-/css-color-list-0.0.1.tgz", @@ -4804,6 +4909,11 @@ } } }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "node_modules/decode-named-character-reference": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", @@ -5005,6 +5115,14 @@ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, + "node_modules/dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -5519,9 +5637,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "funding": [ { "type": "individual", @@ -5569,6 +5687,15 @@ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -7538,6 +7665,21 @@ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/md5/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "node_modules/mdast-squeeze-paragraphs": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", @@ -7916,6 +8058,14 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micro-memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/micro-memoize/-/micro-memoize-4.1.2.tgz", @@ -9411,9 +9561,9 @@ } }, "node_modules/pathe": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz", - "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.3.9.tgz", + "integrity": "sha512-6Y6s0vT112P3jD8dGfuS6r+lpa0qqNrLyHPOwvXMnyNTQaYiwgau2DP3aNDsR13xqtGj7rrPo+jFUATpU6/s+g==", "dev": true }, "node_modules/pend": { @@ -10527,6 +10677,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "node_modules/react-scrollspy": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/react-scrollspy/-/react-scrollspy-3.4.3.tgz", @@ -10537,6 +10692,28 @@ "prop-types": "^15.5.10" } }, + "node_modules/react-smooth": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.5.tgz", + "integrity": "sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==", + "dependencies": { + "fast-equals": "^5.0.0", + "react-transition-group": "2.9.0" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-smooth/node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/react-syntax-highlighter": { "version": "12.2.1", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz", @@ -10560,6 +10737,21 @@ "prop-types": "^15.5.7" } }, + "node_modules/react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "dependencies": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0", + "react-dom": ">=15.0.0" + } + }, "node_modules/react-twitter-embed": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/react-twitter-embed/-/react-twitter-embed-4.0.4.tgz", @@ -10669,6 +10861,50 @@ "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" }, + "node_modules/recharts": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.10.1.tgz", + "integrity": "sha512-9bi0jIzxOTfEda+oYqgimKuYfApmBr0zKnAX8r4Iw56k3Saz/IQyBD4zohZL0eyzfz0oGFRH7alpJBgH1eC57g==", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.19", + "react-is": "^16.10.2", + "react-smooth": "^2.0.5", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "prop-types": "^15.6.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/recharts/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/redis-errors": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", @@ -11629,6 +11865,59 @@ "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" }, + "node_modules/superagent": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.1.tgz", + "integrity": "sha512-VMBFLYgFuRdfeNQSMLbxGSLfmXL/xc+OO+BZp41Za/NRDBet/BNbkRJrYzCUu0u4GU0i/ml2dtT8b9qgkw9z6Q==", + "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", + "dependencies": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.1.1", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/superagent/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/superagent/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -11846,6 +12135,11 @@ "globrex": "^0.1.2" } }, + "node_modules/tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -12530,6 +12824,27 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/victory-vendor": { + "version": "36.6.11", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.11.tgz", + "integrity": "sha512-nT8kCiJp8dQh8g991J/R5w5eE2KnO8EAIP0xocWlh9l2okngMWglOPoMZzJvek8Q1KUc4XE/mJxTZnvOB1sTYg==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -13326,6 +13641,15 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@mailchimp/mailchimp_marketing": { + "version": "3.0.80", + "resolved": "https://registry.npmjs.org/@mailchimp/mailchimp_marketing/-/mailchimp_marketing-3.0.80.tgz", + "integrity": "sha512-Cgz0xPb+1DUjmrl5whAsmqfAChBko+Wf4/PLQE4RvwfPlcq2agfHr1QFiXEhZ8e+GQwQ3hZQn9iLGXwIXwxUCg==", + "requires": { + "dotenv": "^8.2.0", + "superagent": "3.8.1" + } + }, "@mdx-js/loader": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.4.tgz", @@ -13593,6 +13917,12 @@ "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==" }, + "@netlify/blobs": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@netlify/blobs/-/blobs-2.2.0.tgz", + "integrity": "sha512-j2C0+IvWj9CLNGPoiA7ETquMFDExZTrv4CarjfE6Au0eY3zlinnnTVae7DE+VQFK+U0CDM/O0VvelNy1QbsdwQ==", + "dev": true + }, "@netlify/esbuild": { "version": "0.14.39", "resolved": "https://registry.npmjs.org/@netlify/esbuild/-/esbuild-0.14.39.tgz", @@ -13818,14 +14148,15 @@ "dev": true }, "@netlify/plugin-nextjs": { - "version": "4.37.2", - "resolved": "https://registry.npmjs.org/@netlify/plugin-nextjs/-/plugin-nextjs-4.37.2.tgz", - "integrity": "sha512-XDkSMIfz/MHVTXr08JMsirwUrpWEgZZC2qLFQh2IVp6Xb5rT8zlq4HBjxx2AbTyLJUsn3m7LB0uabuyln7XoMg==", + "version": "4.41.2", + "resolved": "https://registry.npmjs.org/@netlify/plugin-nextjs/-/plugin-nextjs-4.41.2.tgz", + "integrity": "sha512-+XByVkr9sRszq7xnsZ52EGi5xeTdAtj5PRxvP//xVywlGAi1jYintizdd6PCbI6Ty0Kegwgb0O6FgRKceyUIwA==", "dev": true, "requires": { + "@netlify/blobs": "^2.2.0", "@netlify/esbuild": "0.14.39", "@netlify/functions": "^1.6.0", - "@netlify/ipx": "^1.4.0", + "@netlify/ipx": "^1.4.6", "@vercel/node-bridge": "^2.1.0", "chalk": "^4.1.2", "chokidar": "^3.5.3", @@ -13840,7 +14171,7 @@ "node-stream-zip": "^1.15.0", "outdent": "^0.8.0", "p-limit": "^3.1.0", - "pathe": "^0.2.0", + "pathe": "^0.3.0", "pretty-bytes": "^5.6.0", "regexp-tree": "^0.1.24", "semver": "^7.3.5", @@ -14364,6 +14695,60 @@ "@types/estree": "*" } }, + "@types/d3-array": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.5.tgz", + "integrity": "sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==" + }, + "@types/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==" + }, + "@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==" + }, + "@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "requires": { + "@types/d3-color": "*" + } + }, + "@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==" + }, + "@types/d3-scale": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.3.tgz", + "integrity": "sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==", + "requires": { + "@types/d3-time": "*" + } + }, + "@types/d3-shape": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.1.tgz", + "integrity": "sha512-6Uh86YFF7LGg4PQkuO2oG6EMBRLuW9cbavUW46zkIO5kuS2PfTqo2o9SkgtQzguBHbLgNnU90UNsITpsX1My+A==", + "requires": { + "@types/d3-path": "*" + } + }, + "@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==" + }, + "@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==" + }, "@types/debug": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", @@ -15183,6 +15568,11 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" + }, "check-more-types": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", @@ -15485,6 +15875,11 @@ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", "dev": true }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -15533,6 +15928,11 @@ "integrity": "sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==", "dev": true }, + "cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, "core-js": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", @@ -15581,6 +15981,11 @@ "which": "^2.0.1" } }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" + }, "css-color-list": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/css-color-list/-/css-color-list-0.0.1.tgz", @@ -16222,6 +16627,11 @@ "ms": "2.1.2" } }, + "decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "decode-named-character-reference": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", @@ -16377,6 +16787,14 @@ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -16818,9 +17236,9 @@ } }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==" }, "for-in": { "version": "1.0.2", @@ -16848,6 +17266,11 @@ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" }, + "formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" + }, "fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -18514,6 +18937,23 @@ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + } + } + }, "mdast-squeeze-paragraphs": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", @@ -18810,6 +19250,11 @@ } } }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, "micro-memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/micro-memoize/-/micro-memoize-4.1.2.tgz", @@ -19845,9 +20290,9 @@ "dev": true }, "pathe": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz", - "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.3.9.tgz", + "integrity": "sha512-6Y6s0vT112P3jD8dGfuS6r+lpa0qqNrLyHPOwvXMnyNTQaYiwgau2DP3aNDsR13xqtGj7rrPo+jFUATpU6/s+g==", "dev": true }, "pend": { @@ -20665,6 +21110,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "react-scrollspy": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/react-scrollspy/-/react-scrollspy-3.4.3.tgz", @@ -20675,6 +21125,22 @@ "prop-types": "^15.5.10" } }, + "react-smooth": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.5.tgz", + "integrity": "sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA==", + "requires": { + "fast-equals": "^5.0.0", + "react-transition-group": "2.9.0" + }, + "dependencies": { + "fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==" + } + } + }, "react-syntax-highlighter": { "version": "12.2.1", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz", @@ -20695,6 +21161,17 @@ "prop-types": "^15.5.7" } }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "react-twitter-embed": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/react-twitter-embed/-/react-twitter-embed-4.0.4.tgz", @@ -20798,6 +21275,41 @@ "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" }, + "recharts": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.10.1.tgz", + "integrity": "sha512-9bi0jIzxOTfEda+oYqgimKuYfApmBr0zKnAX8r4Iw56k3Saz/IQyBD4zohZL0eyzfz0oGFRH7alpJBgH1eC57g==", + "requires": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.19", + "react-is": "^16.10.2", + "react-smooth": "^2.0.5", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "dependencies": { + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + } + } + }, + "recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "requires": { + "decimal.js-light": "^2.4.1" + } + }, "redis-errors": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", @@ -21602,6 +22114,48 @@ "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" }, + "superagent": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.1.tgz", + "integrity": "sha512-VMBFLYgFuRdfeNQSMLbxGSLfmXL/xc+OO+BZp41Za/NRDBet/BNbkRJrYzCUu0u4GU0i/ml2dtT8b9qgkw9z6Q==", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.1.1", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + } + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -21760,6 +22314,11 @@ "globrex": "^0.1.2" } }, + "tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -22270,6 +22829,27 @@ "unist-util-stringify-position": "^3.0.0" } }, + "victory-vendor": { + "version": "36.6.11", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.6.11.tgz", + "integrity": "sha512-nT8kCiJp8dQh8g991J/R5w5eE2KnO8EAIP0xocWlh9l2okngMWglOPoMZzJvek8Q1KUc4XE/mJxTZnvOB1sTYg==", + "requires": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", diff --git a/package.json b/package.json index 4143d2049dc..b6d111ba59d 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "generate:dashboard": "node scripts/dashboard/build-dashboard.js", "generate:videos": "node scripts/build-newsroom-videos.js", "generate:tools": "node scripts/build-tools.js", - "test": "npx cypress run --component", + "test:components": "npx cypress run --component", "cy:open": "cypress open", "cy:run": "cypress run" }, @@ -41,6 +41,7 @@ "@floating-ui/react-dom-interactions": "^0.1.1", "@fullhuman/postcss-purgecss": "^2.2.0", "@heroicons/react": "^1.0.5", + "@mailchimp/mailchimp_marketing": "^3.0.80", "@mdx-js/loader": "1.6.4", "@mdx-js/react": "^1.6.4", "@next/mdx": "^9.4.2", @@ -67,6 +68,7 @@ "lodash": "^4.17.21", "markdown-to-txt": "^2.0.1", "markdown-toc": "1.2.0", + "md5": "^2.3.0", "mermaid": "9.3.0", "moment": "^2.29.4", "next": "^12.0.0", @@ -85,6 +87,7 @@ "react-typing-animation": "^1.6.2", "react-youtube-embed": "^1.0.3", "reading-time": "^1.2.0", + "recharts": "^2.10.1", "remark-frontmatter": "^2.0.0", "remark-gemoji-to-emoji": "^1.1.0", "remark-heading-id": "^1.0.0", @@ -99,7 +102,7 @@ "@anshgoyalevil/eslint-config": "^1.0.3", "@cypress/react": "^7.0.3", "@netlify/functions": "^1.4.0", - "@netlify/plugin-nextjs": "^4.37.2", + "@netlify/plugin-nextjs": "^4.40.2", "cypress": "^10.11.0", "dedent": "^0.7.0", "inquirer": "^8.2.0", diff --git a/pages/404.js b/pages/404.js index ac1655ff108..308dd9b19de 100644 --- a/pages/404.js +++ b/pages/404.js @@ -1,6 +1,4 @@ import React from 'react'; -import NavBar from '../components/navigation/NavBar'; -import StickyNavbar from '../components/navigation/StickyNavbar'; import Heading from '../components/typography/Heading'; import AnnouncementHero from '../components/campaigns/AnnoucementHero'; import Button from '../components/buttons/Button'; @@ -9,9 +7,6 @@ function ErrorPage() { const image = '/img/illustrations/illustration.webp'; return (
    - - -
    diff --git a/pages/[lang]/index.js b/pages/[lang]/index.js index 4cb1e171b4c..650ac78302b 100644 --- a/pages/[lang]/index.js +++ b/pages/[lang]/index.js @@ -1,6 +1,5 @@ import React from 'react'; import Container from '../../components/layout/Container'; -import NavBar from '../../components/navigation/NavBar'; import Hero from '../../components/Hero'; import NewsletterSubscribe from '../../components/NewsletterSubscribe'; import Sponsors from '../../components/sponsors/Sponsors'; @@ -20,7 +19,6 @@ import TextLink from '../../components/typography/TextLink'; import GoldSponsors from '../../components/sponsors/GoldSponsors'; import SilverSponsors from '../../components/sponsors/SilverSponsors'; import SupportUs from '../../components/SupportUs/SupportUs'; -import StickyNavbar from '../../components/navigation/StickyNavbar'; import GoogleCalendarButton from '../../components/buttons/GoogleCalendarButton'; import ICSFileButton from '../../components/buttons/ICSFileButton'; import SubscribeButton from '../../components/buttons/SubscribeButton'; @@ -38,10 +36,6 @@ function HomePage() { return ( <> - - - -
    diff --git a/pages/[lang]/tools/cli.js b/pages/[lang]/tools/cli.js index 7c0813e4db6..51e958fc2f5 100644 --- a/pages/[lang]/tools/cli.js +++ b/pages/[lang]/tools/cli.js @@ -72,7 +72,7 @@ export default function CliPage() { className="block mt-2 md:mt-0 md:inline-block w-full sm:w-auto" href="https://www.github.com/asyncapi/cli" /> -
    ); } @@ -156,7 +156,7 @@ export default function CliPage() {
    - + {t("cli.exampleTitle")}
    diff --git a/pages/_app.js b/pages/_app.js index 4dadaefe311..5a0147e7961 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -15,6 +15,8 @@ import { } from "../lib/i18n"; import loadLocales from "../lib/locales"; import '../styles/globals.css' +import StickyNavbar from '../components/navigation/StickyNavbar'; +import NavBar from '../components/navigation/NavBar'; function App({ Component, pageProps, router }) { @@ -36,6 +38,9 @@ function App({ Component, pageProps, router }) {
    + + + diff --git a/pages/blog/2023-Q4-docs-report.md b/pages/blog/2023-Q4-docs-report.md new file mode 100644 index 00000000000..c3b5f2de3c6 --- /dev/null +++ b/pages/blog/2023-Q4-docs-report.md @@ -0,0 +1,113 @@ +--- +title: "AsyncAPI Docs Report - Q4 2023" +date: 2024-01-22T06:00:00+01:00 +type: Engineering +tags: + - Documentation + - Communication +cover: /img/posts/2023-Q4-docs-report/Q4-docs-diagram-summary.webp +authors: + - name: Alejandra Quetzalli + photo: /img/avatars/canela-ale.webp + link: https://www.linkedin.com/in/alejandra-quetzalli/ + byline: During Q4 2023, AsyncAPI Docs had a total of 19,267 sessions and 6,447 unique users. +excerpt: In Q4, AsyncAPI docs had primary engagement across the tutorials and reference content buckets. +featured: true +--- + +# AsyncAPI Documentation Report - Q4 2023 +As a core maintainer of AsyncAPI Docs, I (Alejandra Quetzalli) volunteer to write periodic updates about the AsyncAPI Docs ecosystem. The goal is to keep the community informed about what's going on in docs and how docs contributors collaborate with other areas in AsyncAPI Initiative. + +## Overview +During Q4 2023, AsyncAPI Docs had a total of **19,267 sessions** and **6,447 unique users**. + +The successful contributions from the _2023 Google Season of Docs_ and the _2023 Technical Writing Mentorship Program_, made significant strides in documenting the intricacies of the new Spec 3 and its enhanced features. + +### Sessions per `content bucket`: +- `/docs/concepts`: **1,861 sessions** with **286 unique users**. +- `/docs/tutorials`: **5,528 sessions** with **2,139 unique users**. +- `/docs/tools`: **2,492 sessions** with **665 unique users**. +- `/docs/guides`: **523 sessions** with **167 unique users**. +- `/docs/reference`: **6,834 sessions** with **2,629 unique users**. + +## Google Season of Docs 2023 (GSoD) +[AsyncAPI was accepted into Google Season of Docs 2023 for two projects](https://developers.google.com/season-of-docs/docs/participants): **documenting the AsyncAPI document in detail** and **create a 100-level interactive learning path**. We received a total budget of $10,350. + +### Project 1: AsyncAPI document structure +Our first identified challenge involved updating the documentation for the structure of an AsyncAPI document to align with the latest specification, version 3.0.0. The new version introduces numerous changes and features, necessitating a revision of the configuration guidelines for AsyncAPI documents. To facilitate easier implementation of Event-Driven Architectures (EDAs), our documentation needs to provide more comprehensive explanations of the different sections within an AsyncAPI document. We've introduced a dedicated `/AsyncAPI-document` subdirectory within the **Concepts** area. That new section delves into the structure of an AsyncAPI document, with each component meticulously detailed on its own page. + +### Project 2: Create a 100-level interactive learning path +The second challenge we've addressed is launching a beginner-friendly, 100-level introduction to AsyncAPI. Our new interactive learning path is enhanced with engaging e-characters and a creative storyline, employing creative metaphors to effectively convey technical concepts. That new interactive educational resource will soon be available on our [AsyncAPI Killercoda profile](https://killercoda.com/asyncapi/). To support this initiative, we've established a dedicated repository for interactive learning content at `https://github.com/asyncapi/learning-paths`. + +Our new interactive learning path features a narrative where the [AsyncAPI mascot Eve assists Chan](https://github.com/asyncapi/brand/blob/master/illustrations/eve-and-chan/eve-chan-v2.png) in repairing his spaceship following an unexpected crash in Eve's backyard. Throughout this journey, various API concepts are elucidated using the engaging theme of fixing Chan's spaceship. In _"Module 1: Introduction to AsyncAPI,"_ Chan's spaceship crash lands in Eve's backyard, serving as a backdrop to explore AsyncAPI, its usage, and real-world applications. The story progresses to _"Module 2: Event-Driven Architectures,"_ where Eve examines the spaceship's engine, introducing event-driven systems and their design using AsyncAPI, particularly for microservices. The _"Module 3: AsyncAPI Specification"_ sees Eve helping Chan program his spaceship, delving into the AsyncAPI document structure, including its various components like info, channels, and schemas. The narrative continues with _"Module 4: Creating and Validating AsyncAPI Code and Documents,"_ where Chan returns to his planet to test communications with Eve, focusing on writing, validating, and hands-on exercises for AsyncAPI documents. The journey concludes with Module 5, a summary of the learning outcomes, a teaser about checking AsyncAPI tools, and a link back to the documentation. + +## AsyncAPI 2023 Mentorship Program - `technical writing` category +In the AsyncAPI 2023 Mentorship Program, the `technical writing` category started documenting how the Kafka and Websocket protocols work with AsyncAPI. We also detailed different kinds of schemas to manage with AsyncAPI. + +The below table lists sample topics covered: + +| **Kafka with AsyncAPI**| **WebSockets with AsyncAPI** | +|------------------------|------------------------------| +| Create AsyncAPI document for app interacting with Kafka | Tutorial for WebSockets with AsyncAPI | +| Kafka Specific Bindings | Tutorial for Request Reply using WebSockets | + + +## Spec 3.0 Docs +All AsyncAPI docs now align with the latest specification, version 3.0.0. The new version introduces numerous changes and features, necessitating a complete revision of the docs. The new `request/reply` feature from version 3 has been comprehensively documented, enriching both our **Concepts** and **Tutorials** sections. + +## Conclusion +Overall, Q4 showed a period of significant growth and achievement for AsyncAPI Docs. The data speaks volumes: with a total of 19,267 sessions and 6,447 unique users, with primary engagement across the `/tutorials` and `/reference` content buckets. + +We enhanced our documentation to align with Spec 3.0.0, introduced a dedicated `/AsyncAPI-document` subdirectory within the **Concepts** area, and created an innovative, interactive 100-level learning path stand. These additions not only provided in-depth knowledge of the new Spec 3.0.0 but also made learning more engaging and accessible to our community. Moreover, our focused efforts in documenting specific protocols like Kafka and WebSockets under the Mentorship Program further diversified and strengthened our content offerings. + +Overall, Q4 2023 was a testament to our commitment to delivering high-quality, relevant, and community-friendly documentation, setting a strong foundation for continued growth and innovation in the coming year. + +```mermaid +graph LR + +style A fill:#FF6EC7,stroke:#000000,stroke-width:2px; +style B fill:#B5EAD7,stroke:#000000,stroke-width:2px; +style C fill:#B5EAD7,stroke:#000000,stroke-width:2px; +style D fill:#B5EAD7,stroke:#000000,stroke-width:2px; +style E fill:#E1FEC1,stroke:#000000,stroke-width:2px; +style F fill:#E1FEC1,stroke:#000000,stroke-width:2px; +style G fill:#E1FEC1,stroke:#000000,stroke-width:2px; +style H fill:#FDD6C1,stroke:#000000,stroke-width:2px; + +A[AsyncAPI Docs - 2023 Q4 Report] +B[2023 Google Season of Docs] +C[100-Level Interactive Learning Path] +D[Document 'AsyncAPI document' Structure] +E[2023 Mentorship Program - Technical Writing] +F[Prioritized Kafka and WebSockets protocols] +G[Documented Managing Schemas with AsyncAPI] +H[AsyncAPI docs align with latest specification, version 3.0.0] + +A --> B +B --> C +B --> D +A --> E +E --> F +E --> G +A --> H +``` + +--- + +### How to contribute to AsyncAPI Docs +Did you know that you can contribute Docs to AsyncAPI as well? Code isn't the only way to contribute to OSS; docs are a **huge** help that benefits the entire OSS ecosystem. At AsyncAPI, we value Doc contributions as much as every other type of contribution. ❀️ + +To get started as a Docs contributor: +1. Familiarize yourself with our [project's Contribution Guide](https://github.com/asyncapi/community/blob/master/CONTRIBUTING.md) and our [Code of Conduct](https://github.com/asyncapi/.github/blob/master/CODE_OF_CONDUCT.md). +2. Head over to our Docs GH Board [here](https://github.com/orgs/asyncapi/projects/12). +3. Pick an issue you would like to contribute to and leave a comment introducing yourself and questions on how to get started. +4. If there is no work done in that Docs issue yet, feel free to open a PR and get started! +5. Send me a DM in Slack! + +#### Tag me in your AsyncAPI Doc PRs +Do you have a documentation contributor question, and you're wondering how to tag me into a GitHub discussion or PR? Never fear! + +Tag me in your AsyncAPI Doc PRs or [GitHub Discussions](https://github.com/asyncapi/community/discussions/categories/docs) via my GitHub handle, [`/alequetzalli`](https://github.com/alequetzalli) πŸ™. + +#### Talk to me +I want and need to listen πŸ‘‚πŸ½ to all of your perspectives and ideas. Please don't be shy to express to me what you think needs to be documented first or what is missing. πŸ“ There's a lot of good work ahead, but **you** determine _our content roadmap_ because the OSS community needs should always come first.✨ diff --git a/pages/blog/2023-july-docs-report.md b/pages/blog/2023-july-docs-report.md index e891131f711..34b0fb11228 100644 --- a/pages/blog/2023-july-docs-report.md +++ b/pages/blog/2023-july-docs-report.md @@ -11,7 +11,6 @@ authors: photo: /img/avatars/canela-ale.webp link: https://www.linkedin.com/in/alejandra-quetzalli/ byline: In July 2023, the AsyncAPI documentation had 7,443 sessions and 3,895 unique users, including 2,345 new users. -featured: true --- # AsyncAPI Docs Report - July 2023 diff --git a/pages/blog/2023-summary.md b/pages/blog/2023-summary.md new file mode 100644 index 00000000000..dd052e2577d --- /dev/null +++ b/pages/blog/2023-summary.md @@ -0,0 +1,164 @@ +--- +title: "Annual Review: State of AsyncAPI Initiative 2023" +date: 2024-01-29T06:00:00+01:00 +type: Communication +tags: + - Project Status +cover: /img/posts/2023-summary/blog-banner-2023.webp +authors: + - name: Thulisile Sibanda + photo: /img/avatars/thulieblack.webp + link: https://www.linkedin.com/in/v-thulisile-sibanda/ + byline: AsyncAPI Community Manager +excerpt: '2023 Year in Review' +featured: true +--- + +It's almost unbelievable that we are in 2024. And if you are reading this, Happy New Year to you and your loved ones. Continuing the tradition, we look at how the community has grown over the last 365 days and look forward to our next phase. + +If you are curious about our past achievements, please [read the previous 2022 AsyncAPI summary](https://www.asyncapi.com/blog/2022-summary). + +## Community Metrics +What better way to reflect on the past year than with numbers? Data is the most significant way to gauge our growth and measure our visible impact as an open-source community. + +### Slack +As of 2024, we are currently at an overall total of **4,471** members in the AsyncAPI workspace. The Slack workspace is our primary communication medium, from updates to helping contributors and new adopters onboard with the AsyncAPI spec and tools. + + +In 2023, we had 1488 people joining our workspace: + +
    + +Below are our top 5 members who joined the community in 2023 and have been the most active among other newcomers. As a community, we are proud of their contributions to our Mentorship programs. They even keep us entertained with memes πŸ˜€. + +
    + + +Additionally, our weekly activity continues to grow as we run different mentorship programs and initiatives that bring traction to our community. + +
    + + +### Social Media + +We use social media to communicate news and updates around our community. We don't use it for marketing. + + +> And honestly, I didn't invest much when it came to socials, so don't expect big big numbers 😝 + +Let's dive into the data: + +#### LinkedIn + +For our LinkedIn page, we are currently sitting at **2988** overall followers. During 2023, we gained a total of **849** followers since 2022. + +
    + +We also don't use any premium or marketing services; everything you see here is 100% organic. Even though LinkedIn still has much to offer, it is better than the X/Twitter app. + +
    + +#### X/Twitter + +We gained almost 1K followers since 2022, and now have 4.4k overall followers. When it comes to website referrals via Twitter, we have seen a decline compared to last year, 2022 + +
    + +Although the decline is shallow, I'm not extremely worried. Most top tweets for this year were appreciation tweets balanced with technical tweets. We don't use advertising because we don't consider the X/Twitter platform worth additional investment. + +#### YouTube + +The AsyncAPI YouTube channel performed way better than expected, especially as we moved from online to in-person conferences. We currently have over 364 people subscribed to our channel, increasing total subscribers to over 1.46k. Our live streams and conference recordings bring in a lot of views, leaving us optimistic for 2024. + +
    + +#### Newsletter +On the 5th of April, 2023, we sent out our first AsyncAPI Community Updates Newsletter. The main aim was to summarize monthly community activities/initiatives straight to your inbox. +Over the past nine months, the December Edition was the most popular due to the release of the AsyncAPI v3 (one of our major accomplishments in 2023). + +
    + +And, of course, I'm not exempt from unsubscribers. Although the number might seem minimal to some, it still stings as a writer. + +
    + +Looking forward to sending the 2024 Editions!!πŸŽ‰πŸŽ‰ + +### Google Analytics + +AsyncAPI website sessions and unique user have increased significantly over the past year. Our major contributor to these metrics comes from docs, and we expect to see more in the coming year as people want to know more about the AsyncAPI v3. + +
    + +We also lost 21 days' worth of data during October due to a PR update that affected the analytics workflow, but we are doing well. + +### Google Search Console + +Google Search Console is one of my favorite tools as it shows how much impact and interest we are gaining. Compared to 2022, we can see a surge in impressions and clicks. + +
    + +### Github + +The number of contributors in the community keeps growing, from having over **1600** contributors in 2022 to **2320** contributors in 2023. + +
    + +Although we have a handful of maintainers, we try our best to manage, resolve, and close issues as much as we can. Additionally, we are focusing on growing the number of maintainers in the coming years. + +
    + +### NPM + +Numbers don't lie; and yes, these are the total downloads of the top AsyncAPI packages hosted in the Node Package Manager. We can also see the adoption of AsyncAPI spec downloads increased from 5M to 17M since 2022. + +
    + +If you are worried about the project slowing down anytime soon, we are still growing strong. + +## Community Achievements + +We achieved so much this year, and here are some of the highlights from the AsyncAPI community in 2023! + +- We had our first community hire, [Thulisile Sibanda](https://www.linkedin.com/in/v-thulisile-sibanda/), to work full-time as the project's Community Manager. +- [Lukasz Gornicki](https://twitter.com/derberq) went from Community Guardian to Executive Director (boss moves right there πŸ˜‚πŸ˜‚). And yes, he's planning to get rid of the title soon. +- The [Ambassador Program](https://www.asyncapi.com/community/ambassadors) increased this year from having 3 ambassadors to 5. +- We launched the AsyncAPI Community Updates newsletter. +- Released the [Parser-JS v2](https://github.com/asyncapi/parser-js). +- We launched the [AsyncAPI Bounty Program](https://github.com/asyncapi/community/pull/897/files#diff-25ecb20a61754c225d6511ca08d7e7c9a14b9ca5a93e89bd42331e51c9ebf26dR155), where we successfully resolved and paid out a total of 11 out of 16 issues during the initial trial and 2023 Q4 round. +- Established our very first [AsyncAPI Code of Conduct Committee](https://github.com/orgs/asyncapi/discussions/682#discussioncomment-7498209). +- BarbaΓ±o GonzΓ‘lez shared a detailed article on [Why Women Are Underrepresented In Open-Source](https://thenewstack.io/why-women-are-underrepresented-in-open-source/). +- Participated in [GSoC'23](https://github.com/orgs/asyncapi/discussions/997) and [GSoD'23](https://github.com/orgs/asyncapi/discussions/961), while kickstarting the [AsyncAPI Mentorship Program II](https://github.com/asyncapi/community/tree/master/mentorship/asyncapi-mentorship/2023). +- Held our first in-person [AsyncAPI Conference on Tour](https://conference.asyncapi.com/) in London, Madrid, Bangalore and Paris. +- Released the [AsyncAPI v3](https://www.asyncapi.com/blog/release-notes-3.0.0). +- Launched the [AsyncAPI Store](https://asyncapi-store.com/). + +We hope you enjoyed a glimpse into our 2023 highlights; we have even more planned for 2024! Learn about our [2024 AsyncAPI Community Building Goals](https://github.com/orgs/asyncapi/discussions/948). \ No newline at end of file diff --git a/pages/blog/2024-february-summary.md b/pages/blog/2024-february-summary.md new file mode 100644 index 00000000000..61c68cc0ccc --- /dev/null +++ b/pages/blog/2024-february-summary.md @@ -0,0 +1,97 @@ +--- +title: "Community Update: February 2024" +date: 2024-02-29T06:00:00+01:00 +type: Communication +tags: + - Project Status +cover: /img/posts/2024-blog-banner/blog-banner-february.webp +authors: + - name: Thulisile Sibanda + photo: /img/avatars/thulieblack.webp + link: https://www.linkedin.com/in/v-thulisile-sibanda/ + byline: AsyncAPI Community Manager +excerpt: 'Community update for February' +featured: true +--- + +We are starting the year off with a bang as we got accepted to the [Google Summer of Code 2024](https://summerofcode.withgoogle.com/programs/2024/organizations/asyncapi) program after two years of rejections. It is an incredible achievement for the community, and we wouldn't have done it without our Doc's Lead, [Alejandra Quetzalli](https://www.linkedin.com/in/alejandra-quetzalli/), who crafted an excellent proposal, and [Elegbede Azeez](https://twitter.com/_acebuild). We are very excited to have received this opportunity, and you can read [the AsyncAPI Project Ideas Page](https://github.com/asyncapi/community/blob/master/mentorship/summerofcode/2024/asyncapi-gsoc-ideas-page.md) for in-depth details on participating projects. + +## AsyncAPI Conf on Tour 2024 +The planning of AACoT'24 is already underway as we prepare for our first conference in Helsinki on the 28th - 29th of May. We are putting in the final touches to update our conference website with the latest details, and we will soon announce the Call for Speakers. In the meantime, be sure to start crafting those proposals and get ready to share your expertise with the community. + +## Financial Sponsors +We are thrilled to share that the initiative has secured new sponsors who generously paid for the entire year in advance. We welcome [Postman](https://www.postman.com/) as a gold sponsor, who contributed $12,000, and [HiveMQ](https://www.hivemq.com/), our silver sponsor, who gave $6,000. + + +postman + + + +hivemq + + +For more information about our financial budget, please [refer to the 2024 Budget discussion](https://github.com/orgs/asyncapi/discussions/1017). + +## Community Discussions +We have important discussions that require the community's attention: + +- ### Marketing Activities + We need to invest in marketing efforts this year, and as the first initial step, we have secured a budget of $24,000. The next step now is to find a workaround to achieve this goal. If you have experience or have insights on how we can spend and efficiently boost our marketing aspects, please [join the Marketing Activities discussion](https://github.com/orgs/asyncapi/discussions/1062). +- ### Doc's Project Ideas for GSoD'24 + Google Season of Docs 2024 is now open, and we plan to participate again this year. We are currently gathering project proposals for our application, and if you have ideas on areas we should improve or focus on in our documentation, please [propose new docs project ideas in the community discussion](https://github.com/orgs/asyncapi/discussions/1069). +- ### Sovereign Tech Fund Application + The [Sovereign Tech Fund](https://www.sovereigntechfund.de/) is opening its applications for open-source organizations in Q2. We have some ideas and areas we should focus on for the application, such as CI/CD infrastructure. Be sure to [join the Sovereign Tech Fund discussion](https://github.com/orgs/asyncapi/discussions/1073) if you want to collaborate or share application ideas. +- ### Code of Conduct Draft Update + The AsyncAPI Code of Conduct Committee is halfway through updating the current Code of Conduct to the latest version. They have created some documents that explain the procedures and guidelines that the CoC Committee will use to enforce the Code of Conduct. You can glimpse [the updated Code of Conduct draft by checking the work-in-progress pull requests](https://github.com/asyncapi/community/issues/994). +- ### Cupid is Looking For Maintainers + We're on the lookout for maintainers for the AsyncAPI Cupid. The library focuses on finding and analyzing the relationships between AsyncAPI documents. If you're well-versed in Event-Driven Architecture and AsyncAPI, please [join the Cupid repository discussion](https://github.com/asyncapi/cupid/issues/182) and help us drive its development. +- ### AsyncAPI Working Groups + We are finally officializing working groups throughout the AsyncAPI community. A working group will be a community where people share similar interests beyond GitHub repositories. You can read the [Working Groups docs](https://github.com/asyncapi/community/blob/master/WORKING_GROUPS.md) or view the [Working Group public discussion](https://github.com/orgs/asyncapi/discussions/1037) for more comprehensive details. + +## TSC Members x Ambassadors + +We are excited to welcome five new [Technical Steering Committee](https://www.asyncapi.com/community/tsc) (TSC) members. + + + +Additionally, we have a new addition to the [AsyncAPI Ambassadors](https://www.asyncapi.com/community/ambassadors) team, raising the number to seven. + + + +Exciting times for our growing community! + +## Coming in March +- **AACoT'24 Helsinki Call for Speakers** - We will announce our Call for Speakers for AACoT'24 Helsinki by the first week of March. Start crafting those proposals and get ready to submit them. +- **AsyncAPI Community Updates Newsletter** - The March Edition issue will drop on the 6th. Make sure [you're subscribed to the AsyncAPI Newsletter](https://www.asyncapi.com/newsletter); you don't want to miss out! \ No newline at end of file diff --git a/pages/blog/conference-2023.md b/pages/blog/conference-2023.md new file mode 100644 index 00000000000..4b33cb335fd --- /dev/null +++ b/pages/blog/conference-2023.md @@ -0,0 +1,168 @@ +--- +title: "AsyncAPI Conference on Tour 2023 Report" +date: 2024-01-25T06:00:00+01:00 +type: Communication +tags: + - Conference +cover: /img/posts/2023-summary/background.webp +authors: + - name: Thulisile Sibanda + photo: /img/avatars/thulieblack.webp + link: https://www.linkedin.com/in/v-thulisile-sibanda/ + byline: AsyncAPI Community Manager +excerpt: In 2023, we hosted our very first in-person conference edition. Find out how it all went down! +featured: true +--- + +For three consecutive years, we have hosted online conferences, and in 2023, we decided to take it up a notch and move to in-person events. +The idea was to have a [conference tour with micro meetups in different cities](https://github.com/orgs/asyncapi/discussions/598), giving birth to the brand **AsyncAPI Conf on Tour (AACoT)**. + +Now imagine this: planning the very first AsyncAPI in-person conference by someone organizing an event for the first time; you would wonder what kind of faith the community had in me. +Being part of AACoT'23 was an adventurous, bumpy ride that came with valuable lessons. + +## The Planning Process + +We initially envisioned having five meetups per continent. For people who started the conference planning late, you would think we were being too optimistic. +At the end of the year, we managed to accommodate and have four confirmed locations. + +
    + +So much had to be put in place, like updating the conference website, starting with the marketing, creating announcements, doing calls for speakers, etc. We had to think on our feet most of the time. + +## Challenges + +Our biggest challenge of all was that the AACoT'23 planning started late. This meant that for every decision and effort we made, we were dashing against the clock. + +- Planning and marketing were complex since most venues were confirmed a few weeks before the summer holidays. +- In terms of promoting the events, we had some challenges in certain locations as we expected some support in this regard. This would have helped boost the event's visibility, but we were partly at fault since this wasn't communicated prior. +- Sometimes, free things can be costly! All the conference tickets were free. Of as many those who redeemed free tickets through Open Collective, only less than 50% showed up. It was very discouraging as food and resources that could have catered for everyone went to waste. +- There was no time to rest between the events as they all happened one after the other. +- We didn't have a sponsorship budget. By the time we thought about this, it was way too late. + +## Lessons + +Time and money are essential! When it comes to building a brand and conference planning. +I can't over-emphasize the importance of early planning, as we have seen in the past year, which we will prioritize for AACoT'24. + +Firstly, having open communication and fostering strong partnerships with our sponsors is undeniable. Before we agree and confirm the location, each venue must meet our community's minimum requirements, especially regarding support in marketing and participation in the planning process. + +Secondly, open up sponsorship tiers for companies and individuals who want to support us. Running AACoT requires a lot of funds, especially when it comes to swag costs, shipping, and going further to provide travel scholarships to community members who would like to participate. So, having a separate budget for AACoT is very crucial in this regard. + +Lastly, spacing all the conferences this year. Instead of what happened in 2023, where we had all meetups lined up a few weeks apart from each other, in 2024, we plan to have one conference each quarter. Additionally, this will give people time to prepare and plan to travel. + +## Attendance + +Though you may have an idea of how the attendance went, the best takeaway is that we had time to network, connect, and learn during the conferences. +Being our first year, we did fairly well regarding attendance numbers. We had 225+ individuals who attended in person, and two of our events were live-streamed, receiving over 820+ views. + +In addition, during our time in Paris, we also organized an `API Specs and Standards` booth, where we held discussions with people from the API world while promoting the conference. + +## Who Made AACoT'23 Possible + +AACoT'23 was only possible with our Event Hosts and Sponsors. These organizations provided a venue to host the conference and sponsored us lunch, breakfast, and refreshments; some even provided live stream coverage for those who couldn't attend. + + + + +ibm + + + + + +sngular + + + + + +postman + + + +apidays + + +We are truly grateful to them for their contributions! + +## Speakers + +What is a conference without our star speakers? These individuals took time out of their busy schedules to share their expertise. +They provided valuable industry insights, and we are proud of the network we built during the events. + +
    + + +You can also catch up on the live recording from [AACoT'23 Madrid](https://www.youtube.com/playlist?list=PLbi1gRlP7pihD-7XYb6c9wcTdkavDzF3_) and [AACoT'23 Bangalore](https://www.youtube.com/playlist?list=PLbi1gRlP7pijVocLZS7FeWKA4NBzJa7_Z). + +## Special Shout-Out + +I want to express my gratitude to these individuals and many others for their unwavering dedication in assisting with AACoT'23 behind the scenes. +They contributed to the design of website prototypes, conference design implementation, creating promotional videos, reviewing Call for Papers (CfPs), editing conference recordings, and providing constant communication and support. I am genuinely thankful for their hard work and commitment. + + + +## Where To Next? + +As we plan for AACoT'24, we are excited to announce that [APIdays](https://www.apidays.global/) will be hosting us in Helsinki on May 28-29th, London on September 17-18th, and Paris on December 3-5th. +Additionally, we are exploring the possibility of holding the event in Lagos in early Q2 or later. + +If you are interested in sponsoring AACoT'24, we welcome financial sponsors or event and host sponsors. + +You can check out our [Open Collective Page](https://opencollective.com/asyncapi/events/asyncapi-conference-on-tour-6b3c0aa1) to see the current sponsorship tiers or [download our conference sponsorship prospectus](https://drive.google.com/file/d/15rQ7cp-LLmxSCcAb2aBFitgJkGhYXBrd/view?usp=sharing) for more information. + diff --git a/pages/blog/designblog.md b/pages/blog/designblog.md new file mode 100644 index 00000000000..fcb41290ac0 --- /dev/null +++ b/pages/blog/designblog.md @@ -0,0 +1,62 @@ +--- +title: "Contributing to Open Source as a Product Design and UX Researcher" +date: 2023-11-09T06:00:00+01:00 +type: Communication +tags: + - Project Status +cover: /img/posts/designcover.webp +authors: + - name: Aishat Muibudeen + photo: /img/avatars/maya_picture.webp + link: https://www.linkedin.com/in/aishatmuibudeen/ + byline: Product Designer and UX Researcher +excerpt: 'Design BlogPost' +--- +Every software has a design system, regardless of whether it is free or not. Suppose you are a UX researcher or designer intending to be part of an Open Source community. In that case, you can begin contributing to the research or design program by collaborating with others. This article clarifies what Open Source is and provides tips on how you can start contributing as a UX researcher or designer. In addition, I’ll share some Open Source communities that you can contribute to as a beginner. + +### What is Open Source? + +public/img/posts/oss_image.webp + +Open Source Software (OSS) refers to software shared with its source code, allowing users to access, modify, and distribute. OSS allows everyone to contribute to the source code, make changes, or suggest new features. You can use the code for your purpose or contribute to improving the entire project’s features. + +Some examples of Open Source Software are available, including AsyncAPI, Linux Kernel, Oppia Foundation, VLC Media Player, Mozilla Firefox, Audacity, Blender, and more. These software are free to download, use, and distribute. It’s essential to recognize that some individuals put in much effort to make these projects available to a broad audience. Pursuing a career in Open Source can be beneficial, as it allows you to give back to the community and assist as many users as possible. + +It is worth noting that not all open-source projects are free of charge. To determine whether a project is free, you can check the project’s LICENSE file on GitHub. + +### My Experience as a Product Designer and UX Researcher in Open Source + +If you want to move faster in your career, I suggest getting started contributing to Open Source projects as early as possible. As a UX personnel, working with dummy users without getting feedback can be frustrating. However, Open Source allows you to learn your expertise and receive real-time feedback from users. Additionally, the collaborative nature of Open Source provides real-life working environments. + +In late 2022, I made my first Open Source contribution by designing speaker cards for the AsyncAPI Virtual Conference. When I received a notification that my pull request had been merged, I felt a sense of fulfillment about seeing my work showcased on a global scene. + +My interest in Open Source Communities made me apply for the Outreachy Internship Program. My collaboration and research skills helped me get into the program. I worked on the Foundational Research for Nigeria, a research project created to understand the learning needs and problems associated with technology learning among children between the ages of 7 and 15 in Nigeria. I also conducted usability testing with Oppia users to evaluate the effectiveness and usability of the Oppia application and website platform. + +Since completing my Internship Program in March, I have worked on other open-source projects. + +### Completed Projects + +- Designed the AsyncAPI Conference on Tour 2023 website (AACoT’23). +- Conducted a UX Design Audit on the AsyncAPI Website. +- Designed the AsyncAPI Financial Summary Page. +- Designed the Community Member’s Page for AsyncAPI. +- I worked with my team to design and create content for the Ladder Library as part of She Code Africa HackFest 2022. + +### On-going Projects + +- Working on the Design system for the AsyncAPI website. +- Creating a UX research plan for usability testing. +- Reviewing all design and research-related issues. + +### What are the advantages of contributing? + +There are numerous benefits to contributing to open source. One of the most prominent reasons is collaboration. For beginners and experienced fellows, collaborating using a version control system is an added advantage to your career. Getting hired based on your open-source contribution and contributing to technologies that make your life better and more accessible. +Finally, open source is time-consuming and can become overwhelming if you do not manage your time. + +### Are you ready to start contributing? + +Check if the applications you frequently use are Open Source and consider joining their communities. You can ask questions, solve issues, and offer assistance to others. Many communities offer issues that are suitable for beginners who are new to open source. + + + + diff --git a/pages/blog/introduction-to-glee-a-spec-first-framework.md b/pages/blog/introduction-to-glee-a-spec-first-framework.md new file mode 100644 index 00000000000..b7962d8f11b --- /dev/null +++ b/pages/blog/introduction-to-glee-a-spec-first-framework.md @@ -0,0 +1,181 @@ +--- +title: An Introduction to Glee +date: 2024-01-15T4:52:19+05:30 +type: Engineering +canonical: https://souvikns.com/blog/AsyncAPI/Introduction-to-glee +tags: ['guide'] +cover: /img/posts/glee-banner.webp +authors: + - name: Souvik De + photo: /img/avatars/souvikns.webp + link: https://twitter.com/souvik_ns + byline: AsyncAPI Maintainer +excerpt: Glee is a powerful spec-first framework that streamlines the building of server-side applications. By integrating your code with the spec, Glee takes care of the heavy lifting involved in creating and managing connections, allowing you to focus on the business logic that truly matters. +--- + +For the last year, I have been working full-time on AsyncAPI, where I have actively taken part in building a new framework called [Glee](https://github.com/asyncapi/glee). This is the first of many blogs to come where I will be talking about Glee and all the cool stuff we can build with it. In this blog, I will introduce Glee and give a broad overview of how to get started and keep up with Glee's development. + +# Introduction + +[Glee](https://github.com/asyncapi/glee) is a powerful spec-first framework that streamlines the process of building server-side applications. By integrating your code with the spec, Glee takes care of the heavy lifting involved in creating and managing connections, allowing you to focus on the business logic that truly matters. + + - It makes sure your code, specification, and documentation are synchronized. Glee eliminates the possibility of straying from the spec, which compels you to embrace a spec-first methodology, ensuring that your API is always entirely defined and coherent. When your API evolves, it includes the specification and documentation. + + - Glee simplifies creating and maintaining connections, allowing you to concentrate solely on developing code that meets your business needs. By handling performance, scalability, resilience, and all other aspects necessary for production readiness, Glee frees you from the burden of managing these technicalities, enabling you to focus on delivering a high-quality application that meets the demands of your users. + + +# Getting Started With Glee + +Let's create a simple WebSocket API using Glee to understand its magic. We will create a simple WebSocket server that receives a current time from the client and then sends a "good morning," "good evening," or "good night," respectively. + +### Setting Up A Glee Project. + +To work with Glee, you must install NPM and NodeJS version 10 or higher. You can just run the following commands in your terminal to check if you have both installed. + +```bash +# check if node is installed +node -v +# or +node --version + +# check if NPM is installed +npm -v +# or +npm --version + +``` + +If you don't have any of the above tools missing, go ahead and install them. + + + +#### Create a Glee project + +We recommend creating a new Glee app using our official [CLI](https://github.com/asyncapi/cli), which sets up everything automatically. (You don't need to create an empty directory, create-glee-app will make one for you.) To create a project, run: + +```bash + +asyncapi new glee + +``` + +> To install AsyncAPI CLI either use [npm](https://www.npmjs.com/package/@asyncapi/cli) or install binaries for your operating system from https://github.com/asyncapi/cli/releases + + +Once the process is complete, you should have a new Glee app ready for development and see these files that were made. + +
    + +![Glee File Structure](/img/posts/glee-introduction/glee-file-structure.webp) + +
    + + + +#### Define The Spec For Our API. + +Glee being a spec-first framework, development starts with defining your API spec. For our case, we will define our API: + + +```yaml:asyncapi.yaml +asyncapi: 3.0.0 +info: + title: Greet Bot + version: 0.1.0 +servers: + websockets: + host: '0.0.0.0:3000' + protocol: ws +channels: + greet: + address: greet + messages: + onGreet.message: + $ref: '#/components/messages/time' + subscribe.message: + $ref: '#/components/messages/greet' +operations: + onGreet: # operationId + action: receive + channel: + $ref: '#/channels/greet' + messages: + - $ref: '#/components/messages/time' + greet.subscribe: + action: send + channel: + $ref: '#/channels/greet' + messages: + - $ref: '#/components/messages/greet' +components: + messages: + time: + payload: + type: object + properties: + currentTime: + type: number + name: + type: string + greet: + payload: + type: string +``` + +This will be the specification that defines our API. In our case, it is very simple, as we will send a name and the time of the day, and our API will greet us accordingly. + +One thing to note here is the `operationId`; this is needed and is a crucial part of Glee, as this is how we will be connecting our business logic with our spec, `operationId` is the name of the function that will be called every time a certain operation occurs. In our case, whenever the `/greet` channel received a message. + +#### Define Our Operation Function. + +Now for our case, we will add a file `functions/onGreet.js` and write up the logic for parsing our time and sending a response. + +```js:functions/onGreet.js +export default async function (event) { + const { name, time } = event.payload + const t = new Date(time) + const curHr = t.getHours() + let response = '' + if (curHr < 12) { + response = `Good Morning ${name}` + } else if (curHr < 18) { + response = `Good Afternoon ${name}` + } else { + response = `Good Evening ${name}` + } + return { + reply: [ + { + payload: response, + }, + ], + } +} +``` + +Every file in the functions folder acts as a handler to develop business logic for Glee. Each file should export an async function that receives an event parameter, where you have access to payload and server details. + + +#### Running And Testing Your Application + +We will not execute the application and carry out testing with Postman to ensure that it is functioning as intended. + +Now to run your Glee application, just execute the following: + +```bash +npm run dev +# or +npm run start +``` + +Then open Postman and checkout the endpoint: + +![postman](/img/posts/glee-introduction/postman-glee-greet.webp) + + +# Conclusion + +So this is how easy it is to build a WebSocket API using Glee. Please do check out [the Greet-Bot example code](https://github.com/Souvikns/greet-bot). + +Glee is rapidly evolving and aims to support a variety of protocols, and while it is still in development, it currently has stable support for MQTT and WebSocket. As a team, we are eager to gather feedback from users like you to help us improve Glee and make it even better. If you are interested in trying out Glee, we would greatly appreciate it if you could test it out and share your thoughts about your experience. Your feedback will be invaluable in helping us identify areas for improvement and making Glee more user-friendly and effective. The best way to communicate with us is through [GitHub Issues](https://github.com/asyncapi/glee/issues). + diff --git a/pages/blog/release-notes-3.0.0.md b/pages/blog/release-notes-3.0.0.md new file mode 100644 index 00000000000..75447e63540 --- /dev/null +++ b/pages/blog/release-notes-3.0.0.md @@ -0,0 +1,362 @@ +--- +title: AsyncAPI 3.0.0 Release Notes +date: 2023-12-05T17:00:00+01:00 +type: Communication +tags: + - Specification + - Release Notes +cover: /img/posts/release-notes-3.0.0/cover.webp +authors: + - name: Jonas Lagoni + photo: /img/avatars/jonaslagoni.webp + link: https://github.com/jonaslagoni +excerpt: 'The release of AsyncAPI v3 is packed with changes such as request/reply, reusable channels, and more!' +featured: true +--- + +The new version of the AsyncAPI specification - 3.0.0 - is now available and is packed with goodies! Some clear up confusion, some add features, and others improve maintainability. + +To make the information as clear as possible, we have split up the information into digestible chunks. + +If you want to get an overview of: +- All the changes done in v3, you are in the right place! +- [Migration guide for all the breaking changes between v2 and v3](/docs/migration/migrating-to-v3) + +## Overview +This post will give you an overview of all the changes done in v3. + +### Operation, channel, and message decoupling + +In v2, it has never been possible to re-use channels, because it was directly coupled with operations of an application. + +In v3, this is now possible, with the mindset that a channel and message should be detached from the operations performed. This means for any message broker, for example, for Kafka, channels now ONLY define topics and the messages it contains. For REST interfaces, it's all the paths and corresponding messages across all request types. For WebSocket, it's all the messages flowing through the WebSocket server. For Socket.Io, it defines all the rooms and messages therein. + +This change makes the channels reusable across multiple AsyncAPI documents. + +``` +asyncapi: 3.0.0 +... +channels: + UserSignup: + address: user/signedup + messages: + UserMessage: + payload: + type: object + properties: + displayName: + type: string + description: Name of the user +operations: + ConsumeUserSignups: + action: receive + channel: + $ref: "#/channels/UserSignup" +``` + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#618](https://github.com/asyncapi/spec/issues/618), [#663](https://github.com/asyncapi/spec/issues/663) | [#806](https://github.com/asyncapi/spec/pull/806), [#827](https://github.com/asyncapi/spec/pull/827) | [Operation, channel, and message decoupling](/docs/migration/migrating-to-v3#operation-channel-and-message-decoupling) | + +### Messages instead of message +As you probably noticed above, messages in channels are no longer singular, and with `oneOf`, instead, messages are defined as key/value pairs in the [Messages Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#messagesObject). This was part of the request-reply feature to enable easier referencing of messages. + +``` +asyncapi: 3.0.0 +... +channels: + UserSignup: + address: user/signedup + messages: + UserMessage: + ... +``` + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#94](https://github.com/asyncapi/spec/issues/94) | [#827](https://github.com/asyncapi/spec/pull/827) | [Messages instead of message](/docs/migration/migrating-to-v3#messages-instead-of-message) | + +### Publish and subscribe confusion +In v2, the `publish` and `subscribe` operation keywords have always been confusing. Does it mean my application is published to the channel? Does it mean you publish for me? Who are you in this context? + +In v3, we try to clear this up. You only need to worry about your application's behavior. No more confusion about what and who does what. We achieve this through two new [Operation Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#operationObject) keywords, `send` and `receive`, i.e. your application either sends or receives something. + +This description, of course, alters slightly based on protocol; for the generic message brokers, you produce or consume messages, but in the abstract AsyncAPI perspective, you still send or receive messages. + +``` +asyncapi: 3.0.0 +... +operations: + SendUserSignedUp: + action: send + ReceiveUserSignedUp: + action: receive +``` + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#829](https://github.com/asyncapi/spec/issues/829) | [#847](https://github.com/asyncapi/spec/pull/847) | [Operation keywords](/docs/migration/migrating-to-v3#operation-keywords) | + +### Request/Reply +One of the longest requested features is request and reply... and it's finally here! + +One thorn in the eye of this feature has always been the publish and subscribe confusion, which complicated any efforts to achieve a workable solution. However, we now have a solution with that out of the way. :fire: + +This feature has been designed with the following use cases in mind: + +- Broker-based messaging with well-defined response topic + "correlationId". +- Broker-based messaging with per process individual inbox aka "replyTopic" + "correlationId". +- Broker-based messaging with a temporary reply topic for an individual response. +- WebSocket, which has no topics, where the channel is a TCP connection where messages flow. + +``` +... +action: send | receive +reply: + address: + location: '$message.header#/replyTo' + channel: + $ref: '#/channels/userSignupReply' + messages: + - $ref: '#/components/messages/userSignedUpReply' +``` + +Read more about the [Operation Reply Object here](https://www.asyncapi.com/docs/reference/specification/v3.0.0#operationReplyObject). + +| Issue(s) | PR(s) | +| ----------- | ----------- | +| [#94](https://github.com/asyncapi/spec/issues/94), [#558](https://github.com/asyncapi/spec/issues/558) | [#847](https://github.com/asyncapi/spec/pull/847) | + +### Optional channels +We have seen many use cases where an AsyncAPI document has been used as a form of menu or collection of definitions. To do this in v2 would require a bit of a hack. But in v3, channels are now entirely optional. This means that it's now possible to have a valid AsyncAPI document as such: + +``` +asyncapi: 3.0.0 +... +components: + ... +``` + +| Issue(s) | PR(s) | +| ----------- | ----------- | +| [#829](https://github.com/asyncapi/spec/issues/829) | [#847](https://github.com/asyncapi/spec/pull/847) | + +### Unified referencing behaviors + +In v2, there were two instances where we used implicit references; server security configuration, by name referencing security requirement object in components, for channels to reference global servers by name. To stay as consistent as possible, we wanted to unify how references were used, which means that in v3, we ONLY use explicit references. + +The `scopes` information in the [Security Schema Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#securitySchemeObject) is also now an array instead of an object. + +``` +asyncapi: 3.0.0 +... +servers: + SomeServer: + security: + - $ref: '#/components/securitySchemes/SomeSecurity' +channels: + SomeChannel: + servers: + - $ref: '#/servers/SomeServer' +components: + securitySchemes: + SomeSecurity: + ... + scopes: [...] +``` + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#829](https://github.com/asyncapi/spec/issues/829) | [#852](https://github.com/asyncapi/spec/pull/852) | [Unifying explicit and implicit references](/docs/migration/migrating-to-v3#unifying-explicit-and-implicit-references) | + +### Common metadata fields +There has been some inconsistency between which metadata fields are available in the different objects. Now we have added a few extra fields: +- added `title`, `summary`, and `externalDocs` fields in the [Server Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serverObject) +- added `title` and `summary` fields in the [Channel Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#channelObject) +- added `title` field in the [Operation Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#operationObject) and [Operation Trait Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#operationTraitObject) + +``` +asyncapi: 3.0.0 +... +servers: + SomeServer: + title: Some Server title + summary: This some server is for something + externalDocs: + ... +channels: + SomeChannel: + title: Some channel title + summary: Some channel summary +operations: + SomeOperation: + title: Some operation title + traits: + - title: Some operation traits title +``` + +| Issue(s) | PR(s) | +| ----------- | ----------- | +| [#795](https://github.com/asyncapi/spec/issues/795) | [#796](https://github.com/asyncapi/spec/pull/796) | + +### Cleaning up the root object +There was two meta information lingering in the root of the AsyncAPI object, which did not make much sense since we have the `info` object for all the meta information. + +Therefore the root `tags` and `externalDocs` have been moved to the [Info Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#infoObject). + +``` +asyncapi: 3.0.0 +... +info: + ... + externalDocs: + description: Find more info here + url: https://www.asyncapi.org + tags: + - name: e-commerce +... +``` + +| PR(s) | Migration Guide | +| ----------- | ----------- | +| [#794](https://github.com/asyncapi/spec/pull/794) | [Moved metadata](/docs/migration/migrating-to-v3#moved-metadata) | + +### Splitting out server URL into host and pathname +There has been some confusion about what the `url` of a server should contain; is it both protocol + host + path? What about the protocol field, then? Therefore each field now has its field for the host, path, and protocol in the [Server Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#serverObject). + +``` +asyncapi: 3.0.0 +... +servers: + localhost: + host: localhost + path: /api/v1, + protocol: mqtt +``` + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#547](https://github.com/asyncapi/spec/issues/547), [#274](https://github.com/asyncapi/spec/issues/274) | [#888](https://github.com/asyncapi/spec/pull/888) | [Server URL splitting up](/docs/migration/migrating-to-v3#server-url-splitting-up) | + +### More reusable objects in components +This is a bit of a mixture between some of the features, that all added a little to this. It's now possible to add more stuff under the [Components Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#componentsObject): +- Replies +- Reply addresses +- Tags +- External docs +- Operations +- Channels + +``` +asyncapi: 3.0.0 +... +components: + ... + replies: + ... + replyAddresses: + ... + tags: + ... + externalDocs: + ... + operations: + ... + channels: + ... +``` + +| Issue(s) | PR(s) | +| ----------- | ----------- | +| [#829](https://github.com/asyncapi/spec/issues/829) | [#847](https://github.com/asyncapi/spec/pull/847), [#792](https://github.com/asyncapi/spec/pull/792), [#806](https://github.com/asyncapi/spec/pull/806), [#827](https://github.com/asyncapi/spec/pull/827) | + +### New trait behavior +Traits in v2 always replaced any duplicate properties that were defined both in traits and the associated object. This meant, for example, if the message traits defined headers and the message object did as well, only the message trait headers would be applied because it overwrote anything you wrote in the message object. + +In v3, this has now been changed so that [a property on a trait MUST NOT override the same property on the target object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#traitsMergeMechanism). + +For example, take a look at this message: +``` +messageId: userSignup +description: A longer description. +payload: + $ref: '#/components/schemas/userSignupPayload' +traits: + - name: UserSignup + title: User signup + summary: Action to sign a user up. + description: Description from trait. +``` +Take notice of how `description` is not overwritten by the traits: + +``` +messageId: userSignup +name: UserSignup +title: User signup +summary: Action to sign a user up. +description: A longer description. # it's still description from "main" object +payload: + $ref: '#/components/schemas/userSignupPayload' +``` + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#505](https://github.com/asyncapi/spec/issues/505) | [#517](https://github.com/asyncapi/spec/pull/517), [#532](https://github.com/asyncapi/spec/pull/532), [#907](https://github.com/asyncapi/spec/pull/907) | [New trait behavior](/docs/migration/migrating-to-v3#new-trait-behavior) | + + +### Schema format and payload definition +With schemas, one thing that has always been impossible was reusing schemas with different schema formats. That's because the schema format information is part of the message object. That means that if you reference a Schema object, it has no information about the schema format because it's not located together. + +In v3, schemaFormat has been removed from the [Message Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#messageObject) and [Message Trait Object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#messageTraitObject), and a new [schema Object called `Multi Format Schema Object`](https://www.asyncapi.com/docs/reference/specification/v3.0.0#multiFormatSchemaObject) has been introduced, which pairs a schema together with its schema format. Which now enables much better reusability: + +``` +asyncapi: 3.0.0 +... +components: + schemas: + avroSchema: + schemaFormat: 'application/vnd.apache.avro+yaml;version=1.9.0' + schema: + type: record + name: User + namespace: com.company + doc: User information + fields: + - name: displayName + type: string +``` + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#622](https://github.com/asyncapi/spec/issues/622) | [#797](https://github.com/asyncapi/spec/pull/797), [#910](https://github.com/asyncapi/spec/pull/910) | [Schema format and schemas](/docs/migration/migrating-to-v3#schema-format-and-schemas) | + +### Simplified Parameters +In v2, it was possible to use the full power of JSON Schema to define parameters, however, it introduced a lot of complexity to parameters, so for v3 it was dialed way down to only allow a very small set of properties. + +In v3, the new [Parameter object](https://www.asyncapi.com/docs/reference/specification/v3.0.0#parameterObject) can now only have the following properties: `enum`, `default`, `description`, `examples`, and `location`. + +``` +asyncapi: 3.0.0 +... +channels: + userSignup: + address: user/{userId}/signedup + parameters: + userId: + description: Id of the user. +``` + +By default this means that any parameter is of type `string`. + +| Issue(s) | PR(s) | Migration Guide | +| ----------- | ----------- | ----------- | +| [#583](https://github.com/asyncapi/spec/issues/583) | [#935](https://github.com/asyncapi/spec/pull/935) | [Restricted parameters object](/docs/migration/migrating-to-v3#restricted-parameters-object) | + +### Editorial Changes + +We have [removed the note that stated we strived to be compatible with OpenAPI where possible]([#933](https://github.com/asyncapi/spec/pull/933)) because, with the recent changes, this is no longer the case. That said, we still strive to make the different specs as interoperable as possible i.e., with Avro, RAML, OpenAPI Schema, etc. + +## Acknowledgements +Spec 3.0 have been a massive undertaking, so I would like to say a huge "thank you!" to everyone who has been involved; maybe you commented on your views, added to discussions, joined the live meetings, championed changes, or reviewed proposed changes; this section is for you! + +Thank you, [Simon Heimler](https://github.com/Fannon), [VladimΓ­r Gorej](https://github.com/char0n), [Fran MΓ©ndez](https://github.com/fmvilas), [Lukasz Gornicki](https://github.com/derberg), [Sergio Moya](https://github.com/smoya), [Michael Davis](https://github.com/damaru-inc), [Maciej UrbaΕ„czyk](https://github.com/magicmatatjahu), [Jesse Menning](https://github.com/jessemenning), [Heiko Henning](https://github.com/GreenRover), [Gerald Loeffler ](https://github.com/GeraldLoeffler), [c-pius](https://github.com/c-pius), [Ian Cooper](https://github.com/iancooper), [Dale Lane](https://github.com/dalelane), [JΓΆrg Walter](https://github.com/joerg-walter-de), [Nic Townsend](https://github.com/nictownsend), [Laurent Broudoux](https://github.com/lbroudoux), [olamiral](https://github.com/olamiral), [IvΓ‘n GarcΓ­a Sainz-Aja](https://github.com/ivangsa), [Fabian BΓΌhler](https://github.com/buehlefs), [John Fallows](https://github.com/jfallows), [Adrian Hope-Bailie](https://github.com/adrianhopebailie), [Christian (prdatur)](https://github.com/prdatur), [Karl Morrison](https://github.com/basickarl), [Javier JimΓ©nez Roda](https://github.com/jjimenezroda), [Marek Sebera](https://github.com/smarek), [NathanaΓ«l LΓ©caudΓ©](https://github.com/natcl), [Jeremy Whitlock](https://github.com/whitlockjc), [souvik](https://github.com/Souvikns), [Animesh Kumar](https://www.github.com/animeshkumar923), [Samir AMZANI](https://github.com/Amzani), [Alejandra Quetzalli](https://github.com/alequetzalli), [Vaishnavi](https://github.com/VaishnaviNandakumar), [Mahfuza](https://github.com/mhmohona), [Bhaswati](https://github.com/BhaswatiRoy), [Cynthia Peter](https://github.com/CynthiaPeter), [Arya Gupta](https://github.com/Arya-Gupta), [Joy Almeida](https://github.com/J0SAL), [Hridyesh](https://github.com/kakabisht), [Rohit](https://github.com/TRohit20), [Ashish Padhy](https://github.com/Shurtu-gal), [Al Amin Muhammad](https://github.com/alaminthespecial), [nickshoe](https://github.com/nickshoe), [Khuda Dad Nomani](https://github.com/KhudaDad414), [V Thulisile Sibanda](https://github.com/thulieblack), [Ace](https://github.com/AceTheCreator), [Mihael Bosnjak](https://github.com/mboss37), [Sambhav Gupta](https://github.com/sambhavgupta0705), [Jonas Lagoni](https://github.com/jonaslagoni), [Afzal Ansari](https://github.com/afzal442) \ No newline at end of file diff --git a/pages/blog/september-2023.md b/pages/blog/september-2023.md index 8907f6b4a68..86ec3687f1e 100644 --- a/pages/blog/september-2023.md +++ b/pages/blog/september-2023.md @@ -11,7 +11,6 @@ authors: link: https://www.linkedin.com/in/v-thulisile-sibanda/ byline: AsyncAPI Community Manager excerpt: 'September and October Community Update' -featured: true --- Our second AsyncAPI Conf on Tour took place on the 19th of October, hosted by SNGULAR in Madrid. The day was well-organized, packed with informative talks from industry experts and great networking sessions, making it a valuable experience for attendees. Additionally, the conference was live-streamed, and every session was recorded, so even if you missed out on attending the event in person, you can still [watch the recordings on YouTube](https://www.youtube.com/playlist?list=PLbi1gRlP7pihD-7XYb6c9wcTdkavDzF3_) and catch up on all the insightful talks. diff --git a/pages/blog/status-update-47-20.md b/pages/blog/status-update-47-20.md index 6020650e143..0f8edc497c1 100644 --- a/pages/blog/status-update-47-20.md +++ b/pages/blog/status-update-47-20.md @@ -106,7 +106,7 @@ Now it should be easier for you to use this component in non-React projects. Tha