fix(oas31): render Callback operations only (#8507)

Before this fix, other Path Item fields were
included into rendering of Operation Objects under
a specific Callback Object.

Refs #8504
This commit is contained in:
Vladimír Gorej
2023-03-23 13:38:35 +01:00
committed by GitHub
parent 7bdb605dcf
commit 3d3fea09c6
3 changed files with 92 additions and 50 deletions

View File

@@ -1,54 +1,49 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import { fromJS } from "immutable"
const Callbacks = (props) => {
let { callbacks, getComponent, specPath } = props
// const Markdown = getComponent("Markdown", true)
const Callbacks = ({ callbacks, specPath, specSelectors, getComponent }) => {
const operationDTOs = specSelectors.callbacksOperations({
callbacks,
specPath,
})
const callbackNames = Object.keys(operationDTOs)
const OperationContainer = getComponent("OperationContainer", true)
if(!callbacks) {
return <span>No callbacks</span>
}
if (callbackNames.length === 0) return <span>No callbacks</span>
let callbackElements = callbacks.entrySeq().map(([callbackName, callback]) => {
return <div key={callbackName}>
<h2>{callbackName}</h2>
{ callback.entrySeq().map(([pathItemName, pathItem]) => {
if(pathItemName === "$$ref") {
return null
}
return <div key={pathItemName}>
{ pathItem.entrySeq().map(([method, operation]) => {
if(method === "$$ref") {
return null
}
let op = fromJS({
operation
})
return <OperationContainer
{...props}
op={op}
key={method}
tag={""}
method={method}
path={pathItemName}
specPath={specPath.push(callbackName, pathItemName, method)}
return (
<div>
{callbackNames.map((callbackName) => (
<div key={`${callbackName}`}>
<h2>{callbackName}</h2>
{operationDTOs[callbackName].map((operationDTO) => (
<OperationContainer
key={`${callbackName}-${operationDTO.path}-${operationDTO.method}`}
op={operationDTO.operation}
tag=""
method={operationDTO.method}
path={operationDTO.path}
specPath={operationDTO.specPath}
allowTryItOut={false}
/>
}) }
/>
))}
</div>
}) }
))}
</div>
})
return <div>
{callbackElements}
</div>
)
}
Callbacks.propTypes = {
getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.shape({
callbacksOperations: PropTypes.func.isRequired,
}).isRequired,
callbacks: ImPropTypes.iterable.isRequired,
specPath: ImPropTypes.list.isRequired,
}

View File

@@ -1,6 +1,12 @@
import { Map } from "immutable"
import { isSwagger2 as isSwagger2Helper, isOAS30 as isOAS30Helper } from "../helpers"
/**
* @prettier
*/
import { List, Map } from "immutable"
import {
isSwagger2 as isSwagger2Helper,
isOAS30 as isOAS30Helper,
} from "../helpers"
/**
* Helpers
@@ -23,18 +29,54 @@ export const isOAS3 = () => (system) => {
}
function onlyOAS3(selector) {
return () => (system, ...args) => {
const spec = system.getSystem().specSelectors.specJson()
if(system.specSelectors.isOAS3(spec)) {
const result = selector(...args)
return typeof result === "function" ? result(system, ...args) : result
} else {
return null
return (state, ...args) =>
(system) => {
if (system.specSelectors.isOAS3()) {
const selectedValue = selector(state, ...args)
return typeof selectedValue === "function"
? selectedValue(system)
: selectedValue
} else {
return null
}
}
}
}
export const servers = onlyOAS3(() => (system) => {
const spec = system.specSelectors.specJson()
return spec.get("servers", map)
})
export const callbacksOperations = onlyOAS3(
(state, { callbacks, specPath }) =>
(system) => {
const validOperationMethods = system.specSelectors.validOperationMethods()
if (!Map.isMap(callbacks)) return {}
return callbacks
.reduce((allOperations, callback, callbackName) => {
if (!Map.isMap(callback)) return allOperations
return callback.reduce((callbackOperations, pathItem, expression) => {
if (!Map.isMap(pathItem)) return callbackOperations
const pathItemOperations = pathItem
.entrySeq()
.filter(([key]) => validOperationMethods.includes(key))
.map(([method, operation]) => ({
operation: Map({ operation }),
method,
path: expression,
callbackName,
specPath: specPath.concat([callbackName, expression, method]),
}))
return callbackOperations.concat(pathItemOperations)
}, List())
}, List())
.groupBy((operationDTO) => operationDTO.callbackName)
.map((operations) => operations.toArray())
.toObject()
}
)

View File

@@ -27,9 +27,13 @@ export const selectWebhooksOperations = createSelector(
(state, system) => system.specSelectors.webhooks(),
(state, system) => system.specSelectors.validOperationMethods(),
(state, system) => system.specSelectors.specResolvedSubtree(["webhooks"]),
(webhooks, validOperationMethods) =>
webhooks
(webhooks, validOperationMethods) => {
if (!Map.isMap(webhooks)) return {}
return webhooks
.reduce((allOperations, pathItem, pathItemName) => {
if (!Map.isMap(pathItem)) return allOperations
const pathItemOperations = pathItem
.entrySeq()
.filter(([key]) => validOperationMethods.includes(key))
@@ -42,9 +46,10 @@ export const selectWebhooksOperations = createSelector(
return allOperations.concat(pathItemOperations)
}, List())
.groupBy((operation) => operation.path)
.groupBy((operationDTO) => operationDTO.path)
.map((operations) => operations.toArray())
.toObject()
}
)
export const license = () => (system) => {