├── .all-contributorsrc ├── .changeset └── config.json ├── .coderabbit.yaml ├── .dockerignore ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .github ├── pull-request-template.md └── workflows │ ├── add-good-first-issue-labels.yml │ ├── automerge-for-humans-add-ready-to-merge-or-do-not-merge-label.yml │ ├── automerge-for-humans-merging.yml │ ├── automerge-for-humans-remove-ready-to-merge-label-on-edit.yml │ ├── automerge-orphans.yml │ ├── automerge.yml │ ├── autoupdate.yml │ ├── bounty-program-commands.yml │ ├── bump.yml │ ├── help-command.yml │ ├── if-nodejs-pr-testing.yml │ ├── issues-prs-notifications.yml │ ├── lint-pr-title.yml │ ├── local-generate-files.yml │ ├── notify-tsc-members-mention.yml │ ├── please-take-a-look-command.yml │ ├── pr-testing-with-test-project.yml │ ├── release-announcements.yml │ ├── release-docker.yml │ ├── release-with-changesets.yml │ ├── scripts │ ├── README.md │ └── mailchimp │ │ ├── htmlContent.js │ │ ├── index.js │ │ ├── package-lock.json │ │ └── package.json │ ├── stale-issues-prs.yml │ ├── transfer-issue.yml │ ├── update-docs-in-website.yml │ ├── update-docs-on-docs-commits.yml │ ├── update-maintainers-trigger.yaml │ ├── update-maintainers.yml │ ├── update-pr.yml │ └── welcome-first-time-contrib.yml ├── .gitignore ├── .npmignore ├── .npmrc ├── .npmrc.template ├── .prettierignore ├── .releaserc ├── .sonarcloud.properties ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Development.md ├── Dockerfile ├── LICENSE ├── README.md ├── apps ├── generator │ ├── .dockerignore │ ├── .gitignore │ ├── CHANGELOG.md │ ├── Dockerfile │ ├── README.md │ ├── cli.js │ ├── docs │ │ ├── README.md │ │ ├── api.md │ │ ├── asyncapi-document.md │ │ ├── configuration-file.md │ │ ├── file-templates.md │ │ ├── generator-template-java.md │ │ ├── generator-template.md │ │ ├── hooks.md │ │ ├── index.md │ │ ├── installation-guide.md │ │ ├── jsdoc2md-handlebars │ │ │ ├── custom-sig-name.hbs │ │ │ ├── defaultvalue.hbs │ │ │ ├── header.hbs │ │ │ ├── link.hbs │ │ │ ├── main.hbs │ │ │ └── params-table.hbs │ │ ├── migration-cli.md │ │ ├── migration-nunjucks-react.md │ │ ├── model-generation.md │ │ ├── nunjucks-render-engine.md │ │ ├── parser.md │ │ ├── react-render-engine.md │ │ ├── special-file-names.md │ │ ├── template-context.md │ │ ├── template-development.md │ │ ├── template.md │ │ ├── typescript-support.md │ │ ├── usage.md │ │ ├── using-private-template.md │ │ └── versioning.md │ ├── jest.config.js │ ├── lib │ │ ├── __mocks__ │ │ │ ├── filtersRegistry.js │ │ │ ├── hooksRegistry.js │ │ │ ├── templateConfigValidator.js │ │ │ └── utils.js │ │ ├── conditionalGeneration.js │ │ ├── filtersRegistry.js │ │ ├── generator.js │ │ ├── hooksRegistry.js │ │ ├── logMessages.js │ │ ├── parser.js │ │ ├── renderer │ │ │ ├── nunjucks.js │ │ │ └── react.js │ │ ├── templateConfigValidator.js │ │ ├── utils.js │ │ └── watcher.js │ ├── package.json │ └── test │ │ ├── __mocks__ │ │ ├── @npmcli │ │ │ ├── arborist.js │ │ │ └── config.js │ │ ├── fs.extra.js │ │ ├── loglevel.js │ │ ├── resolve-from.js │ │ └── resolve-pkg.js │ │ ├── __snapshots__ │ │ └── integration.test.js.snap │ │ ├── docs │ │ ├── apiwithref.json │ │ ├── dummy.yml │ │ ├── dummyV3.yml │ │ ├── shared.json │ │ └── ws.yml │ │ ├── generator.test.js │ │ ├── hooksRegistry.test.js │ │ ├── integration.test.js │ │ ├── parser.test.js │ │ ├── renderer.test.js │ │ ├── templateConfigValidator.test.js │ │ ├── test-project │ │ ├── .npmrc │ │ ├── .yarncr.yml │ │ ├── README.md │ │ ├── docker-compose.yml │ │ ├── package.json │ │ ├── test-global.test.js │ │ ├── test-project.test.js │ │ ├── test-registry.test.js │ │ ├── test.sh │ │ └── verdaccio │ │ │ ├── config.yaml │ │ │ └── htpasswd │ │ ├── test-templates │ │ ├── nunjucks-template │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ └── template │ │ │ │ └── test-file.md │ │ └── react-template │ │ │ ├── .ageneratorrc │ │ │ ├── package.json │ │ │ └── template │ │ │ ├── conditionalFile.txt │ │ │ ├── conditionalFolder │ │ │ └── conditionalFile.txt │ │ │ ├── conditionalFolder2 │ │ │ └── input.txt │ │ │ ├── models.js │ │ │ └── test-file.md.js │ │ └── utils.test.js ├── hooks │ ├── package.json │ ├── src │ │ └── index.js │ └── test │ │ └── index.test.js └── nunjucks-filters │ ├── docs │ └── api.md │ ├── package.json │ └── src │ ├── customFilters.js │ ├── customFilters.test.js │ ├── index.js │ ├── lodashFilters.js │ └── lodashFilters.test.js ├── assets └── readme-banner.png ├── docker-compose.yaml ├── package-lock.json ├── package.json ├── packages ├── .gitignore ├── README.md ├── components │ ├── .gitignore │ ├── package.json │ ├── src │ │ ├── components │ │ │ └── models.js │ │ └── index.js │ └── test │ │ ├── __fixtures__ │ │ └── asyncapi-v3.yml │ │ └── components │ │ ├── __snapshots__ │ │ └── models.test.js.snap │ │ └── models.test.js ├── helpers │ ├── package.json │ ├── src │ │ ├── bindings.js │ │ ├── index.js │ │ ├── operations.js │ │ ├── servers.js │ │ └── utils.js │ └── test │ │ ├── __fixtures__ │ │ └── asyncapi-websocket-query.yml │ │ ├── operations.test.js │ │ ├── servers.test.js │ │ └── utils.test.js └── templates │ └── clients │ └── websocket │ ├── dart │ ├── .ageneratorrc │ ├── README.md │ ├── components │ │ ├── ClientClass.js │ │ ├── ClientFields.js │ │ ├── CloseConnection.js │ │ ├── Connect.js │ │ ├── Constructor.js │ │ ├── FileHeaderInfo.js │ │ ├── HandleMessage.js │ │ ├── RegisterErrorHandler.js │ │ ├── RegisterMessageHandler.js │ │ ├── Requires.js │ │ └── SendEchoMessage.js │ ├── example.dart │ ├── package.json │ ├── template │ │ ├── client.dart.js │ │ └── pubspec.yaml.js │ └── test │ │ ├── __snapshots__ │ │ └── integration.test.js.snap │ │ └── integration.test.js │ ├── javascript │ ├── .ageneratorrc │ ├── README.md │ ├── components │ │ ├── AvailableOperations.js │ │ ├── ClientClass.js │ │ ├── CloseConnection.js │ │ ├── Connect.js │ │ ├── Constructor.js │ │ ├── FileHeaderInfo.js │ │ ├── HandleMessage.js │ │ ├── MessageExamples.js │ │ ├── ModuleExport.js │ │ ├── OperationHeader.js │ │ ├── RegisterErrorHandler.js │ │ ├── RegisterMessageHandler.js │ │ ├── Requires.js │ │ └── SendOperation.js │ ├── example.js │ ├── package.json │ ├── template │ │ ├── README.md.js │ │ └── client.js.js │ └── test │ │ ├── __snapshots__ │ │ └── integration.test.js.snap │ │ ├── components │ │ ├── AvailableOperations.test.js │ │ ├── FileHeaderInfo.test.js │ │ ├── MessageExamples.test.js │ │ ├── OperationHeader.test.js │ │ ├── SendOperation.test.js │ │ └── __snapshots__ │ │ │ ├── AvailableOperations.test.js.snap │ │ │ ├── FileHeaderInfo.test.js.snap │ │ │ ├── MessageExamples.test.js.snap │ │ │ ├── OperationHeader.test.js.snap │ │ │ └── SendOperation.test.js.snap │ │ └── integration.test.js │ ├── python │ ├── .ageneratorrc │ ├── README.md │ ├── components │ │ ├── ClientClass.js │ │ ├── CloseConnection.js │ │ ├── Connect.js │ │ ├── Constructor.js │ │ ├── FileHeaderInfo.js │ │ ├── HandleError.js │ │ ├── HandleMessage.js │ │ ├── InitSignature.js │ │ ├── QueryParamsArgumentsDocs.js │ │ ├── QueryParamsVariables.js │ │ ├── RegisterErrorHandler.js │ │ ├── RegisterMessageHandler.js │ │ ├── RegisterOutgoingProcessor.js │ │ ├── Requires.js │ │ ├── Send.js │ │ └── SendOperation.js │ ├── example-slack.py │ ├── example.py │ ├── package.json │ ├── template │ │ ├── client.py.js │ │ ├── models.js │ │ └── requirements.txt.js │ └── test │ │ ├── __snapshots__ │ │ └── integration.test.js.snap │ │ ├── components │ │ ├── Constructor.test.js │ │ ├── InitSignature.test.js │ │ ├── QueryParamsArgumentsDocs.test.js │ │ ├── SendOperation.test.js │ │ └── __snapshots__ │ │ │ ├── Constructor.test.js.snap │ │ │ ├── InitSignature.test.js.snap │ │ │ ├── QueryParamsArgumentsDocs.test.js.snap │ │ │ └── SendOperation.test.js.snap │ │ └── integration.test.js │ └── test │ ├── README.md │ ├── __fixtures__ │ ├── asyncapi-hoppscotch-client.yml │ ├── asyncapi-hoppscotch-server.yml │ ├── asyncapi-postman-echo.yml │ ├── asyncapi-slack-client.yml │ └── commons │ │ ├── channels.yml │ │ ├── messages.yml │ │ ├── schemas.yml │ │ └── servers.yml │ ├── javascript │ ├── acceptance.test.js │ ├── package.json │ └── utils.js │ ├── microcks-setup │ ├── checkMicrocksReady.sh │ ├── config │ │ ├── application.properties │ │ └── features.properties │ └── microcks-podman.yml │ └── python │ ├── requirements.txt │ └── test_acceptance.py └── turbo.json /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": ["@changesets/changelog-git", { "repo": "asyncapi/generator" }], 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "master", 9 | "updateInternalDependencies": "patch", 10 | "privatePackages": { 11 | "version": true, 12 | "tag": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.coderabbit.yaml: -------------------------------------------------------------------------------- 1 | # CodeRabbit Configuration File 2 | 3 | language: en-US 4 | reviews: 5 | poem: false 6 | suggested_reviewers: false 7 | suggested_labels: false 8 | sequence_diagrams: false 9 | high_level_summary: true 10 | high_level_summary_placeholder: "@coderabbitai summary" 11 | profile: chill 12 | auto_review: 13 | enabled: true 14 | auto_incremental_review: true 15 | review_status: true 16 | commit_status: true 17 | changed_files_summary: true 18 | assess_linked_issues: true 19 | related_issues: true 20 | related_prs: true 21 | chat: 22 | auto_reply: false 23 | 24 | knowledge_base: 25 | learnings: 26 | scope: auto 27 | issues: 28 | scope: auto 29 | pull_requests: 30 | scope: auto 31 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Node modules 2 | **/node_modules 3 | npm-debug.log 4 | yarn-debug.log 5 | yarn-error.log 6 | 7 | # Environment variables 8 | .env 9 | .env.* 10 | 11 | # Build files 12 | dist 13 | build 14 | *.tgz 15 | 16 | # Git 17 | .git 18 | .gitignore 19 | 20 | # IDE files 21 | .idea 22 | .vscode 23 | *.sublime-project 24 | *.sublime-workspace 25 | 26 | # Logs 27 | logs 28 | *.log 29 | 30 | # OS specific 31 | .DS_Store 32 | Thumbs.db 33 | 34 | # Testing 35 | **/coverage 36 | .nyc_output 37 | test-results 38 | 39 | **/Dockerfile 40 | **/docker-compose*.yml 41 | **/docker-compose*.yaml 42 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig 2 | 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [Makefile] 14 | indent_style = tab 15 | 16 | [*.md] 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | apps/generator/output/* 2 | **/node_modules/ 3 | **/temp/* 4 | **/__transpiled/* 5 | packages/components/lib/* 6 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | es6: true 4 | jest/globals: true 5 | 6 | plugins: 7 | - sonarjs 8 | - jest 9 | - react 10 | 11 | extends: 12 | - plugin:react/recommended 13 | - plugin:sonarjs/recommended 14 | 15 | parserOptions: 16 | ecmaVersion: 2020 17 | sourceType: module 18 | ecmaFeatures: 19 | jsx: true 20 | settings: 21 | react: 22 | version: detect 23 | 24 | rules: 25 | # Ignore Rules 26 | strict: 0 27 | no-underscore-dangle: 0 28 | no-mixed-requires: 0 29 | no-process-exit: 0 30 | no-warning-comments: 0 31 | curly: 0 32 | no-multi-spaces: 0 33 | no-alert: 0 34 | consistent-return: 0 35 | consistent-this: [0, self] 36 | func-style: 0 37 | max-nested-callbacks: 0 38 | camelcase: 0 39 | 40 | # Warnings 41 | no-debugger: 1 42 | no-empty: 1 43 | no-invalid-regexp: 1 44 | no-unused-expressions: 1 45 | no-native-reassign: 1 46 | no-fallthrough: 1 47 | sonarjs/cognitive-complexity: 1 48 | 49 | # Errors 50 | eqeqeq: 2 51 | no-undef: 2 52 | no-dupe-keys: 2 53 | no-empty-character-class: 2 54 | no-self-compare: 2 55 | valid-typeof: 2 56 | no-unused-vars: [2, { "args": "none" }] 57 | handle-callback-err: 2 58 | no-shadow-restricted-names: 2 59 | no-new-require: 2 60 | no-mixed-spaces-and-tabs: 2 61 | block-scoped-var: 2 62 | no-else-return: 2 63 | no-throw-literal: 2 64 | no-void: 2 65 | radix: 2 66 | wrap-iife: [2, outside] 67 | no-shadow: 0 68 | no-use-before-define: [2, nofunc] 69 | no-path-concat: 2 70 | valid-jsdoc: [0, {requireReturn: false, requireParamDescription: false, requireReturnDescription: false}] 71 | 72 | # stylistic errors 73 | no-spaced-func: 2 74 | semi-spacing: 2 75 | quotes: [2, 'single'] 76 | key-spacing: [2, { beforeColon: false, afterColon: true }] 77 | indent: [2, 2] 78 | no-lonely-if: 2 79 | no-floating-decimal: 2 80 | brace-style: [2, 1tbs, { allowSingleLine: true }] 81 | comma-style: [2, last] 82 | no-multiple-empty-lines: [2, {max: 1}] 83 | no-nested-ternary: 2 84 | operator-assignment: [2, always] 85 | padded-blocks: [2, never] 86 | quote-props: [2, as-needed] 87 | keyword-spacing: [2, {'before': true, 'after': true, 'overrides': {}}] 88 | space-before-blocks: [2, always] 89 | array-bracket-spacing: [2, never] 90 | computed-property-spacing: [2, never] 91 | space-in-parens: [2, never] 92 | space-unary-ops: [2, {words: true, nonwords: false}] 93 | wrap-regex: 2 94 | linebreak-style: 0 95 | semi: [2, always] 96 | arrow-spacing: [2, {before: true, after: true}] 97 | no-class-assign: 2 98 | no-const-assign: 2 99 | no-dupe-class-members: 2 100 | no-this-before-super: 2 101 | no-var: 2 102 | object-shorthand: [2, always] 103 | prefer-arrow-callback: 2 104 | prefer-const: 2 105 | prefer-spread: 2 106 | prefer-template: 2 107 | 108 | # React 109 | react/jsx-uses-react: off 110 | react/react-in-jsx-scope: off 111 | react/display-name: off 112 | react/prop-types: off 113 | react/jsx-key: off 114 | react/no-unescaped-entities: off -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ensure script files have LF line endings 2 | *.sh text eol=lf 3 | *.bash text eol=lf 4 | -------------------------------------------------------------------------------- /.github/pull-request-template.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | **Description** 8 | 9 | - ... 10 | - ... 11 | - ... 12 | 13 | **Related issue(s)** 14 | -------------------------------------------------------------------------------- /.github/workflows/automerge-for-humans-remove-ready-to-merge-label-on-edit.yml: -------------------------------------------------------------------------------- 1 | # This workflow is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | # Defence from evil contributor that after adding `ready-to-merge` all suddenly makes evil commit or evil change in PR title 5 | # Label is removed once above action is detected 6 | name: Remove ready-to-merge label 7 | 8 | on: 9 | pull_request_target: 10 | types: 11 | - synchronize 12 | - edited 13 | 14 | jobs: 15 | remove-ready-label: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Remove label 19 | uses: actions/github-script@v6 20 | with: 21 | github-token: ${{ secrets.GH_TOKEN }} 22 | script: | 23 | const labelToRemove = 'ready-to-merge'; 24 | const labels = context.payload.pull_request.labels; 25 | const isLabelPresent = labels.some(label => label.name === labelToRemove) 26 | if(!isLabelPresent) return; 27 | github.rest.issues.removeLabel({ 28 | issue_number: context.issue.number, 29 | owner: context.repo.owner, 30 | repo: context.repo.repo, 31 | name: labelToRemove 32 | }) 33 | -------------------------------------------------------------------------------- /.github/workflows/automerge-orphans.yml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | name: 'Notify on failing automerge' 5 | 6 | on: 7 | schedule: 8 | - cron: "0 0 * * *" 9 | 10 | jobs: 11 | identify-orphans: 12 | if: startsWith(github.repository, 'asyncapi/') 13 | name: Find orphans and notify 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v3 18 | - name: Get list of orphans 19 | uses: actions/github-script@v6 20 | id: orphans 21 | with: 22 | github-token: ${{ secrets.GITHUB_TOKEN }} 23 | script: | 24 | const query = `query($owner:String!, $name:String!) { 25 | repository(owner:$owner, name:$name){ 26 | pullRequests(first: 100, states: OPEN){ 27 | nodes{ 28 | title 29 | url 30 | author { 31 | resourcePath 32 | } 33 | } 34 | } 35 | } 36 | }`; 37 | const variables = { 38 | owner: context.repo.owner, 39 | name: context.repo.repo 40 | }; 41 | const { repository: { pullRequests: { nodes } } } = await github.graphql(query, variables); 42 | 43 | let orphans = nodes.filter( (pr) => pr.author.resourcePath === '/asyncapi-bot' || pr.author.resourcePath === '/apps/dependabot') 44 | 45 | if (orphans.length) { 46 | core.setOutput('found', 'true'); 47 | //Yes, this is very naive approach to assume there is just one PR causing issues, there can be a case that more PRs are affected the same day 48 | //The thing is that handling multiple PRs will increase a complexity in this PR that in my opinion we should avoid 49 | //The other PRs will be reported the next day the action runs, or person that checks first url will notice the other ones 50 | core.setOutput('url', orphans[0].url); 51 | core.setOutput('title', orphans[0].title); 52 | } 53 | - if: steps.orphans.outputs.found == 'true' 54 | name: Convert markdown to slack markdown 55 | uses: asyncapi/.github/.github/actions/slackify-markdown@master 56 | id: issuemarkdown 57 | with: 58 | markdown: "-> [${{steps.orphans.outputs.title}}](${{steps.orphans.outputs.url}})" 59 | - if: steps.orphans.outputs.found == 'true' 60 | name: Send info about orphan to slack 61 | uses: rtCamp/action-slack-notify@v2 62 | env: 63 | SLACK_WEBHOOK: ${{secrets.SLACK_CI_FAIL_NOTIFY}} 64 | SLACK_TITLE: 🚨 Not merged PR that should be automerged 🚨 65 | SLACK_MESSAGE: ${{steps.issuemarkdown.outputs.text}} 66 | MSG_MINIMAL: true -------------------------------------------------------------------------------- /.github/workflows/automerge.yml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo. 3 | 4 | name: Automerge PRs from bots 5 | 6 | on: 7 | pull_request_target: 8 | types: 9 | - opened 10 | - synchronize 11 | 12 | jobs: 13 | autoapprove-for-bot: 14 | name: Autoapprove PR comming from a bot 15 | if: > 16 | contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]"]'), github.event.pull_request.user.login) && 17 | contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]"]'), github.actor) && 18 | !contains(github.event.pull_request.labels.*.name, 'released') 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Autoapproving 22 | uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 is used https://github.com/hmarr/auto-approve-action/releases/tag/v3.2.1 23 | with: 24 | github-token: "${{ secrets.GH_TOKEN_BOT_EVE }}" 25 | 26 | - name: Label autoapproved 27 | uses: actions/github-script@v6 28 | with: 29 | github-token: ${{ secrets.GH_TOKEN }} 30 | script: | 31 | github.rest.issues.addLabels({ 32 | issue_number: context.issue.number, 33 | owner: context.repo.owner, 34 | repo: context.repo.repo, 35 | labels: ['autoapproved', 'autoupdate'] 36 | }) 37 | 38 | automerge-for-bot: 39 | name: Automerge PR autoapproved by a bot 40 | needs: [autoapprove-for-bot] 41 | runs-on: ubuntu-latest 42 | steps: 43 | - name: Automerging 44 | uses: pascalgn/automerge-action@22948e0bc22f0aa673800da838595a3e7347e584 #v0.15.6 https://github.com/pascalgn/automerge-action/releases/tag/v0.15.6 45 | env: 46 | GITHUB_TOKEN: "${{ secrets.GH_TOKEN }}" 47 | GITHUB_LOGIN: asyncapi-bot 48 | MERGE_LABELS: "!do-not-merge" 49 | MERGE_METHOD: "squash" 50 | MERGE_COMMIT_MESSAGE: "{pullRequest.title} (#{pullRequest.number})" 51 | MERGE_RETRIES: "20" 52 | MERGE_RETRY_SLEEP: "30000" 53 | -------------------------------------------------------------------------------- /.github/workflows/autoupdate.yml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | # This workflow is designed to work with: 5 | # - autoapprove and automerge workflows for dependabot and asyncapibot. 6 | # - special release branches that we from time to time create in upstream repos. If we open up PRs for them from the very beginning of the release, the release branch will constantly update with new things from the destination branch they are opened against 7 | 8 | # It uses GitHub Action that auto-updates pull requests branches, whenever changes are pushed to their destination branch. 9 | # Autoupdating to latest destination branch works only in the context of upstream repo and not forks 10 | 11 | name: autoupdate 12 | 13 | on: 14 | push: 15 | branches-ignore: 16 | - 'version-bump/**' 17 | - 'dependabot/**' 18 | - 'bot/**' 19 | - 'all-contributors/**' 20 | 21 | jobs: 22 | autoupdate-for-bot: 23 | if: startsWith(github.repository, 'asyncapi/') 24 | name: Autoupdate autoapproved PR created in the upstream 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: Autoupdating 28 | uses: docker://chinthakagodawita/autoupdate-action:v1 29 | env: 30 | GITHUB_TOKEN: '${{ secrets.GH_TOKEN_BOT_EVE }}' 31 | PR_FILTER: "labelled" 32 | PR_LABELS: "autoupdate" 33 | PR_READY_STATE: "ready_for_review" 34 | MERGE_CONFLICT_ACTION: "ignore" 35 | -------------------------------------------------------------------------------- /.github/workflows/bump.yml: -------------------------------------------------------------------------------- 1 | name: Bump package version in dependent repos 2 | 3 | on: 4 | # It cannot run on release event as when release is created then version is not yet bumped in package.json 5 | # This means we cannot extract easily latest version and have a risk that package is not yet on npm 6 | push: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | bump-in-dependent-projects: 12 | name: Bump this package in repositories that depend on it 13 | if: startsWith(github.event.commits[0].message, 'chore(release):') 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repo 17 | uses: actions/checkout@v3 18 | - name: Bumping latest version of this package in other repositories 19 | uses: derberg/npm-dependency-manager-for-your-github-org@1eafd3bf3974f21d395c1abac855cb04b295d570 # using v6.-.- https://github.com/derberg/npm-dependency-manager-for-your-github-org/releases/tag/v6 20 | with: 21 | github_token: ${{ secrets.GH_TOKEN }} 22 | committer_username: asyncapi-bot 23 | committer_email: info@asyncapi.io 24 | repos_to_ignore: spec,bindings,saunter,server-api 25 | packagejson_path: ./apps/generator 26 | custom_id: "dependency update from asyncapi bot" 27 | -------------------------------------------------------------------------------- /.github/workflows/lint-pr-title.yml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | name: Lint PR title 5 | 6 | on: 7 | pull_request_target: 8 | types: [opened, reopened, synchronize, edited, ready_for_review] 9 | 10 | jobs: 11 | lint-pr-title: 12 | name: Lint PR title 13 | runs-on: ubuntu-latest 14 | steps: 15 | # Since this workflow is REQUIRED for a PR to be mergable, we have to have this 'if' statement in step level instead of job level. 16 | - if: ${{ !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor) }} 17 | uses: amannn/action-semantic-pull-request@c3cd5d1ea3580753008872425915e343e351ab54 #version 5.2.0 https://github.com/amannn/action-semantic-pull-request/releases/tag/v5.2.0 18 | id: lint_pr_title 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} 21 | with: 22 | subjectPattern: ^(?![A-Z]).+$ 23 | subjectPatternError: | 24 | The subject "{subject}" found in the pull request title "{title}" should start with a lowercase character. 25 | 26 | # Comments the error message from the above lint_pr_title action 27 | - if: ${{ always() && steps.lint_pr_title.outputs.error_message != null && !contains(fromJson('["asyncapi-bot", "dependabot[bot]", "dependabot-preview[bot]", "allcontributors[bot]"]'), github.actor)}} 28 | name: Comment on PR 29 | uses: marocchino/sticky-pull-request-comment@3d60a5b2dae89d44e0c6ddc69dd7536aec2071cd #use 2.5.0 https://github.com/marocchino/sticky-pull-request-comment/releases/tag/v2.5.0 30 | with: 31 | header: pr-title-lint-error 32 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} 33 | message: | 34 | 35 | We require all PRs to follow [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/). 36 | More details 👇🏼 37 | ``` 38 | ${{ steps.lint_pr_title.outputs.error_message}} 39 | ``` 40 | # deletes the error comment if the title is correct 41 | - if: ${{ steps.lint_pr_title.outputs.error_message == null }} 42 | name: delete the comment 43 | uses: marocchino/sticky-pull-request-comment@3d60a5b2dae89d44e0c6ddc69dd7536aec2071cd #use 2.5.0 https://github.com/marocchino/sticky-pull-request-comment/releases/tag/v2.5.0 44 | with: 45 | header: pr-title-lint-error 46 | delete: true 47 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN}} 48 | -------------------------------------------------------------------------------- /.github/workflows/local-generate-files.yml: -------------------------------------------------------------------------------- 1 | # this workflow runs after releases to generate some files like for example api.md 2 | name: Autogenerate API files 3 | 4 | on: 5 | release: 6 | types: 7 | - published 8 | 9 | jobs: 10 | version_bump: 11 | name: Generate assets and bump NodeJS 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v3 16 | with: 17 | # target branch of release. More info https://docs.github.com/en/rest/reference/repos#releases 18 | # in case release is created from release branch then we need to checkout from given branch 19 | # if @semantic-release/github is used to publish, the minimum version is 7.2.0 for proper working 20 | ref: ${{ github.event.release.target_commitish }} 21 | - name: Check package-lock version 22 | uses: asyncapi/.github/.github/actions/get-node-version-from-package-lock@master 23 | id: lockversion 24 | - name: Setup Node.js 25 | uses: actions/setup-node@v3 26 | with: 27 | node-version: "${{ steps.lockversion.outputs.version }}" 28 | - name: Install dependencies 29 | run: npm ci 30 | - name: Assets generation 31 | run: npm run generate:assets --if-present 32 | - name: Create Pull Request with updated asset files including package.json 33 | uses: peter-evans/create-pull-request@38e0b6e68b4c852a5500a94740f0e535e0d7ba54 # use 4.2.4 https://github.com/peter-evans/create-pull-request/releases/tag/v4.2.4 34 | with: 35 | token: ${{ secrets.GH_TOKEN }} 36 | commit-message: 'chore(release): ${{github.event.release.tag_name}}' 37 | committer: asyncapi-bot 38 | author: asyncapi-bot 39 | title: 'chore: update assets' 40 | body: 'Updating assets like for example API.md, but not only, that shoudl be generated and not manually updated' 41 | branch: assets-update/${{github.event.release.tag_name}} 42 | - if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel 43 | name: Report workflow run status to Slack 44 | uses: 8398a7/action-slack@v3 45 | with: 46 | status: ${{ job.status }} 47 | fields: repo,action,workflow 48 | text: 'Unable to bump the version in package.json after the release' 49 | env: 50 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }} 51 | -------------------------------------------------------------------------------- /.github/workflows/please-take-a-look-command.yml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | # It uses Github actions to listen for comments on issues and pull requests and 5 | # if the comment contains /please-take-a-look or /ptal it will add a comment pinging 6 | # the code-owners who are reviewers for PR 7 | 8 | name: Please take a Look 9 | 10 | on: 11 | issue_comment: 12 | types: [created] 13 | 14 | jobs: 15 | ping-for-attention: 16 | if: > 17 | github.event.issue.pull_request && 18 | github.event.issue.state != 'closed' && 19 | github.actor != 'asyncapi-bot' && 20 | ( 21 | contains(github.event.comment.body, '/please-take-a-look') || 22 | contains(github.event.comment.body, '/ptal') || 23 | contains(github.event.comment.body, '/PTAL') 24 | ) 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: Check for Please Take a Look Command 28 | uses: actions/github-script@v6 29 | with: 30 | github-token: ${{ secrets.GH_TOKEN }} 31 | script: | 32 | const prDetailsUrl = context.payload.issue.pull_request.url; 33 | const { data: pull } = await github.request(prDetailsUrl); 34 | const reviewers = pull.requested_reviewers.map(reviewer => reviewer.login); 35 | 36 | const { data: reviews } = await github.rest.pulls.listReviews({ 37 | owner: context.repo.owner, 38 | repo: context.repo.repo, 39 | pull_number: context.issue.number 40 | }); 41 | 42 | const reviewersWhoHaveReviewed = reviews.map(review => review.user.login); 43 | 44 | const reviewersWhoHaveNotReviewed = reviewers.filter(reviewer => !reviewersWhoHaveReviewed.includes(reviewer)); 45 | 46 | if (reviewersWhoHaveNotReviewed.length > 0) { 47 | const comment = reviewersWhoHaveNotReviewed.filter(reviewer => reviewer !== 'asyncapi-bot-eve' ).map(reviewer => `@${reviewer}`).join(' '); 48 | await github.rest.issues.createComment({ 49 | issue_number: context.issue.number, 50 | owner: context.repo.owner, 51 | repo: context.repo.repo, 52 | body: `${comment} Please take a look at this PR. Thanks! :wave:` 53 | }); 54 | } 55 | -------------------------------------------------------------------------------- /.github/workflows/release-docker.yml: -------------------------------------------------------------------------------- 1 | name: Release Docker Image 2 | on: 3 | release: 4 | types: 5 | - published 6 | 7 | jobs: 8 | 9 | release: 10 | name: Docker build and push 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Get version without v character 14 | id: version 15 | run: | 16 | VERSION=${{github.event.release.tag_name}} 17 | VERSION_WITHOUT_V=${VERSION##*@} 18 | echo "value=${VERSION_WITHOUT_V}" >> $GITHUB_OUTPUT 19 | 20 | - name: Set Up QEMU 21 | uses: docker/setup-qemu-action@v2 22 | 23 | - name: Set Up Docker Buildx 24 | uses: docker/setup-buildx-action@v2 25 | 26 | - name: login to Docker Hub 27 | uses: docker/login-action@v2 28 | with: 29 | username: ${{ secrets.DOCKER_USERNAME }} 30 | password: ${{ secrets.DOCKER_PASSWORD }} 31 | 32 | # This workflow triggers on GitHub Release, but it may start before the npm package is published. 33 | - name: Sleep for 1s seconds 34 | run: sleep 1s 35 | 36 | - name: Build Image 37 | uses: docker/build-push-action@v4 38 | with: 39 | context: "{{defaultContext}}:apps/generator" 40 | push: true 41 | load: false 42 | build-args: | 43 | ASYNCAPI_GENERATOR_VERSION=${{ steps.version.outputs.value }} 44 | tags: | 45 | asyncapi/generator:${{ steps.version.outputs.value }} 46 | asyncapi/generator:latest 47 | platforms: linux/amd64,linux/arm64 48 | cache-from: type=gha 49 | cache-to: type=gha 50 | 51 | - name: Check out the repository 52 | uses: actions/checkout@v4 53 | 54 | - name: Update Docker Hub Readme 55 | uses: meeDamian/sync-readme@v1.0.6 56 | with: 57 | user: ${{ secrets.DOCKER_USERNAME }} 58 | pass: ${{ secrets.DOCKER_PASSWORD }} 59 | slug: asyncapi/generator 60 | readme: ./apps/generator/README.md 61 | description: Use your AsyncAPI definition to generate literally anything. Markdown documentation, Node.js code, HTML documentation, anything! 62 | -------------------------------------------------------------------------------- /.github/workflows/scripts/README.md: -------------------------------------------------------------------------------- 1 | The entire `scripts` directory is centrally managed in [.github](https://github.com/asyncapi/.github/) repository. Any changes in this folder should be done in central repository. -------------------------------------------------------------------------------- /.github/workflows/scripts/mailchimp/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This code is centrally managed in https://github.com/asyncapi/.github/ 3 | * Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 4 | */ 5 | const mailchimp = require('@mailchimp/mailchimp_marketing'); 6 | const core = require('@actions/core'); 7 | const htmlContent = require('./htmlContent.js'); 8 | 9 | /** 10 | * Sending API request to mailchimp to schedule email to subscribers 11 | * Input is the URL to issue/discussion or other resource 12 | */ 13 | module.exports = async (link, title) => { 14 | 15 | let newCampaign; 16 | 17 | mailchimp.setConfig({ 18 | apiKey: process.env.MAILCHIMP_API_KEY, 19 | server: 'us12' 20 | }); 21 | 22 | /* 23 | * First we create campaign 24 | */ 25 | try { 26 | newCampaign = await mailchimp.campaigns.create({ 27 | type: 'regular', 28 | recipients: { 29 | list_id: '6e3e437abe', 30 | segment_opts: { 31 | match: 'any', 32 | conditions: [{ 33 | condition_type: 'Interests', 34 | field: 'interests-2801e38b9f', 35 | op: 'interestcontains', 36 | value: ['f7204f9b90'] 37 | }] 38 | } 39 | }, 40 | settings: { 41 | subject_line: `TSC attention required: ${ title }`, 42 | preview_text: 'Check out the latest topic that TSC members have to be aware of', 43 | title: `New topic info - ${ new Date(Date.now()).toUTCString()}`, 44 | from_name: 'AsyncAPI Initiative', 45 | reply_to: 'info@asyncapi.io', 46 | } 47 | }); 48 | } catch (error) { 49 | return core.setFailed(`Failed creating campaign: ${ JSON.stringify(error) }`); 50 | } 51 | 52 | /* 53 | * Content of the email is added separately after campaign creation 54 | */ 55 | try { 56 | await mailchimp.campaigns.setContent(newCampaign.id, { html: htmlContent(link, title) }); 57 | } catch (error) { 58 | return core.setFailed(`Failed adding content to campaign: ${ JSON.stringify(error) }`); 59 | } 60 | 61 | /* 62 | * We schedule an email to send it immediately 63 | */ 64 | try { 65 | //schedule for next hour 66 | //so if this code was created by new issue creation at 9:46, the email is scheduled for 10:00 67 | //is it like this as schedule has limitiations and you cannot schedule email for 9:48 68 | const scheduleDate = new Date(Date.parse(new Date(Date.now()).toISOString()) + 1 * 1 * 60 * 60 * 1000); 69 | scheduleDate.setUTCMinutes(00); 70 | 71 | await mailchimp.campaigns.schedule(newCampaign.id, { 72 | schedule_time: scheduleDate.toISOString(), 73 | }); 74 | } catch (error) { 75 | return core.setFailed(`Failed scheduling email: ${ JSON.stringify(error) }`); 76 | } 77 | 78 | core.info(`New email campaign created`); 79 | } -------------------------------------------------------------------------------- /.github/workflows/scripts/mailchimp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "schedule-email", 3 | "description": "This code is responsible for scheduling an email campaign. This file is centrally managed in https://github.com/asyncapi/.github/", 4 | "license": "Apache 2.0", 5 | "dependencies": { 6 | "@actions/core": "1.6.0", 7 | "@mailchimp/mailchimp_marketing": "3.0.74" 8 | } 9 | } -------------------------------------------------------------------------------- /.github/workflows/stale-issues-prs.yml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | name: Manage stale issues and PRs 5 | 6 | on: 7 | schedule: 8 | - cron: "0 0 * * *" 9 | 10 | jobs: 11 | stale: 12 | if: startsWith(github.repository, 'asyncapi/') 13 | name: Mark issue or PR as stale 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/stale@99b6c709598e2b0d0841cd037aaf1ba07a4410bd #v5.2.0 but pointing to commit for security reasons 17 | with: 18 | repo-token: ${{ secrets.GITHUB_TOKEN }} 19 | stale-issue-message: | 20 | This issue has been automatically marked as stale because it has not had recent activity :sleeping: 21 | 22 | It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation. 23 | 24 | There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under [open governance model](https://github.com/asyncapi/community/blob/master/CHARTER.md). 25 | 26 | Let us figure out together how to push this issue forward. Connect with us through [one of many communication channels](https://github.com/asyncapi/community/issues/1) we established here. 27 | 28 | Thank you for your patience :heart: 29 | stale-pr-message: | 30 | This pull request has been automatically marked as stale because it has not had recent activity :sleeping: 31 | 32 | It will be closed in 120 days if no further activity occurs. To unstale this pull request, add a comment with detailed explanation. 33 | 34 | There can be many reasons why some specific pull request has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under [open governance model](https://github.com/asyncapi/community/blob/master/CHARTER.md). 35 | 36 | Let us figure out together how to push this pull request forward. Connect with us through [one of many communication channels](https://github.com/asyncapi/community/issues/1) we established here. 37 | 38 | Thank you for your patience :heart: 39 | days-before-stale: 120 40 | days-before-close: 120 41 | stale-issue-label: stale 42 | stale-pr-label: stale 43 | exempt-issue-labels: keep-open 44 | exempt-pr-labels: keep-open 45 | close-issue-reason: not_planned 46 | -------------------------------------------------------------------------------- /.github/workflows/transfer-issue.yml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | name: Transfer Issues between repositories 5 | 6 | on: 7 | issue_comment: 8 | types: 9 | - created 10 | 11 | permissions: 12 | issues: write 13 | 14 | jobs: 15 | transfer: 16 | if: ${{(!github.event.issue.pull_request && github.event.issue.state != 'closed' && github.actor != 'asyncapi-bot') && (startsWith(github.event.comment.body, '/transfer-issue') || startsWith(github.event.comment.body, '/ti'))}} 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout Repository 20 | uses: actions/checkout@v4 21 | - name: Extract Input 22 | id: extract_step 23 | env: 24 | COMMENT: "${{ github.event.comment.body }}" 25 | run: | 26 | REPO=$(echo $COMMENT | awk '{print $2}') 27 | echo repo=$REPO >> $GITHUB_OUTPUT 28 | - name: Check Repo 29 | uses: actions/github-script@v7 30 | with: 31 | github-token: ${{secrets.GH_TOKEN}} 32 | script: | 33 | const r = "${{github.repository}}" 34 | const [owner, repo] = r.split('/') 35 | const repoToMove = process.env.REPO_TO_MOVE 36 | const issue_number = context.issue.number 37 | try { 38 | const {data} = await github.rest.repos.get({ 39 | owner, 40 | repo: repoToMove 41 | }) 42 | }catch (e) { 43 | const body = `${repoToMove} is not a repo under ${owner}. You can only transfer issue to repos that belong to the same organization.` 44 | await github.rest.issues.createComment({ 45 | owner, 46 | repo, 47 | issue_number, 48 | body 49 | }) 50 | process.exit(1) 51 | } 52 | env: 53 | REPO_TO_MOVE: ${{steps.extract_step.outputs.repo}} 54 | - name: Transfer Issue 55 | id: transferIssue 56 | working-directory: ./ 57 | run: | 58 | gh issue transfer ${{github.event.issue.number}} asyncapi/${{steps.extract_step.outputs.repo}} 59 | env: 60 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 61 | 62 | -------------------------------------------------------------------------------- /.github/workflows/update-docs-in-website.yml: -------------------------------------------------------------------------------- 1 | name: Update latest generator documentation in the website 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | paths: 8 | - 'apps/generator/docs/*.md' 9 | - '.github/workflows/update-docs-in-website.yml' 10 | 11 | jobs: 12 | Make-PR: 13 | name: Make PR on website repository with updated latest generator documentation 14 | runs-on: ubuntu-latest 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 17 | steps: 18 | - name: Checkout Current repository 19 | uses: actions/checkout@v3 20 | with: 21 | path: generator 22 | - name: Checkout Another repository 23 | uses: actions/checkout@v3 24 | with: 25 | repository: asyncapi/website 26 | path: website 27 | token: ${{ env.GITHUB_TOKEN }} 28 | - name: Config git 29 | run: | 30 | git config --global user.name asyncapi-bot 31 | git config --global user.email info@asyncapi.io 32 | - name: Create branch 33 | working-directory: ./website 34 | run: | 35 | git checkout -b update-generator-docs-${{ github.sha }} 36 | - name: Copy generator folder from Current Repo to Another 37 | working-directory: ./website 38 | run: | 39 | rm -r ./markdown/docs/tools/generator 40 | mkdir -p ./markdown/docs/tools/generator 41 | rm ../generator/apps/generator/docs/README.md 42 | rm -r ../generator/apps/generator/docs/jsdoc2md-handlebars 43 | printf "%s\ntitle: Generator\nweight: 3\n%s" "---" "---"> ../generator/apps/generator/docs/_section.md 44 | mv ../generator/apps/generator/docs/*.md ./markdown/docs/tools/generator 45 | - name: Commit and push 46 | working-directory: ./website 47 | run: | 48 | git add . 49 | git commit -m "docs(generator): update latest generator docs" 50 | git push https://${{ env.GITHUB_TOKEN }}@github.com/asyncapi/website 51 | - name: Create PR 52 | working-directory: ./website 53 | run: | 54 | gh pr create --title "docs(generator): update latest generator documentation" --body "Updated generator documentation is available and this PR introduces update to generator folder on the website" --head "update-generator-docs-${{ github.sha }}" 55 | -------------------------------------------------------------------------------- /.github/workflows/update-docs-on-docs-commits.yml: -------------------------------------------------------------------------------- 1 | # This workflow is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | # The given workflow is responsible for generating docs and creating PR with them when there is a commit with docs: prefix 5 | 6 | # This workflow will be updated in all repos with the topic get-global-docs-autoupdate 7 | 8 | name: 'Update generated parts of documentation on docs: commits' 9 | 10 | on: 11 | push: 12 | branches: 13 | - master 14 | 15 | jobs: 16 | docs-gen: 17 | name: 'Generate docs and create PR' 18 | runs-on: ubuntu-latest 19 | # PR should be created within this GH action only if it is a docs: commit 20 | # Otherwise it will conflict with release workflow 21 | if: startsWith(github.event.commits[0].message, 'docs:') 22 | steps: 23 | - name: Checkout repo 24 | uses: actions/checkout@v4 25 | - name: Check package-lock version 26 | uses: asyncapi/.github/.github/actions/get-node-version-from-package-lock@master 27 | id: lockversion 28 | - name: Use Node.js 29 | uses: actions/setup-node@v4 30 | with: 31 | node-version: "${{ steps.lockversion.outputs.version }}" 32 | cache: 'npm' 33 | cache-dependency-path: '**/package-lock.json' 34 | - name: Install dependencies 35 | run: npm ci 36 | - name: Regenerate docs 37 | run: npm run generate:assets --if-present 38 | - name: Create Pull Request with updated docs 39 | uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # uses 7.0.8 https://github.com/peter-evans/create-pull-request/releases/tag/v7.0.8 40 | with: 41 | token: ${{ secrets.GH_TOKEN }} 42 | commit-message: 'chore: update generated docs' 43 | committer: asyncapi-bot 44 | author: asyncapi-bot 45 | title: 'chore: update generated docs' 46 | body: 'Update of docs that are generated and were forgotten on PR level.' 47 | branch: gen-docs-update/${{ github.job }} 48 | - name: Report workflow status to Slack 49 | if: failure() # Only, on failure, send a message on the 94_bot-failing-ci slack channel 50 | uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 #using https://github.com/8398a7/action-slack/releases/tag/v3.16.2 51 | with: 52 | status: ${{ job.status }} 53 | fields: repo,action,workflow 54 | text: 'AsyncAPI docs generation workflow failed' 55 | author_name: asyncapi-bot 56 | env: 57 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CI_FAIL_NOTIFY }} -------------------------------------------------------------------------------- /.github/workflows/update-maintainers-trigger.yaml: -------------------------------------------------------------------------------- 1 | # This action is centrally managed in https://github.com/asyncapi/.github/ 2 | # Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo 3 | 4 | name: Trigger MAINTAINERS.yaml file update 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | paths: 10 | # Check all valid CODEOWNERS locations: 11 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-file-location 12 | - 'CODEOWNERS' 13 | - '.github/CODEOWNERS' 14 | - '.docs/CODEOWNERS' 15 | 16 | jobs: 17 | trigger-maintainers-update: 18 | name: Trigger updating MAINTAINERS.yaml because of CODEOWNERS change 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Repository Dispatch 23 | uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # https://github.com/peter-evans/repository-dispatch/releases/tag/v3.0.0 24 | with: 25 | # The PAT with the 'public_repo' scope is required 26 | token: ${{ secrets.GH_TOKEN }} 27 | repository: ${{ github.repository_owner }}/community 28 | event-type: trigger-maintainers-update 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | **/node_modules/ 3 | .DS_Store 4 | # Local env files 5 | .env 6 | .env.local 7 | .env.development.local 8 | .env.test.local 9 | .env.production.local 10 | 11 | # Testing 12 | coverage 13 | 14 | # Turbo 15 | .turbo 16 | 17 | /.idea 18 | temp 19 | __pycache__ 20 | 21 | microcks-data 22 | packages/templates/clients/websocket/test/__fixtures__/bundled.yml -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | .DS_Store 3 | *.swp 4 | .github 5 | lib/__mocks__ 6 | .all-contributorsrc 7 | .dockerignore 8 | .editorconfig 9 | jest.config.js 10 | coverage -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true -------------------------------------------------------------------------------- /.npmrc.template: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_TOKEN} 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | ** -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | branches: 2 | - master 3 | # by default release workflow reacts on push not only to master. 4 | # This is why out of the box semantic release is configured for all these branches 5 | - name: next-spec 6 | prerelease: true 7 | - name: next-major 8 | prerelease: true 9 | - name: next-major-spec 10 | prerelease: true 11 | - name: beta 12 | prerelease: true 13 | - name: alpha 14 | prerelease: true 15 | - name: next 16 | prerelease: true 17 | 18 | plugins: 19 | - - "@semantic-release/commit-analyzer" 20 | - preset: conventionalcommits 21 | - - "@semantic-release/release-notes-generator" 22 | - preset: conventionalcommits 23 | - "@semantic-release/npm": 24 | pkgRoot: ./apps/generator 25 | - "@semantic-release/github" 26 | -------------------------------------------------------------------------------- /.sonarcloud.properties: -------------------------------------------------------------------------------- 1 | #we need to explicitly exclude them as some are commit to the repo 2 | sonar.exclusions=**/test/**/*,**/*__transpiled/**/*.js,packages/templates/clients/**/* 3 | #TODO remove packages/templates/clients/**/* when we are more advanced with templates development and the structure of templates is finalized -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This file provides an overview of code owners in this repository. 2 | 3 | # Each line is a file pattern followed by one or more owners. 4 | # The last matching pattern has the most precedence. 5 | # For more details, read the following article on GitHub: https://help.github.com/articles/about-codeowners/. 6 | 7 | # The default owners are automatically added as reviewers when you open a pull request unless different owners are specified in the file. 8 | 9 | * @derberg @magicmatatjahu @jonaslagoni @asyncapi-bot-eve 10 | 11 | # All .md files 12 | *.md @Florence-Njeri @derberg @asyncapi-bot-eve 13 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG NODE_VERSION=18 2 | FROM node:${NODE_VERSION}-alpine AS base 3 | 4 | WORKDIR /app 5 | 6 | # ---------------------------------------- 7 | # Stage 1: Prepare package.json files 8 | FROM base AS installer 9 | 10 | # COPY the whole project to the container 11 | # The following line raises a security hotspot in SonarQube, but it is necessary to copy the whole project to the container 12 | # We can ignore this and deem it as false positive, because this is mainly for local development and testing 13 | # We have manually marked this as safe in SonarQube UI 14 | COPY . . 15 | 16 | # Run turbo prune to prune the project down to just package.json files of the project 17 | # This creates a new directory called /out with the following structure: 18 | # /out 19 | # ├── json -> package.json files of the project 20 | # ├── full -> full source code of the project 21 | # └── package-lock.json -> package-lock.json of the project 22 | # We have to specify the package names. Some packages are included as dependencies in others, they will be automatically included 23 | RUN npx turbo@1.13.3 prune @asyncapi/generator @asyncapi/template-js-websocket-client @asyncapi/generator-components --docker --out-dir /out 24 | 25 | # ---------------------------------------- 26 | # Stage 2: Install dependencies 27 | FROM base AS final 28 | 29 | # Copy package.json files extracted by turbo prune 30 | COPY --from=installer /out/json/ . 31 | COPY --from=installer /out/package-lock.json ./package-lock.json 32 | 33 | # Install dependencies only with package.json files to make use of cache 34 | RUN npm ci --ignore-scripts 35 | 36 | # Copy the rest of the source code 37 | COPY --from=installer /out/full/ . 38 | 39 | # Change ownership of the /app directory to the node user 40 | RUN chown -R node:node /app 41 | 42 | # Run the application as a non-root user 43 | USER node 44 | 45 | CMD ["npm", "test"] 46 | -------------------------------------------------------------------------------- /apps/generator/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /apps/generator/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | npm-debug.log 4 | output 5 | .vscode 6 | ###################### 7 | # Intellij 8 | ###################### 9 | .idea/ 10 | *.iml 11 | *.iws 12 | *.ipr 13 | *.ids 14 | *.orig 15 | out/ 16 | coverage 17 | test/temp/integrationTestResult 18 | test/temp/reactTemplate 19 | test/test-project/package-lock.json 20 | test/test-project/verdaccio/storage/ 21 | test/test-project/storage/ 22 | __transpiled 23 | -------------------------------------------------------------------------------- /apps/generator/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine 2 | 3 | ARG ASYNCAPI_GENERATOR_VERSION=1.10.9 4 | 5 | WORKDIR /app 6 | 7 | # Since 0.14.0 release of html-template chromium is needed for pdf generation 8 | ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser 9 | ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true 10 | 11 | # Since 0.30.0 release Git is supported and required as a dependency 12 | # Since 0.14.0 release of html-template chromium is needed for pdf generation. 13 | # More custom packages for specific template should not be added to this dockerfile. Instead, we should come up with some extensibility solution. 14 | # Installing latest released npm package 15 | RUN apk --update add git chromium && \ 16 | rm /var/cache/apk/* && \ 17 | npm install --ignore-scripts -g "@asyncapi/generator@${ASYNCAPI_GENERATOR_VERSION}" 18 | 19 | 20 | ENTRYPOINT [ "ag" ] 21 | -------------------------------------------------------------------------------- /apps/generator/docs/README.md: -------------------------------------------------------------------------------- 1 | ## Documentation 2 | 3 | Read the docs on https://www.asyncapi.com/docs/tools/generator. You can still read the docs from here, but some of the links may be broken. -------------------------------------------------------------------------------- /apps/generator/docs/installation-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Installation guide" 3 | weight: 20 4 | --- 5 | 6 | You can use the generator library to generate whatever you want in your event-driven architecture apps. Find your preferred method below: 7 | - [AsyncAPI CLI](#asyncapi-cli) 8 | - [Generator library in Node.js apps](#generator-library-in-nodejs-apps) 9 | 10 | ## Prerequisites 11 | Before you install and use the AsyncAPI CLI and the generator library, ensure you meet the prerequisites below, then [install the CLI](https://www.asyncapi.com/docs/tools/cli/installation). 12 | 1. Node.js v18.12.0 or higher 13 | 2. Npm v8.19.0 or higher 14 | 15 | To verify the versions of Node and Npm you have, run the following command on your terminal: 16 | ``` 17 | npm -v 18 | ``` 19 | ``` 20 | node -v 21 | ``` 22 | 23 | If you don't have either Node or Npm installed, use the [official node.js installer](https://nodejs.org/en/download/). 24 | 25 | If you have the correct versions installed, proceed to the CLI installation guide below. Otherwise, upgrading the Npm or Node version is lower than the recommended versions specified above. 26 | 27 | ## AsyncAPI CLI 28 | The AsyncAPI CLI tool allows you to do many different things with the [AsyncAPI document](asyncapi-document). You can generate message-based API boilerplate code, documentation, or anything else you need as long as you specify it in your [template](template) or the existing template already supports it. To use the generator via the AsyncAPI CLI, you need to install the AsyncAPI CLI tool. For the latest installation instructions, visit the official AsyncAPI CLI [installation guide](https://www.asyncapi.com/docs/tools/cli/installation). 29 | 30 | > :memo: **Note:** To use the generator in your CI/CD pipeline to automate whatever you generate for your event-driven architecture apps, install the AsyncAPI CLI in your pipeline. If you are using GitHub Actions, use [Github Actions for Generator](https://github.com/marketplace/actions/asyncapi-cli-action). 31 | 32 | ## Generator library in Node.js apps 33 | Use the generator library in your Node.js projects by installing it via the following command: `npm install @asyncapi/generator`. 34 | 35 | > Don't include the `-g` flag in the installation command above since you're not installing the generator library globally but in your Node.js project. 36 | -------------------------------------------------------------------------------- /apps/generator/docs/jsdoc2md-handlebars/custom-sig-name.hbs: -------------------------------------------------------------------------------- 1 | {{#if virtual}}*{{/if}}{{#with (parentObject)}}{{#if virtual}}*{{/if~}}{{/with~}} 2 | {{#if name}}{{#sig~}} 3 | {{{@depOpen}~}} 4 | {{{@codeOpen}~}} 5 | {{#if @prefix}}{{@prefix}} {{/if~}} 6 | {{@parent~}} 7 | {{@accessSymbol}}{{#if (isEvent)}}"{{{name}}}"{{else}}{{{escape name}}}{{/if~}} 8 | {{{@codeClose}~}} 9 | {{#if @suffix}} {{@suffix}}{{/if~}} 10 | {{{@depClose}~}} 11 | {{~/sig}}{{/if}} 12 | {{#if virtual}}*{{/if}}{{#with (parentObject)}}{{#if virtual}}*{{/if~}}{{/with~}} 13 | -------------------------------------------------------------------------------- /apps/generator/docs/jsdoc2md-handlebars/defaultvalue.hbs: -------------------------------------------------------------------------------- 1 | {{#unless (equal defaultvalue undefined)}}`{{#if equals}} = {{/if}}{{#if (equal type.names.[0] "string")}}{{{json-stringify defaultvalue}}}{{else}}{{{defaultvalue}}}{{/if}}`{{/unless}} -------------------------------------------------------------------------------- /apps/generator/docs/jsdoc2md-handlebars/header.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{#if (equal kind "class")}} 5 | {{>heading-indent}}{{>custom-sig-name}} 6 | {{~else~}} 7 | {{#if params}} 8 | {{>heading-indent}}{{>custom-sig-name}} 9 | {{~else~}} 10 | * {{>sig-name}}** : 11 | {{/if}} 12 | {{/if}} 13 | -------------------------------------------------------------------------------- /apps/generator/docs/jsdoc2md-handlebars/link.hbs: -------------------------------------------------------------------------------- 1 | {{! usage: link to="namepath" html=true/false caption="optional caption"~}} 2 | 3 | {{~#if html~}} 4 | 5 | 6 | {{~#link to~}} 7 | {{#if url~}} 8 | {{#if ../../caption}}{{../../../caption}}{{else}}{{name}}{{/if}} 9 | {{~else~}} 10 | {{#if ../../caption}}{{../../../caption}}{{else}}{{name}}{{/if~}} 11 | {{/if~}} 12 | {{/link~}} 13 | 14 | 15 | {{~else~}} 16 | 17 | {{#link to~}} 18 | {{#if url~}} 19 | [`{{#if ../../caption}}{{{../../../caption}}}{{else}}{{{name}}}{{/if}}`]({{{url}}}) 20 | {{~else~}} 21 | `{{#if ../../caption}}{{{../../../caption}}}{{else}}{{{name}}}{{/if~}}` 22 | {{~/if~}} 23 | {{/link~}} 24 | 25 | {{/if~}} -------------------------------------------------------------------------------- /apps/generator/docs/jsdoc2md-handlebars/main.hbs: -------------------------------------------------------------------------------- 1 | --- 2 | title: Library API 3 | weight: 75 4 | --- 5 | 6 | Reference API documentation for AsyncAPI Generator library. 7 | {{>main-index~}} 8 | {{>all-docs~}} -------------------------------------------------------------------------------- /apps/generator/docs/jsdoc2md-handlebars/params-table.hbs: -------------------------------------------------------------------------------- 1 | {{#if params}} 2 | {{#params}}**Params** 3 | 4 | {{#each this~}} 5 | {{indent}}- {{name}}{{#if type}} {{>linked-type-list types=type.names delimiter=" | " }}{{/if}}{{#unless (equal defaultvalue undefined)}} {{>defaultvalue equals=true ~}}{{/unless}}{{#if description}} - {{{inlineLinks description}}}{{/if}} 6 | {{/each}} 7 | 8 | {{/params~}} 9 | {{/if}} -------------------------------------------------------------------------------- /apps/generator/docs/migration-cli.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Migrating from `ag` CLI to AsyncAPI CLI" 3 | weight: 260 4 | --- 5 | 6 | This guide provides detailed instructions on how to transition from the old `ag` Generator CLI to the new AsyncAPI CLI. 7 | 8 | ## Options Overview 9 | 10 | Here is a list of `ag` options and their equivalents in the AsyncAPI CLI: 11 | 12 | - **-d, --disable-hook [hooks...]** 13 | - **AsyncAPI CLI equivalent:** `asyncapi generate fromTemplate