mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-08 06:04:56 +03:00
Update callbacks layout
This commit is contained in:
parent
b1ef91379a
commit
aa5d6c0c8e
|
@ -530,14 +530,15 @@ paths:
|
||||||
example: AAA-123-BBB-456
|
example: AAA-123-BBB-456
|
||||||
callbacks:
|
callbacks:
|
||||||
orderInProgress:
|
orderInProgress:
|
||||||
'/{$request.body#/callbackUrl}?event={$request.body#/eventName}':
|
'{$request.body#/callbackUrl}?event={$request.body#/eventName}':
|
||||||
servers:
|
servers:
|
||||||
- url: //petstore.swagger.io/v2
|
- url: //callback-url.path-level/v1
|
||||||
description: Default server callback
|
description: Path level server 1
|
||||||
- url: //petstore.swagger.io/sandbox
|
- url: //callback-url.path-level/v2
|
||||||
description: Sandbox server callback
|
description: Path level server 2
|
||||||
post:
|
post:
|
||||||
description: A callback triggered every time an Order is updated status to "inProgress"
|
summary: Order in Progress (Summary)
|
||||||
|
description: A callback triggered every time an Order is updated status to "inProgress" (Description)
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
|
@ -613,7 +614,12 @@ paths:
|
||||||
var_dump($e->getErrors());
|
var_dump($e->getErrors());
|
||||||
}
|
}
|
||||||
put:
|
put:
|
||||||
description: A Put callback triggered
|
description: Order in Progress (Only Description)
|
||||||
|
servers:
|
||||||
|
- url: //callback-url.operation-level/v1
|
||||||
|
description: Operation level server 1 (Path override)
|
||||||
|
- url: //callback-url.operation-level/v2
|
||||||
|
description: Operation level server 2 (Path override)
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
|
@ -656,9 +662,16 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
example: '123'
|
example: '123'
|
||||||
orderShipped:
|
orderShipped:
|
||||||
'/{$request.body#/callbackUrl}?event={$request.body#/eventName}':
|
'{$request.body#/callbackUrl}?event={$request.body#/eventName}':
|
||||||
post:
|
post:
|
||||||
description: A callback triggered every time an Order is shipped
|
description: |
|
||||||
|
Very long description
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
|
||||||
|
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
|
||||||
|
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||||
|
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
|
||||||
|
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
|
||||||
|
culpa qui officia deserunt mollit anim id est laborum.
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
|
@ -680,8 +693,10 @@ paths:
|
||||||
'200':
|
'200':
|
||||||
description: Callback successfully processed and no retries will be performed
|
description: Callback successfully processed and no retries will be performed
|
||||||
orderDelivered:
|
orderDelivered:
|
||||||
'/{$request.body#/callbackUrl}?event={$request.body#/eventName}':
|
'http://notificationServer.com?url={$request.body#/callbackUrl}&event={$request.body#/eventName}':
|
||||||
post:
|
post:
|
||||||
|
deprecated: true
|
||||||
|
summary: Order delivered
|
||||||
description: A callback triggered every time an Order is delivered to the recipient
|
description: A callback triggered every time an Order is delivered to the recipient
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
|
|
|
@ -6,21 +6,23 @@ import { CallbackDetailsWrap, StyledCallbackTitle } from '../Callbacks/styled.el
|
||||||
import { CallbackDetails } from './CallbackDetails';
|
import { CallbackDetails } from './CallbackDetails';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
|
// TODO: rename to Callback
|
||||||
export class CallbackView extends React.Component<{ callbackOperation: OperationModel }> {
|
export class CallbackView extends React.Component<{ callbackOperation: OperationModel }> {
|
||||||
toggle = () => {
|
toggle = () => {
|
||||||
this.props.callbackOperation.toggle();
|
this.props.callbackOperation.toggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { name, description, expanded } = this.props.callbackOperation;
|
const { name, expanded, httpVerb, deprecated } = this.props.callbackOperation;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StyledCallbackTitle
|
<StyledCallbackTitle
|
||||||
onClick={this.toggle}
|
onClick={this.toggle}
|
||||||
name={name}
|
name={name}
|
||||||
description={description}
|
|
||||||
opened={expanded}
|
opened={expanded}
|
||||||
|
httpVerb={httpVerb}
|
||||||
|
deprecated={deprecated}
|
||||||
/>
|
/>
|
||||||
{expanded && (
|
{expanded && (
|
||||||
<CallbackDetailsWrap>
|
<CallbackDetailsWrap>
|
||||||
|
|
|
@ -3,14 +3,28 @@ import * as React from 'react';
|
||||||
import { OperationModel } from '../../services/models';
|
import { OperationModel } from '../../services/models';
|
||||||
import { OperationItem } from '../ContentItems/ContentItems';
|
import { OperationItem } from '../ContentItems/ContentItems';
|
||||||
import { Endpoint } from '../Endpoint/Endpoint';
|
import { Endpoint } from '../Endpoint/Endpoint';
|
||||||
|
import { Markdown } from '../Markdown/Markdown';
|
||||||
|
import styled from '../../styled-components';
|
||||||
|
|
||||||
export class CallbackDetails extends React.PureComponent<{ callbackOperation: OperationModel }> {
|
export class CallbackDetails extends React.PureComponent<{ callbackOperation: OperationModel }> {
|
||||||
render() {
|
render() {
|
||||||
|
const description = this.props.callbackOperation.description;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Endpoint operation={this.props.callbackOperation} inverted={true} />
|
{description && (
|
||||||
|
<CallbackDescription>
|
||||||
|
<Markdown compact={true} inline={true} source={description} />
|
||||||
|
</CallbackDescription>
|
||||||
|
)}
|
||||||
|
<Endpoint operation={this.props.callbackOperation} inverted={true} compact={true} />
|
||||||
<OperationItem item={this.props.callbackOperation} />
|
<OperationItem item={this.props.callbackOperation} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CallbackDescription = styled.div`
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
`;
|
||||||
|
|
|
@ -1,25 +1,46 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { ShelfIcon } from '../../common-elements';
|
import { ShelfIcon } from '../../common-elements';
|
||||||
import { Markdown } from '../Markdown/Markdown';
|
import { OperationBadge } from '../SideMenu/styled.elements';
|
||||||
|
import { shortenHTTPVerb } from '../../utils/openapi';
|
||||||
|
import styled from '../../styled-components';
|
||||||
|
import { Badge } from '../../common-elements/';
|
||||||
|
import { l } from '../../services/Labels';
|
||||||
|
|
||||||
export interface CallbackTitleProps {
|
export interface CallbackTitleProps {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
|
||||||
opened?: boolean;
|
opened?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
httpVerb: string;
|
||||||
|
deprecated?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CallbackTitle extends React.PureComponent<CallbackTitleProps> {
|
export class CallbackTitle extends React.PureComponent<CallbackTitleProps> {
|
||||||
render() {
|
render() {
|
||||||
const { name, description, opened, className, onClick } = this.props;
|
const { name, opened, className, onClick, httpVerb, deprecated } = this.props;
|
||||||
return (
|
return (
|
||||||
<div className={className} onClick={onClick || undefined}>
|
<CallbackTitleWrapper className={className} onClick={onClick || undefined}>
|
||||||
|
<OperationBadgeStyled type={httpVerb}>{shortenHTTPVerb(httpVerb)}</OperationBadgeStyled>
|
||||||
<ShelfIcon size={'1.5em'} direction={opened ? 'down' : 'right'} float={'left'} />
|
<ShelfIcon size={'1.5em'} direction={opened ? 'down' : 'right'} float={'left'} />
|
||||||
<strong>{name} </strong>
|
<CallbackNameStyled deprecated={deprecated}>{name}</CallbackNameStyled>
|
||||||
{description && <Markdown compact={true} inline={true} source={description} />}
|
{deprecated ? <Badge type="warning"> {l('deprecated')} </Badge> : null}
|
||||||
</div>
|
</CallbackTitleWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CallbackTitleWrapper = styled.div`
|
||||||
|
& > * {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CallbackNameStyled = styled.span<{ deprecated?: boolean }>`
|
||||||
|
text-decoration: ${props => (props.deprecated ? 'line-through' : 'none')};
|
||||||
|
margin-right: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const OperationBadgeStyled = styled(OperationBadge)`
|
||||||
|
margin: 0px 5px 0px 0px;
|
||||||
|
`;
|
||||||
|
|
|
@ -43,7 +43,7 @@ export class CallbacksSwitch extends React.Component<CallbacksSwitchProps, Callb
|
||||||
|
|
||||||
const options = callbacks.map((callback, idx) => {
|
const options = callbacks.map((callback, idx) => {
|
||||||
return {
|
return {
|
||||||
label: `[${callback.httpVerb.toUpperCase()}] ${callback.name}`,
|
label: `${callback.httpVerb.toUpperCase()}: ${callback.name}`,
|
||||||
value: idx.toString(),
|
value: idx.toString(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,6 +21,7 @@ export interface EndpointProps {
|
||||||
|
|
||||||
hideHostname?: boolean;
|
hideHostname?: boolean;
|
||||||
inverted?: boolean;
|
inverted?: boolean;
|
||||||
|
compact?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EndpointState {
|
export interface EndpointState {
|
||||||
|
@ -49,7 +50,9 @@ export class Endpoint extends React.Component<EndpointProps, EndpointState> {
|
||||||
{options => (
|
{options => (
|
||||||
<OperationEndpointWrap>
|
<OperationEndpointWrap>
|
||||||
<EndpointInfo onClick={this.toggle} expanded={expanded} inverted={inverted}>
|
<EndpointInfo onClick={this.toggle} expanded={expanded} inverted={inverted}>
|
||||||
<HttpVerb type={operation.httpVerb}> {operation.httpVerb}</HttpVerb>{' '}
|
<HttpVerb type={operation.httpVerb} compact={this.props.compact}>
|
||||||
|
{operation.httpVerb}
|
||||||
|
</HttpVerb>
|
||||||
<ServerRelativeURL>{operation.path}</ServerRelativeURL>
|
<ServerRelativeURL>{operation.path}</ServerRelativeURL>
|
||||||
<ShelfIcon
|
<ShelfIcon
|
||||||
float={'right'}
|
float={'right'}
|
||||||
|
|
|
@ -34,14 +34,14 @@ export const EndpointInfo = styled.div<{ expanded?: boolean; inverted?: boolean
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const HttpVerb = styled.span.attrs((props: { type: string }) => ({
|
export const HttpVerb = styled.span.attrs((props: { type: string; compact?: boolean }) => ({
|
||||||
className: `http-verb ${props.type}`,
|
className: `http-verb ${props.type}`,
|
||||||
}))<{ type: string }>`
|
}))<{ type: string; compact?: boolean }>`
|
||||||
font-size: 0.929em;
|
font-size: ${props => (props.compact ? '0.8em' : '0.929em')};
|
||||||
line-height: 20px;
|
line-height: ${props => (props.compact ? '18px' : '20px')};
|
||||||
background-color: ${(props: any) => props.theme.colors.http[props.type] || '#999999'};
|
background-color: ${props => props.theme.colors.http[props.type] || '#999999'};
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
padding: 3px 10px;
|
padding: ${props => (props.compact ? '2px 8px' : '3px 10px')};
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-family: ${props => props.theme.typography.headings.fontFamily};
|
font-family: ${props => props.theme.typography.headings.fontFamily};
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -59,7 +59,6 @@ export const ServersOverlay = styled.div<{ expanded: boolean }>`
|
||||||
border-bottom-left-radius: 4px;
|
border-bottom-left-radius: 4px;
|
||||||
border-bottom-right-radius: 4px;
|
border-bottom-right-radius: 4px;
|
||||||
transition: all 0.25s ease;
|
transition: all 0.25s ease;
|
||||||
|
|
||||||
${props => (props.expanded ? '' : 'transform: translateY(-50%) scaleY(0);')}
|
${props => (props.expanded ? '' : 'transform: translateY(-50%) scaleY(0);')}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as React from 'react';
|
||||||
import { Badge, DarkRightPanel, H2, MiddlePanel, Row } from '../../common-elements';
|
import { Badge, DarkRightPanel, H2, MiddlePanel, Row } from '../../common-elements';
|
||||||
import { ShareLink } from '../../common-elements/linkify';
|
import { ShareLink } from '../../common-elements/linkify';
|
||||||
import { OperationModel as OperationType } from '../../services/models';
|
import { OperationModel as OperationType } from '../../services/models';
|
||||||
import styled from '../../styled-components';
|
import styled, { media } from '../../styled-components';
|
||||||
import { CallbacksList } from '../Callbacks';
|
import { CallbacksList } from '../Callbacks';
|
||||||
import { CallbackSamples } from '../CallbackSamples/CallbackSamples';
|
import { CallbackSamples } from '../CallbackSamples/CallbackSamples';
|
||||||
import { Endpoint } from '../Endpoint/Endpoint';
|
import { Endpoint } from '../Endpoint/Endpoint';
|
||||||
|
@ -18,22 +18,6 @@ import { ResponsesList } from '../Responses/ResponsesList';
|
||||||
import { ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
import { ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
||||||
import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
||||||
|
|
||||||
const CallbackMiddlePanel = styled(MiddlePanel)`
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const OperationRow = styled(Row)`
|
|
||||||
backface-visibility: hidden;
|
|
||||||
contain: content;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Description = styled.div`
|
|
||||||
margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export interface OperationProps {
|
export interface OperationProps {
|
||||||
operation: OperationType;
|
operation: OperationType;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +54,7 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
<Extensions extensions={operation.extensions} />
|
<Extensions extensions={operation.extensions} />
|
||||||
<SecurityRequirements securities={operation.security} />
|
<SecurityRequirements securities={operation.security} />
|
||||||
<Parameters parameters={operation.parameters} body={operation.requestBody} />
|
<Parameters parameters={operation.parameters} body={operation.requestBody} />
|
||||||
<ResponsesList responses={operation.responses} />
|
<ResponsesList responses={operation.responses} isCallback={operation.isCallback} />
|
||||||
<CallbacksList callbacks={operation.callbacks} />
|
<CallbacksList callbacks={operation.callbacks} />
|
||||||
</AdaptiveMiddlePanel>
|
</AdaptiveMiddlePanel>
|
||||||
{!operation.isCallback && (
|
{!operation.isCallback && (
|
||||||
|
@ -89,3 +73,22 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CallbackMiddlePanel = styled(MiddlePanel)`
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
${() => media.lessThan('medium', true)`
|
||||||
|
padding: 0
|
||||||
|
`};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const OperationRow = styled(Row)`
|
||||||
|
backface-visibility: hidden;
|
||||||
|
contain: content;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Description = styled.div`
|
||||||
|
margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px;
|
||||||
|
`;
|
||||||
|
|
|
@ -13,11 +13,12 @@ const ResponsesHeader = styled.h3`
|
||||||
|
|
||||||
export interface ResponseListProps {
|
export interface ResponseListProps {
|
||||||
responses: ResponseModel[];
|
responses: ResponseModel[];
|
||||||
|
isCallback?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResponsesList extends React.PureComponent<ResponseListProps> {
|
export class ResponsesList extends React.PureComponent<ResponseListProps> {
|
||||||
render() {
|
render() {
|
||||||
const { responses } = this.props;
|
const { responses, isCallback } = this.props;
|
||||||
|
|
||||||
if (!responses || responses.length === 0) {
|
if (!responses || responses.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -25,7 +26,7 @@ export class ResponsesList extends React.PureComponent<ResponseListProps> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ResponsesHeader> Responses </ResponsesHeader>
|
<ResponsesHeader>{isCallback ? 'Callback responses' : 'Responses'}</ResponsesHeader>
|
||||||
{responses.map(response => {
|
{responses.map(response => {
|
||||||
return <ResponseView key={response.code} response={response} />;
|
return <ResponseView key={response.code} response={response} />;
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe('Components', () => {
|
||||||
|
|
||||||
it('should correctly render CallbackTitle', () => {
|
it('should correctly render CallbackTitle', () => {
|
||||||
const callbackTitleViewElement = shallow(
|
const callbackTitleViewElement = shallow(
|
||||||
<CallbackTitle name={'Test'} className={'.test'} onClick={undefined} />,
|
<CallbackTitle name={'Test'} className={'.test'} onClick={undefined} httpVerb={'get'} />,
|
||||||
).getElement();
|
).getElement();
|
||||||
expect(callbackTitleViewElement.props).toBeDefined();
|
expect(callbackTitleViewElement.props).toBeDefined();
|
||||||
expect(callbackTitleViewElement.props.className).toEqual('.test');
|
expect(callbackTitleViewElement.props.className).toEqual('.test');
|
||||||
|
|
|
@ -39,7 +39,6 @@ export class CallbackModel {
|
||||||
undefined,
|
undefined,
|
||||||
options,
|
options,
|
||||||
true,
|
true,
|
||||||
this.name,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.operations.push(operation);
|
this.operations.push(operation);
|
||||||
|
|
|
@ -86,7 +86,6 @@ export class OperationModel implements IMenuItem {
|
||||||
parent: GroupModel | undefined,
|
parent: GroupModel | undefined,
|
||||||
private options: RedocNormalizedOptions,
|
private options: RedocNormalizedOptions,
|
||||||
isCallback: boolean = false,
|
isCallback: boolean = false,
|
||||||
callbackEventName?: string,
|
|
||||||
) {
|
) {
|
||||||
this.pointer = JsonPointer.compile(['paths', operationSpec.pathName, operationSpec.httpVerb]);
|
this.pointer = JsonPointer.compile(['paths', operationSpec.pathName, operationSpec.httpVerb]);
|
||||||
|
|
||||||
|
@ -112,22 +111,21 @@ export class OperationModel implements IMenuItem {
|
||||||
JsonPointer.compile(['paths', operationSpec.pathName]),
|
JsonPointer.compile(['paths', operationSpec.pathName]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.name = getOperationSummary(operationSpec);
|
||||||
|
|
||||||
if (this.isCallback) {
|
if (this.isCallback) {
|
||||||
// NOTE: Use callback's event name as the view label, not the operationID.
|
|
||||||
this.name = callbackEventName || getOperationSummary(operationSpec);
|
|
||||||
// NOTE: Callbacks by default should not inherit the specification's global `security` definition.
|
// NOTE: Callbacks by default should not inherit the specification's global `security` definition.
|
||||||
// Can be defined individually per-callback in the specification. Defaults to none.
|
// Can be defined individually per-callback in the specification. Defaults to none.
|
||||||
this.security = (operationSpec.security || []).map(
|
this.security = (operationSpec.security || []).map(
|
||||||
security => new SecurityRequirementModel(security, parser),
|
security => new SecurityRequirementModel(security, parser),
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: update getting pathInfo
|
// TODO: update getting pathInfo for overriding servers on path level
|
||||||
this.servers = normalizeServers(
|
this.servers = normalizeServers(
|
||||||
'',
|
'',
|
||||||
operationSpec.servers || (pathInfo && pathInfo.servers) || [],
|
operationSpec.servers || (pathInfo && pathInfo.servers) || [],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.name = getOperationSummary(operationSpec);
|
|
||||||
this.security = (operationSpec.security || parser.spec.security || []).map(
|
this.security = (operationSpec.security || parser.spec.security || []).map(
|
||||||
security => new SecurityRequirementModel(security, parser),
|
security => new SecurityRequirementModel(security, parser),
|
||||||
);
|
);
|
||||||
|
@ -256,6 +254,7 @@ export class OperationModel implements IMenuItem {
|
||||||
|
|
||||||
@memoize
|
@memoize
|
||||||
get callbacks() {
|
get callbacks() {
|
||||||
|
console.log('this.operationSpec.callbacks', this.operationSpec.callbacks);
|
||||||
return Object.keys(this.operationSpec.callbacks || []).map(callbackEventName => {
|
return Object.keys(this.operationSpec.callbacks || []).map(callbackEventName => {
|
||||||
return new CallbackModel(
|
return new CallbackModel(
|
||||||
this.parser,
|
this.parser,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user