feat: add jsonrpc support

This commit is contained in:
jun097kim 2020-11-20 09:49:44 +09:00
parent c6b7d567d9
commit c160fbd991
9 changed files with 37 additions and 18 deletions

View File

@ -22,6 +22,7 @@ export interface EndpointProps {
hideHostname?: boolean;
inverted?: boolean;
compact?: boolean;
isJsonRpc?: boolean;
}
export interface EndpointState {
@ -41,7 +42,7 @@ export class Endpoint extends React.Component<EndpointProps, EndpointState> {
};
render() {
const { operation, inverted, hideHostname } = this.props;
const { operation, inverted, hideHostname, isJsonRpc } = this.props;
const { expanded } = this.state;
// TODO: highlight server variables, e.g. https://{user}.test.com
@ -80,7 +81,7 @@ export class Endpoint extends React.Component<EndpointProps, EndpointState> {
: basePath
: normalizedUrl}
</span>
{operation.path}
{!!isJsonRpc ? `/json` : operation.path}
</ServerUrl>
</SelectOnClick>
</ServerItem>

View File

@ -37,7 +37,7 @@ export class Operation extends React.Component<OperationProps> {
render() {
const { operation } = this.props;
const { name: summary, description, deprecated, externalDocs, isWebhook } = operation;
const { name: summary, description, deprecated, externalDocs, isWebhook, isJsonRpc } = operation;
const hasDescription = !!(description || externalDocs);
return (
@ -49,9 +49,10 @@ export class Operation extends React.Component<OperationProps> {
<ShareLink to={operation.id} />
{summary} {deprecated && <Badge type="warning"> Deprecated </Badge>}
{isWebhook && <Badge type="primary"> Webhook </Badge>}
{isJsonRpc && <Badge type="primary"> JSON-RPC </Badge>}
</H2>
{options.pathInMiddlePanel && !isWebhook && (
<Endpoint operation={operation} inverted={true} />
<Endpoint operation={operation} inverted={true} isJsonRpc={isJsonRpc} />
)}
{hasDescription && (
<Description>
@ -66,7 +67,7 @@ export class Operation extends React.Component<OperationProps> {
<CallbacksList callbacks={operation.callbacks} />
</MiddlePanel>
<DarkRightPanel>
{!options.pathInMiddlePanel && !isWebhook && <Endpoint operation={operation} />}
{!options.pathInMiddlePanel && (!isWebhook || !isJsonRpc) && <Endpoint operation={operation} isJsonRpc={isJsonRpc} />}
<RequestSamples operation={operation} />
<ResponseSamples operation={operation} />
<CallbackSamples callbacks={operation.callbacks} />

View File

@ -91,11 +91,7 @@ export class OperationMenuItemContent extends React.Component<OperationMenuItemC
deprecated={item.deprecated}
ref={this.ref}
>
{item.isWebhook ? (
<OperationBadge type="hook">{l('webhook')}</OperationBadge>
) : (
<OperationBadge type={item.httpVerb}>{shortenHTTPVerb(item.httpVerb)}</OperationBadge>
)}
{this.renderOperationBadge(item)}
<MenuItemTitle width="calc(100% - 38px)">
{item.name}
{this.props.children}
@ -103,4 +99,14 @@ export class OperationMenuItemContent extends React.Component<OperationMenuItemC
</MenuItemLabel>
);
}
renderOperationBadge(item: OperationModel) {
if (item.isWebhook) {
return <OperationBadge type="hook">{l('webhook')}</OperationBadge>
} else if (item.isJsonRpc) {
return <OperationBadge type="rpc">{l('jsonrpc')}</OperationBadge>;
} else {
return <OperationBadge type={item.httpVerb}>{shortenHTTPVerb(item.httpVerb)}</OperationBadge>
}
}
}

View File

@ -7,7 +7,7 @@ import styled, { css, ResolvedThemeInterface } from '../../styled-components';
export const OperationBadge = styled.span.attrs((props: { type: string }) => ({
className: `operation-type ${props.type}`,
}))<{ type: string }>`
width: 9ex;
width: 15ex;
display: inline-block;
height: ${props => props.theme.typography.code.fontSize};
line-height: ${props => props.theme.typography.code.fontSize};
@ -138,6 +138,7 @@ export const MenuItemLabel = styled.label.attrs((props: MenuItemLabelType) => ({
(type === 'section' && depth > 1 && 'padding-left: ' + theme.spacing.unit * 8 + 'px;') || ''}
display: flex;
justify-content: space-between;
align-items: center;
font-family: ${props => props.theme.typography.headings.fontFamily};
${props => menuItemDepth[props.depth]};
background-color: ${props => (props.active ? menuItemActiveBg(props.depth, props) : '')};

View File

@ -9,6 +9,7 @@ export interface LabelsConfig {
recursive: string;
arrayOf: string;
webhook: string;
jsonrpc: string;
}
export type LabelsConfigRaw = Partial<LabelsConfig>;
@ -24,6 +25,7 @@ const labels: LabelsConfig = {
recursive: 'Recursive',
arrayOf: 'Array of ',
webhook: 'Event',
jsonrpc: 'Json-RPC',
};
export function setRedocLabels(_labels?: LabelsConfigRaw) {

View File

@ -30,6 +30,7 @@ export type ExtendedOpenAPIOperation = {
pathParameters: Array<Referenced<OpenAPIParameter>>;
pathServers: Array<OpenAPIServer> | undefined;
isWebhook: boolean;
isJsonRpc: boolean;
} & OpenAPIOperation;
export type TagsInfoMap = Record<string, TagInfo>;
@ -129,10 +130,10 @@ export class MenuBuilder {
}
/**
* Returns array of OperationsGroup items for the tags of the group or for all tags
* @param tagsMap tags info returned from `getTagsWithOperations`
* @param parent parent item
* @param group group which this tag belongs to. if not provided gets all tags
* OperationsGroup .
* @param tagsMap `getTagsWithOperations`
* @param parent
* @param group . .
*/
static getTagsItems(
parser: OpenAPIParser,
@ -213,7 +214,7 @@ export class MenuBuilder {
}
/**
* collects tags and maps each tag to list of operations belonging to this tag
* operations .
*/
static getTagsWithOperations(spec: OpenAPISpec): TagsInfoMap {
const tags: TagsInfoMap = {};
@ -225,8 +226,11 @@ export class MenuBuilder {
if (spec['x-webhooks']) {
getTags(spec['x-webhooks'], true);
}
if (spec['jsonrpc']) {
getTags(spec['jsonrpc'], false, true);
}
function getTags(paths: OpenAPIPaths, isWebhook?: boolean) {
function getTags(paths: OpenAPIPaths, isWebhook?: boolean, isJsonRpc?: boolean) {
for (const pathName of Object.keys(paths)) {
const path = paths[pathName];
const operations = Object.keys(path).filter(isOperationName);
@ -259,6 +263,7 @@ export class MenuBuilder {
pathParameters: path.parameters || [],
pathServers: path.servers,
isWebhook: !!isWebhook,
isJsonRpc: !!isJsonRpc,
});
}
}

View File

@ -7,7 +7,7 @@ import { SecuritySchemesModel } from './models/SecuritySchemes';
import { OpenAPIParser } from './OpenAPIParser';
import { RedocNormalizedOptions } from './RedocNormalizedOptions';
/**
* Store that contains all the specification related information in the form of tree
* specification Store
*/
export class SpecStore {
parser: OpenAPIParser;

View File

@ -76,6 +76,7 @@ export class OperationModel implements IMenuItem {
extensions: Record<string, any>;
isCallback: boolean;
isWebhook: boolean;
isJsonRpc: boolean;
constructor(
private parser: OpenAPIParser,
@ -99,6 +100,7 @@ export class OperationModel implements IMenuItem {
this.path = operationSpec.pathName;
this.isCallback = isCallback;
this.isWebhook = !!operationSpec.isWebhook;
this.isJsonRpc = !!operationSpec.isJsonRpc;
this.name = getOperationSummary(operationSpec);

View File

@ -10,6 +10,7 @@ export interface OpenAPISpec {
tags?: OpenAPITag[];
externalDocs?: OpenAPIExternalDocumentation;
'x-webhooks'?: OpenAPIPaths;
'jsonrpc'?: OpenAPIPaths;
}
export interface OpenAPIInfo {