Skip to content

Commit

Permalink
fix(oas31): render Callback operations only (#8507)
Browse files Browse the repository at this point in the history
Before this fix, other Path Item fields were
included into rendering of Operation Objects under
a specific Callback Object.

Refs #8504
  • Loading branch information
char0n authored Mar 23, 2023
1 parent 7bdb605 commit 3d3fea0
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 50 deletions.
69 changes: 32 additions & 37 deletions src/core/plugins/oas3/components/callbacks.jsx
Original file line number Diff line number Diff line change
@@ -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,
}
Expand Down
62 changes: 52 additions & 10 deletions src/core/plugins/oas3/spec-extensions/selectors.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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()
}
)
11 changes: 8 additions & 3 deletions src/core/plugins/oas31/spec-extensions/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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) => {
Expand Down

0 comments on commit 3d3fea0

Please sign in to comment.