Skip to content

Commit 7378821

Browse files
authored
fix(config): cast configuration values into proper types (#9829)
Refs #9808
1 parent c2b63ab commit 7378821

File tree

28 files changed

+359
-83
lines changed

28 files changed

+359
-83
lines changed

flavors/swagger-ui-react/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ SwaggerUI.defaultProps = {
142142
deepLinking: false,
143143
showExtensions: false,
144144
showCommonExtensions: false,
145-
filter: null,
145+
filter: false,
146146
requestSnippetsEnabled: false,
147147
requestSnippets: {
148148
generators: {
@@ -164,7 +164,7 @@ SwaggerUI.defaultProps = {
164164
},
165165
tryItOutEnabled: false,
166166
displayRequestDuration: false,
167-
withCredentials: undefined,
167+
withCredentials: false,
168168
persistAuthorization: false,
169169
oauth2RedirectUrl: undefined,
170170
}

src/core/components/live-response.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ export default class LiveResponse extends React.Component {
7373

7474
return (
7575
<div>
76-
{ curlRequest && (requestSnippetsEnabled === true || requestSnippetsEnabled === "true"
76+
{ curlRequest && requestSnippetsEnabled
7777
? <RequestSnippets request={ curlRequest }/>
7878
: <Curl request={ curlRequest } />
79-
)}
79+
}
8080
{ url && <div>
8181
<div className="request-url">
8282
<h4>Request URL</h4>

src/core/components/operation-tag.jsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ export default class OperationTag extends React.Component {
4747
deepLinking,
4848
} = getConfigs()
4949

50-
const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
51-
5250
const Collapse = getComponent("Collapse")
5351
const Markdown = getComponent("Markdown", true)
5452
const DeepLink = getComponent("DeepLink")
@@ -80,7 +78,7 @@ export default class OperationTag extends React.Component {
8078
data-is-open={showTag}
8179
>
8280
<DeepLink
83-
enabled={isDeepLinkingEnabled}
81+
enabled={deepLinking}
8482
isShown={showTag}
8583
path={createDeepLinkPath(tag)}
8684
text={tag} />

src/core/config/defaults.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ const defaultOptions = Object.freeze({
1111
urls: null,
1212
layout: "BaseLayout",
1313
docExpansion: "list",
14-
maxDisplayedTags: null,
15-
filter: null,
14+
maxDisplayedTags: -1,
15+
filter: false,
1616
validatorUrl: "https://validator.swagger.io/validator",
1717
oauth2RedirectUrl: `${window.location.protocol}//${window.location.host}${window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/"))}/oauth2-redirect.html`,
1818
persistAuthorization: false,
@@ -30,7 +30,7 @@ const defaultOptions = Object.freeze({
3030
defaultModelsExpandDepth: 1,
3131
showExtensions: false,
3232
showCommonExtensions: false,
33-
withCredentials: undefined,
33+
withCredentials: false,
3434
requestSnippetsEnabled: false,
3535
requestSnippets: {
3636
generators: {

src/core/config/factorization/store.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/**
22
* @prettier
33
*/
4-
import merge from "../merge"
4+
import deepExtend from "deep-extend"
55

66
const storeFactorization = (options) => {
7-
const state = merge(
7+
const state = deepExtend(
88
{
99
layout: {
1010
layout: options.layout,

src/core/config/merge.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
*
88
* NOTE1: lodash.merge & lodash.mergeWith prefers to ignore undefined values
99
* NOTE2: special handling of `domNode` option is now required as `deep-extend` will corrupt it (lodash.merge handles it correctly)
10-
* NOTE3: oauth2RedirectUrl and withCredentials options can be set to undefined. By expecting null instead of undefined, we can't use lodash.merge.
10+
* NOTE3: oauth2RedirectUrl option can be set to undefined. By expecting null instead of undefined, we can't use lodash.merge.
1111
* NOTE4: urls.primaryName needs to handled in special way, because it's an arbitrary property on Array instance
1212
*
1313
* TODO([email protected]): remove deep-extend in favor of lodash.merge
1414
*/
1515
import deepExtend from "deep-extend"
16+
import typeCast from "./type-cast"
1617

1718
const merge = (target, ...sources) => {
1819
let domNode = Symbol.for("domNode")
@@ -51,7 +52,7 @@ const merge = (target, ...sources) => {
5152
merged.urls.primaryName = primaryName
5253
}
5354

54-
return merged
55+
return typeCast(merged)
5556
}
5657

5758
export default merge

src/core/config/type-cast/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @prettier
3+
*/
4+
import has from "lodash/has"
5+
import get from "lodash/get"
6+
import set from "lodash/fp/set"
7+
8+
import typeCasters from "./mappings"
9+
10+
const typeCast = (options) => {
11+
return Object.entries(typeCasters).reduce(
12+
(acc, [optionPath, { typeCaster, defaultValue }]) => {
13+
if (has(acc, optionPath)) {
14+
const uncasted = get(acc, optionPath)
15+
const casted = typeCaster(uncasted, defaultValue)
16+
acc = set(optionPath, casted, acc)
17+
}
18+
return acc
19+
},
20+
{ ...options }
21+
)
22+
}
23+
24+
export default typeCast
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* @prettier
3+
*/
4+
import arrayTypeCaster from "./type-casters/array"
5+
import booleanTypeCaster from "./type-casters/boolean"
6+
import domNodeTypeCaster from "./type-casters/dom-node"
7+
import filterTypeCaster from "./type-casters/filter"
8+
import nullableArrayTypeCaster from "./type-casters/nullable-array"
9+
import nullableStringTypeCaster from "./type-casters/nullable-string"
10+
import numberTypeCaster from "./type-casters/number"
11+
import objectTypeCaster from "./type-casters/object"
12+
import stringTypeCaster from "./type-casters/string"
13+
import syntaxHighlightTypeCaster from "./type-casters/syntax-highlight"
14+
import undefinedStringTypeCaster from "./type-casters/undefined-string"
15+
import defaultOptions from "../defaults"
16+
17+
const typeCasters = {
18+
configUrl: { typeCaster: stringTypeCaster },
19+
deepLinking: {
20+
typeCaster: booleanTypeCaster,
21+
defaultValue: defaultOptions.deepLinking,
22+
},
23+
defaultModelExpandDepth: {
24+
typeCaster: numberTypeCaster,
25+
defaultValue: defaultOptions.defaultModelExpandDepth,
26+
},
27+
defaultModelRendering: { typeCaster: stringTypeCaster },
28+
defaultModelsExpandDepth: {
29+
typeCaster: numberTypeCaster,
30+
defaultValue: defaultOptions.defaultModelsExpandDepth,
31+
},
32+
displayOperationId: {
33+
typeCaster: booleanTypeCaster,
34+
defaultValue: defaultOptions.displayOperationId,
35+
},
36+
displayRequestDuration: {
37+
typeCaster: booleanTypeCaster,
38+
defaultValue: defaultOptions.displayRequestDuration,
39+
},
40+
docExpansion: { typeCaster: stringTypeCaster },
41+
dom_id: { typeCaster: nullableStringTypeCaster },
42+
domNode: { typeCaster: domNodeTypeCaster },
43+
filter: { typeCaster: filterTypeCaster },
44+
layout: { typeCaster: stringTypeCaster },
45+
maxDisplayedTags: {
46+
typeCaster: numberTypeCaster,
47+
defaultValue: defaultOptions.maxDisplayedTags,
48+
},
49+
oauth2RedirectUrl: { typeCaster: undefinedStringTypeCaster },
50+
persistAuthorization: {
51+
typeCaster: booleanTypeCaster,
52+
defaultValue: defaultOptions.persistAuthorization,
53+
},
54+
plugins: {
55+
typeCaster: arrayTypeCaster,
56+
defaultValue: defaultOptions.plugins,
57+
},
58+
pluginsOptions: {
59+
typeCaster: objectTypeCaster,
60+
pluginsOptions: defaultOptions.pluginsOptions,
61+
},
62+
"pluginsOptions.pluginsLoadType": { typeCaster: stringTypeCaster },
63+
presets: {
64+
typeCaster: arrayTypeCaster,
65+
defaultValue: defaultOptions.presets,
66+
},
67+
requestSnippets: {
68+
typeCaster: objectTypeCaster,
69+
defaultValue: defaultOptions.requestSnippets,
70+
},
71+
requestSnippetsEnabled: {
72+
typeCaster: booleanTypeCaster,
73+
defaultValue: defaultOptions.requestSnippetsEnabled,
74+
},
75+
showCommonExtensions: {
76+
typeCaster: booleanTypeCaster,
77+
defaultValue: defaultOptions.showCommonExtensions,
78+
},
79+
showExtensions: {
80+
typeCaster: booleanTypeCaster,
81+
defaultValue: defaultOptions.showExtensions,
82+
},
83+
showMutatedRequest: {
84+
typeCaster: booleanTypeCaster,
85+
defaultValue: defaultOptions.showMutatedRequest,
86+
},
87+
spec: { typeCaster: objectTypeCaster, defaultValue: defaultOptions.spec },
88+
supportedSubmitMethods: {
89+
typeCaster: arrayTypeCaster,
90+
defaultValue: defaultOptions.supportedSubmitMethods,
91+
},
92+
syntaxHighlight: {
93+
typeCaster: syntaxHighlightTypeCaster,
94+
defaultValue: defaultOptions.syntaxHighlight,
95+
},
96+
"syntaxHighlight.activated": {
97+
typeCaster: booleanTypeCaster,
98+
defaultValue: defaultOptions.syntaxHighlight.activated,
99+
},
100+
"syntaxHighlight.theme": { typeCaster: stringTypeCaster },
101+
tryItOutEnabled: {
102+
typeCaster: booleanTypeCaster,
103+
defaultValue: defaultOptions.tryItOutEnabled,
104+
},
105+
url: { typeCaster: stringTypeCaster },
106+
urls: { typeCaster: nullableArrayTypeCaster },
107+
"urls.primaryName": { typeCaster: stringTypeCaster },
108+
validatorUrl: { typeCaster: nullableStringTypeCaster },
109+
withCredentials: {
110+
typeCaster: booleanTypeCaster,
111+
defaultValue: defaultOptions.withCredentials,
112+
},
113+
}
114+
115+
export default typeCasters
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* @prettier
3+
*/
4+
const arrayTypeCaster = (value, defaultValue = []) =>
5+
Array.isArray(value) ? value : defaultValue
6+
7+
export default arrayTypeCaster
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @prettier
3+
*/
4+
const booleanTypeCaster = (value, defaultValue = false) =>
5+
value === true || value === "true" || value === 1 || value === "1"
6+
? true
7+
: value === false || value === "false" || value === 0 || value === "0"
8+
? false
9+
: defaultValue
10+
11+
export default booleanTypeCaster

0 commit comments

Comments
 (0)