mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-07 21:54:53 +03:00
feat: add jsonrpc support
This commit is contained in:
parent
c6b7d567d9
commit
c160fbd991
|
@ -22,6 +22,7 @@ export interface EndpointProps {
|
||||||
hideHostname?: boolean;
|
hideHostname?: boolean;
|
||||||
inverted?: boolean;
|
inverted?: boolean;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
|
isJsonRpc?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EndpointState {
|
export interface EndpointState {
|
||||||
|
@ -41,7 +42,7 @@ export class Endpoint extends React.Component<EndpointProps, EndpointState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { operation, inverted, hideHostname } = this.props;
|
const { operation, inverted, hideHostname, isJsonRpc } = this.props;
|
||||||
const { expanded } = this.state;
|
const { expanded } = this.state;
|
||||||
|
|
||||||
// TODO: highlight server variables, e.g. https://{user}.test.com
|
// TODO: highlight server variables, e.g. https://{user}.test.com
|
||||||
|
@ -80,7 +81,7 @@ export class Endpoint extends React.Component<EndpointProps, EndpointState> {
|
||||||
: basePath
|
: basePath
|
||||||
: normalizedUrl}
|
: normalizedUrl}
|
||||||
</span>
|
</span>
|
||||||
{operation.path}
|
{!!isJsonRpc ? `/json` : operation.path}
|
||||||
</ServerUrl>
|
</ServerUrl>
|
||||||
</SelectOnClick>
|
</SelectOnClick>
|
||||||
</ServerItem>
|
</ServerItem>
|
||||||
|
|
|
@ -37,7 +37,7 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
render() {
|
render() {
|
||||||
const { operation } = this.props;
|
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);
|
const hasDescription = !!(description || externalDocs);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -49,9 +49,10 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
<ShareLink to={operation.id} />
|
<ShareLink to={operation.id} />
|
||||||
{summary} {deprecated && <Badge type="warning"> Deprecated </Badge>}
|
{summary} {deprecated && <Badge type="warning"> Deprecated </Badge>}
|
||||||
{isWebhook && <Badge type="primary"> Webhook </Badge>}
|
{isWebhook && <Badge type="primary"> Webhook </Badge>}
|
||||||
|
{isJsonRpc && <Badge type="primary"> JSON-RPC </Badge>}
|
||||||
</H2>
|
</H2>
|
||||||
{options.pathInMiddlePanel && !isWebhook && (
|
{options.pathInMiddlePanel && !isWebhook && (
|
||||||
<Endpoint operation={operation} inverted={true} />
|
<Endpoint operation={operation} inverted={true} isJsonRpc={isJsonRpc} />
|
||||||
)}
|
)}
|
||||||
{hasDescription && (
|
{hasDescription && (
|
||||||
<Description>
|
<Description>
|
||||||
|
@ -66,7 +67,7 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
<CallbacksList callbacks={operation.callbacks} />
|
<CallbacksList callbacks={operation.callbacks} />
|
||||||
</MiddlePanel>
|
</MiddlePanel>
|
||||||
<DarkRightPanel>
|
<DarkRightPanel>
|
||||||
{!options.pathInMiddlePanel && !isWebhook && <Endpoint operation={operation} />}
|
{!options.pathInMiddlePanel && (!isWebhook || !isJsonRpc) && <Endpoint operation={operation} isJsonRpc={isJsonRpc} />}
|
||||||
<RequestSamples operation={operation} />
|
<RequestSamples operation={operation} />
|
||||||
<ResponseSamples operation={operation} />
|
<ResponseSamples operation={operation} />
|
||||||
<CallbackSamples callbacks={operation.callbacks} />
|
<CallbackSamples callbacks={operation.callbacks} />
|
||||||
|
|
|
@ -91,11 +91,7 @@ export class OperationMenuItemContent extends React.Component<OperationMenuItemC
|
||||||
deprecated={item.deprecated}
|
deprecated={item.deprecated}
|
||||||
ref={this.ref}
|
ref={this.ref}
|
||||||
>
|
>
|
||||||
{item.isWebhook ? (
|
{this.renderOperationBadge(item)}
|
||||||
<OperationBadge type="hook">{l('webhook')}</OperationBadge>
|
|
||||||
) : (
|
|
||||||
<OperationBadge type={item.httpVerb}>{shortenHTTPVerb(item.httpVerb)}</OperationBadge>
|
|
||||||
)}
|
|
||||||
<MenuItemTitle width="calc(100% - 38px)">
|
<MenuItemTitle width="calc(100% - 38px)">
|
||||||
{item.name}
|
{item.name}
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
|
@ -103,4 +99,14 @@ export class OperationMenuItemContent extends React.Component<OperationMenuItemC
|
||||||
</MenuItemLabel>
|
</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>
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import styled, { css, ResolvedThemeInterface } from '../../styled-components';
|
||||||
export const OperationBadge = styled.span.attrs((props: { type: string }) => ({
|
export const OperationBadge = styled.span.attrs((props: { type: string }) => ({
|
||||||
className: `operation-type ${props.type}`,
|
className: `operation-type ${props.type}`,
|
||||||
}))<{ type: string }>`
|
}))<{ type: string }>`
|
||||||
width: 9ex;
|
width: 15ex;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: ${props => props.theme.typography.code.fontSize};
|
height: ${props => props.theme.typography.code.fontSize};
|
||||||
line-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;') || ''}
|
(type === 'section' && depth > 1 && 'padding-left: ' + theme.spacing.unit * 8 + 'px;') || ''}
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
font-family: ${props => props.theme.typography.headings.fontFamily};
|
font-family: ${props => props.theme.typography.headings.fontFamily};
|
||||||
${props => menuItemDepth[props.depth]};
|
${props => menuItemDepth[props.depth]};
|
||||||
background-color: ${props => (props.active ? menuItemActiveBg(props.depth, props) : '')};
|
background-color: ${props => (props.active ? menuItemActiveBg(props.depth, props) : '')};
|
||||||
|
|
|
@ -9,6 +9,7 @@ export interface LabelsConfig {
|
||||||
recursive: string;
|
recursive: string;
|
||||||
arrayOf: string;
|
arrayOf: string;
|
||||||
webhook: string;
|
webhook: string;
|
||||||
|
jsonrpc: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LabelsConfigRaw = Partial<LabelsConfig>;
|
export type LabelsConfigRaw = Partial<LabelsConfig>;
|
||||||
|
@ -24,6 +25,7 @@ const labels: LabelsConfig = {
|
||||||
recursive: 'Recursive',
|
recursive: 'Recursive',
|
||||||
arrayOf: 'Array of ',
|
arrayOf: 'Array of ',
|
||||||
webhook: 'Event',
|
webhook: 'Event',
|
||||||
|
jsonrpc: 'Json-RPC',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function setRedocLabels(_labels?: LabelsConfigRaw) {
|
export function setRedocLabels(_labels?: LabelsConfigRaw) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ export type ExtendedOpenAPIOperation = {
|
||||||
pathParameters: Array<Referenced<OpenAPIParameter>>;
|
pathParameters: Array<Referenced<OpenAPIParameter>>;
|
||||||
pathServers: Array<OpenAPIServer> | undefined;
|
pathServers: Array<OpenAPIServer> | undefined;
|
||||||
isWebhook: boolean;
|
isWebhook: boolean;
|
||||||
|
isJsonRpc: boolean;
|
||||||
} & OpenAPIOperation;
|
} & OpenAPIOperation;
|
||||||
|
|
||||||
export type TagsInfoMap = Record<string, TagInfo>;
|
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
|
* 그룹의 태그 또는 모든 태그에 대한 OperationsGroup 항목의 배열을 반환한다.
|
||||||
* @param tagsMap tags info returned from `getTagsWithOperations`
|
* @param tagsMap `getTagsWithOperations`에서 반환된 태그 정보
|
||||||
* @param parent parent item
|
* @param parent 상위 항목
|
||||||
* @param group group which this tag belongs to. if not provided gets all tags
|
* @param group 이 태그가 속한 그룹. 주어지지 않으면 모든 태그를 가져온다.
|
||||||
*/
|
*/
|
||||||
static getTagsItems(
|
static getTagsItems(
|
||||||
parser: OpenAPIParser,
|
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 {
|
static getTagsWithOperations(spec: OpenAPISpec): TagsInfoMap {
|
||||||
const tags: TagsInfoMap = {};
|
const tags: TagsInfoMap = {};
|
||||||
|
@ -225,8 +226,11 @@ export class MenuBuilder {
|
||||||
if (spec['x-webhooks']) {
|
if (spec['x-webhooks']) {
|
||||||
getTags(spec['x-webhooks'], true);
|
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)) {
|
for (const pathName of Object.keys(paths)) {
|
||||||
const path = paths[pathName];
|
const path = paths[pathName];
|
||||||
const operations = Object.keys(path).filter(isOperationName);
|
const operations = Object.keys(path).filter(isOperationName);
|
||||||
|
@ -259,6 +263,7 @@ export class MenuBuilder {
|
||||||
pathParameters: path.parameters || [],
|
pathParameters: path.parameters || [],
|
||||||
pathServers: path.servers,
|
pathServers: path.servers,
|
||||||
isWebhook: !!isWebhook,
|
isWebhook: !!isWebhook,
|
||||||
|
isJsonRpc: !!isJsonRpc,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { SecuritySchemesModel } from './models/SecuritySchemes';
|
||||||
import { OpenAPIParser } from './OpenAPIParser';
|
import { OpenAPIParser } from './OpenAPIParser';
|
||||||
import { RedocNormalizedOptions } from './RedocNormalizedOptions';
|
import { RedocNormalizedOptions } from './RedocNormalizedOptions';
|
||||||
/**
|
/**
|
||||||
* Store that contains all the specification related information in the form of tree
|
* 모든 specification 관련 정보를 트리 형태로 포함하는 Store
|
||||||
*/
|
*/
|
||||||
export class SpecStore {
|
export class SpecStore {
|
||||||
parser: OpenAPIParser;
|
parser: OpenAPIParser;
|
||||||
|
|
|
@ -76,6 +76,7 @@ export class OperationModel implements IMenuItem {
|
||||||
extensions: Record<string, any>;
|
extensions: Record<string, any>;
|
||||||
isCallback: boolean;
|
isCallback: boolean;
|
||||||
isWebhook: boolean;
|
isWebhook: boolean;
|
||||||
|
isJsonRpc: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private parser: OpenAPIParser,
|
private parser: OpenAPIParser,
|
||||||
|
@ -99,6 +100,7 @@ export class OperationModel implements IMenuItem {
|
||||||
this.path = operationSpec.pathName;
|
this.path = operationSpec.pathName;
|
||||||
this.isCallback = isCallback;
|
this.isCallback = isCallback;
|
||||||
this.isWebhook = !!operationSpec.isWebhook;
|
this.isWebhook = !!operationSpec.isWebhook;
|
||||||
|
this.isJsonRpc = !!operationSpec.isJsonRpc;
|
||||||
|
|
||||||
this.name = getOperationSummary(operationSpec);
|
this.name = getOperationSummary(operationSpec);
|
||||||
|
|
||||||
|
|
1
src/types/open-api.d.ts
vendored
1
src/types/open-api.d.ts
vendored
|
@ -10,6 +10,7 @@ export interface OpenAPISpec {
|
||||||
tags?: OpenAPITag[];
|
tags?: OpenAPITag[];
|
||||||
externalDocs?: OpenAPIExternalDocumentation;
|
externalDocs?: OpenAPIExternalDocumentation;
|
||||||
'x-webhooks'?: OpenAPIPaths;
|
'x-webhooks'?: OpenAPIPaths;
|
||||||
|
'jsonrpc'?: OpenAPIPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenAPIInfo {
|
export interface OpenAPIInfo {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user