diff --git a/components/Asyncapi.js b/components/Asyncapi.js
index d043c4aed..004ed9b6a 100644
--- a/components/Asyncapi.js
+++ b/components/Asyncapi.js
@@ -6,13 +6,11 @@ import { TableOfContents } from './TableOfContents';
// eslint-disable-next-line no-unused-vars
import { AsyncAPIDocumentInterface } from '@asyncapi/parser';
-import { Operationsv3 } from './Operationsv3';
/**
* @param {{asyncapi: AsyncAPIDocumentInterface, params: any}} param0
*/
export function Asyncapi({ asyncapi, params }) {
- const isV3 = asyncapi.version().split('.')[0] === '3';
return (
<>
{params.frontMatter && }
@@ -20,11 +18,7 @@ export function Asyncapi({ asyncapi, params }) {
{params.toc !== 'false' && }
- {
- isV3 ?
- :
-
- }
+
>
);
}
diff --git a/components/Operations.js b/components/Operations.js
index 8af591b08..baf2add56 100644
--- a/components/Operations.js
+++ b/components/Operations.js
@@ -12,6 +12,10 @@ import { FormatHelpers } from '../helpers/format';
// eslint-disable-next-line no-unused-vars
import { AsyncAPIDocumentInterface, OperationInterface, ChannelInterface } from '@asyncapi/parser';
+function isV3({asyncapi}) {
+ return asyncapi.version().split('.')[0] === '3';
+}
+
/**
* @param {{asyncapi: AsyncAPIDocumentInterface}} param0
*/
@@ -31,13 +35,13 @@ export function Operations({ asyncapi }) {
if (operation.reply() !== undefined) {
type = 'request';
} else {
- type = 'publish';
+ type = 'send';
}
} else if (operation.isReceive()) {
if (operation.reply() !== undefined) {
type = 'reply';
} else {
- type = 'subscribe';
+ type = 'receive';
}
}
operationsList.push(
@@ -62,7 +66,31 @@ export function Operations({ asyncapi }) {
>
);
}
-
+function getRenderedTypeForOperation({asyncapi, type}) {
+ const isv3 = isV3({asyncapi});
+ if (isv3) {
+ switch (type) {
+ case 'request':
+ return 'REQUEST';
+ case 'send':
+ return 'SEND';
+ case 'reply':
+ return 'REPLY';
+ case 'receive':
+ return 'RECEIVE';
+ }
+ }
+ // For v2, we render the application view still
+ // Meaning the when you use publish operation it means other publish to your application because your application is subscribing to it.
+ switch (type) {
+ case 'send': // This is the publish operation
+ return 'SUB';
+ case 'receive': // This is the subscribe operation
+ return 'PUB';
+ }
+ // This case should never happen, if it does this function needs to be changed
+ return 'UNKNOWN';
+}
/**
* @param {{asyncapi: AsyncAPIDocumentInterface, type: string, operation: OperationInterface, channelName: string, channel: ChannelInterface}} param0
*/
@@ -76,15 +104,8 @@ function Operation({ asyncapi, type, operation, channelName, channel }) { // NOS
const applyToAllServers = asyncapi.servers().all().length === channel.servers().all().length;
const servers = applyToAllServers ? [] : channel.servers().all();
const security = operation.security();
- let renderedType;
- switch (type) {
- case 'publish':
- renderedType = 'PUB';
- break;
- case 'subscribe':
- renderedType = 'SUB';
- break;
- }
+ const renderedType = getRenderedTypeForOperation({asyncapi, type});
+
const showInfoList = operationId || (servers && servers.length);
return (
@@ -95,7 +116,7 @@ function Operation({ asyncapi, type, operation, channelName, channel }) { // NOS
{operation.summary() && (
- *{operation.summary()}*
+ *{operation.summary().trim()}*
)}
@@ -154,10 +175,13 @@ function Operation({ asyncapi, type, operation, channelName, channel }) { // NOS
-
+
+
+
);
}
+
/**
* @param {{channel: ChannelInterface}} param0
*/
@@ -174,20 +198,36 @@ function OperationParameters({ channel }) {
);
}
+function getOperationMessageText({asyncapi, type}) {
+ let messagesText = 'Accepts **one of** the following messages:';
+ if (isV3({asyncapi})) {
+ if (type === 'send') {
+ messagesText = 'Sending **one of** the following messages:';
+ } else if (type === 'request') {
+ messagesText = 'Request contains **one of** the following messages:';
+ } else if (type === 'receive') {
+ messagesText = 'Receive **one of** the following messages:';
+ } else if (type === 'reply') {
+ messagesText = 'Request contains **one of** the following messages:';
+ }
+ }
+ return messagesText;
+}
/**
- * @param {{operation: OperationInterface}} param0
+ * @param {{operation: OperationInterface, asyncapi: AsyncAPIDocumentInterface, type: string}} param0
*/
-function OperationMessages({ operation }) {
+function OperationMessages({ asyncapi, operation, type }) {
const messages = operation.messages().all();
if (messages.length === 0) {
return null;
}
+ const messageText = getOperationMessageText({asyncapi, type});
return (
<>
{messages.length > 1 && (
- Accepts **one of** the following messages:
+ {messageText}
)}
{messages.map((msg, idx) => (
@@ -196,3 +236,81 @@ function OperationMessages({ operation }) {
>
);
}
+
+/**
+ * @param {{operation: OperationInterface}} param0
+ */
+function OperationReply({ operation, type }) {
+ const reply = operation.reply();
+ if (reply === undefined) {
+ return null;
+ }
+ const explicitChannel = reply.channel();
+
+ let typeText;
+ if (operation.isSend()) {
+ typeText = 'Request';
+ } else if (operation.isReceive()) {
+ typeText = 'Response';
+ }
+
+ let messagesText;
+ if (type === 'request') {
+ messagesText = 'Receive **one of** the following messages as a response to the request:';
+ } else if (type === 'reply') {
+ messagesText = 'Replying with **one of** the following messages:';
+ }
+
+ return (
+
+
+ {`${typeText} information`}
+
+
+ {explicitChannel && {type} should be done to channel: `{explicitChannel.address()}`}
+
+
+
+ <>
+ {reply.messages().length > 1 && (
+
+ {messagesText}
+
+ )}
+ {reply.messages().length > 1 && reply.messages().map((msg, idx) => (
+
+ ))}
+ >
+
+
+ );
+}
+
+/**
+ * @param {{reply: OperationReplyInterface}} param0
+ */
+function OperationReplyAddress({ reply }) {
+ const address = reply.address();
+ if (address === undefined) {
+ return null;
+ }
+ const location = address.location();
+
+ return (
+
+
+ {'Operation reply address information'}
+
+
+ {address.hasDescription() && (
+
+ {address.description()}
+
+ )}
+
+ Operation reply address location: `{location}`
+
+
+
+ );
+}
diff --git a/components/Operationsv3.js b/components/Operationsv3.js
deleted file mode 100644
index 3a11f350b..000000000
--- a/components/Operationsv3.js
+++ /dev/null
@@ -1,295 +0,0 @@
-import { Text } from '@asyncapi/generator-react-sdk';
-import { Bindings } from './Bindings';
-import { Extensions } from './Extensions';
-import { Message } from './Message';
-import { Schema } from './Schema';
-import { Security } from './Security';
-import { Tags } from './Tags';
-import { Header, ListItem, Link } from './common';
-import { SchemaHelpers } from '../helpers/schema';
-import { FormatHelpers } from '../helpers/format';
-
-// eslint-disable-next-line no-unused-vars
-import { AsyncAPIDocumentInterface, OperationInterface, OperationReplyInterface, ChannelInterface } from '@asyncapi/parser';
-
-/**
- * @param {{asyncapi: AsyncAPIDocumentInterface}} param0
- */
-export function Operationsv3({ asyncapi }) {
- const channels = asyncapi.channels();
- if (channels.isEmpty()) {
- return null;
- }
-
- const operationsList = [];
- for (const channel of channels.all()) {
- const channelName = channel.address();
- const operations = channel.operations().all();
- operations.map(operation => {
- let type;
- if (operation.isSend()) {
- if (operation.reply() !== undefined) {
- type = 'request';
- } else {
- type = 'send';
- }
- } else if (operation.isReceive()) {
- if (operation.reply() !== undefined) {
- type = 'reply';
- } else {
- type = 'receive';
- }
- }
- operationsList.push(
-
- );
- });
- }
-
- return (
- <>
-
- {operationsList}
- >
- );
-}
-
-/**
- * @param {{asyncapi: AsyncAPIDocumentInterface, type: string, operation: OperationInterface, channelName: string, channel: ChannelInterface}} param0
- */
-function Operation({ asyncapi, type, operation, channelName, channel }) { // NOSONAR
- if (!operation || !channel) {
- return null;
- }
-
- const operationId = operation.operationId();
- const externalDocs = operation.externalDocs();
- const applyToAllServers = asyncapi.servers().all().length === channel.servers().all().length;
- const servers = applyToAllServers ? [] : channel.servers().all();
- const security = operation.security();
- let renderedType;
- switch (type) {
- case 'request':
- renderedType = 'REQUEST';
- break;
- case 'send':
- renderedType = 'SEND';
- break;
- case 'reply':
- renderedType = 'REPLY';
- break;
- case 'receive':
- renderedType = 'RECEIVE';
- break;
- }
- const showInfoList = operationId || (servers?.length);
-
- return (
-
-
- {`${renderedType} \`${channelName}\` Operation`}
-
-
- {operation.summary() && (
-
- *{operation.summary().trim()}*
-
- )}
-
- {showInfoList ? (
-
- {operationId && Operation ID: `{operationId}`}
- {servers && servers.length && (
-
- Available only on servers:{' '}
- {servers.map(s => {
- const serverId = s.id();
- const slug = FormatHelpers.slugify(serverId);
- return `[${serverId}](#${slug}-server)`;
- }).join(', ')}
-
- )}
-
- ) : null}
-
- {channel.hasDescription() && (
-
- {channel.description()}
-
- )}
- {operation.hasDescription() && (
-
- {operation.description()}
-
- )}
-
- {externalDocs && (
-
-
- {externalDocs.description() || 'Find more info here.'}
-
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-/**
- * @param {{channel: ChannelInterface}} param0
- */
-function OperationParameters({ channel }) {
- const parameters = SchemaHelpers.parametersToSchema(channel.parameters().all());
- if (!parameters) {
- return null;
- }
-
- return (
-
-
-
-
- );
-}
-/**
- * @param {{operation: OperationInterface}} param0
- */
-function OperationMessages({ operation, type }) {
- const messages = operation.messages().all();
- if (messages.length === 0) {
- return null;
- }
-
- let messagesText = 'Accepts **one of** the following messages:';
- if (type === 'send') {
- messagesText = 'Sending **one of** the following messages:';
- } else if (type === 'request') {
- messagesText = 'Request contains **one of** the following messages:';
- } else if (type === 'receive') {
- messagesText = 'Receive **one of** the following messages:';
- } else if (type === 'reply') {
- messagesText = 'Request contains **one of** the following messages:';
- }
-
- return (
- <>
- {messages.length > 1 && (
-
- {messagesText}
-
- )}
- {messages.map((msg, idx) => (
-
- ))}
- >
- );
-}
-
-/**
- * @param {{operation: OperationInterface}} param0
- */
-function OperationReply({ operation, type }) {
- const reply = operation.reply();
- if (reply === undefined) {
- return null;
- }
- const explicitChannel = reply.channel();
-
- let typeText;
- if (operation.isSend()) {
- typeText = 'Request';
- } else if (operation.isReceive()) {
- typeText = 'Response';
- }
-
- let messagesText = 'Accepts **one of** the following messages:';
- if (type === 'request') {
- messagesText = 'Receive **one of** the following messages as a response to the request:';
- } else if (type === 'reply') {
- messagesText = 'Replying with **one of** the following messages:';
- }
-
- return (
-
-
- {`${typeText} information`}
-
-
- {explicitChannel && {type} should be done to channel: `{explicitChannel.address()}`}
-
-
-
- <>
- {reply.messages().length > 1 && (
-
- {messagesText}
-
- )}
- {reply.messages().length > 1 && reply.messages().map((msg, idx) => (
-
- ))}
- >
-
-
- );
-}
-
-/**
- * @param {{reply: OperationReplyInterface}} param0
- */
-function OperationReplyAddress({ reply }) {
- const address = reply.address();
- if (address === undefined) {
- return null;
- }
- const location = address.location();
-
- return (
-
-
- {'Operation reply address information'}
-
-
- {address.hasDescription() && (
-
- {address.description()}
-
- )}
-
- Operation reply address location: `{location}`
-
-
-
- );
-}
diff --git a/helpers/schema.js b/helpers/schema.js
index f30d702a2..190df43a5 100644
--- a/helpers/schema.js
+++ b/helpers/schema.js
@@ -194,6 +194,11 @@ export class SchemaHelpers {
return JSON.stringify(value);
}
+ /**
+ *
+ * @param {import('@asyncapi/parser').ChannelParametersInterface} parameters
+ * @returns
+ */
static parametersToSchema(parameters) {
if (parameters.length === 0) {
return;
@@ -204,7 +209,7 @@ export class SchemaHelpers {
properties: parameters.reduce(
(obj, parameter) => {
const parameterName = parameter.id();
- obj[String(parameterName)] = Object.assign({}, parameter.schema().json());
+ obj[String(parameterName)] = Object.assign({}, parameter.schema() === undefined ? {type: 'string'} : parameter.schema().json());
obj[String(parameterName)].description =
parameter.description() || obj[String(parameterName)].description;
obj[String(parameterName)][this.extParameterLocation] = parameter.location();
diff --git a/package-lock.json b/package-lock.json
index b53ccd5a7..450479c2b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,7 @@
},
"devDependencies": {
"@asyncapi/cli": "^0.58.5",
- "@asyncapi/parser": "^3.0.0-next-major-spec.2",
+ "@asyncapi/parser": "^3.0.0-next-major-spec.3",
"@babel/preset-env": "^7.15.8",
"@babel/preset-react": "^7.14.5",
"@types/react": "^18.2.18",
@@ -1426,9 +1426,9 @@
}
},
"node_modules/@asyncapi/parser": {
- "version": "3.0.0-next-major-spec.2",
- "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-3.0.0-next-major-spec.2.tgz",
- "integrity": "sha512-/gJgCYNYlUSDJhySK3IagjiyFfnwEsAZd5rTe396CB+HxJ6yDWDOZYdHzkFgU2RnCULSGzVOWZGx8t3PK+yuVg==",
+ "version": "3.0.0-next-major-spec.3",
+ "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-3.0.0-next-major-spec.3.tgz",
+ "integrity": "sha512-LCrAQqJpGxraMyU2k1Nh1X6Q1dz7a/YhTRRFFrQHOEo+TUT/kRdoUkRDP++e58dO7h9MBN+/hZK5TaqE+/jQiw==",
"dev": true,
"dependencies": {
"@asyncapi/specs": "^6.0.0-next-major-spec.6",
diff --git a/package.json b/package.json
index 50f1cfd65..b3700a9b8 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
"eslint-plugin-sonarjs": "^0.11.0",
"jest": "^27.2.5",
"markdown-toc": "^1.2.0",
- "@asyncapi/parser": "^3.0.0-next-major-spec.2"
+ "@asyncapi/parser": "^3.0.0-next-major-spec.3"
},
"generator": {
"renderer": "react",
diff --git a/test/components/Operations.test.js b/test/components/Operations.test.js
index eb5be3606..bf01e7113 100644
--- a/test/components/Operations.test.js
+++ b/test/components/Operations.test.js
@@ -1,65 +1,67 @@
import { render } from '@asyncapi/generator-react-sdk';
-import { AsyncAPIDocumentV2 as AsyncAPIDocument, createAsyncAPIDocument } from '@asyncapi/parser';
+import { AsyncAPIDocumentV2 as AsyncAPIDocument, createAsyncAPIDocument, Parser } from '@asyncapi/parser';
import { Operations } from '../../components/Operations';
+const parser = new Parser();
describe('Operations component', () => {
- it('should render operation', () => {
- const asyncapi = createAsyncAPIDocument({
- semver: {
- major: 2,
- minor: 0,
- patch: 0,
- },
- parsed: {
- asyncapi: '2.0.0',
- servers: {
- rabbitmqBrokerInProd: {},
- rabbitmqBrokerInStaging: {},
+ describe('for AsyncAPI v2', () => {
+ it('should render operation', () => {
+ const asyncapi = createAsyncAPIDocument({
+ semver: {
+ major: 2,
+ minor: 0,
+ patch: 0,
},
- channels: {
- 'user/signedup': {
- description: 'This channel is used to exchange messages about users signing up',
- servers: [
- 'rabbitmqBrokerInProd',
- 'rabbitmqBrokerInStaging'
- ],
- subscribe: {
- operationId: 'signedupuser',
- externalDocs: {
- description: 'More info here',
- url: 'https://example.com'
- },
- tags: [
- { name: 'user' },
- { name: 'signup' },
- { name: 'register' }
+ parsed: {
+ asyncapi: '2.0.0',
+ servers: {
+ rabbitmqBrokerInProd: {},
+ rabbitmqBrokerInStaging: {},
+ },
+ channels: {
+ 'user/signedup': {
+ description: 'This channel is used to exchange messages about users signing up',
+ servers: [
+ 'rabbitmqBrokerInProd',
+ 'rabbitmqBrokerInStaging'
],
- summary: 'A user signed up.',
- message: {
- name: 'SomeMessage',
- description: 'A longer description of the message',
- payload: {
- type: 'object',
- properties: {
- user: {
- type: 'string'
- },
- signup: {
- type: 'number'
+ subscribe: {
+ operationId: 'signedupuser',
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'A user signed up.',
+ message: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
}
}
}
- }
+ },
},
},
- },
- }
- });
- const expected = `
+ }
+ });
+ const expected = `
## Operations
-### PUB \`user/signedup\` Operation
+### SUB \`user/signedup\` Operation
*A user signed up.*
@@ -98,66 +100,66 @@ A longer description of the message
}
\`\`\`
`;
-
- const result = render();
- expect(result.trim()).toEqual(expected.trim());
- });
-
- it('should render servers for operation', () => {
- const asyncapi = createAsyncAPIDocument({
- semver: {
- major: 2,
- minor: 0,
- patch: 0,
- },
- parsed: {
- asyncapi: '2.0.0',
- servers: {
- rabbitmqBrokerInProd: {},
- rabbitmqBrokerInStaging: {},
+
+ const result = render();
+ expect(result.trim()).toEqual(expected.trim());
+ });
+
+ it('should render servers for operation', () => {
+ const asyncapi = createAsyncAPIDocument({
+ semver: {
+ major: 2,
+ minor: 0,
+ patch: 0,
},
- channels: {
- 'user/signedup': {
- description: 'This channel is used to exchange messages about users signing up',
- servers: [
- 'rabbitmqBrokerInProd',
- ],
- subscribe: {
- operationId: 'signedupuser',
- externalDocs: {
- description: 'More info here',
- url: 'https://example.com'
- },
- tags: [
- { name: 'user' },
- { name: 'signup' },
- { name: 'register' }
+ parsed: {
+ asyncapi: '2.0.0',
+ servers: {
+ rabbitmqBrokerInProd: {},
+ rabbitmqBrokerInStaging: {},
+ },
+ channels: {
+ 'user/signedup': {
+ description: 'This channel is used to exchange messages about users signing up',
+ servers: [
+ 'rabbitmqBrokerInProd',
],
- summary: 'A user signed up.',
- message: {
- name: 'SomeMessage',
- description: 'A longer description of the message',
- payload: {
- type: 'object',
- properties: {
- user: {
- type: 'string'
- },
- signup: {
- type: 'number'
+ subscribe: {
+ operationId: 'signedupuser',
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'A user signed up.',
+ message: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
}
}
}
- }
+ },
},
},
- },
- }
- });
- const expected = `
+ }
+ });
+ const expected = `
## Operations
-### PUB \`user/signedup\` Operation
+### SUB \`user/signedup\` Operation
*A user signed up.*
@@ -197,37 +199,38 @@ A longer description of the message
}
\`\`\`
`;
-
- const result = render();
- expect(result.trim()).toEqual(expected.trim());
- });
-
- it('should render parameters for operation', () => {
- const asyncapi = new AsyncAPIDocument({
- channels: {
- 'user/{userId}/signup/{foobar}': {
- parameters: {
- userId: {
- description: 'Id of the user.',
- schema: {
- type: 'string'
+
+ const result = render();
+ expect(result.trim()).toEqual(expected.trim());
+ });
+
+ it('should render parameters for operation', () => {
+ const asyncapi = new AsyncAPIDocument({
+ asyncapi: '2.0.0',
+ channels: {
+ 'user/{userId}/signup/{foobar}': {
+ parameters: {
+ userId: {
+ description: 'Id of the user.',
+ schema: {
+ type: 'string'
+ },
+ location: '$message.payload#/user/id'
},
- location: '$message.payload#/user/id'
+ foobar: {
+ schema: {
+ type: 'string'
+ },
+ }
},
- foobar: {
- schema: {
- type: 'string'
- },
- }
- },
- publish: {}
- }
- },
- });
- const expected = `
+ publish: {}
+ }
+ },
+ });
+ const expected = `
## Operations
-### SUB \`user/{userId}/signup/{foobar}\` Operation
+### PUB \`user/{userId}/signup/{foobar}\` Operation
#### Parameters
@@ -236,52 +239,53 @@ A longer description of the message
| userId | string | Id of the user. | - | - | **required**, **parameter location ($message.payload#/user/id)** |
| foobar | string | - | - | - | **required** |
`;
-
- const result = render();
- expect(result.trim()).toEqual(expected.trim());
- });
-
- it('should render multiple messages', () => {
- const asyncapi = new AsyncAPIDocument({
- channels: {
- 'user/{userId}/signup/{foobar}': {
- publish: {
- message: {
- oneOf: [
- {
- messageId: 'some-message',
- description: 'A longer description of the message',
- payload: {
- type: 'object',
- properties: {
- signup: {
- type: 'number'
+
+ const result = render();
+ expect(result.trim()).toEqual(expected.trim());
+ });
+
+ it('should render multiple messages', () => {
+ const asyncapi = new AsyncAPIDocument({
+ asyncapi: '2.0.0',
+ channels: {
+ 'user/{userId}/signup/{foobar}': {
+ publish: {
+ message: {
+ oneOf: [
+ {
+ messageId: 'some-message',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ signup: {
+ type: 'number'
+ }
}
}
- }
- },
- {
- name: 'SomeMessage',
- description: 'A longer description of the message',
- payload: {
- type: 'object',
- properties: {
- user: {
- type: 'string'
- },
+ },
+ {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ }
}
- }
- },
- ]
+ },
+ ]
+ }
}
}
- }
- },
- });
- const expected = `
+ },
+ });
+ const expected = `
## Operations
-### SUB \`user/{userId}/signup/{foobar}\` Operation
+### PUB \`user/{userId}/signup/{foobar}\` Operation
Accepts **one of** the following messages:
@@ -324,56 +328,56 @@ A longer description of the message
}
\`\`\`
`;
-
- const result = render();
- expect(result.trim()).toEqual(expected.trim());
- });
-
- it('should render security', () => {
- const asyncapi = createAsyncAPIDocument({
- semver: {
- major: 2,
- minor: 0,
- patch: 0,
- },
- parsed: {
- asyncapi: '2.0.0',
- channels: {
- 'smartylighting.streetlights.1.0.action.{streetlightId}.turn.on': {
- subscribe: {
- security: [
- {
- streetlights_auth: [
- 'streetlights:read'
- ]
- }
- ]
- }
- }
+
+ const result = render();
+ expect(result.trim()).toEqual(expected.trim());
+ });
+
+ it('should render security', () => {
+ const asyncapi = createAsyncAPIDocument({
+ semver: {
+ major: 2,
+ minor: 0,
+ patch: 0,
},
- components: {
- securitySchemes: {
- streetlights_auth: {
- type: 'oauth2',
- description: 'The oauth security descriptions',
- flows: {
- clientCredentials: {
- tokenUrl: 'https://example.com/api/oauth/dialog',
- scopes: {
- 'streetlights:read': 'Scope required for subscribing to channel',
- 'streetlights:write': 'Scope required for publishing to channel'
+ parsed: {
+ asyncapi: '2.0.0',
+ channels: {
+ 'smartylighting.streetlights.1.0.action.{streetlightId}.turn.on': {
+ subscribe: {
+ security: [
+ {
+ streetlights_auth: [
+ 'streetlights:read'
+ ]
+ }
+ ]
+ }
+ }
+ },
+ components: {
+ securitySchemes: {
+ streetlights_auth: {
+ type: 'oauth2',
+ description: 'The oauth security descriptions',
+ flows: {
+ clientCredentials: {
+ tokenUrl: 'https://example.com/api/oauth/dialog',
+ scopes: {
+ 'streetlights:read': 'Scope required for subscribing to channel',
+ 'streetlights:write': 'Scope required for publishing to channel'
+ }
}
}
}
}
}
- }
- },
- });
- const expected = `
+ },
+ });
+ const expected = `
## Operations
-### PUB \`smartylighting.streetlights.1.0.action.{streetlightId}.turn.on\` Operation
+### SUB \`smartylighting.streetlights.1.0.action.{streetlightId}.turn.on\` Operation
#### Additional security requirements
@@ -395,62 +399,63 @@ A longer description of the message
The oauth security descriptions
`;
-
- const result = render();
- expect(result.trim()).toEqual(expected.trim());
- });
-
- it('should render bindings', () => {
- const asyncapi = new AsyncAPIDocument({
- channels: {
- 'user/{userId}/signup/{foobar}': {
- bindings: {
- http: {
- type: 'request',
- method: 'GET',
- query: {
- type: 'object',
- required: [
- 'companyId'
- ],
- properties: {
- companyId: {
- type: 'number',
- minimum: 1,
- description: 'The Id of the company.'
- }
- },
- additionalProperties: false
- },
- bindingVersion: '0.1.0'
- },
- },
- publish: {
+
+ const result = render();
+ expect(result.trim()).toEqual(expected.trim());
+ });
+
+ it('should render bindings', () => {
+ const asyncapi = new AsyncAPIDocument({
+ asyncapi: '2.0.0',
+ channels: {
+ 'user/{userId}/signup/{foobar}': {
bindings: {
- kafka: {
- groupId: {
- type: 'string',
- enum: [
- 'myGroupId'
- ]
- },
- clientId: {
- type: 'string',
- enum: [
- 'myClientId'
- ]
+ http: {
+ type: 'request',
+ method: 'GET',
+ query: {
+ type: 'object',
+ required: [
+ 'companyId'
+ ],
+ properties: {
+ companyId: {
+ type: 'number',
+ minimum: 1,
+ description: 'The Id of the company.'
+ }
+ },
+ additionalProperties: false
},
bindingVersion: '0.1.0'
- }
+ },
},
+ publish: {
+ bindings: {
+ kafka: {
+ groupId: {
+ type: 'string',
+ enum: [
+ 'myGroupId'
+ ]
+ },
+ clientId: {
+ type: 'string',
+ enum: [
+ 'myClientId'
+ ]
+ },
+ bindingVersion: '0.1.0'
+ }
+ },
+ }
}
- }
- },
- });
- const expected = `
+ },
+ });
+ const expected = `
## Operations
-### SUB \`user/{userId}/signup/{foobar}\` Operation
+### PUB \`user/{userId}/signup/{foobar}\` Operation
#### \`http\` Channel specific information
@@ -470,33 +475,16 @@ A longer description of the message
| clientId | string | - | allowed (\`"myClientId"\`) | - | - |
| bindingVersion | - | - | \`"0.1.0"\` | - | - |
`;
-
- const result = render();
- expect(result.trim()).toEqual(expected.trim());
- });
-
- it('should render extensions', () => {
- const asyncapi = new AsyncAPIDocument({
- channels: {
- 'user/{userId}/signup/{foobar}': {
- 'x-schema-extensions-as-object': {
- type: 'object',
- properties: {
- prop1: {
- type: 'string'
- },
- prop2: {
- type: 'integer',
- minimum: 0
- }
- }
- },
- 'x-schema-extensions-as-primitive': 'dummy',
- 'x-schema-extensions-as-array': [
- 'item1',
- 'item2'
- ],
- publish: {
+
+ const result = render();
+ expect(result.trim()).toEqual(expected.trim());
+ });
+
+ it('should render extensions', () => {
+ const asyncapi = new AsyncAPIDocument({
+ asyncapi: '2.0.0',
+ channels: {
+ 'user/{userId}/signup/{foobar}': {
'x-schema-extensions-as-object': {
type: 'object',
properties: {
@@ -513,15 +501,33 @@ A longer description of the message
'x-schema-extensions-as-array': [
'item1',
'item2'
- ]
+ ],
+ publish: {
+ 'x-schema-extensions-as-object': {
+ type: 'object',
+ properties: {
+ prop1: {
+ type: 'string'
+ },
+ prop2: {
+ type: 'integer',
+ minimum: 0
+ }
+ }
+ },
+ 'x-schema-extensions-as-primitive': 'dummy',
+ 'x-schema-extensions-as-array': [
+ 'item1',
+ 'item2'
+ ]
+ }
}
}
- }
- });
- const expected = `
+ });
+ const expected = `
## Operations
-### SUB \`user/{userId}/signup/{foobar}\` Operation
+### PUB \`user/{userId}/signup/{foobar}\` Operation
#### Channel extensions
@@ -547,104 +553,575 @@ A longer description of the message
| x-schema-extensions-as-array.0 (index) | - | - | \`"item1"\` | - | - |
| x-schema-extensions-as-array.1 (index) | - | - | \`"item2"\` | - | - |
`;
-
- const result = render();
- expect(result.trim()).toEqual(expected.trim());
- });
-
- it('should render nothing if channels with operations are not defined', () => {
- const asyncapi = new AsyncAPIDocument({});
-
- const result = render();
- expect(result).toEqual('');
+
+ const result = render();
+ expect(result.trim()).toEqual(expected.trim());
+ });
+
+ it('should render nothing if channels with operations are not defined', () => {
+ const asyncapi = new AsyncAPIDocument({});
+
+ const result = render();
+ expect(result).toEqual('');
+ });
});
-
- it('should render reply operation', () => {
- const unsubscribeMessaage = {
- description: 'Unsubscribe, can specify a channelID or multiple currency pairs.',
- payload: {
- type: 'object',
- properties: {
- event: {
- type: 'string',
- const: 'unsubscribe'
+ describe('for AsyncAPI v3', () => {
+ it('should render receive operation', async () => {
+ const {document, diagnostics} = await parser.parse({
+ asyncapi: '3.0.0',
+ info: {
+ title: 'test',
+ version: '1.0.0'
+ },
+ servers: {
+ rabbitmqBrokerInProd: {
+ host: 'prod.url:9092',
+ protocol: 'mqtt'
+ },
+ rabbitmqBrokerInStaging: {
+ host: 'prod.url:9093',
+ protocol: 'mqtt'
+ },
+ },
+ channels: {
+ userSignup: {
+ address: 'user/signedup',
+ description: 'This channel is used to exchange messages about users signing up',
+ messages: {
+ SomeMessage: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
}
- }
- }
- };
- const subscribeMessage = {
- description: 'Subscribe to a topic on a single or multiple currency pairs.',
- payload: {
- type: 'object',
- properties: {
- event: {
- type: 'string',
- const: 'subscribe'
+ },
+ operations: {
+ userSignedUp: {
+ action: 'receive',
+ channel: {
+ $ref: '#/channels/userSignup'
+ },
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'A user signed up.',
}
}
- }
- };
- const responseMessage = {
- description: '',
- payload: {
- type: 'object',
- properties: {
- status: {
- type: 'number'
+ });
+
+ expect(diagnostics).toEqual([]);
+ const result = render();
+ expect(result.trim()).toMatchSnapshot();
+ });
+ it('should render send operation', async () => {
+ const {document, diagnostics} = await parser.parse({
+ asyncapi: '3.0.0',
+ info: {
+ title: 'test',
+ version: '1.0.0'
+ },
+ servers: {
+ rabbitmqBrokerInProd: {
+ host: 'prod.url:9092',
+ protocol: 'mqtt'
+ },
+ rabbitmqBrokerInStaging: {
+ host: 'prod.url:9093',
+ protocol: 'mqtt'
+ },
+ },
+ channels: {
+ userSignup: {
+ address: 'user/signedup',
+ description: 'This channel is used to exchange messages about users signing up',
+ messages: {
+ SomeMessage: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ operations: {
+ userSignedUp: {
+ action: 'send',
+ channel: {
+ $ref: '#/channels/userSignup'
+ },
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'A user signed up.',
}
}
- }
- };
- const channel = {
- address: '/',
- messages: {
- subscribe: subscribeMessage,
- unsubscribe: unsubscribeMessaage,
- response: responseMessage
- }
- };
- const asyncapi = createAsyncAPIDocument({
- semver: {
- major: 3,
- minor: 0,
- patch: 0,
- },
- parsed: {
+ });
+
+ expect(diagnostics).toEqual([]);
+ const result = render();
+ expect(result.trim()).toMatchSnapshot();
+ });
+ it('should render request operation', async () => {
+ const {document, diagnostics} = await parser.parse({
asyncapi: '3.0.0',
info: {
- title: 'Kraken Websockets API',
- version: '1.8.0',
+ title: 'test',
+ version: '1.0.0'
+ },
+ servers: {
+ rabbitmqBrokerInProd: {
+ host: 'prod.url:9092',
+ protocol: 'mqtt'
+ },
+ rabbitmqBrokerInStaging: {
+ host: 'prod.url:9093',
+ protocol: 'mqtt'
+ },
},
channels: {
- currencyExchange: channel
+ userSignUp: {
+ address: 'user/signedup',
+ description: 'This channel is used to exchange messages about users signing up',
+ messages: {
+ SomeMessage: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
+ },
+ userSignedUp: {
+ address: 'user/signedup',
+ messages: {
+ SomeReplyMessage: {
+ name: 'SomeReplyMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
+ }
},
operations: {
- subscribe: {
+ userSignUp: {
action: 'send',
- channel,
+ channel: {
+ $ref: '#/channels/userSignUp'
+ },
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'Sign up a user.',
reply: {
- channel,
- messages: [
- responseMessage
- ]
+ channel: {
+ $ref: '#/channels/userSignedUp'
+ }
+ }
+ }
+ }
+ });
+
+ expect(diagnostics).toEqual([]);
+ const result = render();
+ expect(result.trim()).toMatchSnapshot();
+ });
+ it('should render reply operation', async () => {
+ const {document, diagnostics} = await parser.parse({
+ asyncapi: '3.0.0',
+ info: {
+ title: 'test',
+ version: '1.0.0'
+ },
+ servers: {
+ rabbitmqBrokerInProd: {
+ host: 'prod.url:9092',
+ protocol: 'mqtt'
+ },
+ rabbitmqBrokerInStaging: {
+ host: 'prod.url:9093',
+ protocol: 'mqtt'
+ },
+ },
+ channels: {
+ userSignUp: {
+ address: 'user/signedup',
+ description: 'This channel is used to exchange messages about users signing up',
+ messages: {
+ SomeMessage: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
}
},
- unsubscribe: {
+ userSignedUp: {
+ address: 'user/signedup',
+ messages: {
+ SomeReplyMessage: {
+ name: 'SomeReplyMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ operations: {
+ userSignUp: {
action: 'receive',
- channel,
+ channel: {
+ $ref: '#/channels/userSignUp'
+ },
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'Sign up a user.',
reply: {
- channel,
- messages: [
- responseMessage
- ]
+ channel: {
+ $ref: '#/channels/userSignedUp'
+ }
}
}
}
- }
+ });
+
+ expect(diagnostics).toEqual([]);
+ const result = render();
+ expect(result.trim()).toMatchSnapshot();
});
- const result = render();
- const actual = result.trim();
- expect(actual).toMatchSnapshot();
+ it('should render multiple messages', async () => {
+ const {document, diagnostics} = await parser.parse({
+ asyncapi: '3.0.0',
+ info: {
+ title: 'test',
+ version: '1.0.0'
+ },
+ servers: {
+ rabbitmqBrokerInProd: {
+ host: 'prod.url:9092',
+ protocol: 'mqtt'
+ },
+ rabbitmqBrokerInStaging: {
+ host: 'prod.url:9093',
+ protocol: 'mqtt'
+ },
+ },
+ channels: {
+ userSignup: {
+ address: 'user/{userId}/signup/{foobar}',
+ parameters: {
+ userId: {
+ description: 'Id of the user.',
+ location: '$message.payload#/user/id'
+ },
+ foobar: {}
+ },
+ description: 'This channel is used to exchange messages about users signing up',
+ messages: {
+ SomeMessage: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ },
+ SomeMessage2: {
+ messageId: 'SomeMessage2',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ operations: {
+ userSignedUp: {
+ action: 'send',
+ channel: {
+ $ref: '#/channels/userSignup'
+ },
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'A user signed up.',
+ }
+ }
+ });
+
+ expect(diagnostics).toEqual([]);
+ const result = render();
+ expect(result.trim()).toMatchSnapshot();
+ });
+
+ it('should render bindings for channel', async () => {
+ const {document, diagnostics} = await parser.parse({
+ asyncapi: '3.0.0',
+ info: {
+ title: 'test',
+ version: '1.0.0'
+ },
+ servers: {
+ rabbitmqBrokerInProd: {
+ host: 'prod.url:9092',
+ protocol: 'mqtt'
+ },
+ rabbitmqBrokerInStaging: {
+ host: 'prod.url:9093',
+ protocol: 'mqtt'
+ },
+ },
+ channels: {
+ userSignup: {
+ bindings: {
+ http: {
+ type: 'request',
+ method: 'GET',
+ query: {
+ type: 'object',
+ required: [
+ 'companyId'
+ ],
+ properties: {
+ companyId: {
+ type: 'number',
+ minimum: 1,
+ description: 'The Id of the company.'
+ }
+ },
+ additionalProperties: false
+ },
+ bindingVersion: '0.1.0'
+ },
+ },
+ address: 'user/signup',
+ description: 'This channel is used to exchange messages about users signing up',
+ messages: {
+ SomeMessage: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ operations: {
+ userSignedUp: {
+ action: 'send',
+ channel: {
+ $ref: '#/channels/userSignup'
+ },
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'A user signed up.',
+ }
+ }
+ });
+
+ expect(diagnostics).toEqual([]);
+ const result = render();
+ expect(result.trim()).toMatchSnapshot();
+ });
+ it('should render bindings for operation', async () => {
+ const {document, diagnostics} = await parser.parse({
+ asyncapi: '3.0.0',
+ info: {
+ title: 'test',
+ version: '1.0.0'
+ },
+ servers: {
+ rabbitmqBrokerInProd: {
+ host: 'prod.url:9092',
+ protocol: 'mqtt'
+ },
+ rabbitmqBrokerInStaging: {
+ host: 'prod.url:9093',
+ protocol: 'mqtt'
+ },
+ },
+ channels: {
+ userSignup: {
+ address: 'user/signup',
+ description: 'This channel is used to exchange messages about users signing up',
+ messages: {
+ SomeMessage: {
+ name: 'SomeMessage',
+ description: 'A longer description of the message',
+ payload: {
+ type: 'object',
+ properties: {
+ user: {
+ type: 'string'
+ },
+ signup: {
+ type: 'number'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ operations: {
+ userSignedUp: {
+ action: 'send',
+ channel: {
+ $ref: '#/channels/userSignup'
+ },
+ externalDocs: {
+ description: 'More info here',
+ url: 'https://example.com'
+ },
+ tags: [
+ { name: 'user' },
+ { name: 'signup' },
+ { name: 'register' }
+ ],
+ summary: 'A user signed up.',
+ bindings: {
+ kafka: {
+ groupId: {
+ type: 'string',
+ enum: [
+ 'myGroupId'
+ ]
+ },
+ clientId: {
+ type: 'string',
+ enum: [
+ 'myClientId'
+ ]
+ },
+ bindingVersion: '0.1.0'
+ }
+ },
+ }
+ }
+ });
+
+ expect(diagnostics).toEqual([]);
+ const result = render();
+ expect(result.trim()).toMatchSnapshot();
+ });
});
});
diff --git a/test/components/__snapshots__/AsyncAPI.test.js.snap b/test/components/__snapshots__/AsyncAPI.test.js.snap
index a93c99659..d9b93f70e 100644
--- a/test/components/__snapshots__/AsyncAPI.test.js.snap
+++ b/test/components/__snapshots__/AsyncAPI.test.js.snap
@@ -44,7 +44,7 @@ Test broker
## Operations
-### SUB \`smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured\` Operation
+### PUB \`smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured\` Operation
*Inform about environmental lighting conditions of a particular streetlight.*
@@ -132,7 +132,7 @@ On multiple lines.
| message-tag5 | - | [Find more info here](https://www.asyncapi.com/) |
-### PUB \`smartylighting/streetlights/1/0/action/{streetlightId}/turn/on\` Operation
+### SUB \`smartylighting/streetlights/1/0/action/{streetlightId}/turn/on\` Operation
* Operation ID: \`turnOn\`
@@ -191,7 +191,7 @@ On multiple lines.
-### PUB \`smartylighting/streetlights/1/0/action/{streetlightId}/turn/off\` Operation
+### SUB \`smartylighting/streetlights/1/0/action/{streetlightId}/turn/off\` Operation
* Operation ID: \`turnOff\`
@@ -250,7 +250,7 @@ On multiple lines.
-### PUB \`smartylighting/streetlights/1/0/action/{streetlightId}/dim\` Operation
+### SUB \`smartylighting/streetlights/1/0/action/{streetlightId}/dim\` Operation
* Operation ID: \`dimLight\`
@@ -308,7 +308,7 @@ On multiple lines.
-### PUB \`some.channel\` Operation
+### SUB \`some.channel\` Operation
this description shows in markdown
@@ -473,8 +473,7 @@ Kafka DEV cluster for \`dev\` and \`sit\` environments
### REPLY \`adeo-{env}-case-study-COSTING-REQUEST-{version}\` Operation
-*[COSTING] Request one or more Costing calculation for any product
-*
+*[COSTING] Request one or more Costing calculation for any product*
* Operation ID: \`requestCosting\`
@@ -563,17 +562,16 @@ You can try a costing request using our [Conduktor producer template](https://co
#### Response information
-* Response should be done to channel: \`adeo-{env}-case-study-COSTING-RESPONSE-{version}\`
+* should be done to channel: \`adeo-{env}-case-study-COSTING-RESPONSE-{version}\`
#### Operation reply address information
* Operation reply address location: \`$message.header#/REPLY_TOPIC\`
-### PUB \`adeo-{env}-case-study-COSTING-RESPONSE-{version}\` Operation
+### SEND \`adeo-{env}-case-study-COSTING-RESPONSE-{version}\` Operation
-*[COSTING] Get the costing responses matching an initial Costing Request.
-*
+*[COSTING] Get the costing responses matching an initial Costing Request.*
* Operation ID: \`getCostingResponse\`
diff --git a/test/components/__snapshots__/Operations.test.js.snap b/test/components/__snapshots__/Operations.test.js.snap
index 4c80cd458..a9d99bce6 100644
--- a/test/components/__snapshots__/Operations.test.js.snap
+++ b/test/components/__snapshots__/Operations.test.js.snap
@@ -1,142 +1,360 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Operations component should render reply operation 1`] = `
+exports[`Operations component for AsyncAPI v3 should render bindings for channel 1`] = `
"## Operations
-### REQUEST \`/\` Operation
+### SEND \`user/signup\` Operation
-* Operation ID: \`subscribe\`
+*A user signed up.*
-Accepts **one of** the following messages:
+* Operation ID: \`userSignedUp\`
-#### Message \`subscribe\`
+This channel is used to exchange messages about users signing up
-Subscribe to a topic on a single or multiple currency pairs.
+[More info here](https://example.com)
+
+##### Operation tags
+
+| Name | Description | Documentation |
+|---|---|---|
+| user | - | - |
+| signup | - | - |
+| register | - | - |
+
+#### \`http\` Channel specific information
+
+| Name | Type | Description | Value | Constraints | Notes |
+|---|---|---|---|---|---|
+| type | - | - | \`\\"request\\"\` | - | - |
+| method | - | - | \`\\"GET\\"\` | - | - |
+| query | object | - | - | - | **additional properties are NOT allowed** |
+| query.companyId | number | The Id of the company. | - | >= 1 | **required** |
+| bindingVersion | - | - | \`\\"0.1.0\\"\` | - | - |
+
+#### Message \`SomeMessage\`
+
+A longer description of the message
##### Payload
| Name | Type | Description | Value | Constraints | Notes |
|---|---|---|---|---|---|
| (root) | object | - | - | - | **additional properties are allowed** |
-| event | string | - | const (\`\\"subscribe\\"\`) | - | - |
+| user | string | - | - | - | - |
+| signup | number | - | - | - | - |
> Examples of payload _(generated)_
\`\`\`json
{
- \\"event\\": \\"subscribe\\"
+ \\"user\\": \\"string\\",
+ \\"signup\\": 0
}
-\`\`\`
+\`\`\`"
+`;
+
+exports[`Operations component for AsyncAPI v3 should render bindings for operation 1`] = `
+"## Operations
+
+### SEND \`user/signup\` Operation
+
+*A user signed up.*
+* Operation ID: \`userSignedUp\`
-#### Message \`unsubscribe\`
+This channel is used to exchange messages about users signing up
-Unsubscribe, can specify a channelID or multiple currency pairs.
+[More info here](https://example.com)
+
+##### Operation tags
+
+| Name | Description | Documentation |
+|---|---|---|
+| user | - | - |
+| signup | - | - |
+| register | - | - |
+
+#### \`kafka\` Operation specific information
+
+| Name | Type | Description | Value | Constraints | Notes |
+|---|---|---|---|---|---|
+| groupId | string | - | allowed (\`\\"myGroupId\\"\`) | - | - |
+| clientId | string | - | allowed (\`\\"myClientId\\"\`) | - | - |
+| bindingVersion | - | - | \`\\"0.1.0\\"\` | - | - |
+
+#### Message \`SomeMessage\`
+
+A longer description of the message
##### Payload
| Name | Type | Description | Value | Constraints | Notes |
|---|---|---|---|---|---|
| (root) | object | - | - | - | **additional properties are allowed** |
-| event | string | - | const (\`\\"unsubscribe\\"\`) | - | - |
+| user | string | - | - | - | - |
+| signup | number | - | - | - | - |
> Examples of payload _(generated)_
\`\`\`json
{
- \\"event\\": \\"unsubscribe\\"
+ \\"user\\": \\"string\\",
+ \\"signup\\": 0
}
-\`\`\`
+\`\`\`"
+`;
+
+exports[`Operations component for AsyncAPI v3 should render multiple messages 1`] = `
+"## Operations
+
+### SEND \`user/{userId}/signup/{foobar}\` Operation
+*A user signed up.*
-#### Message \`response\`
+* Operation ID: \`userSignedUp\`
+
+This channel is used to exchange messages about users signing up
+
+[More info here](https://example.com)
+
+##### Operation tags
+
+| Name | Description | Documentation |
+|---|---|---|
+| user | - | - |
+| signup | - | - |
+| register | - | - |
+
+#### Parameters
+
+| Name | Type | Description | Value | Constraints | Notes |
+|---|---|---|---|---|---|
+| userId | string | Id of the user. | - | - | **required**, **parameter location ($message.payload#/user/id)** |
+| foobar | string | - | - | - | **required** |
+
+
+Sending **one of** the following messages:
+
+#### Message \`SomeMessage\`
+
+A longer description of the message
##### Payload
| Name | Type | Description | Value | Constraints | Notes |
|---|---|---|---|---|---|
| (root) | object | - | - | - | **additional properties are allowed** |
-| status | number | - | - | - | - |
+| user | string | - | - | - | - |
+| signup | number | - | - | - | - |
> Examples of payload _(generated)_
\`\`\`json
{
- \\"status\\": 0
+ \\"user\\": \\"string\\",
+ \\"signup\\": 0
}
\`\`\`
-#### Request information
+#### Message \`SomeMessage2\`
+
+A longer description of the message
+
+##### Payload
+
+| Name | Type | Description | Value | Constraints | Notes |
+|---|---|---|---|---|---|
+| (root) | object | - | - | - | **additional properties are allowed** |
+| signup | number | - | - | - | - |
+
+> Examples of payload _(generated)_
+
+\`\`\`json
+{
+ \\"signup\\": 0
+}
+\`\`\`"
+`;
-* Request should be done to channel: \`/\`
+exports[`Operations component for AsyncAPI v3 should render receive operation 1`] = `
+"## Operations
+
+### RECEIVE \`user/signedup\` Operation
+
+*A user signed up.*
+
+* Operation ID: \`userSignedUp\`
+This channel is used to exchange messages about users signing up
-### REPLY \`/\` Operation
+[More info here](https://example.com)
-* Operation ID: \`unsubscribe\`
+##### Operation tags
-Accepts **one of** the following messages:
+| Name | Description | Documentation |
+|---|---|---|
+| user | - | - |
+| signup | - | - |
+| register | - | - |
-#### Message \`subscribe\`
+#### Message \`SomeMessage\`
-Subscribe to a topic on a single or multiple currency pairs.
+A longer description of the message
##### Payload
| Name | Type | Description | Value | Constraints | Notes |
|---|---|---|---|---|---|
| (root) | object | - | - | - | **additional properties are allowed** |
-| event | string | - | const (\`\\"subscribe\\"\`) | - | - |
+| user | string | - | - | - | - |
+| signup | number | - | - | - | - |
> Examples of payload _(generated)_
\`\`\`json
{
- \\"event\\": \\"subscribe\\"
+ \\"user\\": \\"string\\",
+ \\"signup\\": 0
}
-\`\`\`
+\`\`\`"
+`;
+
+exports[`Operations component for AsyncAPI v3 should render reply operation 1`] = `
+"## Operations
+
+### REPLY \`user/signedup\` Operation
+
+*Sign up a user.*
+
+* Operation ID: \`userSignUp\`
+
+This channel is used to exchange messages about users signing up
+
+[More info here](https://example.com)
+
+##### Operation tags
+| Name | Description | Documentation |
+|---|---|---|
+| user | - | - |
+| signup | - | - |
+| register | - | - |
-#### Message \`unsubscribe\`
+#### Message \`SomeMessage\`
-Unsubscribe, can specify a channelID or multiple currency pairs.
+A longer description of the message
##### Payload
| Name | Type | Description | Value | Constraints | Notes |
|---|---|---|---|---|---|
| (root) | object | - | - | - | **additional properties are allowed** |
-| event | string | - | const (\`\\"unsubscribe\\"\`) | - | - |
+| user | string | - | - | - | - |
+| signup | number | - | - | - | - |
> Examples of payload _(generated)_
\`\`\`json
{
- \\"event\\": \\"unsubscribe\\"
+ \\"user\\": \\"string\\",
+ \\"signup\\": 0
}
\`\`\`
-#### Message \`response\`
+#### Response information
+
+* should be done to channel: \`user/signedup\`"
+`;
+
+exports[`Operations component for AsyncAPI v3 should render request operation 1`] = `
+"## Operations
+
+### REQUEST \`user/signedup\` Operation
+
+*Sign up a user.*
+
+* Operation ID: \`userSignUp\`
+
+This channel is used to exchange messages about users signing up
+
+[More info here](https://example.com)
+
+##### Operation tags
+
+| Name | Description | Documentation |
+|---|---|---|
+| user | - | - |
+| signup | - | - |
+| register | - | - |
+
+#### Message \`SomeMessage\`
+
+A longer description of the message
##### Payload
| Name | Type | Description | Value | Constraints | Notes |
|---|---|---|---|---|---|
| (root) | object | - | - | - | **additional properties are allowed** |
-| status | number | - | - | - | - |
+| user | string | - | - | - | - |
+| signup | number | - | - | - | - |
> Examples of payload _(generated)_
\`\`\`json
{
- \\"status\\": 0
+ \\"user\\": \\"string\\",
+ \\"signup\\": 0
}
\`\`\`
-#### Response information
+#### Request information
+
+* should be done to channel: \`user/signedup\`"
+`;
+
+exports[`Operations component for AsyncAPI v3 should render send operation 1`] = `
+"## Operations
+
+### SEND \`user/signedup\` Operation
+
+*A user signed up.*
+
+* Operation ID: \`userSignedUp\`
+
+This channel is used to exchange messages about users signing up
+
+[More info here](https://example.com)
+
+##### Operation tags
+
+| Name | Description | Documentation |
+|---|---|---|
+| user | - | - |
+| signup | - | - |
+| register | - | - |
-* Response should be done to channel: \`/\`"
+#### Message \`SomeMessage\`
+
+A longer description of the message
+
+##### Payload
+
+| Name | Type | Description | Value | Constraints | Notes |
+|---|---|---|---|---|---|
+| (root) | object | - | - | - | **additional properties are allowed** |
+| user | string | - | - | - | - |
+| signup | number | - | - | - | - |
+
+> Examples of payload _(generated)_
+
+\`\`\`json
+{
+ \\"user\\": \\"string\\",
+ \\"signup\\": 0
+}
+\`\`\`"
`;