Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(config): cast configuration values into proper types #9829

Merged
merged 9 commits into from
Apr 18, 2024
4 changes: 2 additions & 2 deletions src/core/components/live-response.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ export default class LiveResponse extends React.Component {

return (
<div>
{ curlRequest && (requestSnippetsEnabled === true || requestSnippetsEnabled === "true"
{ curlRequest && requestSnippetsEnabled
? <RequestSnippets request={ curlRequest }/>
: <Curl request={ curlRequest } />
)}
}
{ url && <div>
<div className="request-url">
<h4>Request URL</h4>
Expand Down
4 changes: 1 addition & 3 deletions src/core/components/operation-tag.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ export default class OperationTag extends React.Component {
deepLinking,
} = getConfigs()

const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"

const Collapse = getComponent("Collapse")
const Markdown = getComponent("Markdown", true)
const DeepLink = getComponent("DeepLink")
Expand Down Expand Up @@ -80,7 +78,7 @@ export default class OperationTag extends React.Component {
data-is-open={showTag}
>
<DeepLink
enabled={isDeepLinkingEnabled}
enabled={deepLinking}
isShown={showTag}
path={createDeepLinkPath(tag)}
text={tag} />
Expand Down
3 changes: 2 additions & 1 deletion src/core/config/merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* TODO([email protected]): remove deep-extend in favor of lodash.merge
*/
import deepExtend from "deep-extend"
import typeCast from "./type-cast"

const merge = (target, ...sources) => {
let domNode = Symbol.for("domNode")
Expand Down Expand Up @@ -51,7 +52,7 @@ const merge = (target, ...sources) => {
merged.urls.primaryName = primaryName
}

return merged
return typeCast(merged)
}

export default merge
24 changes: 24 additions & 0 deletions src/core/config/type-cast/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @prettier
*/
import has from "lodash/has"
import get from "lodash/get"
import set from "lodash/fp/set"

import typeCasters from "./mappings"

const typeCast = (options) => {
char0n marked this conversation as resolved.
Show resolved Hide resolved
return Object.entries(typeCasters).reduce(
(acc, [optionPath, typeCaster]) => {
if (has(acc, optionPath)) {
const uncasted = get(acc, optionPath)
const casted = typeCaster(uncasted)
acc = set(optionPath, casted, acc)
}
return acc
},
{ ...options }
)
}

export default typeCast
53 changes: 53 additions & 0 deletions src/core/config/type-cast/mappings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @prettier
*/
import arrayTypeCaster from "./type-casters/array"
import booleanTypeCaster from "./type-casters/boolean"
import domNodeTypeCaster from "./type-casters/dom-node"
import filterTypeCaster from "./type-casters/filter"
import nullableArrayTypeCaster from "./type-casters/nullable-array"
import nullableStringTypeCaster from "./type-casters/nullable-string"
import numberTypeCaster from "./type-casters/number"
import objectTypeCaster from "./type-casters/object"
import stringTypeCaster from "./type-casters/string"
import syntaxHighlightTypeCaster from "./type-casters/syntax-highlight"
import undefinedBooleanTypeCaster from "./type-casters/undefined-boolean"
import undefinedStringTypeCaster from "./type-casters/undefined-string"

const typeCasters = {
configUrl: stringTypeCaster,
deepLinking: booleanTypeCaster("deepLinking"),
char0n marked this conversation as resolved.
Show resolved Hide resolved
defaultModelExpandDepth: numberTypeCaster,
defaultModelRendering: stringTypeCaster,
defaultModelsExpandDepth: numberTypeCaster,
displayOperationId: booleanTypeCaster("displayOperationId"),
displayRequestDuration: booleanTypeCaster("displayRequestDuration"),
docExpansion: stringTypeCaster,
dom_id: nullableStringTypeCaster,
domNode: domNodeTypeCaster,
filter: filterTypeCaster,
maxDisplayedTags: numberTypeCaster,
oauth2RedirectUrl: undefinedStringTypeCaster,
persistAuthorization: booleanTypeCaster("persistAuthorization"),
plugins: arrayTypeCaster("plugins"),
pluginsOptions: objectTypeCaster("pluginsOptions"),
presets: arrayTypeCaster("presets"),
requestSnippets: objectTypeCaster("requestSnippets"),
requestSnippetsEnabled: booleanTypeCaster("requestSnippetsEnabled"),
showCommonExtensions: booleanTypeCaster("showCommonExtensions"),
showExtensions: booleanTypeCaster("showExtensions"),
showMutatedRequest: booleanTypeCaster("showMutatedRequest"),
spec: objectTypeCaster("spec"),
supportedSubmitMethods: arrayTypeCaster("supportedSubmitMethods"),
syntaxHighlight: syntaxHighlightTypeCaster,
"syntaxHighlight.activated": booleanTypeCaster("syntaxHighlight.activated"),
"syntaxHighlight.theme": stringTypeCaster,
tryItOutEnabled: booleanTypeCaster("tryItOutEnabled"),
url: stringTypeCaster,
urls: nullableArrayTypeCaster,
"urls.primaryName": stringTypeCaster,
validatorUrl: nullableStringTypeCaster,
withCredentials: undefinedBooleanTypeCaster,
}

export default typeCasters
10 changes: 10 additions & 0 deletions src/core/config/type-cast/type-casters/array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @prettier
*/
import get from "lodash/get"
import defaultOptions from "../../defaults"

const arrayTypeCaster = (optionPath) => (value) =>
Array.isArray(value) ? value : get(defaultOptions, optionPath)

export default arrayTypeCaster
14 changes: 14 additions & 0 deletions src/core/config/type-cast/type-casters/boolean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @prettier
*/
import get from "lodash/get"
import defaultOptions from "../../defaults"

const booleanTypeCaster = (optionPath) => (value) =>
char0n marked this conversation as resolved.
Show resolved Hide resolved
value === true || value === "true" || value === 1 || value === "1"
? true
: value === false || value === "false" || value === 0 || value === "0"
? false
: get(defaultOptions, optionPath)

export default booleanTypeCaster
7 changes: 7 additions & 0 deletions src/core/config/type-cast/type-casters/dom-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @prettier
*/
const domNodeTypeCaster = (value) =>
value === null || value === "null" ? null : value
char0n marked this conversation as resolved.
Show resolved Hide resolved

export default domNodeTypeCaster
13 changes: 13 additions & 0 deletions src/core/config/type-cast/type-casters/filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @prettier
*/
const filterTypeCaster = (value) =>
value === null || value === "null"
? null
: value === true || value === "true" || value === 1 || value === "1"
? true
: value === false || value === "false" || value === 0 || value === "0"
? false
: String(value)

export default filterTypeCaster
6 changes: 6 additions & 0 deletions src/core/config/type-cast/type-casters/nullable-array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @prettier
*/
const nullableArrayTypeCaster = (value) => (Array.isArray(value) ? value : null)

export default nullableArrayTypeCaster
7 changes: 7 additions & 0 deletions src/core/config/type-cast/type-casters/nullable-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @prettier
*/
const nullableStringTypeCaster = (value) =>
value === null || value === "null" ? null : String(value)

export default nullableStringTypeCaster
9 changes: 9 additions & 0 deletions src/core/config/type-cast/type-casters/number.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @prettier
*/
const numberTypeCaster = (value) => {
char0n marked this conversation as resolved.
Show resolved Hide resolved
const parsedValue = parseInt(value, 10)
return Number.isNaN(parsedValue) ? NaN : parsedValue
char0n marked this conversation as resolved.
Show resolved Hide resolved
}

export default numberTypeCaster
11 changes: 11 additions & 0 deletions src/core/config/type-cast/type-casters/object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @prettier
*/
import isPlainObject from "lodash/isPlainObject"
import get from "lodash/get"
import defaultOptions from "../../defaults"

const objectTypeCaster = (optionPath) => (value) =>
isPlainObject(value) ? value : get(defaultOptions, optionPath)

export default objectTypeCaster
6 changes: 6 additions & 0 deletions src/core/config/type-cast/type-casters/string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @prettier
*/
const stringTypeCaster = (value) => String(value)

export default stringTypeCaster
15 changes: 15 additions & 0 deletions src/core/config/type-cast/type-casters/syntax-highlight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @prettier
*/
import isPlainObject from "lodash/isPlainObject"
import defaultOptions from "../../defaults"

const syntaxHighlightTypeCaster = (value) => {
return isPlainObject(value)
? value
: value === false || value === "false" || value === 0 || value === "0"
? { activated: false }
: defaultOptions.syntaxHighlight
}

export default syntaxHighlightTypeCaster
11 changes: 11 additions & 0 deletions src/core/config/type-cast/type-casters/undefined-boolean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @prettier
*/
const undefinedBooleanTypeCaster = (value) =>
value === true || value === "true" || value === 1 || value === "1"
? true
: value === true || value === "false" || value === 0 || value === "0"
? false
: undefined

export default undefinedBooleanTypeCaster
7 changes: 7 additions & 0 deletions src/core/config/type-cast/type-casters/undefined-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @prettier
*/
const undefinedStringTypeCaster = (value) =>
value === undefined || value === "undefined" ? undefined : String(value)

export default undefinedStringTypeCaster
5 changes: 2 additions & 3 deletions src/core/containers/OperationContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class OperationContainer extends PureComponent {
const { tryItOutEnabled } = props.getConfigs()

this.state = {
tryItOutEnabled: tryItOutEnabled === true || tryItOutEnabled === "true",
tryItOutEnabled,
executeInProgress: false
}
}
Expand Down Expand Up @@ -61,14 +61,13 @@ export default class OperationContainer extends PureComponent {
const showSummary = layoutSelectors.showSummary()
const operationId = op.getIn(["operation", "__originalOperationId"]) || op.getIn(["operation", "operationId"]) || opId(op.get("operation"), props.path, props.method) || op.get("id")
const isShownKey = ["operations", props.tag, operationId]
const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
const allowTryItOut = supportedSubmitMethods.indexOf(props.method) >= 0 && (typeof props.allowTryItOut === "undefined" ?
props.specSelectors.allowTryItOutFor(props.path, props.method) : props.allowTryItOut)
const security = op.getIn(["operation", "security"]) || props.specSelectors.security()

return {
operationId,
isDeepLinkingEnabled,
isDeepLinkingEnabled: deepLinking,
showSummary,
displayOperationId,
displayRequestDuration,
Expand Down
4 changes: 2 additions & 2 deletions src/core/containers/filter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ export default class FilterContainer extends React.Component {

return (
<div>
{filter === null || filter === false || filter === "false" ? null :
{filter === null || filter === false ? null :
char0n marked this conversation as resolved.
Show resolved Hide resolved
<div className="filter-container">
<Col className="filter wrapper" mobile={12}>
<input className={classNames.join(" ")} placeholder="Filter by tag" type="text"
onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter}
onChange={this.onFilterChange} value={filter === true ? "" : filter}
char0n marked this conversation as resolved.
Show resolved Hide resolved
disabled={isLoading}/>
</Col>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/core/plugins/layout/spec-extensions/wrap-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ export const taggedOperations = (oriSelector, system) => (state, ...args) => {
// Filter, if requested
let filter = layoutSelectors.currentFilter()
if (filter) {
if (filter !== true && filter !== "true" && filter !== "false") {
if (filter !== true) {
char0n marked this conversation as resolved.
Show resolved Hide resolved
taggedOps = fn.opsFilter(taggedOps, filter)
}
}
// Limit to [max] items, if specified
if (maxDisplayedTags && !isNaN(maxDisplayedTags) && maxDisplayedTags >= 0) {
if (maxDisplayedTags >= 0) {
taggedOps = taggedOps.slice(0, maxDisplayedTags)
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/plugins/swagger-client/configs-wrap-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ export const loaded = (ori, system) => (...args) => {
const value = system.getConfigs().withCredentials

if(value !== undefined) {
system.fn.fetch.withCredentials = typeof value === "string" ? (value === "true") : !!value
system.fn.fetch.withCredentials = value
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import React from "react"
import PropTypes from "prop-types"
import ReactSyntaxHighlighter from "react-syntax-highlighter/dist/esm/light"
import get from "lodash/get"

const SyntaxHighlighter = ({
language,
Expand All @@ -13,8 +12,7 @@ const SyntaxHighlighter = ({
syntaxHighlighting = {},
children = "",
}) => {
const configs = getConfigs()
const theme = get(configs, "syntaxHighlight.theme")
const theme = getConfigs().syntaxHighlight.theme
const { styles, defaultStyle } = syntaxHighlighting
const style = styles?.[theme] ?? defaultStyle

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
*/
import React from "react"
import PropTypes from "prop-types"
import get from "lodash/get"

const SyntaxHighlighterWrapper = (Original, system) => {
const SyntaxHighlighter = ({ renderPlainText, children, ...rest }) => {
const configs = system.getConfigs()
const canSyntaxHighlight = !!get(configs, "syntaxHighlight.activated")
const canSyntaxHighlight = system.getConfigs().syntaxHighlight.activated
const PlainTextViewer = system.getComponent("PlainTextViewer")

if (!canSyntaxHighlight && typeof renderPlainText === "function") {
Expand Down
Loading