Skip to content

Commit aaf5654

Browse files
authored
Merge pull request #177 from brendo/feauture-112-external-docs-support
Support externalDocs. Closes #112
2 parents f4f49e4 + 18ed955 commit aaf5654

31 files changed

+414
-69
lines changed

CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
66

77
## [Unreleased]
88

9-
- Lincoln can now display `additionalProperties`
9+
### Added
10+
11+
- [#91](https://github.com/temando/open-api-renderer/issues/91) Lincoln learnt how to display `additionalProperties`.
12+
- [#157](https://github.com/temando/open-api-renderer/issues/157) Lincoln learnt how to display `servers` and path information.
13+
- [#112](https://github.com/temando/open-api-renderer/issues/112) Lincoln learnt how to display `externalDocs`.
1014

1115
## [v0.0.6] - 2017-07-07
1216

docs/demo/demo.81f8cdaf8e92e7c02fcc.js

-1
This file was deleted.

docs/demo/demo.d73ff4397f0035ac6394.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/demo/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
77
</head>
8-
<body><script type="text/javascript" src="manifest.64e52d4be3e1405eba34.js"></script><script type="text/javascript" src="vendor.cda98230d6573ec02868.js"></script><script type="text/javascript" src="demo.81f8cdaf8e92e7c02fcc.js"></script></body>
8+
<body><script type="text/javascript" src="manifest.81c1f8c28d950ee22175.js"></script><script type="text/javascript" src="vendor.5e42313e188f293e0550.js"></script><script type="text/javascript" src="demo.d73ff4397f0035ac6394.js"></script></body>
99
</html>

docs/demo/manifest.64e52d4be3e1405eba34.js renamed to docs/demo/manifest.81c1f8c28d950ee22175.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/demo/vendor.cda98230d6573ec02868.js renamed to docs/demo/vendor.5e42313e188f293e0550.js

+11-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/open-api-v3-support.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ This document outlines this project's support for visualising the [Open API V3][
3131
- [ ] [components](#components-object)
3232
- [x] [security](#security-requirement-object)
3333
- [x] [tags](#tag-object)
34-
- [ ] [externalDocs](#external-documentation-object)
34+
- [x] [externalDocs](#external-documentation-object)
3535

3636
### [Info](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#info-object) object
3737

@@ -104,7 +104,7 @@ This is supported by default as all `$ref` are dereferenced before the definitio
104104
- [x] tags
105105
- [x] summary
106106
- [x] description
107-
- [ ] [externalDocs](#external-documentation-object)
107+
- [x] [externalDocs](#external-documentation-object)
108108
- [ ] operationId
109109
- [x] [parameters](#parameter-object)
110110
- [x] [requestBody](#request-body-object)
@@ -116,8 +116,8 @@ This is supported by default as all `$ref` are dereferenced before the definitio
116116

117117
### [External Documentation](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#external-documentation-object) object
118118

119-
- [ ] description
120-
- [ ] url
119+
- [x] description
120+
- [x] url
121121

122122
### [Parameter](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#parameter-object) object
123123

@@ -209,7 +209,7 @@ See [parameter](#parameter-object) object.
209209

210210
- [x] name
211211
- [x] description
212-
- [ ] [externalDocs](#external-documentation-object)
212+
- [x] [externalDocs](#external-documentation-object)
213213

214214
### [Reference](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#reference-object) object
215215

@@ -263,7 +263,7 @@ The OpenAPI specification also supports several additional properties from JSON
263263
- [ ] readOnly
264264
- [ ] writeOnly
265265
- [ ] [xml](#xml-object)
266-
- [ ] [externalDocs](#external-documentation-object)
266+
- [x] [externalDocs](#external-documentation-object)
267267
- [ ] example
268268
- [ ] deprecated
269269

src/components/BodyContent/BodyContent.styles.js

+3-9
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ export const styles = createSheet(({ text, backgrounds, sizes }) => ({
55
'bodyContent': {
66
display: 'table',
77
width: '100%',
8-
padding: '10px',
8+
padding: '1rem 0',
99
boxSizing: 'border-box'
1010
},
1111

1212
'tabs': {
1313
'& > div': {
1414
display: 'inline-block',
15-
padding: '10px 20px',
15+
padding: '1rem 2rem',
1616
cursor: 'pointer',
1717

1818
'&:not($active)': {
@@ -23,12 +23,6 @@ export const styles = createSheet(({ text, backgrounds, sizes }) => ({
2323

2424
'active': {
2525
backgroundColor: `${backgrounds.schema}`,
26-
borderRadius: '10px 10px 0 0'
27-
},
28-
29-
[`@media (max-width: ${sizes.breakpoint})`]: {
30-
'bodyContent': {
31-
padding: '10px 0'
32-
}
26+
borderRadius: '1rem 1rem 0 0'
3327
}
3428
}))

src/components/BodySchema/BodySchema.js

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export default class BodySchema extends Component {
7777
defaultValue={property.defaultValue}
7878
constraints={property.constraints}
7979
attributes={property.attributes}
80+
docs={property.docs}
8081
onClick={hasSubset ? this.onClick : undefined}
8182
isRequired={property.required}
8283
isOpen={isOpen}

src/components/ContentContainer/ContentContainer.styles.js

+2-8
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,13 @@ import { createSheet } from '../../theme'
22

33
export const styles = createSheet(({ sizes }) => ({
44
'contentContainer': {
5-
padding: '20px 0',
6-
7-
'& h2': {
8-
paddingLeft: '2rem'
9-
}
5+
padding: '0.5rem 2rem',
6+
margin: '1rem 0'
107
},
118

129
[`@media (max-width: ${sizes.breakpoint})`]: {
1310
'contentContainer': {
14-
padding: '10px 0',
15-
1611
'& h2': {
17-
paddingLeft: '1rem',
1812
margin: 0
1913
}
2014
}

src/components/Description/Description.styles.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ import { createSheet } from '../../theme'
33

44
export const styles = createSheet(({ text }) => ({
55
'description': {
6-
'&:not($inline)': {
7-
color: `${c(text.default).lighten(0.3)}`,
8-
fontSize: '0.9em'
9-
},
6+
color: `${c(text.default).lighten(0.3)}`,
7+
fontSize: '1rem',
108

119
'&$inline': {
1210
'&, & p': {
@@ -17,5 +15,7 @@ export const styles = createSheet(({ text }) => ({
1715
margin: '.5rem 0'
1816
}
1917
},
20-
'inline': {}
18+
'inline': {
19+
paddingRight: '.2rem'
20+
}
2121
}))

src/components/Docs/Docs.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React, { PureComponent } from 'react'
2+
import PropTypes from 'prop-types'
3+
import classNames from 'classnames'
4+
5+
import Description from '../Description/Description'
6+
import ExternalLink from '../ExternalLink/ExternalLink'
7+
import { styles } from './Docs.styles'
8+
9+
@styles
10+
export default class Docs extends PureComponent {
11+
render () {
12+
const { url, description, classes } = this.props
13+
14+
return (
15+
<div className={classNames(classes.docs)}>
16+
{description && <Description description={description} />}
17+
<ExternalLink href={url}>More information »</ExternalLink>
18+
</div>
19+
)
20+
}
21+
}
22+
23+
Docs.propTypes = {
24+
description: PropTypes.string,
25+
url: PropTypes.string.isRequired,
26+
classes: PropTypes.object
27+
}

src/components/Docs/Docs.styles.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { createSheet } from '../../theme'
2+
3+
export const styles = createSheet(() => ({
4+
'docs': {
5+
margin: '0.5rem 0'
6+
}
7+
}))

src/components/Header/Header.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { PureComponent } from 'react'
22
import PropTypes from 'prop-types'
33

4+
import Docs from '../Docs/Docs'
45
import Description from '../Description/Description'
56
import ExternalLink from '../ExternalLink/ExternalLink'
67
import { styles } from './Header.styles'
@@ -28,6 +29,8 @@ export default class Header extends PureComponent {
2829
{info && info.termsOfService &&
2930
<ExternalLink href={info.termsOfService}>Terms of Service</ExternalLink>}
3031
</nav>
32+
33+
{info && info.docs && <Docs {...info.docs} />}
3134
</header>
3235
)
3336
}
@@ -88,7 +91,11 @@ Header.propTypes = {
8891
info: PropTypes.shape({
8992
contact: PropTypes.object,
9093
license: PropTypes.object,
91-
termsOfService: PropTypes.string
94+
termsOfService: PropTypes.string,
95+
docs: PropTypes.shape({
96+
description: PropTypes.string,
97+
url: PropTypes.string.isRequired
98+
})
9299
}),
93100
definitionUrl: PropTypes.string,
94101
classes: PropTypes.object

src/components/Header/Header.styles.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createSheet } from '../../theme'
22

33
export const styles = createSheet(({ borders, sizes }) => ({
44
'header': {
5-
padding: '0 20px',
5+
padding: '0 2rem',
66

77
'& h1': {
88
marginBottom: '.5rem'

src/components/Method/Method.styles.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const styles = createSheet(({ borders, text, sizes }) => ({
55
method: {
66
borderBottom: `1px solid ${borders.default}`,
77
margin: '0 1rem 2rem 0',
8-
padding: '1rem 2rem',
8+
padding: '1rem 0',
99

1010
'& > h3': {
1111
display: 'inline-block',

src/components/Page/Page.js

+26-3
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,17 @@ export default class Page extends Component {
4848
/>
4949
{security && this.renderSecurity(security)}
5050
<ContentContainer>
51-
{services && services.map(
52-
(service) => <ServiceContainer key={service.title} service={service} initialSchemaTreeDepth={initialSchemaTreeDepth} />
53-
)}
51+
{services && services.map((service) => {
52+
const serviceWithDocs = Object.assign({}, service, this.findTagDocs(service.title, navigation))
53+
54+
return (
55+
<ServiceContainer
56+
key={service.title}
57+
service={serviceWithDocs}
58+
initialSchemaTreeDepth={initialSchemaTreeDepth}
59+
/>
60+
)
61+
})}
5462
</ContentContainer>
5563
</div>
5664
</div>
@@ -68,6 +76,21 @@ export default class Page extends Component {
6876
)
6977
}
7078

79+
findTagDocs (tagHandle, navigation) {
80+
// Find navigation tag that matches given `tagHandle`, and if has docs.
81+
// Note: tag.methods is a way to determine if the navigation has tags at all.
82+
const navigationTag = navigation.find((tag) => (tag.methods && tag.handle === tagHandle && tag.docs))
83+
84+
// No tag, no additional docs.
85+
if (!navigationTag) {
86+
return {}
87+
}
88+
89+
return {
90+
docs: navigationTag.docs
91+
}
92+
}
93+
7194
onToggleNavigation () {
7295
const { isNavOpen } = this.state
7396
if (isNavOpen) {

src/components/Property/Property.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React, { PureComponent } from 'react'
22
import classNames from 'classnames'
33
import PropTypes from 'prop-types'
4+
5+
import Docs from '../Docs/Docs'
46
import Description from '../Description/Description'
57
import Indicator from '../Indicator/Indicator'
68
import PropertyConstraints from './PropertyConstraints/PropertyConstraints'
@@ -47,9 +49,8 @@ export default class Property extends PureComponent {
4749

4850
render () {
4951
const {
50-
type, title, description, constraints, isRequired,
51-
defaultValue, onClick, isOpen, isLast, attributes,
52-
classes
52+
type, title, description, constraints, docs, defaultValue, attributes,
53+
isRequired, isOpen, isLast, onClick, classes
5354
} = this.props
5455

5556
const {name, isEnumTrimmed} = this.state
@@ -99,11 +100,12 @@ export default class Property extends PureComponent {
99100
<span className={classes.format}>&lt;{constraints.format}&gt;</span>}
100101
</span>
101102
<PropertyConstraints constraints={constraints} type={type} isRequired={isRequired} />
102-
{((enumValues && enumValues.length) || defaultValue || description) &&
103+
{((enumValues && enumValues.length) || defaultValue || description || docs) &&
103104
<div className={classes.additionalInfo}>
104105
{enumValues && this.renderEnumValues(enumValues, isEnumTrimmed)}
105106
{defaultValue !== undefined && this.renderDefaultValue(defaultValue)}
106107
{description && <div><Description isInline description={description} /></div>}
108+
{docs && <Docs {...docs} />}
107109
</div>
108110
}
109111
</td>
@@ -184,6 +186,10 @@ Property.propTypes = {
184186
pattern: PropTypes.string,
185187
uniqueItems: PropTypes.bool
186188
}),
189+
docs: PropTypes.shape({
190+
description: PropTypes.string,
191+
url: PropTypes.string.isRequired
192+
}),
187193
enumValues: PropTypes.array,
188194
defaultValue: PropTypes.any,
189195
isRequired: PropTypes.bool,

src/components/SecurityContainer/SecurityContainer.styles.js

+1-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createSheet } from '../../theme'
22

33
export const styles = createSheet(({ backgrounds, borders, sizes }) => ({
44
'securityContainer': {
5-
padding: '1rem 2rem',
5+
padding: '1rem 0',
66
borderBottom: `1px solid ${borders.default}`
77

88
},
@@ -26,11 +26,5 @@ export const styles = createSheet(({ backgrounds, borders, sizes }) => ({
2626
'& > li > span': {
2727
fontWeight: 600
2828
}
29-
},
30-
31-
[`@media (max-width: ${sizes.breakpoint})`]: {
32-
'securityContainer': {
33-
padding: '1rem'
34-
}
3529
}
3630
}))

src/components/ServiceContainer/ServiceContainer.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import React, { PureComponent } from 'react'
22
import PropTypes from 'prop-types'
3+
4+
import Docs from '../Docs/Docs'
35
import Method from '../Method/Method'
46
import { styles } from './ServiceContainer.styles'
57

68
@styles
79
export default class ServiceContainer extends PureComponent {
810
render () {
911
const { service, classes, initialSchemaTreeDepth } = this.props
10-
const { title, methods } = service
12+
const { title, docs, methods } = service
1113

1214
return (
1315
<div className={classes.serviceContainer} id={title}>
1416
<h2>{title}</h2>
17+
{docs && <Docs {...docs} />}
1518
{methods.map(
1619
(method) => <Method key={method.link} method={method} initialSchemaTreeDepth={initialSchemaTreeDepth} />
1720
)}

src/parser/open-api/schemaParser.js

+4
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ function getPropertyNode (nodeName, propertyNode, required = false) {
5555
outputNode.defaultValue = propertyNode.default
5656
}
5757

58+
if (propertyNode.externalDocs) {
59+
outputNode.docs = propertyNode.externalDocs
60+
}
61+
5862
if (propertyNode.additionalProperties === false) {
5963
outputNode.additionalProperties = false
6064
}

src/parser/open-api/v3/navigationParser.js

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ export function getServicesMethod ({path, servers, method, request, params, resp
5454
servicesMethod.description = method.description
5555
}
5656

57+
if (method.externalDocs) {
58+
servicesMethod.docs = method.externalDocs
59+
}
60+
5761
if (params) {
5862
servicesMethod.parameters = params
5963
}

0 commit comments

Comments
 (0)