Skip to content

Commit b86ab24

Browse files
authored
add support for unions (#53)
1 parent f1cae79 commit b86ab24

File tree

4 files changed

+277
-0
lines changed

4 files changed

+277
-0
lines changed

src/renderSchema.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,14 @@ function renderSchema(schema, options) {
139139
const enums = types.filter(type => type.kind === 'ENUM')
140140
const scalars = types.filter(type => type.kind === 'SCALAR')
141141
const interfaces = types.filter(type => type.kind === 'INTERFACE')
142+
const unions = types.filter(type => type.kind === 'UNION')
142143

143144
sortBy(objects, 'name')
144145
sortBy(inputs, 'name')
145146
sortBy(enums, 'name')
146147
sortBy(scalars, 'name')
147148
sortBy(interfaces, 'name')
149+
sortBy(unions, 'name')
148150

149151
if (!skipTitle) {
150152
printer(`${'#'.repeat(headingLevel)} ${title}\n`)
@@ -193,6 +195,12 @@ function renderSchema(schema, options) {
193195
printer(` * [${type.name}](#${type.name.toLowerCase()})`)
194196
})
195197
}
198+
if (unions.length) {
199+
printer(' * [Unions](#unions)')
200+
unions.forEach(type => {
201+
printer(` * [${type.name}](#${type.name.toLowerCase()})`)
202+
})
203+
}
196204
printer('\n</details>')
197205
}
198206

@@ -294,6 +302,40 @@ function renderSchema(schema, options) {
294302
)
295303
}
296304

305+
if (unions.length) {
306+
printer(`\n${'#'.repeat(headingLevel + 1)} Unions`)
307+
unions.forEach(type => {
308+
printer(`\n${'#'.repeat(headingLevel + 2)} ${type.name}\n`)
309+
if (type.description) {
310+
printer(`${type.description}\n`)
311+
}
312+
printer('<table>')
313+
printer('<thead>')
314+
printer('<th align="left">Type</th>')
315+
printer('<th align="left">Description</th>')
316+
printer('</thead>')
317+
printer('<tbody>')
318+
type.possibleTypes.forEach(objType => {
319+
const obj = objects.find(o => objType.name === o.name)
320+
const desc = objType.description || (obj && obj.description)
321+
printer('<tr>')
322+
printer(
323+
`<td valign="top"><strong>${renderType(objType, {
324+
getTypeURL
325+
})}</strong></td>`
326+
)
327+
if (desc) {
328+
printer(`<td valign="top">${desc}</td>`)
329+
} else {
330+
printer('<td></td>')
331+
}
332+
printer('</tr>')
333+
})
334+
printer('</tbody>')
335+
printer('</table>')
336+
})
337+
}
338+
297339
if (epilogue) {
298340
printer(`\n${epilogue}`)
299341
}

test/fixtures/union-test.graphql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"A human being"
2+
type Person {
3+
id: ID!
4+
firstName: String!
5+
lastName: String!
6+
email: String
7+
age: Int
8+
dob: String
9+
}
10+
11+
"A group of persons working together for a purpose"
12+
type Organization {
13+
"Node ID"
14+
id: ID!
15+
"Name of the organization"
16+
name: String!
17+
"Main contact email address"
18+
email: String
19+
"Date the organization was founded"
20+
founded: String
21+
"The CEO"
22+
ceo: Person
23+
}
24+
25+
"Either a person or an organization"
26+
union Party = Person | Organization
27+
28+
type Query {
29+
party(id: ID!): Party
30+
}

test/fixtures/union-test.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Schema Types
2+
3+
<details>
4+
<summary><strong>Table of Contents</strong></summary>
5+
6+
* [Query](#query)
7+
* [Objects](#objects)
8+
* [Organization](#organization)
9+
* [Person](#person)
10+
* [Scalars](#scalars)
11+
* [Boolean](#boolean)
12+
* [ID](#id)
13+
* [Int](#int)
14+
* [String](#string)
15+
* [Unions](#unions)
16+
* [Party](#party)
17+
18+
</details>
19+
20+
## Query
21+
<table>
22+
<thead>
23+
<tr>
24+
<th align="left">Field</th>
25+
<th align="right">Argument</th>
26+
<th align="left">Type</th>
27+
<th align="left">Description</th>
28+
</tr>
29+
</thead>
30+
<tbody>
31+
<tr>
32+
<td colspan="2" valign="top"><strong>party</strong></td>
33+
<td valign="top"><a href="#party">Party</a></td>
34+
<td></td>
35+
</tr>
36+
<tr>
37+
<td colspan="2" align="right" valign="top">id</td>
38+
<td valign="top"><a href="#id">ID</a>!</td>
39+
<td></td>
40+
</tr>
41+
</tbody>
42+
</table>
43+
44+
## Objects
45+
46+
### Organization
47+
48+
A group of persons working together for a purpose
49+
50+
<table>
51+
<thead>
52+
<tr>
53+
<th align="left">Field</th>
54+
<th align="right">Argument</th>
55+
<th align="left">Type</th>
56+
<th align="left">Description</th>
57+
</tr>
58+
</thead>
59+
<tbody>
60+
<tr>
61+
<td colspan="2" valign="top"><strong>id</strong></td>
62+
<td valign="top"><a href="#id">ID</a>!</td>
63+
<td>
64+
65+
Node ID
66+
67+
</td>
68+
</tr>
69+
<tr>
70+
<td colspan="2" valign="top"><strong>name</strong></td>
71+
<td valign="top"><a href="#string">String</a>!</td>
72+
<td>
73+
74+
Name of the organization
75+
76+
</td>
77+
</tr>
78+
<tr>
79+
<td colspan="2" valign="top"><strong>email</strong></td>
80+
<td valign="top"><a href="#string">String</a></td>
81+
<td>
82+
83+
Main contact email address
84+
85+
</td>
86+
</tr>
87+
<tr>
88+
<td colspan="2" valign="top"><strong>founded</strong></td>
89+
<td valign="top"><a href="#string">String</a></td>
90+
<td>
91+
92+
Date the organization was founded
93+
94+
</td>
95+
</tr>
96+
<tr>
97+
<td colspan="2" valign="top"><strong>ceo</strong></td>
98+
<td valign="top"><a href="#person">Person</a></td>
99+
<td>
100+
101+
The CEO
102+
103+
</td>
104+
</tr>
105+
</tbody>
106+
</table>
107+
108+
### Person
109+
110+
A human being
111+
112+
<table>
113+
<thead>
114+
<tr>
115+
<th align="left">Field</th>
116+
<th align="right">Argument</th>
117+
<th align="left">Type</th>
118+
<th align="left">Description</th>
119+
</tr>
120+
</thead>
121+
<tbody>
122+
<tr>
123+
<td colspan="2" valign="top"><strong>id</strong></td>
124+
<td valign="top"><a href="#id">ID</a>!</td>
125+
<td></td>
126+
</tr>
127+
<tr>
128+
<td colspan="2" valign="top"><strong>firstName</strong></td>
129+
<td valign="top"><a href="#string">String</a>!</td>
130+
<td></td>
131+
</tr>
132+
<tr>
133+
<td colspan="2" valign="top"><strong>lastName</strong></td>
134+
<td valign="top"><a href="#string">String</a>!</td>
135+
<td></td>
136+
</tr>
137+
<tr>
138+
<td colspan="2" valign="top"><strong>email</strong></td>
139+
<td valign="top"><a href="#string">String</a></td>
140+
<td></td>
141+
</tr>
142+
<tr>
143+
<td colspan="2" valign="top"><strong>age</strong></td>
144+
<td valign="top"><a href="#int">Int</a></td>
145+
<td></td>
146+
</tr>
147+
<tr>
148+
<td colspan="2" valign="top"><strong>dob</strong></td>
149+
<td valign="top"><a href="#string">String</a></td>
150+
<td></td>
151+
</tr>
152+
</tbody>
153+
</table>
154+
155+
## Scalars
156+
157+
### Boolean
158+
159+
The `Boolean` scalar type represents `true` or `false`.
160+
161+
### ID
162+
163+
The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.
164+
165+
### Int
166+
167+
The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
168+
169+
### String
170+
171+
The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
172+
173+
174+
## Unions
175+
176+
### Party
177+
178+
Either a person or an organization
179+
180+
<table>
181+
<thead>
182+
<th align="left">Type</th>
183+
<th align="left">Description</th>
184+
</thead>
185+
<tbody>
186+
<tr>
187+
<td valign="top"><strong><a href="#person">Person</a></strong></td>
188+
<td valign="top">A human being</td>
189+
</tr>
190+
<tr>
191+
<td valign="top"><strong><a href="#organization">Organization</a></strong></td>
192+
<td valign="top">A group of persons working together for a purpose</td>
193+
</tr>
194+
</tbody>
195+
</table>

test/index.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ describe('renderSchema()', () => {
6464
const expected = await readFile('./fixtures/no-toc.md')
6565
expect(printer.output).toBe(expected)
6666
})
67+
68+
it('supports unions', async () => {
69+
const schema = await loadSchemaJSON(
70+
path.resolve(__dirname, './fixtures/union-test.graphql')
71+
)
72+
const printer = createPrinter()
73+
renderSchema(schema, { printer })
74+
const expected = await readFile('./fixtures/union-test.md')
75+
expect(printer.output).toBe(expected)
76+
})
6777
})
6878

6979
describe('diffSchema()', () => {

0 commit comments

Comments
 (0)