refactor(oas31): concentrate OpenAPI 3.1.0 code to separate plugin (#8475)
Refs #8474
This commit is contained in:
@@ -1,41 +1,53 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
import { OrderedMap, Map, List } from "immutable"
|
||||
import { isOAS3 as isOAS3Helper } from "./helpers"
|
||||
import { getDefaultRequestBodyValue } from "./components/request-body"
|
||||
import { stringify } from "../../utils"
|
||||
|
||||
// Helpers
|
||||
|
||||
function onlyOAS3(selector) {
|
||||
return (...args) => (system) => {
|
||||
const spec = system.getSystem().specSelectors.specJson()
|
||||
if(isOAS3Helper(spec)) {
|
||||
return selector(...args)
|
||||
} else {
|
||||
return null
|
||||
return (...args) =>
|
||||
(system) => {
|
||||
if (system.getSystem().specSelectors.isOAS3()) {
|
||||
return selector(...args)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateRequestBodyIsRequired(selector) {
|
||||
return (...args) => (system) => {
|
||||
const specJson = system.getSystem().specSelectors.specJson()
|
||||
const argsList = [...args]
|
||||
// expect argsList[0] = state
|
||||
let pathMethod = argsList[1] || []
|
||||
let isOas3RequestBodyRequired = specJson.getIn(["paths", ...pathMethod, "requestBody", "required"])
|
||||
return (...args) =>
|
||||
(system) => {
|
||||
const specJson = system.getSystem().specSelectors.specJson()
|
||||
const argsList = [...args]
|
||||
// expect argsList[0] = state
|
||||
let pathMethod = argsList[1] || []
|
||||
let isOas3RequestBodyRequired = specJson.getIn([
|
||||
"paths",
|
||||
...pathMethod,
|
||||
"requestBody",
|
||||
"required",
|
||||
])
|
||||
|
||||
if (isOas3RequestBodyRequired) {
|
||||
return selector(...args)
|
||||
} else {
|
||||
// validation pass b/c not required
|
||||
return true
|
||||
if (isOas3RequestBodyRequired) {
|
||||
return selector(...args)
|
||||
} else {
|
||||
// validation pass b/c not required
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const validateRequestBodyValueExists = (state, pathMethod) => {
|
||||
pathMethod = pathMethod || []
|
||||
let oas3RequestBodyValue = state.getIn(["requestData", ...pathMethod, "bodyValue"])
|
||||
let oas3RequestBodyValue = state.getIn([
|
||||
"requestData",
|
||||
...pathMethod,
|
||||
"bodyValue",
|
||||
])
|
||||
// context: bodyValue can be a String, or a Map
|
||||
if (!oas3RequestBodyValue) {
|
||||
return false
|
||||
@@ -44,68 +56,85 @@ const validateRequestBodyValueExists = (state, pathMethod) => {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
export const selectedServer = onlyOAS3((state, namespace) => {
|
||||
const path = namespace ? [namespace, "selectedServer"] : ["selectedServer"]
|
||||
return state.getIn(path) || ""
|
||||
}
|
||||
)
|
||||
const path = namespace ? [namespace, "selectedServer"] : ["selectedServer"]
|
||||
return state.getIn(path) || ""
|
||||
})
|
||||
|
||||
export const requestBodyValue = onlyOAS3((state, path, method) => {
|
||||
return state.getIn(["requestData", path, method, "bodyValue"]) || null
|
||||
}
|
||||
)
|
||||
return state.getIn(["requestData", path, method, "bodyValue"]) || null
|
||||
})
|
||||
|
||||
export const shouldRetainRequestBodyValue = onlyOAS3((state, path, method) => {
|
||||
return state.getIn(["requestData", path, method, "retainBodyValue"]) || false
|
||||
}
|
||||
)
|
||||
return state.getIn(["requestData", path, method, "retainBodyValue"]) || false
|
||||
})
|
||||
|
||||
export const selectDefaultRequestBodyValue = (state, path, method) => (system) => {
|
||||
const {oas3Selectors, specSelectors} = system.getSystem()
|
||||
const spec = specSelectors.specJson()
|
||||
if(isOAS3Helper(spec)) {
|
||||
const currentMediaType = oas3Selectors.requestContentType(path, method)
|
||||
if (currentMediaType) {
|
||||
return getDefaultRequestBodyValue(
|
||||
specSelectors.specResolvedSubtree(["paths", path, method, "requestBody"]),
|
||||
currentMediaType,
|
||||
oas3Selectors.activeExamplesMember(
|
||||
path, method,
|
||||
"requestBody",
|
||||
"requestBody",
|
||||
export const selectDefaultRequestBodyValue =
|
||||
(state, path, method) => (system) => {
|
||||
const { oas3Selectors, specSelectors } = system.getSystem()
|
||||
|
||||
if (specSelectors.isOAS3()) {
|
||||
const currentMediaType = oas3Selectors.requestContentType(path, method)
|
||||
if (currentMediaType) {
|
||||
return getDefaultRequestBodyValue(
|
||||
specSelectors.specResolvedSubtree([
|
||||
"paths",
|
||||
path,
|
||||
method,
|
||||
"requestBody",
|
||||
]),
|
||||
currentMediaType,
|
||||
oas3Selectors.activeExamplesMember(
|
||||
path,
|
||||
method,
|
||||
"requestBody",
|
||||
"requestBody"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const hasUserEditedBody = (state, path, method) => (system) => {
|
||||
const {oas3Selectors, specSelectors} = system.getSystem()
|
||||
const spec = specSelectors.specJson()
|
||||
if(isOAS3Helper(spec)) {
|
||||
const { oas3Selectors, specSelectors } = system.getSystem()
|
||||
|
||||
if (specSelectors.isOAS3()) {
|
||||
let userHasEditedBody = false
|
||||
const currentMediaType = oas3Selectors.requestContentType(path, method)
|
||||
let userEditedRequestBody = oas3Selectors.requestBodyValue(path, method)
|
||||
if (Map.isMap(userEditedRequestBody)) {
|
||||
// context is not application/json media-type
|
||||
userEditedRequestBody = stringify(userEditedRequestBody.mapEntries((kv) => Map.isMap(kv[1]) ? [kv[0], kv[1].get("value")] : kv).toJS())
|
||||
userEditedRequestBody = stringify(
|
||||
userEditedRequestBody
|
||||
.mapEntries((kv) =>
|
||||
Map.isMap(kv[1]) ? [kv[0], kv[1].get("value")] : kv
|
||||
)
|
||||
.toJS()
|
||||
)
|
||||
}
|
||||
if(List.isList(userEditedRequestBody)) {
|
||||
if (List.isList(userEditedRequestBody)) {
|
||||
userEditedRequestBody = stringify(userEditedRequestBody)
|
||||
}
|
||||
if (currentMediaType) {
|
||||
const currentMediaTypeDefaultBodyValue = getDefaultRequestBodyValue(
|
||||
specSelectors.specResolvedSubtree(["paths", path, method, "requestBody"]),
|
||||
specSelectors.specResolvedSubtree([
|
||||
"paths",
|
||||
path,
|
||||
method,
|
||||
"requestBody",
|
||||
]),
|
||||
currentMediaType,
|
||||
oas3Selectors.activeExamplesMember(
|
||||
path, method,
|
||||
"requestBody",
|
||||
path,
|
||||
method,
|
||||
"requestBody",
|
||||
"requestBody"
|
||||
)
|
||||
)
|
||||
userHasEditedBody = !!userEditedRequestBody && userEditedRequestBody !== currentMediaTypeDefaultBodyValue
|
||||
userHasEditedBody =
|
||||
!!userEditedRequestBody &&
|
||||
userEditedRequestBody !== currentMediaTypeDefaultBodyValue
|
||||
}
|
||||
return userHasEditedBody
|
||||
} else {
|
||||
@@ -114,106 +143,114 @@ export const hasUserEditedBody = (state, path, method) => (system) => {
|
||||
}
|
||||
|
||||
export const requestBodyInclusionSetting = onlyOAS3((state, path, method) => {
|
||||
return state.getIn(["requestData", path, method, "bodyInclusion"]) || Map()
|
||||
}
|
||||
)
|
||||
return state.getIn(["requestData", path, method, "bodyInclusion"]) || Map()
|
||||
})
|
||||
|
||||
export const requestBodyErrors = onlyOAS3((state, path, method) => {
|
||||
return state.getIn(["requestData", path, method, "errors"]) || null
|
||||
}
|
||||
)
|
||||
return state.getIn(["requestData", path, method, "errors"]) || null
|
||||
})
|
||||
|
||||
export const activeExamplesMember = onlyOAS3((state, path, method, type, name) => {
|
||||
return state.getIn(["examples", path, method, type, name, "activeExample"]) || null
|
||||
export const activeExamplesMember = onlyOAS3(
|
||||
(state, path, method, type, name) => {
|
||||
return (
|
||||
state.getIn(["examples", path, method, type, name, "activeExample"]) ||
|
||||
null
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
export const requestContentType = onlyOAS3((state, path, method) => {
|
||||
return state.getIn(["requestData", path, method, "requestContentType"]) || null
|
||||
}
|
||||
)
|
||||
return (
|
||||
state.getIn(["requestData", path, method, "requestContentType"]) || null
|
||||
)
|
||||
})
|
||||
|
||||
export const responseContentType = onlyOAS3((state, path, method) => {
|
||||
return state.getIn(["requestData", path, method, "responseContentType"]) || null
|
||||
}
|
||||
)
|
||||
return (
|
||||
state.getIn(["requestData", path, method, "responseContentType"]) || null
|
||||
)
|
||||
})
|
||||
|
||||
export const serverVariableValue = onlyOAS3((state, locationData, key) => {
|
||||
let path
|
||||
let path
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if(namespace) {
|
||||
path = [namespace, "serverVariableValues", server, key]
|
||||
} else {
|
||||
path = ["serverVariableValues", server, key]
|
||||
}
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if (typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if (namespace) {
|
||||
path = [namespace, "serverVariableValues", server, key]
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server, key]
|
||||
}
|
||||
|
||||
return state.getIn(path) || null
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server, key]
|
||||
}
|
||||
)
|
||||
|
||||
return state.getIn(path) || null
|
||||
})
|
||||
|
||||
export const serverVariables = onlyOAS3((state, locationData) => {
|
||||
let path
|
||||
let path
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if(namespace) {
|
||||
path = [namespace, "serverVariableValues", server]
|
||||
} else {
|
||||
path = ["serverVariableValues", server]
|
||||
}
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if (typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if (namespace) {
|
||||
path = [namespace, "serverVariableValues", server]
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server]
|
||||
}
|
||||
|
||||
return state.getIn(path) || OrderedMap()
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server]
|
||||
}
|
||||
)
|
||||
|
||||
return state.getIn(path) || OrderedMap()
|
||||
})
|
||||
|
||||
export const serverEffectiveValue = onlyOAS3((state, locationData) => {
|
||||
var varValues, serverValue
|
||||
var varValues, serverValue
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
serverValue = server
|
||||
if(namespace) {
|
||||
varValues = state.getIn([namespace, "serverVariableValues", serverValue])
|
||||
} else {
|
||||
varValues = state.getIn(["serverVariableValues", serverValue])
|
||||
}
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if (typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
serverValue = server
|
||||
if (namespace) {
|
||||
varValues = state.getIn([namespace, "serverVariableValues", serverValue])
|
||||
} else {
|
||||
serverValue = locationData
|
||||
varValues = state.getIn(["serverVariableValues", serverValue])
|
||||
}
|
||||
|
||||
varValues = varValues || OrderedMap()
|
||||
let str = serverValue
|
||||
|
||||
varValues.map((val, key) => {
|
||||
str = str.replace(new RegExp(`{${key}}`, "g"), val)
|
||||
})
|
||||
|
||||
return str
|
||||
} else {
|
||||
serverValue = locationData
|
||||
varValues = state.getIn(["serverVariableValues", serverValue])
|
||||
}
|
||||
)
|
||||
|
||||
varValues = varValues || OrderedMap()
|
||||
let str = serverValue
|
||||
|
||||
varValues.map((val, key) => {
|
||||
str = str.replace(new RegExp(`{${key}}`, "g"), val)
|
||||
})
|
||||
|
||||
return str
|
||||
})
|
||||
|
||||
export const validateBeforeExecute = validateRequestBodyIsRequired(
|
||||
(state, pathMethod) => validateRequestBodyValueExists(state, pathMethod)
|
||||
)
|
||||
|
||||
export const validateShallowRequired = (state, { oas3RequiredRequestBodyContentType, oas3RequestContentType, oas3RequestBodyValue} ) => {
|
||||
export const validateShallowRequired = (
|
||||
state,
|
||||
{
|
||||
oas3RequiredRequestBodyContentType,
|
||||
oas3RequestContentType,
|
||||
oas3RequestBodyValue,
|
||||
}
|
||||
) => {
|
||||
let missingRequiredKeys = []
|
||||
// context: json => String; urlencoded, form-data => Map
|
||||
if (!Map.isMap(oas3RequestBodyValue)) {
|
||||
@@ -221,16 +258,19 @@ export const validateShallowRequired = (state, { oas3RequiredRequestBodyContentT
|
||||
}
|
||||
let requiredKeys = []
|
||||
// Cycle through list of possible contentTypes for matching contentType and defined requiredKeys
|
||||
Object.keys(oas3RequiredRequestBodyContentType.requestContentType).forEach((contentType) => {
|
||||
if (contentType === oas3RequestContentType) {
|
||||
let contentTypeVal = oas3RequiredRequestBodyContentType.requestContentType[contentType]
|
||||
contentTypeVal.forEach((requiredKey) => {
|
||||
if (requiredKeys.indexOf(requiredKey) < 0 ) {
|
||||
requiredKeys.push(requiredKey)
|
||||
}
|
||||
})
|
||||
Object.keys(oas3RequiredRequestBodyContentType.requestContentType).forEach(
|
||||
(contentType) => {
|
||||
if (contentType === oas3RequestContentType) {
|
||||
let contentTypeVal =
|
||||
oas3RequiredRequestBodyContentType.requestContentType[contentType]
|
||||
contentTypeVal.forEach((requiredKey) => {
|
||||
if (requiredKeys.indexOf(requiredKey) < 0) {
|
||||
requiredKeys.push(requiredKey)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
requiredKeys.forEach((key) => {
|
||||
let requiredKeyValue = oas3RequestBodyValue.getIn([key, "value"])
|
||||
if (!requiredKeyValue) {
|
||||
|
||||
Reference in New Issue
Block a user