diff --git a/.github/workflows/notify-triager.yml b/.github/workflows/notify-triager.yml index bcdd6ef3d352..6539dc230174 100644 --- a/.github/workflows/notify-triager.yml +++ b/.github/workflows/notify-triager.yml @@ -11,13 +11,17 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4.1.1 with: + fetch-depth: 0 repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.sha }} - name: Get commit message id: commit-message run: | + # Extract the commit message commit_message=$(git log --format=%B -n 1 ${{ github.event.pull_request.head.sha }}) + commit_message=$(echo "$commit_message" | tr '\n' ' ') + commit_message=$(echo "$commit_message" | sed 's/[<>|]//g' | sed 's/[][]//g' | sed 's/(//g' | sed 's/)//g' | xargs) echo "commit_message=$commit_message" >> $GITHUB_OUTPUT - name: Check if last commit is a merge commit @@ -31,23 +35,23 @@ jobs: echo "isMergeCommit=false" >> $GITHUB_OUTPUT fi - - name: Checkout asyncapi/website Repository - uses: actions/checkout@v4.1.1 + - name: Count changed files + id: changed_files + run: | + # Get the list of files changed in the latest commit + changed_files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}) - - name: Check PR Changes for .md files - id: md-pr-changes - uses: tj-actions/changed-files@aa08304bd477b800d468db44fe10f6c61f7f7b11 # version 42.1.0 https://github.com/tj-actions/changed-files/releases/tag/v42.1.0 - with: - files: | - **.md + # Initialize counters + md_count=0 + non_md_count=0 - - name: Check PR Changes for non-.md files - id: non-md-pr-changes - uses: tj-actions/changed-files@aa08304bd477b800d468db44fe10f6c61f7f7b11 # version 42.1.0 https://github.com/tj-actions/changed-files/releases/tag/v42.1.0 - with: - files: | - !**.md + # Count .md files + md_count=$(echo "$changed_files" | grep -c '\.md$' || true) + # Count non-.md files + non_md_count=$(echo "$changed_files" | grep -vc '\.md$' || true) + echo "md_count=$md_count" >> $GITHUB_OUTPUT + echo "non_md_count=$non_md_count" >> $GITHUB_OUTPUT - name: Extract Doc Triage Maintainers id: doc-triager @@ -68,7 +72,7 @@ jobs: echo "codeTriagers=$codeTriagers" >> $GITHUB_ENV - name: Add Reviewers for code files - if: steps.check-merge-branch.outputs.isMergeCommit == 'false' && steps.non-md-pr-changes.outputs.any_changed == 'true' + if: ${{ steps.check-merge-branch.outputs.isMergeCommit == 'false' && steps.changed_files.outputs.non_md_count > 0 }} run: | IFS=' ' read -r -a codeTriagers <<< "${{ env.codeTriagers }}" reviewers=$(printf ', "%s"' "${codeTriagers[@]}") @@ -83,7 +87,7 @@ jobs: }" - name: Add Reviewers for doc files - if: steps.check-merge-branch.outputs.isMergeCommit == 'false' && steps.md-pr-changes.outputs.any_changed == 'true' + if: ${{ steps.check-merge-branch.outputs.isMergeCommit == 'false' && steps.changed_files.outputs.md_count > 0 }} run: | IFS=' ' read -r -a docTriagers <<< "${{ env.docTriagers }}" reviewers=$(printf ', "%s"' "${docTriagers[@]}") @@ -96,3 +100,4 @@ jobs: -d "{ \"reviewers\": $reviewers }" + diff --git a/components/AlgoliaSearch.tsx b/components/AlgoliaSearch.tsx index a7d3604fafb7..06d37889c473 100644 --- a/components/AlgoliaSearch.tsx +++ b/components/AlgoliaSearch.tsx @@ -312,6 +312,8 @@ export function SearchButton({ children, indexName = INDEX_NAME, ...props }: ISe useEffect(() => { if (typeof children === 'function') { setChildren(children({ actionKey })); + } else { + setChildren(children); } }, []); diff --git a/config/AMBASSADORS_MEMBERS.json b/config/AMBASSADORS_MEMBERS.json index 7e0bb122ce72..5643ae8a3ef6 100644 --- a/config/AMBASSADORS_MEMBERS.json +++ b/config/AMBASSADORS_MEMBERS.json @@ -542,6 +542,24 @@ "month": "June" }, "link": "https://confengine.com/conferences/selenium-conf-2024/proposal/20021/unshackling-your-system-under-test-shift-left-testing-through-dependency-isolation" + }, + { + "type": "talk", + "title": "Using API spec as an Executable Contract To Mock and Test Microservices", + "date": { + "year": 2024, + "month": "October" + }, + "link": "https://www.youtube.com/watch?v=wiM20HTCerM" + }, + { + "type": "talk", + "title": "Contract-Driven Development for Event-Driven Architectures", + "date": { + "year": 2024, + "month": "December" + }, + "link": "https://conference.asyncapi.com/venue/Paris" } ] }, diff --git a/config/MAINTAINERS.json b/config/MAINTAINERS.json index ee02bec23fbd..dd55db0fbbdd 100644 --- a/config/MAINTAINERS.json +++ b/config/MAINTAINERS.json @@ -897,28 +897,6 @@ ], "githubID": 743192 }, - { - "name": "Vinit Shahdeo", - "github": "vinitshahdeo", - "twitter": "Vinit_Shahdeo", - "availableForHire": true, - "isTscMember": false, - "repos": [ - "diff" - ], - "githubID": 20594326 - }, - { - "name": "Anubhav Vats", - "github": "onbit-uchenik", - "twitter": "postmanlabs", - "availableForHire": true, - "isTscMember": false, - "repos": [ - "diff" - ], - "githubID": 46771418 - }, { "name": "Akshaya Gurlhosur", "github": "AGurlhosur", diff --git a/config/all-tags.json b/config/all-tags.json index 9e30fdec6d5c..f72cb51c6a70 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":"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":"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":"Java","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":"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 CLI","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]"},{"name":"Java","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}]} \ No newline at end of file diff --git a/config/casestudies/hdi.yml b/config/casestudies/hdi.yml index 521f8aa90044..9d43467d0d16 100644 --- a/config/casestudies/hdi.yml +++ b/config/casestudies/hdi.yml @@ -4,29 +4,31 @@ company: description: The HDI brand operates in Germany and internationally, offering life and property/casualty insurance services. They cater to both private individuals and corporate clients, and have been providing industrial insurance since 2016. customers: "5000" industry: Insurance - revenue: 9.1 Mrd. EUR + revenue: 9.1B EUR website: https://www.hdi.global/ logo: /img/casestudies/hdi/hdi_logo.svg contact: - name: Vladislav Zwenihorodski link: https://www.linkedin.com/in/vladislav-zwenihorodski-9680a1209/ challenges: | - The HDI has various platform teams, among them the Integration Platform Team, which offers three products: Azure API Management, Azure Event Hub, and the Azure Service Bus. - For synchronous communication, we already use OpenAPI, as such we want to ensure the same level of transparency and discoverability for asynchronous scenarios as well. - Our central platform team offers the Azure Service Bus with self-service capabilities. - Customers are able to manage their own topics and subscriptions by simply modifying the according values in their repositories. - This means that most of the data required to document asynchronous communication is already available, although distributed between different repositories. - This necessitated the creation of a comprehensive catalog of existing topics, allowing potential subscribers easy access to messages from any topics of their choosing. + The HDI has various platform teams, among them the Integration Platform team, which offers three products: Azure API Management, Azure Event Hub, and the Azure Service Bus. + For synchronous communication OpenAPI is used as a standard. For asynchronous scenarios we want to use AsyncAPI to achieve the same level of transparency and discoverability. + We as platform team offer the Azure Service Bus with self-service capabilities. Our customers are able to manage their own topics and subscriptions by maintaining a custom + configuration model in a GitOps fashion. + We want to establish AsyncAPI as documentation standard in HDI's organization. Information about the available message formats and topics is already available in distributed + sources (e.g. repositories) and needs to be aggregated. + To achieve discoverability the creation of a comprehensive catalog of existing topics is necessary, allowing potential subscribers access to information about + messages from the available topics, so they can choose which ones to subscribe to. solution: | - The solution was to create an an AsyncAPI document where each topic owned by the customer is represented as a channel. - This document is automatically generated by a pipeline whenever there's a change in the topic configuration. + The solution is to create AsyncAPI documents where each topic owned by the customer is represented as a channel. + As we are using the GitOps setup it is straightforward to run pipeline whenever there is a change (commit) in the topic configuration. The necessary information is read from the customer repositories and then passed to a bash script as input. After successful creation, this file, along with a generated markdown for it, is saved within a documentation repository. This documentation repository serves as the basis for our Azure DevOps wiki, ensuring that all project documentation is centralized and easily accessible. - This ensures that the information is readily accessible to every developer, allowing easy access to messages from any topics of their choosing. - This approach makes our asynchronous communication is as transparent and discoverable as our synchronous communication. + As the documentation wiki is public the information is accessible to every developer, allowing easy access to messages from any topics of their choice. + This approach makes our asynchronous communication as transparent and discoverable as our synchronous communication. technical: #We need some more technical information related to case study. languages: - java, .net, bash @@ -198,7 +200,9 @@ asyncapi: #More specific details about AsyncAPI itself and how is it used. usecase: | - The AsyncAPI documents are used for documentation purposes by the platform team. It provides a comprehensive overview of the asynchronous communication in our system, including the available topics and the structure of the messages. - - (Future Plans) The AsyncAPI document will be used to generate Java DTOs using the AsyncAPI Java generator, ensuring type safety and clear data structure understanding. + - (Outlook) The AsyncAPI document will be used to generate Java DTOs, ensuring type safety and clear data structure understanding. + - (Outlook) Having the AsyncAPI documents at hand we are currently planning to use them to configure an internal developer portal (IDP) that will aggregate async and sync APIs among other things. + - (Outlook) Evaluate if replacing the custom configuration model and use AsyncAPI documents in the center to configure asynchronous communication instead. versions: - '3.0.0' storage: | @@ -209,7 +213,7 @@ asyncapi: #More specific details about AsyncAPI itself and how is it used. This pipeline uses a bash script to read the updated configuration from the customer's repository. It then generates a new AsyncAPI document reflecting these changes. - The AsyncAPI document is validated using the AsyncAPI CLI to confirm that the document is correctly formatted and adheres to the AsyncAPI specification right after creation and befor being commited to the documentation repository. + The AsyncAPI document is validated using the AsyncAPI CLI to confirm that the document is correctly formatted and adheres to the AsyncAPI specification right after creation and before being commited to the documentation repository. maintainers: | Customers maintain this document automatically by maintaining their own topic configurations. audience: #Specify if AsyncAPI audience is internal or external or both. diff --git a/config/meetings.json b/config/meetings.json index a6db3de6e5be..591d94c3810f 100644 --- a/config/meetings.json +++ b/config/meetings.json @@ -1,25 +1,4 @@ [ - { - "title": "Essential Building Blocks Working Group", - "calLink": "https://www.google.com/calendar/event?eid=c28zazMxcDk3MThpMWFpNG9lYzRrbmIzNW8gY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/1342", - "banner": "", - "date": "2024-08-27T18:00:00.000Z" - }, - { - "title": "Marketing WG Meeting", - "calLink": "https://www.google.com/calendar/event?eid=MmpwdGxqb29wcHQyaGk3dXU1cTJ0M3E2aGMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/1354", - "banner": "", - "date": "2024-09-10T14:00:00.000Z" - }, - { - "title": "Community Meeting", - "calLink": "https://www.google.com/calendar/event?eid=b2lsN3YwcGNmdWZiNTltNm1lM25wYXYwc3MgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", - "url": "https://github.com/asyncapi/community/issues/1355", - "banner": "https://github.com/user-attachments/assets/399c2eec-5123-47e9-ad41-024cd478a667", - "date": "2024-09-03T08:00:00.000Z" - }, { "title": "Community Meeting", "calLink": "https://www.google.com/calendar/event?eid=dG1nMGxqMWg4ajVqZ3Z2NHRpYW42bmUyNWMgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", @@ -138,5 +117,12 @@ "url": "https://github.com/asyncapi/community/issues/1599", "banner": "https://github.com/user-attachments/assets/739381b2-b7de-4e08-b845-04e5a07ba7e0", "date": "2024-12-03T13:00:00.000Z" + }, + { + "title": "Marketing WG Meeting", + "calLink": "https://www.google.com/calendar/event?eid=a3FvM3ZyOTUwcjJpZm5wOWxzZWcwZ3Bja2sgY19xOXRzZWlnbG9tZHNqNm5qdWh2YnB0czExY0Bn", + "url": "https://github.com/asyncapi/community/issues/1616", + "banner": "", + "date": "2024-12-17T14:00:00.000Z" } ] \ No newline at end of file diff --git a/config/newsroom_videos.json b/config/newsroom_videos.json index c9fb91e4a6a9..f2fcd28148b9 100644 --- a/config/newsroom_videos.json +++ b/config/newsroom_videos.json @@ -1,9 +1,9 @@ [ { - "image_url": "https://i.ytimg.com/vi/XirMXiBNaBM/hqdefault.jpg", - "title": "Community Meeting, 16:00 UTC Tuesday November 26th 2024", - "description": "", - "videoId": "XirMXiBNaBM" + "image_url": "https://i.ytimg.com/vi/5hY8yi6DXyE/hqdefault.jpg", + "title": "Marketing WG Meeting, 14:00 UTC Tuesday December 17th 2024", + "description": "Welcoming the 2024 cohort of the AsyncAPI mentorship program.", + "videoId": "5hY8yi6DXyE" }, { "image_url": "https://i.ytimg.com/vi/QWRcCvDmf04/hqdefault.jpg", @@ -11,6 +11,12 @@ "description": "Welcoming the 2024 cohort of the AsyncAPI mentorship program.", "videoId": "QWRcCvDmf04" }, + { + "image_url": "https://i.ytimg.com/vi/XirMXiBNaBM/hqdefault.jpg", + "title": "Community Meeting, 16:00 UTC Tuesday November 26th 2024", + "description": "", + "videoId": "XirMXiBNaBM" + }, { "image_url": "https://i.ytimg.com/vi/Q2cvxsUUgzA/hqdefault.jpg", "title": "AsyncAPI-Powered Event Feeds: 3 Steps to Streaming", @@ -22,11 +28,5 @@ "title": "Broadening the API Landscape: AsyncAPI and CloudEvents in the Enterprise - Daniel Kocot", "description": "", "videoId": "9MaHh4b-rmc" - }, - { - "image_url": "https://i.ytimg.com/vi/Q1q6JoFG0zM/hqdefault.jpg", - "title": "The Many Meanings Of An AsyncAPI File - Swen-Helge Huber", - "description": "", - "videoId": "Q1q6JoFG0zM" } ] \ No newline at end of file diff --git a/config/tools-automated.json b/config/tools-automated.json index 7a8ac6ee6e6e..8848e656e6ee 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": "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 } }, { - "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 } } ] @@ -71,6 +71,28 @@ "isAsyncAPIOwner": false } }, + { + "title": "Zod Sockets", + "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", + "links": { + "websiteUrl": "https://www.npmjs.com/package/zod-sockets", + "repoUrl": "https://github.com/RobinTail/zod-sockets" + }, + "filters": { + "language": "TypeScript", + "technology": [ + "Node.js", + "TypeScript" + ], + "categories": [ + "code-first", + "dsl", + "framework" + ], + "hasCommercial": false, + "isAsyncAPIOwner": false + } + }, { "title": "nestjs-asyncapi", "description": "Utilize decorators to generate AsyncAPI document utilizing DTOs (similar to @nestjs/swagger) and a web UI.", @@ -111,34 +133,33 @@ "hasCommercial": false, "isAsyncAPIOwner": false } - }, + } + ] + }, + "Code Generators": { + "description": "The following is a list of tools that generate code from an AsyncAPI document; not the other way around.", + "toolsList": [ { - "title": "Zod Sockets", - "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", + "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://www.npmjs.com/package/zod-sockets", - "repoUrl": "https://github.com/RobinTail/zod-sockets" + "websiteUrl": "https://modelina.org", + "docsUrl": "https://github.com/asyncapi/modelina/tree/master/docs", + "repoUrl": "https://github.com/asyncapi/modelina" }, "filters": { "language": "TypeScript", "technology": [ - "Node.js", - "TypeScript" + "React JS", + "Docker" ], "categories": [ - "code-first", - "dsl", - "framework" + "code-generator" ], "hasCommercial": false, - "isAsyncAPIOwner": false + "isAsyncAPIOwner": true } - } - ] - }, - "Code Generators": { - "description": "The following is a list of tools that generate code from an AsyncAPI document; not the other way around.", - "toolsList": [ + }, { "title": "ZenWave SDK", "description": "DDD and API-First for Event-Driven Microservices", @@ -165,27 +186,6 @@ "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", - "links": { - "websiteUrl": "https://modelina.org", - "docsUrl": "https://github.com/asyncapi/modelina/tree/master/docs", - "repoUrl": "https://github.com/asyncapi/modelina" - }, - "filters": { - "language": "TypeScript", - "technology": [ - "React JS", - "Docker" - ], - "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", @@ -289,6 +289,28 @@ "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": "Zod Sockets", + "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", + "links": { + "websiteUrl": "https://www.npmjs.com/package/zod-sockets", + "repoUrl": "https://github.com/RobinTail/zod-sockets" + }, + "filters": { + "language": "TypeScript", + "technology": [ + "Node.js", + "TypeScript" + ], + "categories": [ + "code-first", + "dsl", + "framework" + ], + "hasCommercial": false, + "isAsyncAPIOwner": false + } + }, { "title": "ZenWave SDK", "description": "DDD and API-First for Event-Driven Microservices", @@ -314,7 +336,12 @@ "hasCommercial": false, "isAsyncAPIOwner": false } - }, + } + ] + }, + "Frameworks": { + "description": "The following is a list of API/application frameworks that make use of AsyncAPI.", + "toolsList": [ { "title": "Zod Sockets", "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", @@ -336,12 +363,7 @@ "hasCommercial": false, "isAsyncAPIOwner": false } - } - ] - }, - "Frameworks": { - "description": "The following is a list of API/application frameworks that make use of AsyncAPI.", - "toolsList": [ + }, { "title": "Glee", "description": "Glee — The AsyncAPI framework that will make you smile again :)", @@ -358,28 +380,6 @@ "hasCommercial": false, "isAsyncAPIOwner": true } - }, - { - "title": "Zod Sockets", - "description": "Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.", - "links": { - "websiteUrl": "https://www.npmjs.com/package/zod-sockets", - "repoUrl": "https://github.com/RobinTail/zod-sockets" - }, - "filters": { - "language": "TypeScript", - "technology": [ - "Node.js", - "TypeScript" - ], - "categories": [ - "code-first", - "dsl", - "framework" - ], - "hasCommercial": false, - "isAsyncAPIOwner": false - } } ] }, @@ -387,20 +387,20 @@ "description": "The following is a list of GitHub Actions that you can use in your workflows", "toolsList": [ { - "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 } }, { @@ -421,20 +421,20 @@ } }, { - "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", + "title": "GitHub Action for Generator", + "description": null, "links": { - "repoUrl": "https://github.com/asyncapi/github-action-for-cli" + "repoUrl": "https://github.com/actions-marketplace-validations/asyncapi_github-action-for-generator" }, "filters": { "technology": [ - "AsyncAPI CLI" + "AsyncAPI Generator" ], "categories": [ "github-action" ], "hasCommercial": false, - "isAsyncAPIOwner": true + "isAsyncAPIOwner": false } } ] @@ -581,6 +581,25 @@ "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": [ + "TypeScript" + ], + "categories": [ + "others", + "cli" + ], + "hasCommercial": false, + "isAsyncAPIOwner": true + } + }, { "title": "ZenWave SDK", "description": "DDD and API-First for Event-Driven Microservices", @@ -607,25 +626,6 @@ "isAsyncAPIOwner": false } }, - { - "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": [ - "TypeScript" - ], - "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", @@ -718,15 +718,15 @@ "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": "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.", + "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/nodejs-ws-template" + "repoUrl": "https://github.com/asyncapi/html-template" }, "filters": { "language": "javascript", "technology": [ - "Node.js" + "HTML" ], "categories": [ "generator-template" @@ -736,18 +736,15 @@ } }, { - "title": "Java Spring Cloud Stream Template", - "description": "Java Spring Cloud Stream template for the AsyncAPI Generator", + "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/java-spring-cloud-stream-template" + "repoUrl": "https://github.com/asyncapi/nodejs-ws-template" }, "filters": { - "language": [ - "javascript" - ], + "language": "javascript", "technology": [ - "Spring Cloud Streams", - "Maven" + "Node.js" ], "categories": [ "generator-template" @@ -757,17 +754,18 @@ } }, { - "title": "Java Template", - "description": "Java template for the AsyncAPI Generator", + "title": "Java Spring Cloud Stream Template", + "description": "Java Spring Cloud Stream template for the AsyncAPI Generator", "links": { - "repoUrl": "https://github.com/asyncapi/java-template" + "repoUrl": "https://github.com/asyncapi/java-spring-cloud-stream-template" }, "filters": { "language": [ "javascript" ], "technology": [ - "Java" + "Spring Cloud Streams", + "Maven" ], "categories": [ "generator-template" @@ -799,15 +797,17 @@ } }, { - "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.", + "title": "Java Template", + "description": "Java template for the AsyncAPI Generator", "links": { - "repoUrl": "https://github.com/asyncapi/html-template" + "repoUrl": "https://github.com/asyncapi/java-template" }, "filters": { - "language": "javascript", + "language": [ + "javascript" + ], "technology": [ - "HTML" + "Java" ], "categories": [ "generator-template" diff --git a/config/tools.json b/config/tools.json index 0265d466afdb..76958308318f 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":"AsyncApi.Net.Generator","description":"Code-first AsyncAPI documentation generator and ui","links":{"repoUrl":"https://github.com/yurvon-screamo/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":["code-first"],"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":[]}},{"title":"Zod Sockets","description":"Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.","links":{"websiteUrl":"https://www.npmjs.com/package/zod-sockets","repoUrl":"https://github.com/RobinTail/zod-sockets"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","dsl","framework"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"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/","docsUrl":"https://docs.bump.sh/help/","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}},{"title":"Zod Sockets","description":"Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.","links":{"websiteUrl":"https://www.npmjs.com/package/zod-sockets","repoUrl":"https://github.com/RobinTail/zod-sockets"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","dsl","framework"],"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":[]}},{"title":"Glee","description":"Glee — The AsyncAPI framework that will make you smile again :)","links":{"repoUrl":"https://github.com/asyncapi/glee"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["framework"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Zod Sockets","description":"Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.","links":{"websiteUrl":"https://www.npmjs.com/package/zod-sockets","repoUrl":"https://github.com/RobinTail/zod-sockets"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","dsl","framework"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"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}},{"title":"GitHub Action for Generator","description":"CLI to work with your AsyncAPI files. You can validate them and in the future use a generator and even bootstrap a new file. Contributions are welcomed!","links":{"repoUrl":"https://github.com/asyncapi/cli"},"filters":{"technology":[{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["github-actions"],"hasCommercial":false,"isAsyncAPIOwner":true}}]},"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.io","docsUrl":"https://specmatic.io/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":"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 Cloud Stream Template","description":"Java Spring Cloud Stream template for the AsyncAPI Generator","links":{"repoUrl":"https://github.com/asyncapi/java-spring-cloud-stream-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"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 +{"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":"AsyncApi.Net.Generator","description":"Code-first AsyncAPI documentation generator and ui","links":{"repoUrl":"https://github.com/yurvon-screamo/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":["code-first"],"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":[]}},{"title":"Zod Sockets","description":"Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.","links":{"websiteUrl":"https://www.npmjs.com/package/zod-sockets","repoUrl":"https://github.com/RobinTail/zod-sockets"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","dsl","framework"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"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/","docsUrl":"https://docs.bump.sh/help/","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}},{"title":"Zod Sockets","description":"Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.","links":{"websiteUrl":"https://www.npmjs.com/package/zod-sockets","repoUrl":"https://github.com/RobinTail/zod-sockets"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","dsl","framework"],"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":[]}},{"title":"Glee","description":"Glee — The AsyncAPI framework that will make you smile again :)","links":{"repoUrl":"https://github.com/asyncapi/glee"},"filters":{"technology":[{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["framework"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"Zod Sockets","description":"Socket.IO solution with I/O validation and the ability to generate AsyncAPI specification and a contract for consumers.","links":{"websiteUrl":"https://www.npmjs.com/package/zod-sockets","repoUrl":"https://github.com/RobinTail/zod-sockets"},"filters":{"language":[{"name":"TypeScript","color":"bg-[#7DBCFE]","borderColor":"border-[#2C78C7]"}],"technology":[{"name":"Node.js","color":"bg-[#BDFF67]","borderColor":"border-[#84CE24]"},{"name":"TypeScript","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["code-first","dsl","framework"],"hasCommercial":false,"isAsyncAPIOwner":false}}]},"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 CLI","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["github-action"],"hasCommercial":false,"isAsyncAPIOwner":true}},{"title":"GitHub Action for Generator","description":"CLI to work with your AsyncAPI files. You can validate them and in the future use a generator and even bootstrap a new file. Contributions are welcomed!","links":{"repoUrl":"https://github.com/asyncapi/cli"},"filters":{"technology":[{"name":"AsyncAPI Generator","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"}],"categories":["github-actions"],"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.io","docsUrl":"https://specmatic.io/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":"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 Cloud Stream Template","description":"Java Spring Cloud Stream template for the AsyncAPI Generator","links":{"repoUrl":"https://github.com/asyncapi/java-spring-cloud-stream-template"},"filters":{"language":[{"name":"JavaScript","color":"bg-[#F2F1C7]","borderColor":"border-[#BFBE86]"}],"technology":[{"name":"Spring Cloud Streams","color":"bg-[#61d0f2]","borderColor":"border-[#40ccf7]"},{"name":"Maven","color":"bg-[#FF6B80]","borderColor":"border-[#CA1A33]"}],"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/dashboard.json b/dashboard.json index a2b37a65dc79..2e12b1e2b827 100644 --- a/dashboard.json +++ b/dashboard.json @@ -1,5 +1,16 @@ { "hotDiscussions": [ + { + "id": "PR_kwDOBW5R_c5-T7mG", + "isPR": true, + "isAssigned": false, + "title": "feat: add tests for build post list script", + "author": "vishvamsinh28", + "resourcePath": "/asyncapi/website/pull/3284", + "repo": "asyncapi/website", + "labels": [], + "score": 36.471172771155864 + }, { "id": "I_kwDOFLhIt84-OUI3", "isPR": false, @@ -16,26 +27,6 @@ ], "score": 34.46095064991105 }, - { - "id": "I_kwDODou01c5BZZv-", - "isPR": false, - "isAssigned": false, - "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": 31.302030173669205 - }, { "id": "I_kwDOGQYLdM5AX1lK", "isPR": false, @@ -54,29 +45,18 @@ "color": "0E8A16" } ], - "score": 28.430284286176615 - }, - { - "id": "PR_kwDOBW5R_c5-T7mG", - "isPR": true, - "isAssigned": false, - "title": "feat: add tests for build post list script", - "author": "vishvamsinh28", - "resourcePath": "/asyncapi/website/pull/3284", - "repo": "asyncapi/website", - "labels": [], - "score": 27.28158593117958 + "score": 29.004633463675134 }, { - "id": "PR_kwDOBW5R_c59FBoR", + "id": "PR_kwDOBW5R_c6DrMsy", "isPR": true, "isAssigned": false, - "title": "feat: add tests for tool-object script", - "author": "vishvamsinh28", - "resourcePath": "/asyncapi/website/pull/3265", + "title": "chore(blog): add marketing report", + "author": "iambami", + "resourcePath": "/asyncapi/website/pull/3439", "repo": "asyncapi/website", "labels": [], - "score": 25.845712987433288 + "score": 28.430284286176615 }, { "id": "PR_kwDOFLhIt85bqKL8", @@ -121,17 +101,6 @@ ], "score": 21.825268744943667 }, - { - "id": "PR_kwDOBW5R_c6BZLuT", - "isPR": true, - "isAssigned": false, - "title": "feat: add tests for check markdown script", - "author": "vishvamsinh28", - "resourcePath": "/asyncapi/website/pull/3378", - "repo": "asyncapi/website", - "labels": [], - "score": 20.67657038994663 - }, { "id": "PR_kwDOFLhIt855u7Eb", "isPR": true, @@ -143,22 +112,6 @@ "labels": [], "score": 20.102221212448114 }, - { - "id": "PR_kwDOBW5R_c535wDj", - "isPR": true, - "isAssigned": false, - "title": "feat: add test for combine tools script", - "author": "vishvamsinh28", - "resourcePath": "/asyncapi/website/pull/3136", - "repo": "asyncapi/website", - "labels": [ - { - "name": "gsoc", - "color": "F4D03F" - } - ], - "score": 17.804824502454043 - }, { "id": "I_kwDOBW5R_c5RVOOY", "isPR": false, @@ -189,9 +142,90 @@ "repo": "asyncapi/community", "labels": [], "score": 16.08177696995849 + }, + { + "id": "I_kwDOFLhIt85bebeO", + "isPR": false, + "isAssigned": false, + "title": "Meeting Banners Storage", + "author": "AceTheCreator", + "resourcePath": "/asyncapi/community/issues/568", + "repo": "asyncapi/community", + "labels": [], + "score": 15.794602381209232 + }, + { + "id": "I_kwDODou01c5BZZv-", + "isPR": false, + "isAssigned": false, + "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": 15.087185824232376 + }, + { + "id": "I_kwDODou01c5ZAFWh", + "isPR": false, + "isAssigned": true, + "title": "Please support File References", + "author": "philCryoport", + "resourcePath": "/asyncapi/studio/issues/528", + "repo": "asyncapi/studio", + "labels": [ + { + "name": "enhancement", + "color": "a2eeef" + }, + { + "name": "bounty", + "color": "0E8A16" + } + ], + "score": 14.07155484871368 } ], "goodFirstIssues": [ + { + "id": "I_kwDOFDnrNc6jnDp4", + "title": "Workflow `.github/workflows/test-action.yml` needs urgent update before end of January 2025", + "isAssigned": false, + "resourcePath": "/asyncapi/cli/issues/1597", + "repo": "asyncapi/cli", + "author": "derberg", + "area": "Unknown", + "labels": [ + { + "name": "bug", + "color": "d73a4a" + } + ] + }, + { + "id": "I_kwDOFLhIt86ihL5I", + "title": "[BUG] voting summary has some errors in `isVotedInLast3Months`", + "isAssigned": false, + "resourcePath": "/asyncapi/community/issues/1614", + "repo": "asyncapi/community", + "author": "derberg", + "area": "javascript", + "labels": [ + { + "name": "bug", + "color": "d73a4a" + } + ] + }, { "id": "I_kwDOFLhIt86hMsxx", "title": "Create an announcement design for the new TSC member (Ashmit Jagtap)", @@ -241,21 +275,6 @@ } ] }, - { - "id": "I_kwDOBW5R_c6ddpHW", - "title": "[BUG] algolia search icon not visible on website navbar", - "isAssigned": false, - "resourcePath": "/asyncapi/website/issues/3371", - "repo": "asyncapi/website", - "author": "anshgoyalevil", - "area": "Unknown", - "labels": [ - { - "name": "bug", - "color": "ee0701" - } - ] - }, { "id": "I_kwDOBW5R_c6crqQz", "title": "Improve image type detection in build-rss.js", @@ -400,6 +419,21 @@ "area": "design", "labels": [] }, + { + "id": "I_kwDOBW5R_c6UMuUM", + "title": "normalize the logos of sponsors ", + "isAssigned": false, + "resourcePath": "/asyncapi/website/issues/3158", + "repo": "asyncapi/website", + "author": "derberg", + "area": "Unknown", + "labels": [ + { + "name": "enhancement", + "color": "84b6eb" + } + ] + }, { "id": "I_kwDOFLhIt86O7jFN", "title": "[DESIGN] Holopin Design Tracking", @@ -415,21 +449,6 @@ } ] }, - { - "id": "I_kwDODwv8N86Lel9M", - "title": "[FEATURE] Resolve the existing Next.js lint issues", - "isAssigned": false, - "resourcePath": "/asyncapi/conference-website/issues/328", - "repo": "asyncapi/conference-website", - "author": "ashmit-coder", - "area": "javascript", - "labels": [ - { - "name": "enhancement", - "color": "a2eeef" - } - ] - }, { "id": "I_kwDOE8Qh386HJeIz", "title": "[BUG] Implement avro schema data type ", @@ -608,6 +627,10 @@ { "name": "enhancement", "color": "a2eeef" + }, + { + "name": "stale", + "color": "ededed" } ] }, @@ -664,21 +687,6 @@ } ] }, - { - "id": "I_kwDOBGu-185qGt6A", - "title": "Ensure consistency when using either `Application` or `API` terms", - "isAssigned": false, - "resourcePath": "/asyncapi/spec/issues/949", - "repo": "asyncapi/spec", - "author": "smoya", - "area": "Unknown", - "labels": [ - { - "name": "enhancement", - "color": "a2eeef" - } - ] - }, { "id": "I_kwDOE8Qh385m4AtC", "title": "C# generator add xml docs from the async api description", @@ -711,10 +719,6 @@ "author": "CynthiaPeter", "area": "docs", "labels": [ - { - "name": "stale", - "color": "ededed" - }, { "name": "📑 docs", "color": "E50E99" diff --git a/markdown/blog/2024-december-and-paris.md b/markdown/blog/2024-december-and-paris.md new file mode 100644 index 000000000000..e0f7a365bc19 --- /dev/null +++ b/markdown/blog/2024-december-and-paris.md @@ -0,0 +1,138 @@ +--- +title: "November and December Community Update And AsyncAPI Conf in Paris 2024" +date: 2024-12-16T06:00:00+01:00 +type: Communication +tags: + - Project Status +cover: /img/posts/2024-blog-banner/blog-banner-december.webp +authors: + - name: Thulisile Sibanda + photo: /img/avatars/thulieblack.webp + link: https://www.linkedin.com/in/v-thulisile-sibanda/ + byline: Community Builder and Open Source Fanatic! +excerpt: 'November and December Community Update And Paris Conference Summary' +featured: true +--- +I can't believe we are in the final weeks of the year, and it has been an eventful one. As a community, we have experienced both proud and painful moments, celebrated our victories, and faced challenges and losses. However, in the end, we overcame those difficulties and emerged stronger and better. + +Although this summary is a bit later than usual, I am excited to share the details of what happened in November and December and the highlights from the last conference of the year, which took place in Paris. + +## AsyncAPI Community Building and Maintenance Goals Proposal 2025 + +The 2025 community building and maintenance goals proposal is currently open for discussion and will soon be put to a vote for TSC members. We would love your thoughts and suggestions, particularly when solving our community's challenges. +[Please take a moment to review the open PR related to the AsyncAPI Community Building Goals for 2025](https://github.com/asyncapi/community/pull/1575) to participate in the discussion and share your ideas and solutions. + +## AsyncAPI Conf in Paris 2024 + +The AsyncAPI Conf was back again in Paris this December, thanks to [Mehdi Medjaoui](https://www.linkedin.com/in/mehdimedjaoui/) and the amazing team at [APIdays](https://www.apidays.global/) for hosting and sponsoring the venue. We participated in the three-day event, celebrating a year of the `API Standards` booth alongside friends from OpenAPI, JSON Schema, and GraphQL. Special thanks to all the members of the AsyncAPI community who could join the conference and help at the booth: [Hugo Guerrero](https://www.linkedin.com/in/hugoguerrero/), [Fran Méndez](https://www.linkedin.com/in/fmvilas/), [Richard Coppen](https://www.linkedin.com/in/richard-coppen/), [Hari Krishnan](https://www.linkedin.com/in/harikrishnan83/), and [Lukasz Gornicki](https://www.linkedin.com/in/lukasz-gornicki-a621914/). + +The AsyncAPI Conf track took place on the 3rd day of the conference, featuring an impressive lineup of sessions that attracted a diverse audience. The event was consistently packed, with attendees engaged throughout the day. + +
+ +[Fran Méndez](https://www.linkedin.com/in/fmvilas/) and [Lukasz Gornicki](https://www.linkedin.com/in/lukasz-gornicki-a621914/) started the track with a welcome speech and mentioned that AsyncAPI recently celebrated its 8th anniversary in November. + +
+ +[Naresh Jain](https://www.linkedin.com/in/nareshjain/) and [Pierre Gauthier](https://www.linkedin.com/in/pierre-gauthier-46080916/) presented their keynote on `TMForum's AsyncAPI for a New Era of Event-Driven Architecture`. During the session, Pierre announced TMForum adopts AsyncAPI as a standard, with over 120 telco APIs already in production. TMForum has around 800 telco companies, and they will implement all APIs in an async manner, extensively utilizing the request-reply pattern. + +
+ +[Frank Kilcommins](https://www.linkedin.com/in/frank-kilcommins) demonstrated how treating API governance as an enabler unlocks the ability to deliver compelling developer experiences for producers and consumers in event-driven architecture (EDA). + +
+ +[Leonid Lukyanov](https://www.linkedin.com/in/leonid-lukyanov/) shared how EDAs introduce new data models, protocols, and APIs not found in the traditional REST/CRUD application stack. And how one can abstract these elements to make them feel familiar to application developers, allowing them to create streaming applications seamlessly. + +
+ +[Hugo Guerrero](https://www.linkedin.com/in/hugoguerrero/) then shared how the AsyncAPI Initiative is not only in charge of the specification but has created open-source projects to make it easier for developers to work with the specification documents. + +
+ +[Julien Testut](https://www.linkedin.com/in/julientestut/) and [Alessandro Cagnetti](https://www.linkedin.com/in/cagnetti/) shared how organizations can harness the full potential of event-driven integration by leveraging GoldenGate Data Streams, AsyncAPI, and Solace PubSub+ Event Mesh. They shared a great use case for AI and how it can be trained real-time and standardized with AsyncAPI. + +
+ +[Annegret Junker](https://www.linkedin.com/in/dr-annegret-junker-141a99a4/) explained how to design effective asynchronous APIs by using an API-first approach. The importance of defining Kafka topics and structuring your definitions. + +
+ + +[Jonathan Michaux](https://www.linkedin.com/in/jmcx/) spoke on how leveraging AI agents with AsyncAPI can create conversational interfaces that dynamically interact with event streams and asynchronous messaging systems. + +
+ +[Hari Krishnan](https://www.linkedin.com/in/harikrishnan83) and [Joel Rosario](https://www.linkedin.com/in/joel-c-rosario/) touched on leveraging the AsyncAPI specification as an executable contract and how to isolate and test each component within an EDA. + +
+ +[Laurent Broudoux](https://www.linkedin.com/in/laurentbroudoux/) and [Hugo Guerrero](https://www.linkedin.com/in/hugoguerrero/) ended the day by explaining how to use Microcks to provide a solution for mocking and contract-testing your async APIs without extensive coding and empowering you to build extensive and reliable integration tests. + +
+ +## Technical Steering Committee + +Part of doing mentorships is witnessing the growth within the community, and we are excited to welcome [Ashmit Jagtap](https://www.linkedin.com/in/ashmit-jagtap) as our newest addition to the maintainers list and TSC member. We are proud of the work you have done so far. + + + +## Final Remarks + +It's been a privilege to write the AsyncAPI monthly summary blog consistently. As this is the final blog for the year, I am genuinely grateful for the opportunity to serve and continue supporting the community. + +As we approach the holidays, I wish everyone happy holidays and a fantastic 2025. + +I'll be back next year with an overall review summary of 2024. + +**Until then, stay safe, and happy holidays!** \ No newline at end of file diff --git a/markdown/blog/2024-gsoc-wrap.md b/markdown/blog/2024-gsoc-wrap.md new file mode 100644 index 000000000000..4570a0c17595 --- /dev/null +++ b/markdown/blog/2024-gsoc-wrap.md @@ -0,0 +1,172 @@ +--- +title: "2024 Google Summer Of Code Wrap Up" +date: 2024-12-18T06:00:00+01:00 +type: Community +tags: + - Mentorship + - GSoC + - AsyncAPI + - OSS +cover: /img/posts/gsoc.webp +authors: + - name: Azeez Elegbede + photo: /img/avatars/ace.webp + link: https://twitter.com/_acebuild + byline: AsyncAPI Preacher +--- + +For the first time in our history with Google Summer of Code (GSoC), AsyncAPI proudly participated as an independent organization. In previous years, we had joined the program under Postman’s umbrella due to the challenges of being selected as a participating organization. With Postman’s higher chances of acceptance, they graciously allowed us to include some of our projects under their organization. This year, however, marked a significant milestone as AsyncAPI stepped into the spotlight on its own. + +The goal of this post is to share our GSoC journey and offer valuable insights for future organizations and contributors. By reflecting on what went well, the challenges we encountered, and the lessons learned, we hope to help others make the most of this incredible program. + +Now, let’s dive into the key achievements and challenges of our participation this year. + +## Key Achievements + +Without a doubt, our biggest achievement this year has been participating in GSoC as an individual organization. For several years, AsyncAPI applied as a standalone organization but was never selected. + +So, what changed this time? We took a step back to analyse potential reasons for our previous rejections and used those insights to refine our approach. One significant change was starting our preparation well ahead of the deadline. Special thanks go to [Azeez Elegbede](https://github.com/AceTheCreator), who led the effort by curating project ideas, crafting our organization application, reaching out to potential mentors, and engaging with interested contributors. Azeez worked closely with the incredible [Quetzalli](https://github.com/quetzalliwrites), whose expertise played a significant role in reviewing the application and project ideas, providing valuable guidance and support throughout the process. + +To showcase the impact of this year’s participation, let’s look at some key community accomplishments achieved during GSoC 2024. + +- This year, we achieved our highest number of project idea slots in the history of our GSoC participation, with a total of **7 slots**. +- For the first time, we had **4 ex-GSoC participants** return to the program as mentors, marking a significant milestone in building a cycle of mentorship and growth within our community. +- We received an impressive **77 project proposals**, the most we've ever had in our GSoC journey. +- Over **100 new contributors** joined our community from GSoC, showcasing the growing interest and engagement with AsyncAPI. +- AsyncAPI proudly participated as an organization at the **GSoC Summit in San Francisco**, where [Lukasz Gornicki](https://github.com/derberg), one of our community members, delivered a lightning talk. His presentation focused on fostering a system that guides GSoC contributors toward becoming maintainers with mentor support, showcasing our commitment to strengthening the open-source ecosystem. + +We had a range of successful contributions that significantly advanced AsyncAPI projects such as: + +- **[Ashmit Jagtap](https://github.com/ashmit-coder)** who contributed extensively to the AsyncAPI Conference website by addressing existing issues and bugs, adding testing capabilities with Cypress to improve the contributor experience, and implementing support for call for speakers registration for the online edition of the conference. Additionally, Ashmit reviewed pull requests, mentored potential contributors, and ultimately became a project maintainer. + +- **[Vishvamsinh Vaghela](https://github.com/vishvamsinh28)** enhanced the stability of scripts on the AsyncAPI website by ensuring all scripts functioned as expected and writing comprehensive unit tests to ensure smooth operations on the website, particularly as the number of contributors grew and more people worked on critical parts of the website. + +- **[Ankit Dash](https://github.com/helios2003)** added dynamic preview image generation for AsyncAPI documents shared via the AsyncAPI Studio website. Ankit also shared his GSoC journey and contributions during the online edition of the [AsyncAPI Conference](https://conference.asyncapi.com/venue/Online). + + +- **[Mintu Gogoi](https://github.com/Gmin2)** and **[Yuan Yuan](https://github.com/lmgyuan)** focused on the AsyncAPI Generator project, resolving existing issues and bugs, triaging new ones, improving code through refactoring, and writing tests. Yuan shared their GSoC experience during the online edition of the [AsyncAPI Conference](https://conference.asyncapi.com/). + + +- **[Ashmit JaiSarita Gupta](https://github.com/devilkiller-ag)** developed a UI kit for the AsyncAPI website, based on the stunning designs by **[Aishat Muibudeen](https://github.com/mayaleeeee)**. By using Storybook, Ashmit ensured brand visual consistency and created a modular, easy-to-maintain design system that streamlined further development. + +- **[Esther Xiao](https://github.com/FelicixAwe)** is making significant improvements to the AsyncAPI VS Code extension by introducing an autofix feature. This enhancement helps streamline the editing process by automatically resolving common Spectral linting errors directly within the IDE. + +Each of these project ideas tackles key challenges within their respective repositories, bringing the initiative closer to its mission of fostering exponential community growth. + +We’re also beginning to see promising signs of these projects attracting long-term contributors, not only from this year’s GSoC participants but also from the broader AsyncAPI community. + +## An Unexpected Turn of Event + +Sometimes, things happen that are beyond your control, and that’s exactly what happened during the final phase of this year’s program. + +At AsyncAPI, we recognize that a project's final pull request may not always be merged within the program’s duration. This often serves as an opportunity to encourage participants to stay engaged and contribute beyond the program timeline. + +Here’s what happened: after successfully passing the final evaluation, one of our contributors announced on social media that their project was complete. However, their pull request was still under review by the mentor. While the mentor had passed the contributor during the evaluation due to the program’s deadlines and acknowledged their consistent hard work, they found the announcement to be unprofessional. + +Thanks to the mentor’s awareness, the contributor quickly removed the post and issued a heartfelt apology to both the mentor and the organizers. + +In light of this, we’d like to remind future GSoC participants and contributors in similar programs to avoid declaring your project “complete” until your final pull request has been merged and your mentor has confirmed the project’s completion. Let’s strive for professionalism and clarity in our contributions. + +## The Sad Story + +Every year, when applying for GSoC, we’ve taken a two-way approach which is, applying as an independent organization while also submitting some AsyncAPI project ideas under Postman’s application just in case we weren’t selected. This year was no different, but we were fortunate enough to have both organizations accepted, giving us the flexibility to push all seven of our project ideas forward. + +Now, you might be wondering how is this even possible. Well, a few of us were employed by Postman specifically to work on AsyncAPI, which allowed us to coordinate participation for both organizations. With Postman’s higher likelihood of being selected, it made sense to submit some AsyncAPI ideas under their umbrella. + +What we didn’t foresee, however, was the sudden change of things. Postman unexpectedly laid off the entire AsyncAPI team, which not only marked the end of our roles there but also brought Postman’s participation in GSoC to a halt(possibly for future years as well). In light of this, GSoC organizers transferred all AsyncAPI-related projects from Postman to AsyncAPI, ensuring they continued under our banner. + +This turn of events means that moving forward, our participation in GSoC rests entirely on our ability to be selected as an independent organization. What if we don’t get selected next year? While that’s a possibility, I choose to remain optimistic. If we make it this year, we can do it again. And even if we aren’t selected, we have the AsyncAPI Mentorship Program, a program we created for moments like this. You can read more about why we started our mentorship program [here](https://www.asyncapi.com/blog/beyond-boundaries). + +This sudden change has made us face unexpected challenges as individuals, but we’re stronger, more determined, and deeply committed to our mission of fostering growth in the AsyncAPI community. + +## Tips for further participants + +While I believe that reaching for the stars is just the beginning for us as an open-source community, and with even more exciting project ideas lined up for future GSoC programs at AsyncAPI, here are some valuable tips for contributors aspiring to participate in GSoC with us: + +- **Start Early and Engage with the Community:** Over the years, contributors who actively engage with the AsyncAPI community before GSoC even begins tend to have better chances of being selected. Early engagement allows you to build connections, understand the community’s needs, and showcase your commitment. It also helps you stand out to potential mentors and other contributors. + +- **Respect Maintainers’ Time:** Remember, maintainers and mentors are often juggling multiple responsibilities, including their professional roles. Be mindful of their time by doing your homework before asking questions. Read available documentation, search for existing discussions, and ask clear questions when you need help. This respectful approach makes a strong impression. + +- **Focus on Quality Over Quantity:** Avoid making superficial contributions just to show activity. Mentors value meaningful, impactful contributions over sheer numbers. It doesn’t matter if you’ve only contributed to the website repo instead of the generator repo, what counts is the thoughtfulness and effort behind your work. + +- **Participate Beyond Code Contributions:** Being a successful GSoC contributor isn’t just about writing code. Engage in discussions, provide feedback on other contributions, and help answer questions from community members. Demonstrating your willingness to contribute in diverse ways shows your dedication to the community. + +- **Set Clear Project Timelines and Deliverables:** When preparing your GSoC proposal, ensure your timeline is realistic and achievable. Break your project into smaller milestones with clear deliverables for each phase. This demonstrates your organizational skills and helps mentors see your plan for success. + +- **Communicate Clearly and Effectively:** Good communication is key. Keep your mentors and the community updated on your progress, ask thoughtful questions, and don’t hesitate to seek guidance. Be proactive in addressing issues and responsive to feedback. Helping others in the community can also set you apart as a standout contributor. + +- **Seek and Act on Feedback:** Throughout the program, regularly request feedback from mentors and implement it into your work. Showing that you can learn, adapt, and improve is a critical skill that mentors highly value. + +By following these tips, you’ll not only increase your chances of being selected but also leave a lasting positive impact on the AsyncAPI community. + +## Special Shoutouts + + + +We want to take a moment to extend our gratitude to the mentors above, whose dedication to the program made them go above and beyond to support and pass on their knowledge and forge meaningful relationships with our mentees. This program would not be possible without their unwavering support. + +A special shoutout goes to Postman, who has always allowed us to push some of our project ideas under their umbrella over the last few years, while it's sad to see this come to an end, we love and appreciate the opportunities, and the community as a whole will never take it for granted. + +A special thanks to Google for their belief in Free and Open Source Software (FOSS), for making this program possible every year as a show of their support to the open source ecosystem, and for allowing organizations like ours to bring passionate contributors and mentors to collaborate on a project all for the love of opensource. + +Finally, a wonderful shout to [Stephanie Taylor](https://www.linkedin.com/in/stephaniertaylor/), the incredible program manager of Google Summer of Code, for her unwavering support during the transition of our projects after Postman’s departure. Her assistance with transferring mentor stipends to our preferred account was phenomena, and we truly appreciate her dedication and guidance! + + +## Closing Remark + +If you’re considering joining GSoC with AsyncAPI next year, we encourage you to hop into our [Slack community](https://asyncapi.com/slack-invite) and say hello in the **#mentorship** channel. We’re always excited to welcome new contributors and mentors into our growing family. + +We’re already looking forward to next year’s program and are committed to using this year’s lessons to make the experience even better. + +Until then, see you all next year, and stay connected! ✌🏾 \ No newline at end of file diff --git a/markdown/blog/2024-october-summary.md b/markdown/blog/2024-october-summary.md index 88d9e7b9e36a..1093df77ba1c 100644 --- a/markdown/blog/2024-october-summary.md +++ b/markdown/blog/2024-october-summary.md @@ -11,7 +11,6 @@ authors: link: https://www.linkedin.com/in/v-thulisile-sibanda/ byline: AsyncAPI Community Manager excerpt: 'October Community Update And Online Conference Summary' -featured: true --- October marked the third AsyncAPI Conference, this time an online edition. As someone fortunate enough to be extensively involved in organizing the conferences, I saw the challenges that came with in-person events. diff --git a/markdown/blog/asyncapi-github-actions.md b/markdown/blog/asyncapi-github-actions.md index 54d0c3655082..1af6c08c183a 100644 --- a/markdown/blog/asyncapi-github-actions.md +++ b/markdown/blog/asyncapi-github-actions.md @@ -16,7 +16,7 @@ excerpt: AsyncAPI community got rich with two GitHub Actions that you can use fo --- > tl;dr -> AsyncAPI community got rich with two GitHub Actions that you can use for [validation](https://github.com/marketplace/actions/asyncapi-github-action) and [generation](https://github.com/marketplace/actions/generator-for-asyncapi-documents). +> AsyncAPI community got rich with two GitHub Actions that you can use for [validation](https://github.com/marketplace/actions/asyncapi-github-action) and [generation](https://github.com/marketplace/actions/generator-validator-converter-and-others-all-in-one-for-your-asyncapi-docs). GitHub organized a [hackathon for GitHub Actions](https://githubhackathon.com/#hackathon). There is no better reason to work on a solution if there is a bag of swags waiting for you @@ -25,7 +25,7 @@ The hackathon was only a trigger, the right moment to decide that we should enga Two AsyncAPI related actions we crafted in March are: - Our community member, [Waleed Ashraf](https://twitter.com/WaleedAshraf01/) created [an action](https://github.com/marketplace/actions/asyncapi-github-action) to validate AsyncAPI documents with our [parser](https://github.com/asyncapi/parser-js/) -- We also created [official AsyncAPI action](https://github.com/marketplace/actions/generator-for-asyncapi-documents) for our [generator](https://github.com/asyncapi/generator/). +- We also created [official AsyncAPI action](https://github.com/marketplace/actions/generator-validator-converter-and-others-all-in-one-for-your-asyncapi-docs) for our [generator](https://github.com/asyncapi/generator/). ## Writing a GitHub Action diff --git a/markdown/blog/status-update-47-20.md b/markdown/blog/status-update-47-20.md index 0f8edc497c17..1265e9b470b1 100644 --- a/markdown/blog/status-update-47-20.md +++ b/markdown/blog/status-update-47-20.md @@ -39,7 +39,7 @@ Try out the project by following :point_down: instructions: ### Generator GitHub Action 1.0 -Yes, our official [GitHub Action for Generator](https://github.com/marketplace/actions/generator-for-asyncapi-documents) already uses the latest Generator and is released under v1. +Yes, our official [GitHub Action for Generator](https://github.com/marketplace/actions/generator-validator-converter-and-others-all-in-one-for-your-asyncapi-docs) already uses the latest Generator and is released under v1. ```yaml - name: Generating HTML from my AsyncAPI document diff --git a/markdown/docs/tools/cli/usage.md b/markdown/docs/tools/cli/usage.md index 84f59e8803c4..af6eb4531a29 100644 --- a/markdown/docs/tools/cli/usage.md +++ b/markdown/docs/tools/cli/usage.md @@ -27,7 +27,7 @@ $ npm install -g @asyncapi/cli $ asyncapi COMMAND running command... $ asyncapi (--version) -@asyncapi/cli/2.11.0 linux-x64 node-v18.20.5 +@asyncapi/cli/2.12.0 linux-x64 node-v18.20.5 $ asyncapi --help [COMMAND] USAGE $ asyncapi COMMAND @@ -101,7 +101,7 @@ EXAMPLES $ asyncapi bundle ./asyncapi.yaml -o final-asyncapi.yaml --base ../public-api/main.yaml --baseDir ./social-media/comments-service ``` -_See code: [src/commands/bundle.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/bundle.ts)_ +_See code: [src/commands/bundle.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/bundle.ts)_ ## `asyncapi config` @@ -115,7 +115,7 @@ DESCRIPTION CLI config settings ``` -_See code: [src/commands/config/index.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/index.ts)_ +_See code: [src/commands/config/index.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/index.ts)_ ## `asyncapi config analytics` @@ -135,7 +135,7 @@ DESCRIPTION Enable or disable analytics for metrics collection ``` -_See code: [src/commands/config/analytics.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/analytics.ts)_ +_See code: [src/commands/config/analytics.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/analytics.ts)_ ## `asyncapi config context` @@ -149,7 +149,7 @@ DESCRIPTION Manage short aliases for full paths to AsyncAPI documents ``` -_See code: [src/commands/config/context/index.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/index.ts)_ +_See code: [src/commands/config/context/index.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/index.ts)_ ## `asyncapi config context add CONTEXT-NAME SPEC-FILE-PATH` @@ -171,7 +171,7 @@ DESCRIPTION Add a context to the store ``` -_See code: [src/commands/config/context/add.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/add.ts)_ +_See code: [src/commands/config/context/add.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/add.ts)_ ## `asyncapi config context current` @@ -188,7 +188,7 @@ DESCRIPTION Shows the current context that is being used ``` -_See code: [src/commands/config/context/current.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/current.ts)_ +_See code: [src/commands/config/context/current.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/current.ts)_ ## `asyncapi config context edit CONTEXT-NAME NEW-SPEC-FILE-PATH` @@ -209,7 +209,7 @@ DESCRIPTION Edit a context in the store ``` -_See code: [src/commands/config/context/edit.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/edit.ts)_ +_See code: [src/commands/config/context/edit.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/edit.ts)_ ## `asyncapi config context init [CONTEXT-FILE-PATH]` @@ -232,7 +232,7 @@ DESCRIPTION Initialize context ``` -_See code: [src/commands/config/context/init.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/init.ts)_ +_See code: [src/commands/config/context/init.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/init.ts)_ ## `asyncapi config context list` @@ -249,7 +249,7 @@ DESCRIPTION List all the stored contexts in the store ``` -_See code: [src/commands/config/context/list.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/list.ts)_ +_See code: [src/commands/config/context/list.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/list.ts)_ ## `asyncapi config context remove CONTEXT-NAME` @@ -269,7 +269,7 @@ DESCRIPTION Delete a context from the store ``` -_See code: [src/commands/config/context/remove.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/remove.ts)_ +_See code: [src/commands/config/context/remove.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/remove.ts)_ ## `asyncapi config context use CONTEXT-NAME` @@ -289,7 +289,7 @@ DESCRIPTION Set a context as current ``` -_See code: [src/commands/config/context/use.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/context/use.ts)_ +_See code: [src/commands/config/context/use.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/context/use.ts)_ ## `asyncapi config versions` @@ -306,7 +306,7 @@ DESCRIPTION Show versions of AsyncAPI tools used ``` -_See code: [src/commands/config/versions.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/config/versions.ts)_ +_See code: [src/commands/config/versions.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/config/versions.ts)_ ## `asyncapi convert [SPEC-FILE]` @@ -334,7 +334,7 @@ DESCRIPTION Convert asyncapi documents older to newer versions or OpenAPI/postman-collection documents to AsyncAPI ``` -_See code: [src/commands/convert.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/convert.ts)_ +_See code: [src/commands/convert.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/convert.ts)_ ## `asyncapi diff OLD NEW` @@ -375,7 +375,7 @@ DESCRIPTION Find diff between two asyncapi files ``` -_See code: [src/commands/diff.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/diff.ts)_ +_See code: [src/commands/diff.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/diff.ts)_ ## `asyncapi format [SPEC-FILE]` @@ -398,7 +398,7 @@ DESCRIPTION Convert asyncapi documents from any format to yaml, yml or JSON ``` -_See code: [src/commands/format.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/format.ts)_ +_See code: [src/commands/format.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/format.ts)_ ## `asyncapi generate` @@ -412,7 +412,7 @@ DESCRIPTION Generate typed models or other things like clients, applications or docs using AsyncAPI Generator templates. ``` -_See code: [src/commands/generate/index.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/generate/index.ts)_ +_See code: [src/commands/generate/index.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/generate/index.ts)_ ## `asyncapi generate fromTemplate ASYNCAPI TEMPLATE` @@ -457,7 +457,7 @@ EXAMPLES $ asyncapi generate fromTemplate asyncapi.yaml @asyncapi/html-template --param version=1.0.0 singleFile=true --output ./docs --force-write ``` -_See code: [src/commands/generate/fromTemplate.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/generate/fromTemplate.ts)_ +_See code: [src/commands/generate/fromTemplate.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/generate/fromTemplate.ts)_ ## `asyncapi generate models LANGUAGE FILE` @@ -527,7 +527,7 @@ DESCRIPTION Generates typed models ``` -_See code: [src/commands/generate/models.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/generate/models.ts)_ +_See code: [src/commands/generate/models.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/generate/models.ts)_ ## `asyncapi new` @@ -585,7 +585,7 @@ EXAMPLES $ asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty - create a new file with a specific name, using one of the examples and without interactive mode ``` -_See code: [src/commands/new/index.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/new/index.ts)_ +_See code: [src/commands/new/index.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/new/index.ts)_ ## `asyncapi new file` @@ -643,7 +643,7 @@ EXAMPLES $ asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty - create a new file with a specific name, using one of the examples and without interactive mode ``` -_See code: [src/commands/new/file.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/new/file.ts)_ +_See code: [src/commands/new/file.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/new/file.ts)_ ## `asyncapi new glee` @@ -665,7 +665,7 @@ DESCRIPTION Creates a new Glee project ``` -_See code: [src/commands/new/glee.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/new/glee.ts)_ +_See code: [src/commands/new/glee.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/new/glee.ts)_ ## `asyncapi new template` @@ -689,7 +689,7 @@ DESCRIPTION Creates a new template ``` -_See code: [src/commands/new/template.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/new/template.ts)_ +_See code: [src/commands/new/template.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/new/template.ts)_ ## `asyncapi optimize [SPEC-FILE]` @@ -731,7 +731,7 @@ EXAMPLES $ asyncapi optimize ./asyncapi.yaml --ignore=schema ``` -_See code: [src/commands/optimize.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/optimize.ts)_ +_See code: [src/commands/optimize.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/optimize.ts)_ ## `asyncapi pretty SPEC-FILE` @@ -756,7 +756,7 @@ EXAMPLES $ asyncapi pretty ./asyncapi.yaml --output formatted-asyncapi.yaml ``` -_See code: [src/commands/pretty.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/pretty.ts)_ +_See code: [src/commands/pretty.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/pretty.ts)_ ## `asyncapi start` @@ -770,7 +770,7 @@ DESCRIPTION Starts AsyncAPI-related services. Currently, it supports launching the AsyncAPI Studio ``` -_See code: [src/commands/start/index.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/start/index.ts)_ +_See code: [src/commands/start/index.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/start/index.ts)_ ## `asyncapi start studio` @@ -789,7 +789,7 @@ DESCRIPTION starts a new local instance of Studio ``` -_See code: [src/commands/start/studio.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/start/studio.ts)_ +_See code: [src/commands/start/studio.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/start/studio.ts)_ ## `asyncapi validate [SPEC-FILE]` @@ -820,5 +820,5 @@ DESCRIPTION validate asyncapi file ``` -_See code: [src/commands/validate.ts](https://github.com/asyncapi/cli/blob/v2.11.0/src/commands/validate.ts)_ +_See code: [src/commands/validate.ts](https://github.com/asyncapi/cli/blob/v2.12.0/src/commands/validate.ts)_ diff --git a/package-lock.json b/package-lock.json index 87b500419b87..4b7c34acddba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "md5": "^2.3.0", "mermaid": "9.3.0", "moment": "^2.30.1", - "next": "14.2.12", + "next": "14.2.20", "next-i18next": "^15.3.0", "next-language-detector": "^1.1.0", "next-mdx-remote": "^4.4.1", @@ -4829,9 +4829,9 @@ } }, "node_modules/@next/env": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.12.tgz", - "integrity": "sha512-3fP29GIetdwVIfIRyLKM7KrvJaqepv+6pVodEbx0P5CaMLYBtx+7eEg8JYO5L9sveJO87z9eCReceZLi0hxO1Q==" + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.20.tgz", + "integrity": "sha512-JfDpuOCB0UBKlEgEy/H6qcBSzHimn/YWjUHzKl1jMeUO+QVRdzmTTl8gFJaNO87c8DXmVKhFCtwxQ9acqB3+Pw==" }, "node_modules/@next/eslint-plugin-next": { "version": "14.1.0", @@ -4903,9 +4903,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.12.tgz", - "integrity": "sha512-crHJ9UoinXeFbHYNok6VZqjKnd8rTd7K3Z2zpyzF1ch7vVNKmhjv/V7EHxep3ILoN8JB9AdRn/EtVVyG9AkCXw==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.20.tgz", + "integrity": "sha512-WDfq7bmROa5cIlk6ZNonNdVhKmbCv38XteVFYsxea1vDJt3SnYGgxLGMTXQNfs5OkFvAhmfKKrwe7Y0Hs+rWOg==", "cpu": [ "arm64" ], @@ -4918,9 +4918,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.12.tgz", - "integrity": "sha512-JbEaGbWq18BuNBO+lCtKfxl563Uw9oy2TodnN2ioX00u7V1uzrsSUcg3Ep9ce+P0Z9es+JmsvL2/rLphz+Frcw==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.20.tgz", + "integrity": "sha512-XIQlC+NAmJPfa2hruLvr1H1QJJeqOTDV+v7tl/jIdoFvqhoihvSNykLU/G6NMgoeo+e/H7p/VeWSOvMUHKtTIg==", "cpu": [ "x64" ], @@ -4933,9 +4933,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.12.tgz", - "integrity": "sha512-qBy7OiXOqZrdp88QEl2H4fWalMGnSCrr1agT/AVDndlyw2YJQA89f3ttR/AkEIP9EkBXXeGl6cC72/EZT5r6rw==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.20.tgz", + "integrity": "sha512-pnzBrHTPXIMm5QX3QC8XeMkpVuoAYOmyfsO4VlPn+0NrHraNuWjdhe+3xLq01xR++iCvX+uoeZmJDKcOxI201Q==", "cpu": [ "arm64" ], @@ -4948,9 +4948,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.12.tgz", - "integrity": "sha512-EfD9L7o9biaQxjwP1uWXnk3vYZi64NVcKUN83hpVkKocB7ogJfyH2r7o1pPnMtir6gHZiGCeHKagJ0yrNSLNHw==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.20.tgz", + "integrity": "sha512-WhJJAFpi6yqmUx1momewSdcm/iRXFQS0HU2qlUGlGE/+98eu7JWLD5AAaP/tkK1mudS/rH2f9E3WCEF2iYDydQ==", "cpu": [ "arm64" ], @@ -4963,9 +4963,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.12.tgz", - "integrity": "sha512-iQ+n2pxklJew9IpE47hE/VgjmljlHqtcD5UhZVeHICTPbLyrgPehaKf2wLRNjYH75udroBNCgrSSVSVpAbNoYw==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.20.tgz", + "integrity": "sha512-ao5HCbw9+iG1Kxm8XsGa3X174Ahn17mSYBQlY6VGsdsYDAbz/ZP13wSLfvlYoIDn1Ger6uYA+yt/3Y9KTIupRg==", "cpu": [ "x64" ], @@ -4978,9 +4978,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.12.tgz", - "integrity": "sha512-rFkUkNwcQ0ODn7cxvcVdpHlcOpYxMeyMfkJuzaT74xjAa5v4fxP4xDk5OoYmPi8QNLDs3UgZPMSBmpBuv9zKWA==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.20.tgz", + "integrity": "sha512-CXm/kpnltKTT7945np6Td3w7shj/92TMRPyI/VvveFe8+YE+/YOJ5hyAWK5rpx711XO1jBCgXl211TWaxOtkaA==", "cpu": [ "x64" ], @@ -4993,9 +4993,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.12.tgz", - "integrity": "sha512-PQFYUvwtHs/u0K85SG4sAdDXYIPXpETf9mcEjWc0R4JmjgMKSDwIU/qfZdavtP6MPNiMjuKGXHCtyhR/M5zo8g==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.20.tgz", + "integrity": "sha512-upJn2HGQgKNDbXVfIgmqT2BN8f3z/mX8ddoyi1I565FHbfowVK5pnMEwauvLvaJf4iijvuKq3kw/b6E9oIVRWA==", "cpu": [ "arm64" ], @@ -5008,9 +5008,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.12.tgz", - "integrity": "sha512-FAj2hMlcbeCV546eU2tEv41dcJb4NeqFlSXU/xL/0ehXywHnNpaYajOUvn3P8wru5WyQe6cTZ8fvckj/2XN4Vw==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.20.tgz", + "integrity": "sha512-igQW/JWciTGJwj3G1ipalD2V20Xfx3ywQy17IV0ciOUBbFhNfyU1DILWsTi32c8KmqgIDviUEulW/yPb2FF90w==", "cpu": [ "ia32" ], @@ -5023,9 +5023,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.12.tgz", - "integrity": "sha512-yu8QvV53sBzoIVRHsxCHqeuS8jYq6Lrmdh0briivuh+Brsp6xjg80MAozUsBTAV9KNmY08KlX0KYTWz1lbPzEg==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.20.tgz", + "integrity": "sha512-AFmqeLW6LtxeFTuoB+MXFeM5fm5052i3MU6xD0WzJDOwku6SkZaxb1bxjBaRC8uNqTRTSPl0yMFtjNowIVI67w==", "cpu": [ "x64" ], @@ -13722,9 +13722,9 @@ } }, "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -13745,7 +13745,7 @@ "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", + "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", @@ -13760,6 +13760,10 @@ }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/debug": { @@ -20942,9 +20946,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -21012,11 +21016,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/next": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.12.tgz", - "integrity": "sha512-cDOtUSIeoOvt1skKNihdExWMTybx3exnvbFbb9ecZDIxlvIbREQzt9A5Km3Zn3PfU+IFjyYGsHS+lN9VInAGKA==", + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.20.tgz", + "integrity": "sha512-yPvIiWsiyVYqJlSQxwmzMIReXn5HxFNq4+tlVQ812N1FbvhmE+fDpIAD7bcS2mGYQwPJ5vAsQouyme2eKsxaug==", "dependencies": { - "@next/env": "14.2.12", + "@next/env": "14.2.20", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -21031,15 +21035,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.12", - "@next/swc-darwin-x64": "14.2.12", - "@next/swc-linux-arm64-gnu": "14.2.12", - "@next/swc-linux-arm64-musl": "14.2.12", - "@next/swc-linux-x64-gnu": "14.2.12", - "@next/swc-linux-x64-musl": "14.2.12", - "@next/swc-win32-arm64-msvc": "14.2.12", - "@next/swc-win32-ia32-msvc": "14.2.12", - "@next/swc-win32-x64-msvc": "14.2.12" + "@next/swc-darwin-arm64": "14.2.20", + "@next/swc-darwin-x64": "14.2.20", + "@next/swc-linux-arm64-gnu": "14.2.20", + "@next/swc-linux-arm64-musl": "14.2.20", + "@next/swc-linux-x64-gnu": "14.2.20", + "@next/swc-linux-x64-musl": "14.2.20", + "@next/swc-win32-arm64-msvc": "14.2.20", + "@next/swc-win32-ia32-msvc": "14.2.20", + "@next/swc-win32-x64-msvc": "14.2.20" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -23339,9 +23343,9 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" }, "node_modules/path-type": { "version": "4.0.0", diff --git a/package.json b/package.json index 84f538697d4d..9ab53b799d8b 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "md5": "^2.3.0", "mermaid": "9.3.0", "moment": "^2.30.1", - "next": "14.2.12", + "next": "14.2.20", "next-i18next": "^15.3.0", "next-language-detector": "^1.1.0", "next-mdx-remote": "^4.4.1", diff --git a/pages/community/tsc.tsx b/pages/community/tsc.tsx index 755652736f1b..03040adfa4b6 100644 --- a/pages/community/tsc.tsx +++ b/pages/community/tsc.tsx @@ -1,5 +1,4 @@ import { sortBy } from 'lodash'; -import React, { useState } from 'react'; import type { Tsc } from '@/types/pages/community/Community'; @@ -66,11 +65,9 @@ function addAdditionalUserInfo(user: Tsc) { * @returns The Twitter SVG component. */ function TwitterSVG() { - const [isHovered, setIsHovered] = useState(false); - return ( -
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}> - +
+
); } @@ -81,11 +78,9 @@ function TwitterSVG() { * @returns The GitHub SVG component. */ function GitHubSVG() { - const [isHovered, setIsHovered] = useState(false); - return ( -
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}> - +
+
); } @@ -96,12 +91,9 @@ function GitHubSVG() { * @returns The LinkedIn SVG component. */ function LinkedInSVG() { - const [isHovered, setIsHovered] = useState(false); - return ( -
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}> - {/* Use the imported SVG icon component */} - +
+
); } diff --git a/public/img/posts/2024-blog-banner/blog-banner-december.webp b/public/img/posts/2024-blog-banner/blog-banner-december.webp new file mode 100644 index 000000000000..043e9283a837 Binary files /dev/null and b/public/img/posts/2024-blog-banner/blog-banner-december.webp differ diff --git a/public/img/posts/gsoc.webp b/public/img/posts/gsoc.webp new file mode 100644 index 000000000000..a1848818af91 Binary files /dev/null and b/public/img/posts/gsoc.webp differ diff --git a/public/img/posts/paris-conf-2024/annegret.webp b/public/img/posts/paris-conf-2024/annegret.webp new file mode 100644 index 000000000000..87de55e1fe39 Binary files /dev/null and b/public/img/posts/paris-conf-2024/annegret.webp differ diff --git a/public/img/posts/paris-conf-2024/frank.webp b/public/img/posts/paris-conf-2024/frank.webp new file mode 100644 index 000000000000..b9249192f509 Binary files /dev/null and b/public/img/posts/paris-conf-2024/frank.webp differ diff --git a/public/img/posts/paris-conf-2024/full-room.webp b/public/img/posts/paris-conf-2024/full-room.webp new file mode 100644 index 000000000000..590c3c880206 Binary files /dev/null and b/public/img/posts/paris-conf-2024/full-room.webp differ diff --git a/public/img/posts/paris-conf-2024/hari-and-joel.webp b/public/img/posts/paris-conf-2024/hari-and-joel.webp new file mode 100644 index 000000000000..20cad1725c12 Binary files /dev/null and b/public/img/posts/paris-conf-2024/hari-and-joel.webp differ diff --git a/public/img/posts/paris-conf-2024/hugo.webp b/public/img/posts/paris-conf-2024/hugo.webp new file mode 100644 index 000000000000..6f34ad741f84 Binary files /dev/null and b/public/img/posts/paris-conf-2024/hugo.webp differ diff --git a/public/img/posts/paris-conf-2024/jonathan.webp b/public/img/posts/paris-conf-2024/jonathan.webp new file mode 100644 index 000000000000..d84c181c896e Binary files /dev/null and b/public/img/posts/paris-conf-2024/jonathan.webp differ diff --git a/public/img/posts/paris-conf-2024/julien-and-alessandro.webp b/public/img/posts/paris-conf-2024/julien-and-alessandro.webp new file mode 100644 index 000000000000..c93b90a6014a Binary files /dev/null and b/public/img/posts/paris-conf-2024/julien-and-alessandro.webp differ diff --git a/public/img/posts/paris-conf-2024/laurent-and-hugo.webp b/public/img/posts/paris-conf-2024/laurent-and-hugo.webp new file mode 100644 index 000000000000..318a2f81ccd1 Binary files /dev/null and b/public/img/posts/paris-conf-2024/laurent-and-hugo.webp differ diff --git a/public/img/posts/paris-conf-2024/leonid.webp b/public/img/posts/paris-conf-2024/leonid.webp new file mode 100644 index 000000000000..87f11a883aa1 Binary files /dev/null and b/public/img/posts/paris-conf-2024/leonid.webp differ diff --git a/public/img/posts/paris-conf-2024/lukasz-and-fran.webp b/public/img/posts/paris-conf-2024/lukasz-and-fran.webp new file mode 100644 index 000000000000..9417295f9bc9 Binary files /dev/null and b/public/img/posts/paris-conf-2024/lukasz-and-fran.webp differ diff --git a/public/img/posts/paris-conf-2024/naresh-and-pierre.webp b/public/img/posts/paris-conf-2024/naresh-and-pierre.webp new file mode 100644 index 000000000000..3850ded92269 Binary files /dev/null and b/public/img/posts/paris-conf-2024/naresh-and-pierre.webp differ diff --git a/public/locales/en/landing-page.json b/public/locales/en/landing-page.json index d9537bdb40ae..ae14df4c0145 100644 --- a/public/locales/en/landing-page.json +++ b/public/locales/en/landing-page.json @@ -50,7 +50,7 @@ "title": "Join our great community!", "subtitle": "We're a community of great people who are passionate about AsyncAPI and event-driven architectures.", "slackCTATitle": "Join our Slack workspace", - "slackCTADesc": "We welcome everyone to join our Slack workspace. If you have a question on how to use AsyncAPI, want to contribute, or simply want to say hello 👋  you're welcome to join us. We're nice people 🙂", + "slackCTADesc": "We welcome everyone to join our Slack workspace. If you have a question on how to use AsyncAPI, want to contribute, or simply want to say hello 👋, you're welcome to join us. We're nice people 🙂", "slackCTABtn": "Join us!", "meetingTitle": "Join our public meetings", "meetingDesc": "AsyncAPI hosts different meetings every week. They are focused on different topics, sometimes purely technical and sometimes about community building. Pick one and join us!", diff --git a/scripts/markdown/check-markdown.js b/scripts/markdown/check-markdown.js index 8979f7e0b4ab..cd3bd7ddd1c5 100644 --- a/scripts/markdown/check-markdown.js +++ b/scripts/markdown/check-markdown.js @@ -1,4 +1,4 @@ -const fs = require('fs'); +const fs = require('fs').promises; const matter = require('gray-matter'); const path = require('path'); @@ -98,14 +98,10 @@ function validateDocs(frontmatter) { * @param {Function} validateFunction - The function used to validate the frontmatter. * @param {string} [relativePath=''] - The relative path of the folder for logging purposes. */ -function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { - fs.readdir(folderPath, (err, files) => { - if (err) { - console.error('Error reading directory:', err); - return; - } - - files.forEach(file => { +async function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { + try { + const files = await fs.readdir(folderPath); + const filePromises = files.map(async (file) => { const filePath = path.join(folderPath, file); const relativeFilePath = path.join(relativePath, file); @@ -114,17 +110,13 @@ function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { return; } - fs.stat(filePath, (err, stats) => { - if (err) { - console.error('Error reading file stats:', err); - return; - } + const stats = await fs.stat(filePath); // Recurse if directory, otherwise validate markdown file if (stats.isDirectory()) { - checkMarkdownFiles(filePath, validateFunction, relativeFilePath); + await checkMarkdownFiles(filePath, validateFunction, relativeFilePath); } else if (path.extname(file) === '.md') { - const fileContent = fs.readFileSync(filePath, 'utf-8'); + const fileContent = await fs.readFile(filePath, 'utf-8'); const { data: frontmatter } = matter(fileContent); const errors = validateFunction(frontmatter); @@ -134,13 +126,33 @@ function checkMarkdownFiles(folderPath, validateFunction, relativePath = '') { process.exitCode = 1; } } - }); }); - }); + + await Promise.all(filePromises); + } catch (err) { + console.error(`Error in directory ${folderPath}:`, err); + throw err; + } } const docsFolderPath = path.resolve(__dirname, '../../markdown/docs'); const blogsFolderPath = path.resolve(__dirname, '../../markdown/blog'); -checkMarkdownFiles(docsFolderPath, validateDocs); -checkMarkdownFiles(blogsFolderPath, validateBlogs); +async function main() { + try { + await Promise.all([ + checkMarkdownFiles(docsFolderPath, validateDocs), + checkMarkdownFiles(blogsFolderPath, validateBlogs) + ]); + } catch (error) { + console.error('Failed to validate markdown files:', error); + process.exit(1); + } +} + +/* istanbul ignore next */ +if (require.main === module) { + main(); +} + +module.exports = { validateBlogs, validateDocs, checkMarkdownFiles, main, isValidURL }; diff --git a/scripts/tools/combine-tools.js b/scripts/tools/combine-tools.js index 602262428fa1..1b1367b15ccb 100644 --- a/scripts/tools/combine-tools.js +++ b/scripts/tools/combine-tools.js @@ -106,37 +106,44 @@ const getFinalTool = async (toolObject) => { // Combine the automated tools and manual tools list into single JSON object file, and // lists down all the language and technology tags in one JSON file. const combineTools = async (automatedTools, manualTools, toolsPath, tagsPath) => { - for (const key in automatedTools) { - let finalToolsList = []; - if (automatedTools[key].toolsList.length) { - for (const tool of automatedTools[key].toolsList) { - finalToolsList.push(await getFinalTool(tool)) + try { + for (const key in automatedTools) { + let finalToolsList = []; + if (automatedTools[key].toolsList.length) { + for (const tool of automatedTools[key].toolsList) { + finalToolsList.push(await getFinalTool(tool)) + } } - } - if (manualTools[key] && manualTools[key].toolsList.length) { - for (const tool of manualTools[key].toolsList) { - let isAsyncAPIrepo; - const isValid = await validate(tool) - if (isValid) { - if (tool?.links?.repoUrl) { - const url = new URL(tool.links.repoUrl) - isAsyncAPIrepo = url.href.startsWith("https://github.com/asyncapi/") - } else isAsyncAPIrepo = false - let toolObject = await createToolObject(tool, "", "", isAsyncAPIrepo) - finalToolsList.push(await getFinalTool(toolObject)) - } else { - console.error('Script is not failing, it is just dropping errors for further investigation'); - console.error(`Invalid ${tool.title} .asyncapi-tool file.`); - console.error(`Located in manual-tools.json file`); - console.error('Validation errors:', JSON.stringify(validate.errors, null, 2)); + if (manualTools[key]?.toolsList?.length) { + for (const tool of manualTools[key].toolsList) { + let isAsyncAPIrepo; + const isValid = await validate(tool) + if (isValid) { + if (tool?.links?.repoUrl) { + const url = new URL(tool.links.repoUrl) + isAsyncAPIrepo = url.href.startsWith("https://github.com/asyncapi/") + } else isAsyncAPIrepo = false + let toolObject = await createToolObject(tool, "", "", isAsyncAPIrepo) + finalToolsList.push(await getFinalTool(toolObject)) + } else { + console.error({ + message: 'Tool validation failed', + tool: tool.title, + source: 'manual-tools.json', + errors: validate.errors, + note: 'Script continues execution, error logged for investigation' + }); + } } } + finalToolsList.sort((tool, anotherTool) => tool.title.localeCompare(anotherTool.title)); + finalTools[key].toolsList = finalToolsList } - finalToolsList.sort((tool, anotherTool) => tool.title.localeCompare(anotherTool.title)); - finalTools[key].toolsList = finalToolsList + fs.writeFileSync(toolsPath, JSON.stringify(finalTools)); + fs.writeFileSync(tagsPath, JSON.stringify({ languages: languageList, technologies: technologyList }),) + } catch (err) { + throw new Error(`Error combining tools: ${err}`); } - fs.writeFileSync(toolsPath,JSON.stringify(finalTools)); - fs.writeFileSync(tagsPath,JSON.stringify({ languages: languageList, technologies: technologyList }),) } -module.exports = { combineTools } \ No newline at end of file +module.exports = { combineTools } diff --git a/scripts/tools/tools-object.js b/scripts/tools/tools-object.js index e5a30334f7d3..1d8c73f8074b 100644 --- a/scripts/tools/tools-object.js +++ b/scripts/tools/tools-object.js @@ -9,7 +9,6 @@ addFormats(ajv, ["uri"]) const validate = ajv.compile(schema) const { convertToJson } = require('../utils'); - // Config options set for the Fuse object const options = { includeScore: true, @@ -25,8 +24,8 @@ const fuse = new Fuse(categoryList, options) // isAsyncAPIrepo boolean variable to define whether the tool repository is under // AsyncAPI organization or not, to create a JSON tool object as required in the frontend // side to show ToolCard. -const createToolObject = async (toolFile, repositoryUrl='', repoDescription='', isAsyncAPIrepo='') => { - let resultantObject = { +const createToolObject = async (toolFile, repositoryUrl = '', repoDescription = '', isAsyncAPIrepo = '') => { + const resultantObject = { title: toolFile.title, description: toolFile?.description ? toolFile.description : repoDescription, links: { @@ -47,67 +46,71 @@ const createToolObject = async (toolFile, repositoryUrl='', repoDescription='', // and creating a JSON tool object in which all the tools are listed in defined // categories order, which is then updated in `automated-tools.json` file. async function convertTools(data) { - let finalToolsObject = {}; - const dataArray = data.items; - - // initialising finalToolsObject with all categories inside it with proper elements in each category - for (var index in categoryList) { - finalToolsObject[categoryList[index].name] = { - description: categoryList[index].description, - toolsList: [] - }; - } + try { + let finalToolsObject = {}; + const dataArray = data.items; - for (let tool of dataArray) { - try { - if (tool.name.startsWith('.asyncapi-tool')) { - // extracting the reference id of the repository which will be used to extract the path of the .asyncapi-tool file in the Tools repository - // ex: for a url = "https://api.github.com/repositories/351453552/contents/.asyncapi-tool?ref=61855e7365a881e98c2fe667a658a0005753d873" - // the text (id) present after '=' gives us a reference id for the repo - let reference_id = tool.url.split("=")[1]; - let download_url = `https://raw.githubusercontent.com/${tool.repository.full_name}/${reference_id}/${tool.path}`; + // initialising finalToolsObject with all categories inside it with proper elements in each category + finalToolsObject = Object.fromEntries( + categoryList.map((category) => [ + category.name, + { + description: category.description, + toolsList: [] + } + ]) + ); - const { data: toolFileContent } = await axios.get(download_url); + await Promise.all(dataArray.map(async (tool) => { + try { + if (tool.name.startsWith('.asyncapi-tool')) { + const referenceId = tool.url.split('=')[1]; + const downloadUrl = `https://raw.githubusercontent.com/${tool.repository.full_name}/${referenceId}/${tool.path}`; - //some stuff can be YAML - const jsonToolFileContent = await convertToJson(toolFileContent) + const { data: toolFileContent } = await axios.get(downloadUrl); - //validating against JSON Schema for tools file - const isValid = await validate(jsonToolFileContent) + //some stuff can be YAML + const jsonToolFileContent = await convertToJson(toolFileContent) - if (isValid) { - let repositoryUrl = tool.repository.html_url; - let repoDescription = tool.repository.description; - let isAsyncAPIrepo = tool.repository.owner.login === "asyncapi"; - let toolObject = await createToolObject(jsonToolFileContent, repositoryUrl, repoDescription, isAsyncAPIrepo); + //validating against JSON Schema for tools file + const isValid = await validate(jsonToolFileContent) - // Tool Object is appended to each category array according to Fuse search for categories inside Tool Object - jsonToolFileContent.filters.categories.forEach(async (category) => { - const categorySearch = await fuse.search(category); + if (isValid) { + const repositoryUrl = tool.repository.html_url; + const repoDescription = tool.repository.description; + const isAsyncAPIrepo = tool.repository.owner.login === 'asyncapi'; + const toolObject = await createToolObject( + jsonToolFileContent, + repositoryUrl, + repoDescription, + isAsyncAPIrepo + ); - if (categorySearch.length) { - let searchedCategoryName = categorySearch[0].item.name - if (!finalToolsObject[searchedCategoryName].toolsList.find((element => element === toolObject))) - finalToolsObject[searchedCategoryName].toolsList.push(toolObject); - } else { - // if Tool object has a category, not defined in our categorylist, then this provides a `other` category to the tool. - if (!finalToolsObject['Others'].toolsList.find((element => element === toolObject))) - finalToolsObject['Others'].toolsList.push(toolObject); - } - }); - } else { - console.error('Script is not failing, it is just dropping errors for further investigation'); - console.error('Invalid .asyncapi-tool file.'); - console.error(`Located in: ${tool.html_url}`); - console.error('Validation errors:', JSON.stringify(validate.errors, null, 2)); + // Tool Object is appended to each category array according to Fuse search for categories inside Tool Object + await Promise.all(jsonToolFileContent.filters.categories.map(async (category) => { + const categorySearch = await fuse.search(category); + const targetCategory = categorySearch.length ? categorySearch[0].item.name : 'Others'; + const { toolsList } = finalToolsObject[targetCategory]; + if (!toolsList.includes(toolObject)) { + toolsList.push(toolObject); + } + })); + } else { + console.error('Script is not failing, it is just dropping errors for further investigation'); + console.error('Invalid .asyncapi-tool file.'); + console.error(`Located in: ${tool.html_url}`); + console.error('Validation errors:', JSON.stringify(validate.errors, null, 2)); + } } + } catch (err) { + console.error(err) + throw err; } - } catch (err) { - console.error(err) - throw err; - } + })) + return finalToolsObject; + } catch (err) { + throw new Error(`Error processing tool: ${err.message}`) } - return finalToolsObject; } -module.exports = {convertTools, createToolObject} \ No newline at end of file +module.exports = { convertTools, createToolObject } diff --git a/tests/fixtures/combineToolsData.js b/tests/fixtures/combineToolsData.js new file mode 100644 index 000000000000..452764ac9192 --- /dev/null +++ b/tests/fixtures/combineToolsData.js @@ -0,0 +1,212 @@ +const expectedDataT1 = { + languages: [ + { + name: 'JavaScript', + color: 'bg-[#57f281]', + borderColor: 'border-[#37f069]', + }, + { + name: 'Python', + color: 'bg-[#3572A5]', + borderColor: 'border-[#3572A5]', + }, + ], + technologies: [ + { + name: 'Node.js', + color: 'bg-[#61d0f2]', + borderColor: 'border-[#40ccf7]', + }, + { + name: 'Flask', + color: 'bg-[#000000]', + borderColor: 'border-[#FFFFFF]', + }, + ], +}; + +const manualToolsWithMissingData = [ + { + title: 'Tool C', + filters: {}, + links: { repoUrl: 'https://github.com/asyncapi/tool-c' }, + }, +]; + +const manualToolsToSort = { + category1: { + description: 'Sample Category', + toolsList: [ + { + title: 'Tool Z', + filters: { language: 'JavaScript' }, + links: { repoUrl: 'https://github.com/asyncapi/tool-z' }, + }, + { + title: 'Tool A', + filters: { language: 'Python' }, + links: { repoUrl: 'https://github.com/asyncapi/tool-a' }, + }, + ], + }, +}; + +const toolWithMultipleLanguages = { + title: 'Multi-Language Tool', + filters: { + language: ['JavaScript', 'Python', 'NewLanguage'], + technology: ['Node.js'], + }, + links: { repoUrl: 'https://github.com/example/multi-language-tool' }, +}; + +const automatedToolsT5 = { + category1: { + description: 'Category 1 Description', + toolsList: [toolWithMultipleLanguages], + }, +}; + +const invalidToolT4 = { title: 'Invalid Tool' }; + +const automatedToolsT4 = { + category1: { + description: 'Category 1 Description', + toolsList: [], + }, +}; +const manualToolsT4 = { + category1: { + toolsList: [invalidToolT4], + }, +}; + +const toolWithNewTagsT6 = { + title: 'New Tags Tool', + filters: { + language: 'NewLanguage', + technology: ['NewTechnology'], + }, + links: { repoUrl: 'https://github.com/example/new-tags-tool' }, +}; + +const automatedToolsT6 = { + category1: { + description: 'Category 1 Description', + toolsList: [toolWithNewTagsT6], + }, +}; + +const toolWithNewLanguageT7 = { + title: 'New Language Tool', + filters: { + language: 'Go', + technology: ['Node.js'], + }, + links: { repoUrl: 'https://github.com/example/new-language-tool' }, +}; + +const automatedToolsT7 = { + category1: { + description: 'Category 1 Description', + toolsList: [toolWithNewLanguageT7], + }, +}; + +const validToolT8 = { + title: 'Valid Tool', + filters: { + language: 'JavaScript', + technology: ['Node.js'], + }, + links: { repoUrl: 'https://github.com/asyncapi/valid-tool' }, +}; + +const automatedToolsT8 = { + category1: { + description: 'Category 1 Description', + toolsList: [], + }, +}; + +const manualToolsT8 = { + category1: { + toolsList: [validToolT8], + }, +}; + +const toolWithoutRepoUrlT9 = { + title: 'Tool Without Repo', + filters: { + language: 'Python', + technology: ['Flask'], + }, + links: {}, +}; + +const automatedToolsT9 = { + category1: { + description: 'Category 1 Description', + toolsList: [], + }, +}; + +const manualToolsT9 = { + category1: { + toolsList: [toolWithoutRepoUrlT9], + }, +}; + +const invalidAutomatedToolsT10 = { + invalidCategory: { + description: 'Invalid Category Description', + toolsList: [], + }, +}; + +const manualToolsWithInvalidURLT11 = { + category1: { + toolsList: [ + { + title: 'Tool with Invalid URL', + filters: { language: 'JavaScript' }, + links: { repoUrl: 'invalid-url' }, + }, + ], + }, +}; + +const circularTool = { + title: 'Circular Tool', + filters: { + language: 'JavaScript', + technology: ['Node.js'], + }, + links: { repoUrl: 'https://github.com/asyncapi/circular-tool' }, +}; + +const automatedToolsT12 = { + category1: { + description: 'Category 1', + toolsList: [circularTool], + }, +}; + +module.exports = { + expectedDataT1, + manualToolsWithMissingData, + manualToolsToSort, + automatedToolsT5, + automatedToolsT4, + manualToolsT4, + automatedToolsT6, + automatedToolsT7, + automatedToolsT8, + manualToolsT8, + automatedToolsT9, + manualToolsT9, + circularTool, + automatedToolsT12, + invalidAutomatedToolsT10, + manualToolsWithInvalidURLT11, +}; diff --git a/tests/fixtures/tools/automated-tools.json b/tests/fixtures/tools/automated-tools.json new file mode 100644 index 000000000000..1184da03e718 --- /dev/null +++ b/tests/fixtures/tools/automated-tools.json @@ -0,0 +1,17 @@ +{ + "category1": { + "description": "Sample Category", + "toolsList": [ + { + "title": "Tool B", + "filters": { + "language": "Python", + "technology": ["Flask"] + }, + "links": { + "repoUrl": "https://github.com/asyncapi/tool-b" + } + } + ] + } +} diff --git a/tests/fixtures/tools/manual-tools.json b/tests/fixtures/tools/manual-tools.json new file mode 100644 index 000000000000..47469bc1a7e7 --- /dev/null +++ b/tests/fixtures/tools/manual-tools.json @@ -0,0 +1,12 @@ +[ + { + "title": "Tool A", + "filters": { + "language": "JavaScript", + "technology": ["Node.js"] + }, + "links": { + "repoUrl": "https://github.com/asyncapi/tool-a" + } + } +] diff --git a/tests/helper/toolsObjectData.js b/tests/helper/toolsObjectData.js new file mode 100644 index 000000000000..929d985f9773 --- /dev/null +++ b/tests/helper/toolsObjectData.js @@ -0,0 +1,79 @@ +const createToolRepositoryData = ({ + name = '.asyncapi-tool', + refId = '61855e7365a881e98c2fe667a658a0005753d873', + owner = 'asyncapi', + repoName = 'example-repo', + description = 'Example repository', + path = '.asyncapi-tool' +} = {}) => ({ + name, + url: `https://api.github.com/repositories/351453552/contents/${path}?ref=${refId}`, + repository: { + full_name: `${owner}/${repoName}`, + html_url: `https://github.com/${owner}/${repoName}`, + description, + owner: { login: owner } + }, + path +}); + +const createToolFileContent = ({ + title = 'Example Tool', + description = 'This is an example tool.', + repoUrl = null, + categories = ['Category1'], + hasCommercial = false, + additionalLinks = {}, + additionalFilters = {} +} = {}) => ({ + title, + description, + links: { + repoUrl: repoUrl || `https://github.com/asyncapi/${encodeURIComponent(title.toLowerCase().replace(/\s+/g, '-'))}`, + ...additionalLinks + }, + filters: { categories, hasCommercial, ...additionalFilters } +}); + +const createExpectedToolObject = ({ + title = 'Example Tool', + description = 'This is an example tool.', + repoUrl = null, + categories = ['Category1'], + hasCommercial = false, + isAsyncAPIOwner = true, + additionalLinks = {}, + additionalFilters = {} +} = {}) => + createToolFileContent({ + title, + description, + repoUrl, + categories, + hasCommercial, + additionalLinks, + additionalFilters: { isAsyncAPIOwner, ...additionalFilters } + }); + +const createMockData = (tools = []) => ({ + items: tools.map((tool) => + typeof tool === 'string' + ? createToolRepositoryData({ name: `.asyncapi-tool-${tool}`, repoName: tool }) + : createToolRepositoryData(tool) + ) +}); + +const createMalformedYAML = ({ + title = 'Malformed Tool', + description = 'This tool has malformed YAML.', + repoUrl = 'https://github.com/asyncapi/malformed-repo' } = {}) => ` + title: ${title} + description: ${description} + links: + repoUrl: ${repoUrl} + filters: + categories: + - Category1 +`; + +module.exports = { createToolFileContent, createExpectedToolObject, createMockData, createMalformedYAML }; diff --git a/tests/markdown/check-markdown.test.js b/tests/markdown/check-markdown.test.js new file mode 100644 index 000000000000..85e06b70383f --- /dev/null +++ b/tests/markdown/check-markdown.test.js @@ -0,0 +1,150 @@ +const fs = require('fs').promises; +const path = require('path'); +const os = require('os'); +const { + isValidURL, + main, + validateBlogs, + validateDocs, + checkMarkdownFiles +} = require('../../scripts/markdown/check-markdown'); + +describe('Frontmatter Validator', () => { + let tempDir; + let mockConsoleError; + let mockProcessExit; + + beforeEach(async () => { + mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); + mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); + tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-config')); + }); + + afterEach(async () => { + mockConsoleError.mockRestore(); + mockProcessExit.mockRestore(); + await fs.rm(tempDir, { recursive: true, force: true }); + }); + + it('validates authors array and returns specific errors', async () => { + const frontmatter = { + title: 'Test Blog', + date: '2024-01-01', + type: 'blog', + tags: ['test'], + cover: 'cover.jpg', + authors: [{ name: 'John' }, { photo: 'jane.jpg' }, { name: 'Bob', photo: 'bob.jpg', link: 'not-a-url' }] + }; + + const errors = validateBlogs(frontmatter); + expect(errors).toEqual(expect.arrayContaining([ + 'Author at index 0 is missing a photo', + 'Author at index 1 is missing a name', + 'Invalid URL for author at index 2: not-a-url' + ])); + }); + + it('validates docs frontmatter for required fields', async () => { + const frontmatter = { title: 123, weight: 'not-a-number' }; + const errors = validateDocs(frontmatter); + expect(errors).toEqual(expect.arrayContaining([ + 'Title is missing or not a string', + 'Weight is missing or not a number' + ])); + }); + + it('checks for errors in markdown files in a directory', async () => { + await fs.writeFile(path.join(tempDir, 'invalid.md'), `---\ntitle: Invalid Blog\n---`); + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + + await checkMarkdownFiles(tempDir, validateBlogs); + + expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('Errors in file invalid.md:')); + mockConsoleLog.mockRestore(); + }); + + it('returns multiple validation errors for invalid blog frontmatter', async () => { + const frontmatter = { + title: 123, + date: 'invalid-date', + type: 'blog', + tags: 'not-an-array', + cover: ['not-a-string'], + authors: { name: 'John Doe' } + }; + const errors = validateBlogs(frontmatter); + + expect(errors).toEqual([ + 'Invalid date format: invalid-date', + 'Tags should be an array', + 'Cover must be a string', + 'Authors should be an array']); + }); + + it('logs error to console when an error occurs in checkMarkdownFiles', async () => { + const invalidFolderPath = path.join(tempDir, 'non-existent-folder'); + + await expect(checkMarkdownFiles(invalidFolderPath, validateBlogs)) + .rejects.toThrow('ENOENT'); + + expect(mockConsoleError.mock.calls[0][0]).toContain('Error in directory'); + }); + + it('skips the "reference/specification" folder during validation', async () => { + const referenceSpecDir = path.join(tempDir, 'reference', 'specification'); + await fs.mkdir(referenceSpecDir, { recursive: true }); + await fs.writeFile(path.join(referenceSpecDir, 'skipped.md'), `---\ntitle: Skipped File\n---`); + + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + + await checkMarkdownFiles(tempDir, validateDocs); + + expect(mockConsoleLog).not.toHaveBeenCalledWith(expect.stringContaining('Errors in file reference/specification/skipped.md')); + mockConsoleLog.mockRestore(); + }); + + it('logs and rejects when an exception occurs while processing a file', async () => { + const filePath = path.join(tempDir, 'invalid.md'); + await fs.writeFile(filePath, `---\ntitle: Valid Title\n---`); + + const mockReadFile = jest.spyOn(fs, 'readFile').mockRejectedValue(new Error('Test readFile error')); + + await expect(checkMarkdownFiles(tempDir, validateBlogs)).rejects.toThrow('Test readFile error'); + expect(mockConsoleError).toHaveBeenCalledWith( + expect.stringContaining(`Error in directory`), + expect.any(Error) + ); + + mockReadFile.mockRestore(); + }); + + it('should handle main function errors and exit with status 1', async () => { + jest.spyOn(fs, 'readdir').mockRejectedValue(new Error('Test error')); + + await main(); + + expect(mockProcessExit).toHaveBeenCalledWith(1); + + expect(mockConsoleError).toHaveBeenCalledWith( + 'Failed to validate markdown files:', + expect.any(Error) + ); + }); + + it('should handle successful main function execution', async () => { + + await main(); + + expect(mockConsoleError).not.toHaveBeenCalledWith(); + }); + + it('should return true or false for URLs', () => { + expect(isValidURL('http://example.com')).toBe(true); + expect(isValidURL('https://www.example.com')).toBe(true); + expect(isValidURL('ftp://ftp.example.com')).toBe(true); + expect(isValidURL('invalid-url')).toBe(false); + expect(isValidURL('/path/to/file')).toBe(false); + expect(isValidURL('www.example.com')).toBe(false); + }); + +}); diff --git a/tests/tools/combine-tools.test.js b/tests/tools/combine-tools.test.js new file mode 100644 index 000000000000..622067a57462 --- /dev/null +++ b/tests/tools/combine-tools.test.js @@ -0,0 +1,229 @@ +const fs = require('fs'); +const path = require('path'); +const { combineTools } = require('../../scripts/tools/combine-tools'); +const { + expectedDataT1, + manualToolsWithMissingData, + manualToolsToSort, + automatedToolsT5, + automatedToolsT4, + manualToolsT4, + automatedToolsT6, + automatedToolsT7, + automatedToolsT8, + manualToolsT8, + automatedToolsT9, + manualToolsT9, + automatedToolsT12, + invalidAutomatedToolsT10, + manualToolsWithInvalidURLT11, + circularTool +} = require('../fixtures/combineToolsData'); + +jest.mock('ajv', () => { + return jest.fn().mockImplementation(() => ({ + compile: jest.fn().mockImplementation(() => (data) => data.title !== 'Invalid Tool'), + })); +}); + + +jest.mock('ajv-formats', () => { + return jest.fn(); +}); + +jest.mock('../../scripts/tools/tags-color', () => ({ + languagesColor: [ + { name: 'JavaScript', color: 'bg-[#57f281]', borderColor: 'border-[#37f069]' }, + { name: 'Python', color: 'bg-[#3572A5]', borderColor: 'border-[#3572A5]' } + ], + technologiesColor: [ + { name: 'Node.js', color: 'bg-[#61d0f2]', borderColor: 'border-[#40ccf7]' }, + { name: 'Flask', color: 'bg-[#000000]', borderColor: 'border-[#FFFFFF]' } + ] +})); + +jest.mock('../../scripts/tools/categorylist', () => ({ + categoryList: [ + { name: 'category1', description: 'Sample Category 1' }, + { name: 'category2', description: 'Sample Category 2' } + ] +})); + +const readJSON = (filePath) => JSON.parse(fs.readFileSync(filePath, 'utf-8')); + +describe('combineTools function', () => { + const toolsPath = path.join(__dirname, '../', 'fixtures', 'tools', 'tools.json'); + const tagsPath = path.join(__dirname, '../', 'fixtures', 'tools', 'tags.json'); + const manualToolsPath = path.join(__dirname, '../', 'fixtures', 'tools', 'manual-tools.json'); + const automatedToolsPath = path.join(__dirname, '../', 'fixtures', 'tools', 'automated-tools.json'); + + let manualTools; + let automatedTools; + let consoleErrorMock; + + beforeAll(() => { + manualTools = readJSON(manualToolsPath); + automatedTools = readJSON(automatedToolsPath); + }); + + afterAll(() => { + if (fs.existsSync(toolsPath)) fs.unlinkSync(toolsPath); + if (fs.existsSync(tagsPath)) fs.unlinkSync(tagsPath); + + consoleErrorMock.mockRestore(); + }); + + beforeEach(() => { + consoleErrorMock = jest.spyOn(console, 'error').mockImplementation(() => { }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should combine tools and create correct JSON files', async () => { + await combineTools(automatedTools, manualTools, toolsPath, tagsPath); + + const combinedTools = readJSON(toolsPath); + expect(combinedTools).toHaveProperty('category1'); + + const tagsData = readJSON(tagsPath); + expect(tagsData).toHaveProperty('languages'); + expect(tagsData).toHaveProperty('technologies'); + expect(tagsData).toEqual(expectedDataT1) + }); + + it('should handle tools with missing language or technology', async () => { + await combineTools({}, manualToolsWithMissingData, toolsPath, tagsPath); + + const combinedTools = readJSON(toolsPath); + expect(combinedTools).toHaveProperty('category1'); + }); + + it('should sort tools alphabetically by title', async () => { + await combineTools(manualToolsToSort, {}, toolsPath, tagsPath); + + const combinedTools = readJSON(toolsPath); + const toolTitles = combinedTools.category1.toolsList.map(tool => tool.title); + expect(toolTitles).toEqual(['Tool A', 'Tool Z']); + }); + + it('should log validation errors to console.error', async () => { + await combineTools(automatedToolsT4, manualToolsT4, toolsPath, tagsPath); + + const { message, tool, source, note } = console.error.mock.calls[0][0]; + + expect(message).toBe('Tool validation failed'); + expect(tool).toBe('Invalid Tool'); + expect(source).toBe('manual-tools.json'); + expect(note).toBe('Script continues execution, error logged for investigation'); + + expect(fs.existsSync(toolsPath)).toBe(true); + expect(fs.existsSync(tagsPath)).toBe(true); + }); + + it('should handle tools with multiple languages, including new ones', async () => { + await combineTools(automatedToolsT5, {}, toolsPath, tagsPath); + + const combinedTools = readJSON(toolsPath); + const tool = combinedTools.category1.toolsList[0]; + + expect(tool.filters.language).toHaveLength(3); + expect(tool.filters.language).toContainEqual(expect.objectContaining({ name: 'JavaScript' })); + expect(tool.filters.language).toContainEqual(expect.objectContaining({ name: 'Python' })); + expect(tool.filters.language).toContainEqual(expect.objectContaining({ name: 'NewLanguage' })); + + const tagsData = readJSON(tagsPath); + expect(tagsData.languages).toContainEqual(expect.objectContaining({ name: 'NewLanguage' })); + }); + + it('should add a new language and technology when not found in the existing lists', async () => { + await combineTools(automatedToolsT6, {}, toolsPath, tagsPath); + + const combinedTools = readJSON(toolsPath); + const tool = combinedTools.category1.toolsList[0]; + + expect(tool.filters.language).toHaveLength(1); + expect(tool.filters.language).toContainEqual(expect.objectContaining({ name: 'NewLanguage' })); + + expect(tool.filters.technology).toHaveLength(1); + expect(tool.filters.technology).toContainEqual(expect.objectContaining({ name: 'NewTechnology' })); + + const tagsData = readJSON(tagsPath); + expect(tagsData.languages).toContainEqual({ + name: 'NewLanguage', + color: 'bg-[#57f281]', + borderColor: 'border-[#37f069]' + }); + expect(tagsData.technologies).toContainEqual({ + name: 'NewTechnology', + color: 'bg-[#61d0f2]', + borderColor: 'border-[#40ccf7]' + }); + }); + + it('should add a new language when it is not found in the existing languages list', async () => { + await combineTools(automatedToolsT7, {}, toolsPath, tagsPath); + + const combinedTools = readJSON(toolsPath); + const tool = combinedTools.category1.toolsList[0]; + + expect(tool.filters.language).toHaveLength(1); + expect(tool.filters.language).toContainEqual(expect.objectContaining({ name: 'Go' })); + + const tagsData = readJSON(tagsPath); + expect(tagsData.languages).toContainEqual({ + name: 'Go', + color: 'bg-[#57f281]', + borderColor: 'border-[#37f069]' + }); + }); + + it('should handle valid tool objects', async () => { + await combineTools(automatedToolsT8, manualToolsT8, toolsPath, tagsPath); + + const tagsData = readJSON(tagsPath); + expect(tagsData.languages).toContainEqual({ + name: 'JavaScript', + color: 'bg-[#57f281]', + borderColor: 'border-[#37f069]' + }); + expect(tagsData.technologies).toContainEqual({ + name: 'Node.js', + color: 'bg-[#61d0f2]', + borderColor: 'border-[#40ccf7]' + }); + }); + + it('should handle tool objects without repoUrl', async () => { + await combineTools(automatedToolsT9, manualToolsT9, toolsPath, tagsPath); + + const combinedTools = readJSON(toolsPath); + const tool = combinedTools.category1.toolsList[0]; + + expect(tool.isAsyncAPIrepo).toBeUndefined(); + }); + + it('should throw an error when fs.writeFileSync fails', async () => { + const invalidPath = 'this/is/not/valid'; + await expect(combineTools(automatedTools, manualTools, invalidPath, invalidPath)) + .rejects.toThrow(/ENOENT|EACCES/); + }); + + it('should throw an error when there is an invalid category', async () => { + await expect(combineTools(invalidAutomatedToolsT10, manualTools, toolsPath, tagsPath)) + .rejects.toThrow('Error combining tools'); + }); + + it('should throw an error when URL parsing fails', async () => { + await expect(combineTools(automatedTools, manualToolsWithInvalidURLT11, toolsPath, tagsPath)) + .rejects.toThrow('Invalid URL'); + }); + + it('should handle errors when processing tools with circular references', async () => { + circularTool.circular = circularTool; + await expect(combineTools(automatedToolsT12, {}, toolsPath, tagsPath)) + .rejects.toThrow('Converting circular structure to JSON'); + }); + +}); diff --git a/tests/tools/tools-object.test.js b/tests/tools/tools-object.test.js new file mode 100644 index 000000000000..2577a2a27d94 --- /dev/null +++ b/tests/tools/tools-object.test.js @@ -0,0 +1,161 @@ +const axios = require('axios'); +const { convertTools, createToolObject } = require('../../scripts/tools/tools-object'); +const { + createToolFileContent, + createExpectedToolObject, + createMockData, + createMalformedYAML +} = require('../helper/toolsObjectData'); + +jest.mock('axios'); +jest.mock('../../scripts/tools/categorylist', () => ({ + categoryList: [ + { name: 'Category1', tag: 'Category1', description: 'Description for Category1' }, + { name: 'Others', tag: 'Others', description: 'Other tools category' }, + ] +})); + +describe('Tools Object', () => { + beforeEach(() => { + axios.get.mockClear(); + console.error = jest.fn(); + }); + + const mockToolData = (toolContent, toolNames = ['valid-tool']) => { + const mockData = createMockData(toolNames.map((name) => ({ name: `.asyncapi-tool-${name}`, repoName: name }))); + axios.get.mockResolvedValue({ data: toolContent }); + return mockData; + }; + + it('should create a tool object with provided parameters', async () => { + const toolFile = createToolFileContent({ + title: 'Test Tool', + description: 'Test Description', + hasCommercial: true, + additionalLinks: { docsUrl: 'https://docs.example.com' } + }); + + const expected = createExpectedToolObject({ + title: 'Test Tool', + description: 'Test Description', + hasCommercial: true, + additionalLinks: { docsUrl: 'https://docs.example.com' } + }); + + const result = await createToolObject( + toolFile, + expected.links.repoUrl, + 'Repository Description', + true + ); + + expect(result).toEqual(expected); + }); + + it('should convert tools data correctly', async () => { + const toolContent = createToolFileContent({ title: 'Valid Tool', categories: ['Category1'] }); + const mockData = mockToolData(toolContent); + + const result = await convertTools(mockData); + + expect(result.Category1.toolsList).toHaveLength(1); + expect(result.Category1.toolsList[0].title).toBe('Valid Tool'); + }); + + it('should assign tool to Others category if no matching category is found', async () => { + const toolContent = createToolFileContent({ title: 'Unknown Category Tool', categories: ['UnknownCategory'] }); + const mockData = mockToolData(toolContent); + + const result = await convertTools(mockData); + + expect(result.Others.toolsList).toHaveLength(1); + expect(result.Others.toolsList[0].title).toBe('Unknown Category Tool'); + }); + + it('should log errors for invalid .asyncapi-tool file', async () => { + const invalidContent = createToolFileContent({ + title: 'Invalid Tool', + additionalFilters: { invalidField: true } + }); + const mockData = mockToolData(invalidContent); + + await convertTools(mockData); + + expect(console.error).toHaveBeenCalledWith(expect.stringContaining('Script is not failing')); + expect(console.error).toHaveBeenCalledWith(expect.stringContaining('Invalid .asyncapi-tool file')); + }); + + it('should add duplicate tool objects to the same category', async () => { + const toolContent = createToolFileContent({ + title: 'Duplicate Tool', + categories: ['Category1'] + }); + + const mockData = createMockData([ + { name: '.asyncapi-tool-dup1', repoName: 'dup1' }, + { name: '.asyncapi-tool-dup2', repoName: 'dup2' } + ]); + + axios.get.mockResolvedValue({ data: toolContent }); + + const result = await convertTools(mockData); + + expect(result.Category1.toolsList).toHaveLength(2); + expect(result.Category1.toolsList[0].title).toBe('Duplicate Tool'); + expect(result.Category1.toolsList[1].title).toBe('Duplicate Tool'); + }); + + it('should add tool to Others category only once', async () => { + const toolContent = createToolFileContent({ + title: 'Duplicate Tool in Others', + categories: ['UnknownCategory'] + }); + + const mockData = mockToolData(toolContent); + + const result = await convertTools(mockData); + + expect(result.Others.toolsList).toHaveLength(1); + expect(result.Others.toolsList[0].title).toBe('Duplicate Tool in Others'); + }); + + it('should throw an error if axios.get fails', async () => { + const mockData = createMockData([{ + name: '.asyncapi-tool-error', + repoName: 'error-tool' + }]); + + axios.get.mockRejectedValue(new Error('Network Error')); + + await expect(convertTools(mockData)).rejects.toThrow('Network Error'); + }); + + it('should handle malformed JSON in tool file', async () => { + const malformedContent = createMalformedYAML(); + await expect(convertTools(malformedContent)).rejects.toThrow(); + }); + + it('should use repository description when tool description is missing', async () => { + const toolFile = createToolFileContent({ + title: 'No Description Tool', + description: '', + }); + + const repositoryDescription = 'Fallback Repository Description'; + const mockData = createMockData([{ + name: '.asyncapi-tool-no-description', + repoName: 'no-description', + description: repositoryDescription + }]); + + axios.get.mockResolvedValue({ data: toolFile }); + + const result = await convertTools(mockData); + + const toolObject = result.Category1.toolsList[0]; + + expect(toolObject.description).toBe(repositoryDescription); + expect(toolObject.title).toBe('No Description Tool'); + }); + +});