Skip to content

Commit

Permalink
added support for req/rep
Browse files Browse the repository at this point in the history
  • Loading branch information
AceTheCreator committed Sep 20, 2023
1 parent f19da7e commit a5f9594
Show file tree
Hide file tree
Showing 9 changed files with 1,149 additions and 26,552 deletions.
4 changes: 2 additions & 2 deletions library/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions library/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export interface ConfigInterface {
parserOptions?: any;
publishLabel?: string;
subscribeLabel?: string;
requestLabel?: string;
replyLabel?: string;
}

export interface ShowConfig {
Expand Down
4 changes: 4 additions & 0 deletions library/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export const PUBLISH_TEXT = 'Publish';
export const PUBLISH_LABEL_DEFAULT_TEXT = 'PUB';
export const SUBSCRIBE_TEXT = 'Subscribe';
export const SUBSCRIBE_LABEL_DEFAULT_TEXT = 'SUB';
export const REQUEST_TEXT = 'Request';
export const REQUEST_LABEL_DEFAULT_TEXT = 'REQUEST';
export const REPLIER_TEXT = 'Reply';
export const REPLIER_LABEL_DEFAULT_TEXT = 'REPLY';
export const REQUIRED_TEXT = 'Required';
export const GENERATED_TEXT = 'Generated';

Expand Down
14 changes: 12 additions & 2 deletions library/src/containers/Messages/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const Message: React.FunctionComponent<Props> = ({
}

// check typeof as fallback for older version than `2.4.0`
const messageId = typeof message.id === 'function' && message.id();
let messageId = typeof message.id === 'function' && message.id();
const title = message.title();
const summary = message.summary();
const payload = message.payload();
Expand All @@ -49,6 +49,16 @@ export const Message: React.FunctionComponent<Props> = ({
const externalDocs = message.externalDocs();
const showInfoList = contentType || externalDocs;

// For some reason the parser is returning the wrong message ID,
// when retrieving reply() messages that's the reason retrieving it this way
const xParserMessageName = message.json()['x-parser-message-name'];
if (
!messageId ||
Number(messageId) == index ||
(Number(messageId) == 0 && xParserMessageName)
) {
messageId = xParserMessageName;
}
return (
<div className="panel-item">
<div className="panel-item--center px-8">
Expand All @@ -59,7 +69,7 @@ export const Message: React.FunctionComponent<Props> = ({
)}
{title && <span className="text-gray-700 mr-2">{title}</span>}
<span className="border text-orange-600 rounded text-xs py-0 px-2">
{message.id()}
{messageId}
</span>
</div>

Expand Down
166 changes: 160 additions & 6 deletions library/src/containers/Operations/Operation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { ChannelInterface, OperationInterface } from '@asyncapi/parser';

import { Message } from '../Messages/Message';
Expand All @@ -10,13 +10,16 @@ import {
Bindings,
Tags,
Extensions,
CollapseButton,
} from '../../components';

import { useConfig } from '../../contexts';
import { CommonHelpers, SchemaHelpers } from '../../helpers';
import {
EXTERAL_DOCUMENTATION_TEXT,
PUBLISH_LABEL_DEFAULT_TEXT,
REPLIER_LABEL_DEFAULT_TEXT,
REQUEST_LABEL_DEFAULT_TEXT,
SUBSCRIBE_LABEL_DEFAULT_TEXT,
} from '../../constants';
import { PayloadType } from '../../types';
Expand All @@ -30,7 +33,7 @@ interface Props {

export const Operation: React.FunctionComponent<Props> = props => {
const config = useConfig();
const { type = PayloadType.PUBLISH, operation, channelName, channel } = props;
const { type = PayloadType.SEND, operation, channelName, channel } = props;

if (!operation || !channel) {
return null;
Expand Down Expand Up @@ -168,36 +171,53 @@ export const Operation: React.FunctionComponent<Props> = props => {
</div>
)}
</div>

<OperationReplyInfo {...props} />
</div>
);
};

function getTypeInformation({
type = PayloadType.PUBLISH,
type = PayloadType.SEND,
config,
}: {
type: PayloadType;
config: ConfigInterface;
}): { borderColor: string; typeLabel: string } {
if (type === PayloadType.SUBSCRIBE) {
if (type === PayloadType.RECIEVE) {
return {
borderColor: 'border-green-600 text-green-600',
typeLabel: config.subscribeLabel ?? SUBSCRIBE_LABEL_DEFAULT_TEXT,
};
}
// type === PayloadType.PUBLISH
if (type === PayloadType.REPLY) {
return {
borderColor: 'border-orange-600 text-orange-600',
typeLabel: config.replyLabel || REPLIER_LABEL_DEFAULT_TEXT,
};
}
if (type === PayloadType.REQUEST) {
return {
borderColor: 'border-red-600 text-red-600',
typeLabel: config.requestLabel || REQUEST_LABEL_DEFAULT_TEXT,
};
}
return {
borderColor: 'border-blue-600 text-blue-500',
typeLabel: config.publishLabel ?? PUBLISH_LABEL_DEFAULT_TEXT,
};
}

export const OperationInfo: React.FunctionComponent<Props> = props => {
const { type = PayloadType.PUBLISH, operation, channelName, channel } = props;
const { operation, channelName, channel } = props;
let type = PayloadType.SEND;
const config = useConfig();
const operationSummary = operation.summary();
const externalDocs = operation.externalDocs();
const operationId = operation.id();
if (operation.action() !== type) {
type = PayloadType.RECIEVE;
}
const { borderColor, typeLabel } = getTypeInformation({ type, config });

return (
Expand Down Expand Up @@ -256,3 +276,137 @@ export const OperationInfo: React.FunctionComponent<Props> = props => {
</>
);
};

export const OperationReplyInfo: React.FunctionComponent<Props> = props => {
const { type = PayloadType.SEND, operation } = props;
const [showMessages, setShowMessages] = useState(false);
if (type !== PayloadType.REPLY && type !== PayloadType.REQUEST) return <></>;
const reply = operation.reply();
if (reply === undefined) return <></>;
const config = useConfig();
const { typeLabel } = getTypeInformation({ type, config });
const replyMessages = reply.messages();
const explicitChannel = reply.channel();

return (
<>
<div className="font-mono px-8 py-4">
<div className="border rounded">
<div className="flex items-center pt-4">
<div
className={`w-1 h-11 ${
typeLabel === 'SEND' ? 'bg-red-600' : 'bg-orange-600'
}`}
></div>
<div className="p-4">
<h3 className="text-sm">
<span className="mr-2 uppercase" title={type}>
{typeLabel === 'SEND' ? 'Requester' : 'Replier'} information
</span>
</h3>
{explicitChannel && (
<div className="text-xs text-gray-700">
{typeLabel} should be done on channel
<span className="border text-orange-600 rounded text-xs ml-2 py-0 px-2">
{explicitChannel.address()}
</span>
</div>
)}
</div>
</div>
{replyMessages.isEmpty() === false && (
<div className="px-4 py-2">
<CollapseButton
onClick={() => setShowMessages(prev => !prev)}
expanded={showMessages}
>
<span className="inline-block py-0.5 mr-1 text-gray-500 text-sm text-center rounded focus:outline-none">
Expected Reply{' '}
{replyMessages.length > 1 ? 'Messages' : 'Message'}
</span>
</CollapseButton>
<div
className={`w-full mt-4 ${showMessages ? 'block' : 'hidden'}`}
>
{replyMessages.length > 1 ? (
<div className="mt-2">
<ul>
{replyMessages.all().map((msg, idx) => (
<li className="mt-4" key={idx}>
<Message
message={msg}
index={idx}
showExamples={true}
/>
</li>
))}
</ul>
</div>
) : (
<div className="mt-2">
<div className="mt-2">
<Message
message={replyMessages.all()[0]}
showExamples={true}
/>
</div>
</div>
)}
</div>
</div>
)}
</div>
</div>
<OperationReplyAddressInfo {...props} />

<Extensions name="Operation Reply Extensions" item={reply} />
</>
);
};

export const OperationReplyAddressInfo: React.FunctionComponent<Props> = ({
type = PayloadType.SEND,
operation,
}) => {
if (type !== PayloadType.REPLY && type !== PayloadType.REQUEST) return <></>;
const reply = operation.reply();
if (reply === undefined || !reply.hasAddress()) return <></>;
const config = useConfig();
const { typeLabel } = getTypeInformation({ type, config });
const replyAddress = reply.address()!;
const replyAddressLocation = replyAddress.location();

return (
<>
<div className="mb-4">
<h3>
<span
className={`font-mono border uppercase p-1 rounded mr-2`}
title={type}
>
Operation {typeLabel} address information
</span>
</h3>
</div>

{replyAddress.hasDescription() && (
<div className="mt-2">
<Markdown>{replyAddress.description()}</Markdown>
</div>
)}

{replyAddressLocation && (
<div className="border bg-gray-100 rounded px-4 py-2 mt-2">
<div className="text-sm text-gray-700">
Operation {typeLabel} address location
<span className="border text-orange-600 rounded text-xs ml-2 py-0 px-2">
{replyAddressLocation}
</span>
</div>
</div>
)}

<Extensions name="Operation Reply Address Extensions" item={reply} />
</>
);
};
Loading

0 comments on commit a5f9594

Please sign in to comment.