Skip to content

Commit 01c41b2

Browse files
refactor: introduce function for getting Schema Object type (#10330)
Co-authored-by: Robert Hebel <robert.hebel@smartbear.com>
1 parent fc6fb24 commit 01c41b2

File tree

12 files changed

+109
-111
lines changed

12 files changed

+109
-111
lines changed

src/core/components/parameter-row.jsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Map, List, fromJS } from "immutable"
33
import PropTypes from "prop-types"
44
import ImPropTypes from "react-immutable-proptypes"
55
import win from "core/window"
6-
import { getExtensions, getCommonExtensions, numberToString, stringify, isEmptyValue, immutableToJS } from "core/utils"
6+
import { getExtensions, getCommonExtensions, numberToString, stringify, isEmptyValue } from "core/utils"
77
import getParameterSchema from "core/utils/get-parameter-schema.js"
88

99
export default class ParameterRow extends Component {
@@ -152,13 +152,13 @@ export default class ParameterRow extends Component {
152152

153153
//// Dispatch the initial value
154154

155-
const type = fn.jsonSchema202012.foldType(immutableToJS(schema?.get("type")))
156-
const itemType = fn.jsonSchema202012.foldType(immutableToJS(schema?.getIn(["items", "type"])))
155+
const schemaObjectType = fn.getSchemaObjectType(schema)
156+
const schemaItemsType = fn.getSchemaObjectType(schema?.get("items"))
157157

158158
if(initialValue !== undefined) {
159159
this.onChangeWrapper(initialValue)
160160
} else if(
161-
type === "object"
161+
schemaObjectType === "object"
162162
&& generatedSampleValue
163163
&& !paramWithMeta.get("examples")
164164
) {
@@ -174,10 +174,10 @@ export default class ParameterRow extends Component {
174174
stringify(generatedSampleValue)
175175
)
176176
)
177-
}
177+
}
178178
else if (
179-
type === "array"
180-
&& itemType === "object"
179+
schemaObjectType === "array"
180+
&& schemaItemsType === "object"
181181
&& generatedSampleValue
182182
&& !paramWithMeta.get("examples")
183183
) {
@@ -251,17 +251,17 @@ export default class ParameterRow extends Component {
251251
if (isOAS3) {
252252
schema = this.composeJsonSchema(schema)
253253
}
254-
254+
255255
let format = schema ? schema.get("format") : null
256256
let isFormData = inType === "formData"
257257
let isFormDataSupported = "FormData" in win
258258
let required = param.get("required")
259259

260-
const typeLabel = fn.jsonSchema202012.getType(immutableToJS(schema))
261-
const type = fn.jsonSchema202012.foldType(immutableToJS(schema?.get("type")))
262-
const itemType = fn.jsonSchema202012.foldType(immutableToJS(schema?.getIn(["items", "type"])))
263-
const isObject = !bodyParam && type === "object"
264-
const isArrayOfObjects = !bodyParam && itemType === "object"
260+
const schemaObjectType = fn.getSchemaObjectType(schema)
261+
const schemaItemsType = fn.getSchemaObjectType(schema?.get("items"))
262+
const schemaObjectTypeLabel = fn.getSchemaObjectTypeLabel(schema)
263+
const isObject = !bodyParam && schemaObjectType === "object"
264+
const isArrayOfObjects = !bodyParam && schemaItemsType === "object"
265265

266266
let value = paramWithMeta ? paramWithMeta.get("value") : ""
267267
let commonExt = showCommonExtensions ? getCommonExtensions(schema) : null
@@ -322,7 +322,7 @@ export default class ParameterRow extends Component {
322322
{ !required ? null : <span>&nbsp;*</span> }
323323
</div>
324324
<div className="parameter__type">
325-
{ typeLabel }
325+
{ schemaObjectTypeLabel }
326326
{ format && <span className="prop-format">(${format})</span>}
327327
</div>
328328
<div className="parameter__deprecated">
@@ -371,7 +371,7 @@ export default class ParameterRow extends Component {
371371
}
372372

373373
{ (isObject || isArrayOfObjects) ? (
374-
<ModelExample
374+
<ModelExample
375375
getComponent={getComponent}
376376
specPath={specPath.push("schema")}
377377
getConfigs={getConfigs}
@@ -380,7 +380,7 @@ export default class ParameterRow extends Component {
380380
schema={schema}
381381
example={jsonSchemaForm}
382382
/>
383-
) : jsonSchemaForm
383+
) : jsonSchemaForm
384384
}
385385

386386
{

src/core/components/response.jsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { fromJS, Seq, Iterable, List, Map } from "immutable"
66
import { getExtensions, fromJSOrdered, stringify } from "core/utils"
77
import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse"
88

9-
/* eslint-disable react/jsx-no-bind */
109

1110
const getExampleComponent = ( sampleResponse, HighlightCode ) => {
1211
if (sampleResponse == null) return null
@@ -140,8 +139,8 @@ export default class Response extends React.Component {
140139
const targetExample = examplesForMediaType
141140
.get(targetExamplesKey, Map({}))
142141
const getMediaTypeExample = (targetExample) =>
143-
Map.isMap(targetExample)
144-
? targetExample.get("value")
142+
Map.isMap(targetExample)
143+
? targetExample.get("value")
145144
: undefined
146145
mediaTypeExample = getMediaTypeExample(targetExample)
147146
if(mediaTypeExample === undefined) {

src/core/plugins/json-schema-5-samples/fn/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import XML from "xml"
22
import RandExp from "randexp"
33
import isEmpty from "lodash/isEmpty"
4-
import { objectify, isFunc, normalizeArray, deeplyStripKey } from "core/utils"
4+
import { deeplyStripKey, isFunc, normalizeArray, objectify, immutableToJS } from "core/utils"
55
import memoizeN from "core/utils/memoizeN"
66

77
const generateStringFromRegex = (pattern) => {
@@ -628,6 +628,7 @@ export const createXMLExample = (schema, config, o) => {
628628
return XML(json, { declaration: true, indent: "\t" })
629629
}
630630

631+
631632
export const sampleFromSchema = (schema, config, o) =>
632633
sampleFromSchemaGeneric(schema, config, o, false)
633634

@@ -636,3 +637,5 @@ const resolver = (arg1, arg2, arg3) => [arg1, JSON.stringify(arg2), JSON.stringi
636637
export const memoizedCreateXMLExample = memoizeN(createXMLExample, resolver)
637638

638639
export const memoizedSampleFromSchema = memoizeN(sampleFromSchema, resolver)
640+
641+
export const getSchemaObjectType = (schema) => immutableToJS(schema)?.type ?? "string"

src/core/plugins/json-schema-5-samples/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
memoizedCreateXMLExample,
1010
memoizedSampleFromSchema,
1111
mergeJsonSchema,
12+
getSchemaObjectType,
1213
} from "./fn/index"
1314
import makeGetJsonSampleSchema from "./fn/get-json-sample-schema"
1415
import makeGetYamlSampleSchema from "./fn/get-yaml-sample-schema"
@@ -47,6 +48,7 @@ const JSONSchema5SamplesPlugin = ({ getSystem }) => {
4748
getXmlSampleSchema,
4849
getSampleSchema,
4950
mergeJsonSchema,
51+
getSchemaObjectType,
5052
},
5153
}
5254
}

src/core/plugins/json-schema-5/components/json-schema-components.jsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import { List, fromJS } from "immutable"
44
import cx from "classnames"
55
import ImPropTypes from "react-immutable-proptypes"
66
import DebounceInput from "react-debounce-input"
7-
import { stringify, isImmutable, immutableToJS } from "core/utils"
8-
9-
/* eslint-disable react/jsx-no-bind */
7+
import { stringify, isImmutable } from "core/utils"
108

119
const noop = ()=> {}
1210
const JsonSchemaPropShape = {
@@ -50,7 +48,7 @@ export class JsonSchemaForm extends Component {
5048
let { schema, errors, value, onChange, getComponent, fn, disabled } = this.props
5149
const format = schema && schema.get ? schema.get("format") : null
5250
const type = schema && schema.get ? schema.get("type") : null
53-
const foldedType = fn.jsonSchema202012.foldType(immutableToJS(type))
51+
const objectType = fn.getSchemaObjectType(schema)
5452
const isFileUploadIntended = fn.isFileUploadIntended(schema)
5553

5654
let getComponentSilently = (name) => getComponent(name, false, { failSilently: true })
@@ -59,7 +57,7 @@ export class JsonSchemaForm extends Component {
5957
getComponentSilently(`JsonSchema_${type}`) :
6058
getComponent("JsonSchema_string")
6159

62-
if (!isFileUploadIntended && List.isList(type) && (foldedType === "array" || foldedType === "object")) {
60+
if (!isFileUploadIntended && List.isList(type) && (objectType === "array" || objectType === "object")) {
6361
Comp = getComponent("JsonSchema_object")
6462
}
6563

@@ -192,23 +190,23 @@ export class JsonSchema_array extends PureComponent {
192190
.map(e => e.error)
193191
const value = this.state.value // expect Im List
194192
const shouldRenderValue =
195-
value && value.count && value.count() > 0 ? true : false
193+
!!(value && value.count && value.count() > 0)
196194
const schemaItemsEnum = schema.getIn(["items", "enum"])
197-
const schemaItemsType = schema.getIn(["items", "type"])
198-
const foldedSchemaItemsType = fn.jsonSchema202012.foldType(immutableToJS(schemaItemsType))
199-
const schemaItemsTypeLabel = fn.jsonSchema202012.getType(immutableToJS(schema.get("items")))
195+
const schemaItems = schema.get("items")
196+
const schemaItemsType = fn.getSchemaObjectType(schemaItems)
197+
const schemaItemsTypeLabel = fn.getSchemaObjectTypeLabel(schemaItems)
200198
const schemaItemsFormat = schema.getIn(["items", "format"])
201199
const schemaItemsSchema = schema.get("items")
202200
let ArrayItemsComponent
203201
let isArrayItemText = false
204-
let isArrayItemFile = (schemaItemsType === "file" || (schemaItemsType === "string" && schemaItemsFormat === "binary")) ? true : false
202+
let isArrayItemFile = (schemaItemsType === "file" || (schemaItemsType === "string" && schemaItemsFormat === "binary"))
205203
if (schemaItemsType && schemaItemsFormat) {
206204
ArrayItemsComponent = getComponent(`JsonSchema_${schemaItemsType}_${schemaItemsFormat}`)
207205
} else if (schemaItemsType === "boolean" || schemaItemsType === "array" || schemaItemsType === "object") {
208206
ArrayItemsComponent = getComponent(`JsonSchema_${schemaItemsType}`)
209207
}
210208

211-
if (List.isList(schemaItemsType) && (foldedSchemaItemsType === "array" || foldedSchemaItemsType === "object")) {
209+
if (List.isList(schemaItems?.get("type")) && (schemaItemsType === "array" || schemaItemsType === "object")) {
212210
ArrayItemsComponent = getComponent(`JsonSchema_object`)
213211
}
214212

src/core/plugins/json-schema-5/fn.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44
import { Map } from "immutable"
55
import isPlainObject from "lodash/isPlainObject"
6+
import { immutableToJS } from "core/utils"
67

78
export const hasSchemaType = (schema, type) => {
89
const isSchemaImmutable = Map.isMap(schema)
@@ -17,3 +18,34 @@ export const hasSchemaType = (schema, type) => {
1718
type === schemaType || (Array.isArray(type) && type.includes(schemaType))
1819
)
1920
}
21+
22+
const getType = (schema, processedSchemas = new WeakSet()) => {
23+
if (schema == null) {
24+
return "any"
25+
}
26+
27+
if (processedSchemas.has(schema)) {
28+
return "any" // detect a cycle
29+
}
30+
31+
processedSchemas.add(schema)
32+
33+
const { type, items } = schema
34+
35+
const getArrayType = () => {
36+
if (items) {
37+
const itemsType = getType(items, processedSchemas)
38+
return `array<${itemsType}>`
39+
} else {
40+
return "array<any>"
41+
}
42+
}
43+
44+
if (Object.hasOwn(schema, "items")) {
45+
return getArrayType()
46+
}
47+
return type
48+
}
49+
50+
export const getSchemaObjectTypeLabel = (schema) =>
51+
getType(immutableToJS(schema))

src/core/plugins/json-schema-5/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Schemes from "./components/schemes"
1414
import SchemesContainer from "./containers/schemes"
1515
import * as JSONSchemaComponents from "./components/json-schema-components"
1616
import { ModelExtensions } from "./components/model-extensions"
17-
import { hasSchemaType } from "./fn"
17+
import { getSchemaObjectTypeLabel, hasSchemaType } from "./fn"
1818

1919
const JSONSchema5Plugin = () => ({
2020
components: {
@@ -34,6 +34,7 @@ const JSONSchema5Plugin = () => ({
3434
},
3535
fn: {
3636
hasSchemaType,
37+
getSchemaObjectTypeLabel,
3738
},
3839
})
3940

src/core/plugins/oas3/components/request-body.jsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ import React from "react"
22
import PropTypes from "prop-types"
33
import ImPropTypes from "react-immutable-proptypes"
44
import { Map, OrderedMap, List, fromJS } from "immutable"
5-
import { getCommonExtensions, stringify, isEmptyValue, immutableToJS } from "core/utils"
5+
import { getCommonExtensions, stringify, isEmptyValue } from "core/utils"
66
import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse"
77

8-
/* eslint-disable react/jsx-no-bind */
9-
108
export const getDefaultRequestBodyValue = (requestBody, mediaType, activeExamplesKey, fn) => {
119
const mediaTypeValue = requestBody.getIn(["content", mediaType]) ?? OrderedMap()
1210
const schema = mediaTypeValue.get("schema", OrderedMap()).toJS()
@@ -160,9 +158,9 @@ const RequestBody = ({
160158

161159
let commonExt = showCommonExtensions ? getCommonExtensions(schema) : null
162160
const required = schemaForMediaType.get("required", List()).includes(key)
163-
const typeLabel = fn.jsonSchema202012.getType(immutableToJS(schema))
164-
const type = fn.jsonSchema202012.foldType(immutableToJS(schema?.get("type")))
165-
const itemType = fn.jsonSchema202012.foldType(immutableToJS(schema?.getIn(["items", "type"])))
161+
const objectType = fn.getSchemaObjectType(schema)
162+
const objectTypeLabel = fn.getSchemaObjectTypeLabel(schema)
163+
const schemaItemsType = fn.getSchemaObjectType(schema?.get("items"))
166164
const format = schema.get("format")
167165
const description = schema.get("description")
168166
const currentValue = requestBodyValue.getIn([key, "value"])
@@ -181,11 +179,11 @@ const RequestBody = ({
181179
initialValue = "0"
182180
}
183181

184-
if (typeof initialValue !== "string" && type === "object") {
182+
if (typeof initialValue !== "string" && objectType === "object") {
185183
initialValue = stringify(initialValue)
186184
}
187185

188-
if (typeof initialValue === "string" && type === "array") {
186+
if (typeof initialValue === "string" && objectType === "array") {
189187
initialValue = JSON.parse(initialValue)
190188
}
191189

@@ -212,7 +210,7 @@ const RequestBody = ({
212210
{ !required ? null : <span>&nbsp;*</span> }
213211
</div>
214212
<div className="parameter__type">
215-
{ typeLabel }
213+
{ objectTypeLabel }
216214
{ format && <span className="prop-format">(${format})</span>}
217215
{!showCommonExtensions || !commonExt.size ? null : commonExt.entrySeq().map(([key, v]) => <ParameterExt key={`${key}-${v}`} xKey={key} xVal={v} />)}
218216
</div>
@@ -223,7 +221,7 @@ const RequestBody = ({
223221
<td className="parameters-col_description">
224222
<Markdown source={ description }></Markdown>
225223
{isExecute ? <div>
226-
{(type === "object" || itemType === "object") ? (
224+
{(objectType === "object" || schemaItemsType === "object") ? (
227225
<ModelExample
228226
getComponent={getComponent}
229227
specPath={specPath.push("schema")}

src/core/plugins/oas31/after-load.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from "./json-schema-2020-12-extensions/fn"
88
import { wrapOAS31Fn } from "./fn"
99
import { makeIsFileUploadIntended } from "./oas3-extensions/fn"
10+
import { immutableToJS } from "core/utils"
1011

1112
function afterLoad({ fn, getSystem }) {
1213
// overrides for fn.jsonSchema202012
@@ -33,6 +34,10 @@ function afterLoad({ fn, getSystem }) {
3334
getXmlSampleSchema: fn.jsonSchema202012.getXmlSampleSchema,
3435
getSampleSchema: fn.jsonSchema202012.getSampleSchema,
3536
mergeJsonSchema: fn.jsonSchema202012.mergeJsonSchema,
37+
getSchemaObjectTypeLabel: (schema) =>
38+
fn.jsonSchema202012.getType(immutableToJS(schema)),
39+
getSchemaObjectType: (schema) =>
40+
fn.jsonSchema202012.foldType(immutableToJS(schema)?.type),
3641
},
3742
getSystem()
3843
)

0 commit comments

Comments
 (0)