Skip to content

Commit ca9ce9d

Browse files
committed
fix: handle recursive json schema
1 parent 41ed7d3 commit ca9ce9d

File tree

6 files changed

+467
-180
lines changed

6 files changed

+467
-180
lines changed

package-lock.json

Lines changed: 30 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/JSONSchema/JSONSchema.tsx

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import React, { Component } from "react";
2-
import { Typography } from "@material-ui/core";
32
import _ from "lodash";
43
import JSONSchemaFields from "./fields/JSONSchemaFields";
5-
import PrimitiveField from "./fields/JSONSchemaPrimitiveField";
64
import { JSONSchema4 } from "json-schema";
75

86
interface IProps {
@@ -12,44 +10,7 @@ interface IProps {
1210
class JSONSchema extends Component<IProps> {
1311
public render() {
1412
const { schema } = this.props;
15-
if (!schema) { return null; }
16-
if (_.isEmpty(schema)) { return null; }
17-
if (schema && !schema.properties && schema.oneOf) {
18-
return (
19-
<>
20-
{schema.oneOf &&
21-
<>
22-
<Typography variant="body1">one of</Typography>
23-
{schema.oneOf.map((item) => {
24-
return (
25-
<JSONSchema schema={item} />
26-
);
27-
})}
28-
</>
29-
}
30-
</>
31-
);
32-
}
33-
let arrayWithItems = schema && schema.type === "array" && (schema.items || schema.contains);
34-
if (arrayWithItems) {
35-
arrayWithItems = _.isArray(arrayWithItems) ? arrayWithItems : [arrayWithItems];
36-
return (
37-
<>
38-
<Typography variant="body1">array of</Typography>
39-
<JSONSchemaFields schema={schema} />
40-
{arrayWithItems.map((item: JSONSchema4) => {
41-
return (
42-
<JSONSchema schema={item} />
43-
);
44-
})}
45-
</>
46-
);
47-
}
48-
if (schema && schema.properties) {
49-
return <JSONSchemaFields schema={schema} />;
50-
}
51-
52-
return <PrimitiveField schema={schema} />;
13+
return <JSONSchemaFields schema={schema} />;
5314
}
5415
}
5516

src/JSONSchema/SchemaRenderer.tsx

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import React from "react";
2+
import { JSONSchema4 } from "json-schema";
3+
import { TableRow, TableCell, Typography } from "@material-ui/core";
4+
import JSONSchemaFields from "./fields/JSONSchemaFields";
5+
import _ from "lodash";
6+
7+
interface IProps {
8+
schema: JSONSchema4;
9+
required?: boolean;
10+
name?: string;
11+
}
12+
13+
const styles = {
14+
cellWidth: {
15+
margin: "5px",
16+
padding: "5px",
17+
width: "70px",
18+
},
19+
};
20+
21+
const SchemaRenderer: React.FC<IProps> = ({ schema, required, name }) => {
22+
if (schema.type === "object" || schema.properties) {
23+
return (
24+
<TableRow>
25+
<TableCell colSpan={1} style={styles.cellWidth}>
26+
{schema.title || name}
27+
</TableCell>
28+
<TableCell colSpan={1} style={styles.cellWidth}>
29+
<Typography variant="body1" color="primary">object</Typography>
30+
</TableCell>
31+
<TableCell colSpan={5}>
32+
{schema.properties && Object.entries(schema.properties).map(([n, prop]: [string, JSONSchema4], i: number) => {
33+
return (
34+
<JSONSchemaFields
35+
key={n}
36+
schema={prop}
37+
name={n}
38+
hideHeader={i !== 0}
39+
required={schema.required && schema.required.includes(n)}
40+
/>
41+
);
42+
})}
43+
</TableCell>
44+
</TableRow>
45+
);
46+
}
47+
if (schema.anyOf) {
48+
return (
49+
<TableRow>
50+
<TableCell colSpan={1} style={styles.cellWidth}>
51+
{schema.title || name}
52+
</TableCell>
53+
<TableCell colSpan={1} style={styles.cellWidth}>
54+
<Typography variant="body1" color="primary">any of</Typography>
55+
</TableCell>
56+
<TableCell colSpan={5}>
57+
{schema.anyOf.map((p, i) => <JSONSchemaFields schema={p} key={i} />)}
58+
</TableCell>
59+
</TableRow>
60+
);
61+
}
62+
if (schema.allOf) {
63+
return (
64+
<TableRow>
65+
<TableCell colSpan={1} style={styles.cellWidth}>
66+
{schema.title || name}
67+
</TableCell>
68+
<TableCell colSpan={1} style={styles.cellWidth}>
69+
<Typography variant="body1" color="primary">all of</Typography>
70+
</TableCell>
71+
<TableCell colSpan={5}>
72+
{schema.allOf.map((p, i) => <JSONSchemaFields schema={p} key={i} />)}
73+
</TableCell>
74+
</TableRow>
75+
);
76+
}
77+
if (schema.oneOf) {
78+
return (
79+
<TableRow>
80+
<TableCell colSpan={1} style={styles.cellWidth}>
81+
{schema.title || name}
82+
</TableCell>
83+
<TableCell colSpan={1} style={styles.cellWidth}>
84+
<Typography variant="body1" color="primary">one of</Typography>
85+
</TableCell>
86+
<TableCell colSpan={5}>
87+
{schema.oneOf.map((p, i) => <JSONSchemaFields schema={p} key={i} />)}
88+
</TableCell>
89+
</TableRow>
90+
);
91+
}
92+
if (schema.type === "array" && schema.items instanceof Array) {
93+
return (
94+
<TableRow>
95+
<TableCell colSpan={1} style={styles.cellWidth}>
96+
{schema.title || name}
97+
</TableCell>
98+
<TableCell colSpan={1} style={styles.cellWidth}>
99+
<Typography variant="body1" color="primary">array of</Typography>
100+
</TableCell>
101+
<TableCell colSpan={5}>
102+
{schema.items.map((p, i) => <JSONSchemaFields schema={p} key={i} />)}
103+
</TableCell>
104+
</TableRow>
105+
);
106+
}
107+
if (schema.type === "array" && schema.items) {
108+
return (
109+
<TableRow>
110+
<TableCell colSpan={1} style={styles.cellWidth}>
111+
{schema.title || name}
112+
</TableCell>
113+
<TableCell colSpan={1} style={styles.cellWidth}>
114+
<Typography variant="body1" color="primary">array of</Typography>
115+
</TableCell>
116+
<TableCell colSpan={5}>
117+
<JSONSchemaFields schema={schema.items} />
118+
</TableCell>
119+
</TableRow>
120+
);
121+
}
122+
return (
123+
<TableRow key={schema.title}>
124+
<TableCell component="th" scope="row" style={styles.cellWidth}>
125+
{schema.title || name}
126+
</TableCell>
127+
<TableCell style={styles.cellWidth}>{schema.type}</TableCell>
128+
<TableCell style={styles.cellWidth}>{schema.pattern}</TableCell>
129+
<TableCell style={styles.cellWidth}>{required ? "required" : "optional"}</TableCell>
130+
<TableCell style={styles.cellWidth}>{schema.description}</TableCell>
131+
</TableRow>
132+
);
133+
};
134+
135+
export default SchemaRenderer;

0 commit comments

Comments
 (0)