Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f29aa7e1 | ||
|
|
cdf3dfa075 | ||
|
|
8f73519cc7 | ||
|
|
3ee4f8d6e3 | ||
|
|
213f6d7080 | ||
|
|
7254e8b3fa | ||
|
|
13eed0d0f7 | ||
|
|
0256b97855 | ||
|
|
61eb86ed50 | ||
|
|
bb57fd2406 | ||
|
|
6f5649c6ba | ||
|
|
d7d061b5af | ||
|
|
0f86524514 | ||
|
|
ba90c70b34 | ||
|
|
ef3ccd7a23 | ||
|
|
0c0c9a6519 | ||
|
|
945d7a3a0f | ||
|
|
b3c549055d | ||
|
|
efd02106a2 | ||
|
|
7e9d8f0b37 | ||
|
|
ab7af75ab4 | ||
|
|
5d3efbb5f7 | ||
|
|
0997c5e5d4 | ||
|
|
21ff236e43 | ||
|
|
07a9410ee5 | ||
|
|
25b9fb28dc | ||
|
|
9603905d1d | ||
|
|
a7a50b8457 | ||
|
|
00a059b8dd | ||
|
|
d003df2e5a | ||
|
|
50153487ba | ||
|
|
d5a4cab383 | ||
|
|
e6ecb201c7 | ||
|
|
ec787cfeb6 | ||
|
|
67132ca920 | ||
|
|
0fa532d35c | ||
|
|
15cf495452 | ||
|
|
5224932cf9 | ||
|
|
8d1d15ca4a | ||
|
|
e17a5f40f5 | ||
|
|
2325118540 | ||
|
|
ade47ca40e | ||
|
|
8223710e92 | ||
|
|
de7e0910bb | ||
|
|
713d1a1bb8 | ||
|
|
40bd720eb4 | ||
|
|
a6dd9d60e7 | ||
|
|
5db4131046 | ||
|
|
52693254e9 | ||
|
|
51a68c0d8e | ||
|
|
91e7ade059 | ||
|
|
88e98ce281 | ||
|
|
6bb5a95424 | ||
|
|
23fd8a4d73 | ||
|
|
640050e54e | ||
|
|
c70e0f8c38 | ||
|
|
b42e2a7045 | ||
|
|
469b4d6323 | ||
|
|
d3cc636dde | ||
|
|
32ff344bdd | ||
|
|
40f8481127 | ||
|
|
7b13f41be7 | ||
|
|
7f237f3b23 | ||
|
|
dc7706e262 | ||
|
|
20cf8a3b1b | ||
|
|
f697e45362 | ||
|
|
4f13d6dda6 | ||
|
|
1695f655bb | ||
|
|
dc29e06d66 | ||
|
|
be8ce8688e | ||
|
|
ef256de050 | ||
|
|
01d84cdc0f | ||
|
|
9f18e02ace | ||
|
|
44d9234971 | ||
|
|
88eda43c46 | ||
|
|
a7818d5983 | ||
|
|
a2f09896f7 | ||
|
|
04daadafd5 | ||
|
|
3c2af93589 | ||
|
|
cfc7b1a192 | ||
|
|
8ff2d77398 | ||
|
|
7c1126ce51 | ||
|
|
e2d0bd7628 | ||
|
|
774acb1f28 | ||
|
|
31694d7533 | ||
|
|
2831c59e70 | ||
|
|
0d0b3279bb | ||
|
|
f929d4fdd6 | ||
|
|
40c2c28a7d | ||
|
|
ee5d9a8c34 | ||
|
|
91dab7b166 | ||
|
|
83dd9f3dfc | ||
|
|
7b83f64676 | ||
|
|
233dacde71 | ||
|
|
45a0295c0e | ||
|
|
5231c13579 | ||
|
|
a58cd25f08 | ||
|
|
fc3ac17710 | ||
|
|
9a66acf37f | ||
|
|
44c422eba3 |
@@ -6,3 +6,4 @@
|
||||
!dist/swagger-ui.js.map
|
||||
!dist/swagger-ui.css
|
||||
!dist/swagger-ui.css.map
|
||||
!dist/oauth2-redirect.html
|
||||
|
||||
@@ -13,6 +13,7 @@ ENV OAUTH_APP_NAME "**None**"
|
||||
ENV OAUTH_ADDITIONAL_PARAMS "**None**"
|
||||
ENV SWAGGER_JSON "/app/swagger.json"
|
||||
ENV PORT 80
|
||||
ENV BASE_URL ""
|
||||
|
||||
RUN apk add --update nginx
|
||||
RUN mkdir -p /run/nginx
|
||||
|
||||
@@ -22,7 +22,7 @@ The OpenAPI Specification has undergone 5 revisions since initial creation in 20
|
||||
|
||||
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
|
||||
------------------ | ------------ | -------------------------- | -----
|
||||
3.4.5 | 2017-11-03 | 2.0, 3.0 | [tag v3.4.5](https://github.com/swagger-api/swagger-ui/tree/v3.4.5)
|
||||
3.6.0 | 2017-12-01 | 2.0, 3.0 | [tag v3.5=6.0](https://github.com/swagger-api/swagger-ui/tree/v3.6.0)
|
||||
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
|
||||
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10)
|
||||
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5)
|
||||
@@ -49,6 +49,14 @@ Or you can provide your own swagger.json on your host
|
||||
docker run -p 80:8080 -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui
|
||||
```
|
||||
|
||||
The base URL of the web application can be changed by specifying the `BASE_URL` environment variable:
|
||||
|
||||
```
|
||||
docker run -p 80:8080 -e BASE_URL=/swagger -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui
|
||||
```
|
||||
|
||||
This will serve Swagger UI at `/swagger` instead of `/`.
|
||||
|
||||
##### Prerequisites
|
||||
- Node 6.x
|
||||
- NPM 3.x
|
||||
@@ -162,9 +170,10 @@ displayRequestDuration | Controls the display of the request duration (in millis
|
||||
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
|
||||
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
|
||||
deepLinking | If set to `true`, enables dynamic deep linking for tags and operations. [Docs](https://github.com/swagger-api/swagger-ui/blob/master/docs/deep-linking.md)
|
||||
requestInterceptor | MUST be a function. Function to intercept try-it-out requests. Accepts one argument requestInterceptor(request) and must return the potentially modified request.
|
||||
responseInterceptor | MUST be a function. Function to intercept try-it-out responses. Accepts one argument responseInterceptor(response) and must return the potentially modified response.
|
||||
requestInterceptor | MUST be a function. Function to intercept remote definition, Try-It-Out, and OAuth2 requests. Accepts one argument requestInterceptor(request) and must return the potentially modified request.
|
||||
responseInterceptor | MUST be a function. Function to intercept remote definition, Try-It-Out, and OAuth2 responses. Accepts one argument responseInterceptor(response) and must return the potentially modified response.
|
||||
showMutatedRequest | If set to `true` (the default), uses the mutated request returned from a rquestInterceptor to produce the curl command in the UI, otherwise the request before the requestInterceptor was applied is used.
|
||||
showExtensions | Controls the display of vendor extension (`x-`) fields and values for Operations, Parameters, and Schema. The default is `false`.
|
||||
|
||||
### Plugins
|
||||
|
||||
|
||||
Vendored
+15
-15
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+3
-3
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -21,6 +21,16 @@ replace_or_delete_in_index () {
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "${BASE_URL}" ]; then
|
||||
NGINX_WITH_BASE_URL="${NGINX_ROOT}${BASE_URL}"
|
||||
|
||||
mkdir -p ${NGINX_WITH_BASE_URL}
|
||||
mv ${NGINX_ROOT}/*.* ${NGINX_WITH_BASE_URL}/
|
||||
|
||||
INDEX_FILE=$NGINX_WITH_BASE_URL/index.html
|
||||
NGINX_ROOT=$NGINX_WITH_BASE_URL
|
||||
fi
|
||||
|
||||
replace_in_index myApiKeyXXXX123456789 $API_KEY
|
||||
replace_or_delete_in_index your-client-id $OAUTH_CLIENT_ID
|
||||
replace_or_delete_in_index your-client-secret-if-required $OAUTH_CLIENT_SECRET
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "swagger-ui",
|
||||
"version": "3.4.5",
|
||||
"version": "3.6.0",
|
||||
"main": "dist/swagger-ui.js",
|
||||
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
||||
"contributors": [
|
||||
@@ -81,7 +81,7 @@
|
||||
"scroll-to-element": "^2.0.0",
|
||||
"serialize-error": "2.0.0",
|
||||
"shallowequal": "0.2.2",
|
||||
"swagger-client": "^3.3.4",
|
||||
"swagger-client": "^3.4.0",
|
||||
"url-parse": "^1.1.8",
|
||||
"whatwg-fetch": "0.11.1",
|
||||
"worker-loader": "^0.7.1",
|
||||
|
||||
@@ -7,6 +7,7 @@ export default class ArrayModel extends Component {
|
||||
static propTypes = {
|
||||
schema: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
name: PropTypes.string,
|
||||
required: PropTypes.bool,
|
||||
@@ -15,7 +16,7 @@ export default class ArrayModel extends Component {
|
||||
}
|
||||
|
||||
render(){
|
||||
let { getComponent, schema, depth, expandDepth, name } = this.props
|
||||
let { getComponent, getConfigs, schema, depth, expandDepth, name } = this.props
|
||||
let description = schema.get("description")
|
||||
let items = schema.get("items")
|
||||
let title = schema.get("title") || name
|
||||
@@ -46,7 +47,7 @@ export default class ArrayModel extends Component {
|
||||
!description ? null :
|
||||
<Markdown source={ description } />
|
||||
}
|
||||
<span><Model { ...this.props } name={null} schema={ items } required={ false } depth={ depth + 1 } /></span>
|
||||
<span><Model { ...this.props } getConfigs={ getConfigs } name={null} schema={ items } required={ false } depth={ depth + 1 } /></span>
|
||||
]
|
||||
</ModelCollapse>
|
||||
</span>
|
||||
|
||||
@@ -41,6 +41,13 @@ export default class Auths extends React.Component {
|
||||
authActions.logout(auths)
|
||||
}
|
||||
|
||||
close =(e) => {
|
||||
e.preventDefault()
|
||||
let { authActions } = this.props
|
||||
|
||||
authActions.showDefinitions(false)
|
||||
}
|
||||
|
||||
render() {
|
||||
let { definitions, getComponent, authSelectors, errSelectors } = this.props
|
||||
const AuthItem = getComponent("AuthItem")
|
||||
@@ -74,6 +81,7 @@ export default class Auths extends React.Component {
|
||||
}).toArray()
|
||||
}
|
||||
<div className="auth-btn-wrapper">
|
||||
<Button className="btn modal-btn auth btn-done" onClick={ this.close }>Done</Button>
|
||||
{
|
||||
nonOauthDefinitions.size === authorizedAuth.size ? <Button className="btn modal-btn auth" onClick={ this.logoutClick }>Logout</Button>
|
||||
: <Button type="submit" className="btn modal-btn auth authorize">Authorize</Button>
|
||||
|
||||
@@ -200,11 +200,11 @@ export default class Oauth2 extends React.Component {
|
||||
<Row key={ name }>
|
||||
<div className="checkbox">
|
||||
<Input data-value={ name }
|
||||
id={`${name}-checkbox-${this.state.name}`}
|
||||
id={`${name}-${flow}-checkbox-${this.state.name}`}
|
||||
disabled={ isAuthorized }
|
||||
type="checkbox"
|
||||
onChange={ this.onScopeChange }/>
|
||||
<label htmlFor={`${name}-checkbox-${this.state.name}`}>
|
||||
<label htmlFor={`${name}-${flow}-checkbox-${this.state.name}`}>
|
||||
<span className="item"></span>
|
||||
<div className="text">
|
||||
<p className="name">{name}</p>
|
||||
|
||||
@@ -2,20 +2,24 @@ import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import Im from "immutable"
|
||||
|
||||
const propStyle = { color: "#999", fontStyle: "italic" }
|
||||
|
||||
export default class Headers extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
headers: PropTypes.object.isRequired
|
||||
headers: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
let { headers } = this.props
|
||||
let { headers, getComponent } = this.props
|
||||
const Property = getComponent("Property")
|
||||
|
||||
if ( !headers || !headers.size )
|
||||
return null
|
||||
|
||||
return (
|
||||
return (
|
||||
<div className="headers-wrapper">
|
||||
<h4 className="headers__title">Headers:</h4>
|
||||
<table className="headers">
|
||||
@@ -32,10 +36,13 @@ export default class Headers extends React.Component {
|
||||
if(!Im.Map.isMap(header)) {
|
||||
return null
|
||||
}
|
||||
const type = header.getIn(["schema"]) ? header.getIn(["schema", "type"]) : header.getIn(["type"])
|
||||
const schemaExample = header.getIn(["schema", "example"])
|
||||
|
||||
return (<tr key={ key }>
|
||||
<td className="header-col">{ key }</td>
|
||||
<td className="header-col">{ header.get( "description" ) }</td>
|
||||
<td className="header-col">{ header.get( "type" ) }</td>
|
||||
<td className="header-col">{ type } { schemaExample ? <Property propKey={ "Example" } propVal={ schemaExample } propStyle={ propStyle } /> : null }</td>
|
||||
</tr>)
|
||||
}).toArray()
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ export class Select extends React.Component {
|
||||
{ allowEmptyValue ? <option value="">--</option> : null }
|
||||
{
|
||||
allowedValues.map(function (item, key) {
|
||||
return <option key={ key } value={ String(item) }>{ item }</option>
|
||||
return <option key={ key } value={ String(item) }>{ String(item) }</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
|
||||
@@ -94,8 +94,9 @@ export default class BaseLayout extends React.Component {
|
||||
) : null }
|
||||
|
||||
{ servers && servers.size ? (
|
||||
<div className="server-container">
|
||||
<div className="global-server-container">
|
||||
<Col className="servers wrapper" mobile={12}>
|
||||
<span className="servers-title">Server</span>
|
||||
<Servers
|
||||
servers={servers}
|
||||
currentServer={oas3Selectors.selectedServer()}
|
||||
|
||||
@@ -52,6 +52,7 @@ export default class ModelExample extends React.Component {
|
||||
{
|
||||
!isExecute && this.state.activeTab === "model" && <ModelWrapper schema={ schema }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
specSelectors={ specSelectors }
|
||||
expandDepth={ defaultModelExpandDepth } />
|
||||
|
||||
|
||||
@@ -6,18 +6,17 @@ export default class ModelComponent extends Component {
|
||||
schema: PropTypes.object.isRequired,
|
||||
name: PropTypes.string,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
expandDepth: PropTypes.number
|
||||
}
|
||||
|
||||
render(){
|
||||
let { getComponent } = this.props
|
||||
let { getComponent, getConfigs } = this.props
|
||||
const Model = getComponent("Model")
|
||||
|
||||
return <div className="model-box">
|
||||
<Model { ...this.props } depth={ 1 } expandDepth={ this.props.expandDepth || 0 }/>
|
||||
<Model { ...this.props } getConfigs={ getConfigs } depth={ 1 } expandDepth={ this.props.expandDepth || 0 }/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import React, { PureComponent } from "react"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export default class Model extends PureComponent {
|
||||
static propTypes = {
|
||||
schema: PropTypes.object.isRequired,
|
||||
schema: ImPropTypes.orderedMap.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
name: PropTypes.string,
|
||||
isRef: PropTypes.bool,
|
||||
@@ -29,7 +31,7 @@ export default class Model extends PureComponent {
|
||||
}
|
||||
|
||||
render () {
|
||||
let { getComponent, specSelectors, schema, required, name, isRef } = this.props
|
||||
let { getComponent, getConfigs, specSelectors, schema, required, name, isRef } = this.props
|
||||
const ObjectModel = getComponent("ObjectModel")
|
||||
const ArrayModel = getComponent("ArrayModel")
|
||||
const PrimitiveModel = getComponent("PrimitiveModel")
|
||||
@@ -53,6 +55,7 @@ export default class Model extends PureComponent {
|
||||
case "object":
|
||||
return <ObjectModel
|
||||
className="object" { ...this.props }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
name={ name }
|
||||
deprecated={deprecated}
|
||||
@@ -60,6 +63,7 @@ export default class Model extends PureComponent {
|
||||
case "array":
|
||||
return <ArrayModel
|
||||
className="array" { ...this.props }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
name={ name }
|
||||
deprecated={deprecated}
|
||||
@@ -72,6 +76,7 @@ export default class Model extends PureComponent {
|
||||
return <PrimitiveModel
|
||||
{ ...this.props }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
name={ name }
|
||||
deprecated={deprecated}
|
||||
|
||||
@@ -36,6 +36,7 @@ export default class Models extends Component {
|
||||
expandDepth={ defaultModelExpandDepth }
|
||||
schema={ model }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
specSelectors={ specSelectors }/>
|
||||
</div>
|
||||
}).toArray()
|
||||
|
||||
@@ -9,6 +9,7 @@ export default class ObjectModel extends Component {
|
||||
static propTypes = {
|
||||
schema: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
name: PropTypes.string,
|
||||
isRef: PropTypes.bool,
|
||||
@@ -17,7 +18,7 @@ export default class ObjectModel extends Component {
|
||||
}
|
||||
|
||||
render(){
|
||||
let { schema, name, isRef, getComponent, depth, expandDepth, ...otherProps } = this.props
|
||||
let { schema, name, isRef, getComponent, getConfigs, depth, expandDepth, ...otherProps } = this.props
|
||||
let { specSelectors } = otherProps
|
||||
let { isOAS3 } = specSelectors
|
||||
|
||||
@@ -25,6 +26,8 @@ export default class ObjectModel extends Component {
|
||||
return null
|
||||
}
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
|
||||
let description = schema.get("description")
|
||||
let properties = schema.get("properties")
|
||||
let additionalProperties = schema.get("additionalProperties")
|
||||
@@ -91,12 +94,37 @@ export default class ObjectModel extends Component {
|
||||
<Model key={ `object-${name}-${key}_${value}` } { ...otherProps }
|
||||
required={ isRequired }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ value }
|
||||
depth={ depth + 1 } />
|
||||
</td>
|
||||
</tr>)
|
||||
}).toArray()
|
||||
}
|
||||
{
|
||||
// empty row befor extensions...
|
||||
!showExtensions ? null : <tr> </tr>
|
||||
}
|
||||
{
|
||||
!showExtensions ? null :
|
||||
schema.entrySeq().map(
|
||||
([key, value]) => {
|
||||
if(key.slice(0,2) !== "x-") {
|
||||
return
|
||||
}
|
||||
|
||||
const normalizedValue = !value ? null : value.toJS ? value.toJS() : value
|
||||
|
||||
return (<tr key={key} style={{ color: "#777" }}>
|
||||
<td>
|
||||
{ key }
|
||||
</td>
|
||||
<td style={{ verticalAlign: "top" }}>
|
||||
{ JSON.stringify(normalizedValue) }
|
||||
</td>
|
||||
</tr>)
|
||||
}).toArray()
|
||||
}
|
||||
{
|
||||
!additionalProperties || !additionalProperties.size ? null
|
||||
: <tr>
|
||||
@@ -104,6 +132,7 @@ export default class ObjectModel extends Component {
|
||||
<td>
|
||||
<Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ additionalProperties }
|
||||
depth={ depth + 1 } />
|
||||
</td>
|
||||
@@ -117,6 +146,7 @@ export default class ObjectModel extends Component {
|
||||
{anyOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
})}
|
||||
@@ -131,6 +161,7 @@ export default class ObjectModel extends Component {
|
||||
{oneOf.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
})}
|
||||
@@ -142,12 +173,14 @@ export default class ObjectModel extends Component {
|
||||
: <tr>
|
||||
<td>{ "not ->" }</td>
|
||||
<td>
|
||||
{not.map((schema, k) => {
|
||||
return <div key={k}><Model { ...otherProps } required={ false }
|
||||
getComponent={ getComponent }
|
||||
schema={ schema }
|
||||
depth={ depth + 1 } /></div>
|
||||
})}
|
||||
<div>
|
||||
<Model { ...otherProps }
|
||||
required={ false }
|
||||
getComponent={ getComponent }
|
||||
getConfigs={ getConfigs }
|
||||
schema={ not }
|
||||
depth={ depth + 1 } />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export const OperationExtRow = ({ xKey, xVal }) => {
|
||||
const xNormalizedValue = !xVal ? null : xVal.toJS ? xVal.toJS() : xVal
|
||||
|
||||
return (<tr>
|
||||
<td>{ xKey }</td>
|
||||
<td>{ JSON.stringify(xNormalizedValue) }</td>
|
||||
</tr>)
|
||||
}
|
||||
OperationExtRow.propTypes = {
|
||||
xKey: PropTypes.string,
|
||||
xVal: PropTypes.any
|
||||
}
|
||||
|
||||
export default OperationExtRow
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export const OperationExt = ({ extensions, getComponent }) => {
|
||||
let OperationExtRow = getComponent("OperationExtRow")
|
||||
return (
|
||||
<div className="opblock-section">
|
||||
<div className="opblock-section-header">
|
||||
<h4>Extensions</h4>
|
||||
</div>
|
||||
<div className="table-container">
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="col col_header">Field</td>
|
||||
<td className="col col_header">Value</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
extensions.entrySeq().map(([k, v]) => <OperationExtRow key={`${k}-${v}`} xKey={k} xVal={v} />)
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
OperationExt.propTypes = {
|
||||
extensions: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
export default OperationExt
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { PureComponent } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { getList } from "core/utils"
|
||||
import { sanitizeUrl } from "core/utils"
|
||||
import { getExtensions, sanitizeUrl } from "core/utils"
|
||||
import { Iterable } from "immutable"
|
||||
|
||||
export default class Operation extends PureComponent {
|
||||
@@ -22,6 +22,7 @@ export default class Operation extends PureComponent {
|
||||
specActions: PropTypes.object.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
oas3Actions: PropTypes.object.isRequired,
|
||||
oas3Selectors: PropTypes.object.isRequired,
|
||||
layoutActions: PropTypes.object.isRequired,
|
||||
layoutSelectors: PropTypes.object.isRequired,
|
||||
fn: PropTypes.object.isRequired
|
||||
@@ -48,7 +49,8 @@ export default class Operation extends PureComponent {
|
||||
specSelectors,
|
||||
authActions,
|
||||
authSelectors,
|
||||
oas3Actions
|
||||
oas3Actions,
|
||||
oas3Selectors
|
||||
} = this.props
|
||||
let operationProps = this.props.operation
|
||||
|
||||
@@ -85,6 +87,7 @@ export default class Operation extends PureComponent {
|
||||
let parameters = getList(operation, ["parameters"])
|
||||
let operationScheme = specSelectors.operationScheme(path, method)
|
||||
let isShownKey = ["operations", tag, operationId]
|
||||
let extensions = getExtensions(operation)
|
||||
|
||||
const Responses = getComponent("responses")
|
||||
const Parameters = getComponent( "parameters" )
|
||||
@@ -95,6 +98,10 @@ export default class Operation extends PureComponent {
|
||||
const Collapse = getComponent( "Collapse" )
|
||||
const Markdown = getComponent( "Markdown" )
|
||||
const Schemes = getComponent( "schemes" )
|
||||
const OperationServers = getComponent( "OperationServers" )
|
||||
const OperationExt = getComponent( "OperationExt" )
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
|
||||
// Merge in Live Response
|
||||
if(responses && response && response.size > 0) {
|
||||
@@ -149,17 +156,18 @@ export default class Operation extends PureComponent {
|
||||
</div>
|
||||
}
|
||||
{
|
||||
externalDocs && externalDocs.get("url") ?
|
||||
externalDocs && externalDocs.url ?
|
||||
<div className="opblock-external-docs-wrapper">
|
||||
<h4 className="opblock-title_normal">Find more details</h4>
|
||||
<div className="opblock-external-docs">
|
||||
<span className="opblock-external-docs__description">
|
||||
<Markdown source={ externalDocs.get("description") } />
|
||||
<Markdown source={ externalDocs.description } />
|
||||
</span>
|
||||
<a className="opblock-external-docs__link" href={ sanitizeUrl(externalDocs.get("url")) }>{ externalDocs.get("url") }</a>
|
||||
<a target="_blank" className="opblock-external-docs__link" href={ sanitizeUrl(externalDocs.url) }>{ externalDocs.url }</a>
|
||||
</div>
|
||||
</div> : null
|
||||
}
|
||||
|
||||
<Parameters
|
||||
parameters={parameters}
|
||||
operation={operation}
|
||||
@@ -177,6 +185,21 @@ export default class Operation extends PureComponent {
|
||||
getConfigs={ getConfigs }
|
||||
/>
|
||||
|
||||
{ !tryItOutEnabled ? null :
|
||||
<OperationServers
|
||||
getComponent={getComponent}
|
||||
path={path}
|
||||
method={method}
|
||||
operationServers={operation.get("servers")}
|
||||
pathServers={specSelectors.paths().getIn([path, "servers"])}
|
||||
getSelectedServer={oas3Selectors.selectedServer}
|
||||
setSelectedServer={oas3Actions.setSelectedServer}
|
||||
setServerVariableValue={oas3Actions.setServerVariableValue}
|
||||
getServerVariable={oas3Selectors.serverVariableValue}
|
||||
getEffectiveServerValue={oas3Selectors.serverEffectiveValue}
|
||||
/>
|
||||
}
|
||||
|
||||
{!tryItOutEnabled || !allowTryItOut ? null : schemes && schemes.size ? <div className="opblock-schemes">
|
||||
<Schemes schemes={ schemes }
|
||||
path={ path }
|
||||
@@ -225,6 +248,10 @@ export default class Operation extends PureComponent {
|
||||
displayRequestDuration={ displayRequestDuration }
|
||||
fn={fn} />
|
||||
}
|
||||
|
||||
{ !showExtensions || !extensions.size ? null :
|
||||
<OperationExt extensions={ extensions } getComponent={ getComponent } />
|
||||
}
|
||||
</div>
|
||||
</Collapse>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
|
||||
export const ParameterExt = ({ xKey, xVal }) => {
|
||||
return <div className="parameter__extension">{ xKey }: { String(xVal) }</div>
|
||||
}
|
||||
ParameterExt.propTypes = {
|
||||
xKey: PropTypes.string,
|
||||
xVal: PropTypes.any
|
||||
}
|
||||
|
||||
export default ParameterExt
|
||||
@@ -2,6 +2,7 @@ import React, { Component } from "react"
|
||||
import { Map } from "immutable"
|
||||
import PropTypes from "prop-types"
|
||||
import win from "core/window"
|
||||
import { getExtensions } from "core/utils"
|
||||
|
||||
export default class ParameterRow extends Component {
|
||||
static propTypes = {
|
||||
@@ -72,6 +73,8 @@ export default class ParameterRow extends Component {
|
||||
|
||||
let { isOAS3 } = specSelectors
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
|
||||
// const onChangeWrapper = (value) => onChange(param, value)
|
||||
const JsonSchemaForm = getComponent("JsonSchemaForm")
|
||||
const ParamBody = getComponent("ParamBody")
|
||||
@@ -91,6 +94,7 @@ export default class ParameterRow extends Component {
|
||||
|
||||
const ModelExample = getComponent("modelExample")
|
||||
const Markdown = getComponent("Markdown")
|
||||
const ParameterExt = getComponent("ParameterExt")
|
||||
|
||||
let schema = param.get("schema")
|
||||
let type = isOAS3 && isOAS3() ? param.getIn(["schema", "type"]) : param.get("type")
|
||||
@@ -100,6 +104,7 @@ export default class ParameterRow extends Component {
|
||||
let itemType = param.getIn(isOAS3 && isOAS3() ? ["schema", "items", "type"] : ["items", "type"])
|
||||
let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in"))
|
||||
let value = parameter ? parameter.get("value") : ""
|
||||
let extensions = getExtensions(param)
|
||||
|
||||
return (
|
||||
<tr>
|
||||
@@ -113,6 +118,7 @@ export default class ParameterRow extends Component {
|
||||
{ isOAS3 && isOAS3() && param.get("deprecated") ? "deprecated": null }
|
||||
</div>
|
||||
<div className="parameter__in">({ param.get("in") })</div>
|
||||
{ !showExtensions || !extensions.size ? null : extensions.map((v, key) => <ParameterExt key={`${key}-${v}`} xKey={key} xVal={v} /> )}
|
||||
</td>
|
||||
|
||||
<td className="col parameters-col_description">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { getExtensions } from "core/utils"
|
||||
|
||||
const propStyle = { color: "#999", fontStyle: "italic" }
|
||||
|
||||
@@ -7,12 +8,15 @@ export default class Primitive extends Component {
|
||||
static propTypes = {
|
||||
schema: PropTypes.object.isRequired,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
name: PropTypes.string,
|
||||
depth: PropTypes.number
|
||||
}
|
||||
|
||||
render(){
|
||||
let { schema, getComponent, name, depth } = this.props
|
||||
let { schema, getComponent, getConfigs, name, depth } = this.props
|
||||
|
||||
const { showExtensions } = getConfigs()
|
||||
|
||||
if(!schema || !schema.get) {
|
||||
// don't render if schema isn't correctly formed
|
||||
@@ -25,7 +29,10 @@ export default class Primitive extends Component {
|
||||
let enumArray = schema.get("enum")
|
||||
let title = schema.get("title") || name
|
||||
let description = schema.get("description")
|
||||
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
||||
let extensions = getExtensions(schema)
|
||||
let properties = schema
|
||||
.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
||||
.filterNot( (v, key) => extensions.has(key) )
|
||||
const Markdown = getComponent("Markdown")
|
||||
const EnumModel = getComponent("EnumModel")
|
||||
const Property = getComponent("Property")
|
||||
@@ -38,6 +45,9 @@ export default class Primitive extends Component {
|
||||
{
|
||||
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <Property key={`${key}-${v}`} propKey={ key } propVal={ v } propStyle={ propStyle } />) : null
|
||||
}
|
||||
{
|
||||
showExtensions && extensions.size ? extensions.entrySeq().map( ( [ key, v ] ) => <Property key={`${key}-${v}`} propKey={ key } propVal={ v } propStyle={ propStyle } />) : null
|
||||
}
|
||||
{
|
||||
!description ? null :
|
||||
<Markdown source={ description } />
|
||||
|
||||
@@ -57,9 +57,6 @@ export default class ResponseBody extends React.Component {
|
||||
(headers["Content-Description"] && (/File Transfer/i).test(headers["Content-Description"])) ||
|
||||
(headers["content-description"] && (/File Transfer/i).test(headers["content-description"]))) {
|
||||
|
||||
let contentLength = headers["content-length"] || headers["Content-Length"]
|
||||
if ( !(+contentLength) ) return null
|
||||
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
|
||||
|
||||
if (!isSafari && "Blob" in window) {
|
||||
|
||||
@@ -153,7 +153,10 @@ export default class Response extends React.Component {
|
||||
) : null}
|
||||
|
||||
{ headers ? (
|
||||
<Headers headers={ headers }/>
|
||||
<Headers
|
||||
headers={ headers }
|
||||
getComponent={ getComponent }
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ export default class OperationContainer extends PureComponent {
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
authActions: PropTypes.object,
|
||||
oas3Actions: PropTypes.object,
|
||||
oas3Selectors: PropTypes.object,
|
||||
authSelectors: PropTypes.object,
|
||||
specActions: PropTypes.object.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
@@ -149,6 +150,7 @@ export default class OperationContainer extends PureComponent {
|
||||
authActions,
|
||||
authSelectors,
|
||||
oas3Actions,
|
||||
oas3Selectors,
|
||||
fn
|
||||
} = this.props
|
||||
|
||||
@@ -189,6 +191,7 @@ export default class OperationContainer extends PureComponent {
|
||||
specActions={ specActions }
|
||||
specSelectors={ specSelectors }
|
||||
oas3Actions={oas3Actions}
|
||||
oas3Selectors={oas3Selectors}
|
||||
layoutActions={ layoutActions }
|
||||
layoutSelectors={ layoutSelectors }
|
||||
authActions={ authActions }
|
||||
|
||||
@@ -46,6 +46,7 @@ module.exports = function SwaggerUI(opts) {
|
||||
showMutatedRequest: true,
|
||||
defaultModelRendering: "example",
|
||||
defaultModelExpandDepth: 1,
|
||||
showExtensions: false,
|
||||
|
||||
// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
|
||||
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.
|
||||
|
||||
@@ -36,7 +36,7 @@ export class JsonSchemaForm extends Component {
|
||||
|
||||
let { type, format="" } = schema
|
||||
|
||||
let Comp = getComponent(`JsonSchema_${type}_${format}`) || getComponent(`JsonSchema_${type}`) || getComponent("JsonSchema_string")
|
||||
let Comp = (format ? getComponent(`JsonSchema_${type}_${format}`) : getComponent(`JsonSchema_${type}`)) || getComponent("JsonSchema_string")
|
||||
return <Comp { ...this.props } fn={fn} getComponent={getComponent} value={value} onChange={onChange} schema={schema}/>
|
||||
}
|
||||
|
||||
@@ -68,19 +68,19 @@ export class JsonSchema_string extends Component {
|
||||
const isDisabled = schema["in"] === "formData" && !("FormData" in window)
|
||||
const Input = getComponent("Input")
|
||||
if (schema["type"] === "file") {
|
||||
return (<Input type="file"
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
return (<Input type="file"
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
title={ errors.length ? errors : ""}
|
||||
onChange={ this.onChange }
|
||||
onChange={ this.onChange }
|
||||
disabled={isDisabled}/>)
|
||||
}
|
||||
else {
|
||||
return (<Input type={ schema.format === "password" ? "password" : "text" }
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
return (<Input type={ schema.format === "password" ? "password" : "text" }
|
||||
className={ errors.length ? "invalid" : ""}
|
||||
title={ errors.length ? errors : ""}
|
||||
value={value}
|
||||
placeholder={description}
|
||||
onChange={ this.onChange }
|
||||
value={value}
|
||||
placeholder={description}
|
||||
onChange={ this.onChange }
|
||||
disabled={isDisabled}/>)
|
||||
}
|
||||
}
|
||||
@@ -189,8 +189,8 @@ export class JsonSchema_boolean extends Component {
|
||||
return (<Select className={ errors.length ? "invalid" : ""}
|
||||
title={ errors.length ? errors : ""}
|
||||
value={ String(value) }
|
||||
allowedValues={ fromJS(["true", "false"]) }
|
||||
allowEmptyValue={ true }
|
||||
allowedValues={ fromJS(schema.enum || ["true", "false"]) }
|
||||
allowEmptyValue={ !this.props.required }
|
||||
onChange={ this.onEnumChange }/>)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ export const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl
|
||||
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers})
|
||||
}
|
||||
|
||||
export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, authSelectors } ) => {
|
||||
export const authorizeRequest = ( data ) => ( { fn, getConfigs, authActions, errActions, authSelectors } ) => {
|
||||
let { body, query={}, headers={}, name, url, auth } = data
|
||||
let { additionalQueryStringParams } = authSelectors.getConfigs() || {}
|
||||
let fetchUrl = url
|
||||
@@ -158,7 +158,9 @@ export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, aut
|
||||
method: "post",
|
||||
headers: _headers,
|
||||
query: query,
|
||||
body: body
|
||||
body: body,
|
||||
requestInterceptor: getConfigs().requestInterceptor,
|
||||
responseInterceptor: getConfigs().responseInterceptor
|
||||
})
|
||||
.then(function (response) {
|
||||
let token = JSON.parse(response.data)
|
||||
|
||||
@@ -7,10 +7,10 @@ export const UPDATE_REQUEST_CONTENT_TYPE = "oas3_set_request_content_type"
|
||||
export const UPDATE_RESPONSE_CONTENT_TYPE = "oas3_set_response_content_type"
|
||||
export const UPDATE_SERVER_VARIABLE_VALUE = "oas3_set_server_variable_value"
|
||||
|
||||
export function setSelectedServer (selectedServerUrl) {
|
||||
export function setSelectedServer (selectedServerUrl, namespace) {
|
||||
return {
|
||||
type: UPDATE_SELECTED_SERVER,
|
||||
payload: selectedServerUrl
|
||||
payload: {selectedServerUrl, namespace}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ export function setResponseContentType ({ value, path, method }) {
|
||||
}
|
||||
}
|
||||
|
||||
export function setServerVariableValue ({ server, key, val }) {
|
||||
export function setServerVariableValue ({ server, namespace, key, val }) {
|
||||
return {
|
||||
type: UPDATE_SERVER_VARIABLE_VALUE,
|
||||
payload: { server, key, val }
|
||||
payload: { server, namespace, key, val }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import OperationLink from "./operation-link.jsx"
|
||||
import Servers from "./servers"
|
||||
import RequestBodyEditor from "./request-body-editor"
|
||||
import HttpAuth from "./http-auth"
|
||||
import OperationServers from "./operation-servers"
|
||||
|
||||
export default {
|
||||
Callbacks,
|
||||
@@ -11,5 +12,6 @@ export default {
|
||||
RequestBody,
|
||||
Servers,
|
||||
RequestBodyEditor,
|
||||
OperationServers,
|
||||
operationLink: OperationLink
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import ImPropTypes from "react-immutable-proptypes"
|
||||
|
||||
export default class OperationServers extends React.Component {
|
||||
static propTypes = {
|
||||
// for self
|
||||
path: PropTypes.string.isRequired,
|
||||
method: PropTypes.string.isRequired,
|
||||
operationServers: ImPropTypes.list,
|
||||
pathServers: ImPropTypes.list,
|
||||
setSelectedServer: PropTypes.func.isRequired,
|
||||
setServerVariableValue: PropTypes.func.isRequired,
|
||||
getSelectedServer: PropTypes.func.isRequired,
|
||||
getServerVariable: PropTypes.func.isRequired,
|
||||
getEffectiveServerValue: PropTypes.func.isRequired,
|
||||
|
||||
// utils
|
||||
getComponent: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
setSelectedServer = (server) => {
|
||||
const { path, method } = this.props
|
||||
// FIXME: we should be keeping up with this in props/state upstream of us
|
||||
// instead of cheating™ with `forceUpdate`
|
||||
this.forceUpdate()
|
||||
return this.props.setSelectedServer(server, `${path}:${method}`)
|
||||
}
|
||||
|
||||
setServerVariableValue = (obj) => {
|
||||
const { path, method } = this.props
|
||||
// FIXME: we should be keeping up with this in props/state upstream of us
|
||||
// instead of cheating™ with `forceUpdate`
|
||||
this.forceUpdate()
|
||||
return this.props.setServerVariableValue({
|
||||
...obj,
|
||||
namespace: `${path}:${method}`
|
||||
})
|
||||
}
|
||||
|
||||
getSelectedServer = () => {
|
||||
const { path, method } = this.props
|
||||
return this.props.getSelectedServer(`${path}:${method}`)
|
||||
}
|
||||
|
||||
getServerVariable = (server, key) => {
|
||||
const { path, method } = this.props
|
||||
return this.props.getServerVariable({
|
||||
namespace: `${path}:${method}`,
|
||||
server
|
||||
}, key)
|
||||
}
|
||||
|
||||
getEffectiveServerValue = (server) => {
|
||||
const { path, method } = this.props
|
||||
return this.props.getEffectiveServerValue({
|
||||
server,
|
||||
namespace: `${path}:${method}`
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
// for self
|
||||
operationServers,
|
||||
pathServers,
|
||||
|
||||
// util
|
||||
getComponent
|
||||
} = this.props
|
||||
|
||||
if(!operationServers && !pathServers) {
|
||||
return null
|
||||
}
|
||||
|
||||
const Servers = getComponent("Servers")
|
||||
|
||||
const serversToDisplay = operationServers || pathServers
|
||||
const displaying = operationServers ? "operation" : "path"
|
||||
|
||||
return <div className="opblock-section operation-servers">
|
||||
<div className="opblock-section-header">
|
||||
<div className="tab-header">
|
||||
<h4 className="opblock-title">Servers</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div className="opblock-description-wrapper">
|
||||
<h4 className="message">
|
||||
These {displaying}-level options override the global server options.
|
||||
</h4>
|
||||
<Servers
|
||||
servers={serversToDisplay}
|
||||
currentServer={this.getSelectedServer()}
|
||||
setSelectedServer={this.setSelectedServer}
|
||||
setServerVariableValue={this.setServerVariableValue}
|
||||
getServerVariable={this.getServerVariable}
|
||||
getEffectiveServerValue={this.getEffectiveServerValue}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,11 @@ export default class Servers extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { servers } = this.props
|
||||
let { servers, currentServer } = this.props
|
||||
|
||||
if(currentServer) {
|
||||
return
|
||||
}
|
||||
|
||||
//fire 'change' event to set default 'value' of select
|
||||
this.setServer(servers.first().get("url"))
|
||||
@@ -93,9 +97,8 @@ export default class Servers extends React.Component {
|
||||
let shouldShowVariableUI = currentServerVariableDefs.size !== 0
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="servers">
|
||||
<label htmlFor="servers">
|
||||
<span className="servers-title">Servers</span>
|
||||
<select onChange={ this.onServerChange }>
|
||||
{ servers.valueSeq().map(
|
||||
( server ) =>
|
||||
@@ -109,13 +112,14 @@ export default class Servers extends React.Component {
|
||||
</label>
|
||||
{ shouldShowVariableUI ?
|
||||
<div>
|
||||
<h4>Server variables</h4>
|
||||
|
||||
<div className={"computed-url"}>
|
||||
Computed URL:
|
||||
<code>
|
||||
{getEffectiveServerValue(currentServer)}
|
||||
</code>
|
||||
</div>
|
||||
<h4>Server variables</h4>
|
||||
<table>
|
||||
<tbody>
|
||||
{
|
||||
|
||||
@@ -7,8 +7,9 @@ import {
|
||||
} from "./actions"
|
||||
|
||||
export default {
|
||||
[UPDATE_SELECTED_SERVER]: (state, { payload: selectedServerUrl } ) =>{
|
||||
return state.setIn( [ "selectedServer" ], selectedServerUrl)
|
||||
[UPDATE_SELECTED_SERVER]: (state, { payload: { selectedServerUrl, namespace } } ) =>{
|
||||
const path = namespace ? [ namespace, "selectedServer"] : [ "selectedServer"]
|
||||
return state.setIn( path, selectedServerUrl)
|
||||
},
|
||||
[UPDATE_REQUEST_BODY_VALUE]: (state, { payload: { value, pathMethod } } ) =>{
|
||||
let [path, method] = pathMethod
|
||||
@@ -21,7 +22,8 @@ export default {
|
||||
[UPDATE_RESPONSE_CONTENT_TYPE]: (state, { payload: { value, path, method } } ) =>{
|
||||
return state.setIn( [ "requestData", path, method, "responseContentType" ], value)
|
||||
},
|
||||
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, key, val } } ) =>{
|
||||
return state.setIn( [ "serverVariableValues", server, key ], val)
|
||||
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, namespace, key, val } } ) =>{
|
||||
const path = namespace ? [ namespace, "serverVariableValues", server, key ] : [ "serverVariableValues", server, key ]
|
||||
return state.setIn(path, val)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ function onlyOAS3(selector) {
|
||||
}
|
||||
}
|
||||
|
||||
export const selectedServer = onlyOAS3(state => {
|
||||
return state.getIn(["selectedServer"]) || ""
|
||||
export const selectedServer = onlyOAS3((state, namespace) => {
|
||||
const path = namespace ? [namespace, "selectedServer"] : ["selectedServer"]
|
||||
return state.getIn(path) || ""
|
||||
}
|
||||
)
|
||||
|
||||
@@ -35,19 +36,68 @@ export const responseContentType = onlyOAS3((state, path, method) => {
|
||||
}
|
||||
)
|
||||
|
||||
export const serverVariableValue = onlyOAS3((state, server, key) => {
|
||||
return state.getIn(["serverVariableValues", server, key]) || null
|
||||
export const serverVariableValue = onlyOAS3((state, locationData, key) => {
|
||||
let path
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if(namespace) {
|
||||
path = [namespace, "serverVariableValues", server, key]
|
||||
} else {
|
||||
path = ["serverVariableValues", server, key]
|
||||
}
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server, key]
|
||||
}
|
||||
|
||||
return state.getIn(path) || null
|
||||
}
|
||||
)
|
||||
|
||||
export const serverVariables = onlyOAS3((state, server) => {
|
||||
return state.getIn(["serverVariableValues", server]) || OrderedMap()
|
||||
export const serverVariables = onlyOAS3((state, locationData) => {
|
||||
let path
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
if(namespace) {
|
||||
path = [namespace, "serverVariableValues", server]
|
||||
} else {
|
||||
path = ["serverVariableValues", server]
|
||||
}
|
||||
} else {
|
||||
const server = locationData
|
||||
path = ["serverVariableValues", server]
|
||||
}
|
||||
|
||||
return state.getIn(path) || OrderedMap()
|
||||
}
|
||||
)
|
||||
|
||||
export const serverEffectiveValue = onlyOAS3((state, server) => {
|
||||
let varValues = state.getIn(["serverVariableValues", server]) || OrderedMap()
|
||||
let str = server
|
||||
export const serverEffectiveValue = onlyOAS3((state, locationData) => {
|
||||
var varValues, serverValue
|
||||
|
||||
// locationData may take one of two forms, for backwards compatibility
|
||||
// Object: ({server, namespace?}) or String:(server)
|
||||
if(typeof locationData !== "string") {
|
||||
const { server, namespace } = locationData
|
||||
serverValue = server
|
||||
if(namespace) {
|
||||
varValues = state.getIn([namespace, "serverVariableValues", serverValue])
|
||||
} else {
|
||||
varValues = state.getIn(["serverVariableValues", serverValue])
|
||||
}
|
||||
} else {
|
||||
serverValue = locationData
|
||||
varValues = state.getIn(["serverVariableValues", serverValue])
|
||||
}
|
||||
|
||||
varValues = varValues || OrderedMap()
|
||||
let str = serverValue
|
||||
|
||||
varValues.map((val, key) => {
|
||||
str = str.replace(new RegExp(`{${key}}`, "g"), val)
|
||||
|
||||
@@ -8,12 +8,13 @@ class ModelComponent extends Component {
|
||||
schema: PropTypes.object.isRequired,
|
||||
name: PropTypes.string,
|
||||
getComponent: PropTypes.func.isRequired,
|
||||
getConfigs: PropTypes.func.isRequired,
|
||||
specSelectors: PropTypes.object.isRequired,
|
||||
expandDepth: PropTypes.number
|
||||
}
|
||||
|
||||
render(){
|
||||
let { schema } = this.props
|
||||
let { getConfigs, schema } = this.props
|
||||
let classes = ["model-box"]
|
||||
let isDeprecated = schema.get("deprecated") === true
|
||||
let message = null
|
||||
@@ -26,6 +27,7 @@ class ModelComponent extends Component {
|
||||
return <div className={classes.join(" ")}>
|
||||
{message}
|
||||
<Model { ...this.props }
|
||||
getConfigs={ getConfigs }
|
||||
depth={ 1 }
|
||||
expandDepth={ this.props.expandDepth || 0 }
|
||||
/>
|
||||
|
||||
@@ -228,9 +228,18 @@ export const executeRequest = (req) =>
|
||||
}
|
||||
|
||||
if(specSelectors.isOAS3()) {
|
||||
// OAS3 request feature support
|
||||
req.server = oas3Selectors.selectedServer()
|
||||
req.serverVariables = oas3Selectors.serverVariables(req.server).toJS()
|
||||
const namespace = `${pathName}:${method}`
|
||||
|
||||
req.server = oas3Selectors.selectedServer(namespace) || oas3Selectors.selectedServer()
|
||||
|
||||
const namespaceVariables = oas3Selectors.serverVariables({
|
||||
server: req.server,
|
||||
namespace
|
||||
}).toJS()
|
||||
const globalVariables = oas3Selectors.serverVariables({ server: req.server }).toJS()
|
||||
|
||||
req.serverVariables = Object.keys(namespaceVariables).length ? namespaceVariables : globalVariables
|
||||
|
||||
req.requestContentType = oas3Selectors.requestContentType(pathName, method)
|
||||
req.responseContentType = oas3Selectors.responseContentType(pathName, method) || "*/*"
|
||||
const requestBody = oas3Selectors.requestBodyValue(pathName, method)
|
||||
|
||||
@@ -30,11 +30,14 @@ import LiveResponse from "core/components/live-response"
|
||||
import OnlineValidatorBadge from "core/components/online-validator-badge"
|
||||
import Operations from "core/components/operations"
|
||||
import Operation from "core/components/operation"
|
||||
import OperationExt from "core/components/operation-extensions"
|
||||
import OperationExtRow from "core/components/operation-extension-row"
|
||||
import HighlightCode from "core/components/highlight-code"
|
||||
import Responses from "core/components/responses"
|
||||
import Response from "core/components/response"
|
||||
import ResponseBody from "core/components/response-body"
|
||||
import Parameters from "core/components/parameters"
|
||||
import ParameterExt from "core/components/parameter-extension"
|
||||
import ParameterRow from "core/components/parameter-row"
|
||||
import Execute from "core/components/execute"
|
||||
import Headers from "core/components/headers"
|
||||
@@ -115,6 +118,9 @@ export default function() {
|
||||
Markdown,
|
||||
BaseLayout,
|
||||
VersionStamp,
|
||||
OperationExt,
|
||||
OperationExtRow,
|
||||
ParameterExt,
|
||||
OperationContainer
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -473,6 +473,9 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||
let required = param.get("required")
|
||||
|
||||
let paramDetails = isOAS3 ? param.get("schema") : param
|
||||
|
||||
if(!paramDetails) return errors
|
||||
|
||||
let maximum = paramDetails.get("maximum")
|
||||
let minimum = paramDetails.get("minimum")
|
||||
let type = paramDetails.get("type")
|
||||
@@ -480,7 +483,7 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||
let maxLength = paramDetails.get("maxLength")
|
||||
let minLength = paramDetails.get("minLength")
|
||||
let pattern = paramDetails.get("pattern")
|
||||
|
||||
|
||||
|
||||
/*
|
||||
If the parameter is required OR the parameter has a value (meaning optional, but filled in)
|
||||
@@ -506,7 +509,7 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||
let err = validatePattern(value, pattern)
|
||||
if (err) errors.push(err)
|
||||
}
|
||||
|
||||
|
||||
if (maxLength || maxLength === 0) {
|
||||
let err = validateMaxLength(value, maxLength)
|
||||
if (err) errors.push(err)
|
||||
@@ -692,3 +695,5 @@ export function getAcceptControllingResponse(responses) {
|
||||
|
||||
export const createDeepLinkPath = (str) => typeof str == "string" || str instanceof String ? str.trim().replace(/\s/g, "_") : ""
|
||||
export const escapeDeepLinkPath = (str) => cssEscape( createDeepLinkPath(str) )
|
||||
|
||||
export const getExtensions = (defObj) => defObj.filter((v, k) => /^x-/.test(k))
|
||||
|
||||
@@ -3,3 +3,8 @@
|
||||
if(!window.Promise) {
|
||||
require("core-js/fn/promise")
|
||||
}
|
||||
|
||||
// Required by IE 11
|
||||
if(!String.prototype.startsWith) {
|
||||
require("core-js/es6/string")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
padding: 10px 0;
|
||||
|
||||
justify-content: center;
|
||||
|
||||
.btn-done {
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-wrapper
|
||||
|
||||
@@ -650,78 +650,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.server-container
|
||||
{
|
||||
margin: 0 0 20px 0;
|
||||
padding: 30px 0;
|
||||
|
||||
background: $server-container-background-color;
|
||||
box-shadow: 0 1px 2px 0 rgba($server-container-box-shadow-color,.15);
|
||||
|
||||
.computed-url {
|
||||
margin: 2em 0;
|
||||
|
||||
code {
|
||||
color: $server-container-computed-url-code-font-color;
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
font-size: 16px;
|
||||
margin: 0 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.servers
|
||||
{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.servers-title {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
> label
|
||||
{
|
||||
font-size: 12px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
margin: -20px 15px 0 0;
|
||||
|
||||
@include text_headline();
|
||||
|
||||
select
|
||||
{
|
||||
min-width: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
tr {
|
||||
width: 30em;
|
||||
}
|
||||
td {
|
||||
display: inline-block;
|
||||
max-width: 15em;
|
||||
vertical-align: middle;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
&:first-of-type {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.loading-container
|
||||
{
|
||||
padding: 40px 0 60px;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
.servers
|
||||
{
|
||||
> label
|
||||
{
|
||||
font-size: 12px;
|
||||
|
||||
margin: -20px 15px 0 0;
|
||||
|
||||
@include text_headline();
|
||||
|
||||
select
|
||||
{
|
||||
min-width: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
h4.message {
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
table {
|
||||
tr {
|
||||
width: 30em;
|
||||
}
|
||||
td {
|
||||
display: inline-block;
|
||||
max-width: 15em;
|
||||
vertical-align: middle;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
&:first-of-type {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.computed-url {
|
||||
margin: 2em 0;
|
||||
|
||||
code {
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
font-size: 16px;
|
||||
margin: 0 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.global-server-container
|
||||
{
|
||||
margin: 0 0 20px 0;
|
||||
padding: 30px 0;
|
||||
|
||||
background: $server-container-background-color;
|
||||
box-shadow: 0 1px 2px 0 rgba($server-container-box-shadow-color,.15);
|
||||
|
||||
.servers-title {
|
||||
line-height: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.operation-servers {
|
||||
h4.message {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ table
|
||||
|
||||
&:first-of-type
|
||||
{
|
||||
width: 124px;
|
||||
width: 174px;
|
||||
padding: 0 0 0 2em;
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,8 @@ table
|
||||
}
|
||||
}
|
||||
|
||||
.parameter__in
|
||||
.parameter__in,
|
||||
.parameter__extension
|
||||
{
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
@import 'form';
|
||||
@import 'modal';
|
||||
@import 'models';
|
||||
@import 'servers';
|
||||
@import 'table';
|
||||
@import 'topbar';
|
||||
@import 'information';
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/* eslint-env mocha */
|
||||
import React from "react"
|
||||
import expect, { createSpy } from "expect"
|
||||
import { Select, Input } from "components/layout-utils"
|
||||
import { render } from "enzyme"
|
||||
import * as JsonSchemaComponents from "core/json-schema-components"
|
||||
import { JsonSchemaForm } from "core/json-schema-components"
|
||||
|
||||
const components = {...JsonSchemaComponents, Select, Input}
|
||||
|
||||
const getComponentStub = (name) => {
|
||||
if(components[name]) return components[name]
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
describe("<JsonSchemaForm/>", function(){
|
||||
describe("strings", function() {
|
||||
it("should render the correct options for a string enum parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "string",
|
||||
enum: ["one", "two"]
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(3)
|
||||
expect(wrapper.find("select option").eq(0).text()).toEqual("--")
|
||||
expect(wrapper.find("select option").eq(1).text()).toEqual("one")
|
||||
expect(wrapper.find("select option").eq(2).text()).toEqual("two")
|
||||
})
|
||||
|
||||
it("should render the correct options for a required string enum parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
required: true,
|
||||
schema: {
|
||||
type: "string",
|
||||
enum: ["one", "two"]
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(2)
|
||||
expect(wrapper.find("select option").eq(0).text()).toEqual("one")
|
||||
expect(wrapper.find("select option").eq(1).text()).toEqual("two")
|
||||
})
|
||||
})
|
||||
describe("booleans", function() {
|
||||
it("should render the correct options for a boolean parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "boolean"
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(3)
|
||||
expect(wrapper.find("select option").eq(0).text()).toEqual("--")
|
||||
expect(wrapper.find("select option").eq(1).text()).toEqual("true")
|
||||
expect(wrapper.find("select option").eq(2).text()).toEqual("false")
|
||||
})
|
||||
|
||||
it("should render the correct options for a required enum boolean parameter", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
required: true,
|
||||
schema: {
|
||||
type: "boolean",
|
||||
enum: ["true"]
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("select").length).toEqual(1)
|
||||
expect(wrapper.find("select option").length).toEqual(1)
|
||||
expect(wrapper.find("select option").first().text()).toEqual("true")
|
||||
})
|
||||
})
|
||||
describe("unknown types", function() {
|
||||
it("should render unknown types as strings", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "yo",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "NotARealType"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("input").length).toEqual(1)
|
||||
// expect(wrapper.find("select input").length).toEqual(1)
|
||||
// expect(wrapper.find("select option").first().text()).toEqual("true")
|
||||
})
|
||||
|
||||
it("should render unknown types as strings when a format is passed", function(){
|
||||
|
||||
let props = {
|
||||
getComponent: getComponentStub,
|
||||
value: "yo",
|
||||
onChange: () => {},
|
||||
keyName: "",
|
||||
fn: {},
|
||||
schema: {
|
||||
type: "NotARealType",
|
||||
format: "NotARealFormat"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let wrapper = render(<JsonSchemaForm {...props}/>)
|
||||
|
||||
expect(wrapper.find("input").length).toEqual(1)
|
||||
// expect(wrapper.find("select input").length).toEqual(1)
|
||||
// expect(wrapper.find("select option").first().text()).toEqual("true")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -19,6 +19,11 @@ describe("<ObjectModel />", function() {
|
||||
}
|
||||
const props = {
|
||||
getComponent: c => components[c],
|
||||
getConfigs: () => {
|
||||
return {
|
||||
showExtensions: true
|
||||
}
|
||||
},
|
||||
isRef : false,
|
||||
schema: Immutable.fromJS(
|
||||
{
|
||||
|
||||
@@ -14,6 +14,9 @@ describe("<PrimitiveModel/>", function() {
|
||||
}
|
||||
const props = {
|
||||
getComponent: c => components[c],
|
||||
getConfigs: () => ({
|
||||
showExtensions: false
|
||||
}),
|
||||
name: "Name from props",
|
||||
depth: 1,
|
||||
schema: fromJS({
|
||||
@@ -46,4 +49,4 @@ describe("<PrimitiveModel/>", function() {
|
||||
})
|
||||
|
||||
})
|
||||
} )
|
||||
} )
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
import expect from "expect"
|
||||
import { fromJS, OrderedMap } from "immutable"
|
||||
|
||||
import {
|
||||
selectedServer,
|
||||
serverVariableValue,
|
||||
serverVariables,
|
||||
serverEffectiveValue
|
||||
} from "corePlugins/oas3/selectors"
|
||||
|
||||
import reducers from "corePlugins/oas3/reducers"
|
||||
|
||||
import {
|
||||
setSelectedServer,
|
||||
setServerVariableValue,
|
||||
} from "corePlugins/oas3/actions"
|
||||
|
||||
describe("OAS3 plugin - state", function() {
|
||||
describe("action + reducer + selector integration", function() {
|
||||
describe("selectedServer", function() {
|
||||
it("should set and get a global selectedServer", function() {
|
||||
const state = new OrderedMap()
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setSelectedServer("http://google.com")
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_servers"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = selectedServer(newState)(system)
|
||||
|
||||
expect(res).toEqual("http://google.com")
|
||||
})
|
||||
|
||||
it("should set and get a namespaced selectedServer", function() {
|
||||
const state = fromJS({
|
||||
selectedServer: "http://yahoo.com"
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setSelectedServer("http://google.com", "myOperation")
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_servers"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = selectedServer(newState, "myOperation")(system)
|
||||
|
||||
// Get the global selected server
|
||||
const globalRes = selectedServer(newState)(system)
|
||||
|
||||
expect(res).toEqual("http://google.com")
|
||||
expect(globalRes).toEqual("http://yahoo.com")
|
||||
})
|
||||
})
|
||||
|
||||
describe("serverVariableValue", function() {
|
||||
it("should set and get a global serverVariableValue", function() {
|
||||
const state = new OrderedMap()
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariableValue(newState, "google.com", "foo")(system)
|
||||
|
||||
expect(res).toEqual("bar")
|
||||
})
|
||||
it("should set and get a namespaced serverVariableValue", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com": {
|
||||
foo: "123"
|
||||
}
|
||||
}
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
namespace: "myOperation",
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariableValue(newState, {
|
||||
namespace: "myOperation",
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
// Get the global value, to cross-check
|
||||
const globalRes = serverVariableValue(newState, {
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
expect(res).toEqual("bar")
|
||||
expect(globalRes).toEqual("123")
|
||||
})
|
||||
})
|
||||
|
||||
describe("serverVariables", function() {
|
||||
it("should set and get global serverVariables", function() {
|
||||
const state = new OrderedMap()
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariables(newState, "google.com", "foo")(system)
|
||||
|
||||
expect(res.toJS()).toEqual({
|
||||
foo: "bar"
|
||||
})
|
||||
})
|
||||
|
||||
it("should set and get namespaced serverVariables", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com": {
|
||||
foo: "123"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
namespace: "myOperation",
|
||||
server: "google.com",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverVariables(newState, {
|
||||
namespace: "myOperation",
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
// Get the global value, to cross-check
|
||||
const globalRes = serverVariables(newState, {
|
||||
server: "google.com"
|
||||
}, "foo")(system)
|
||||
|
||||
expect(res.toJS()).toEqual({
|
||||
foo: "bar"
|
||||
})
|
||||
|
||||
expect(globalRes.toJS()).toEqual({
|
||||
foo: "123"
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("serverEffectiveValue", function() {
|
||||
it("should set variable values and compute a URL for a namespaced server", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com/{foo}": {
|
||||
foo: "123"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the action
|
||||
const action = setServerVariableValue({
|
||||
namespace: "myOperation",
|
||||
server: "google.com/{foo}",
|
||||
key: "foo",
|
||||
val: "bar"
|
||||
})
|
||||
|
||||
// Collect the new state
|
||||
const newState = reducers["oas3_set_server_variable_value"](state, action)
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverEffectiveValue(newState, {
|
||||
namespace: "myOperation",
|
||||
server: "google.com/{foo}"
|
||||
})(system)
|
||||
|
||||
// Get the global value, to cross-check
|
||||
const globalRes = serverEffectiveValue(newState, {
|
||||
server: "google.com/{foo}"
|
||||
})(system)
|
||||
|
||||
expect(res).toEqual("google.com/bar")
|
||||
|
||||
expect(globalRes).toEqual("google.com/123")
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
describe("selectors", function() {
|
||||
describe("serverEffectiveValue", function() {
|
||||
it("should compute global serverEffectiveValues", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com/{foo}/{bar}": {
|
||||
foo: "123",
|
||||
bar: "456"
|
||||
}
|
||||
}
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverEffectiveValue(state, "google.com/{foo}/{bar}")(system)
|
||||
|
||||
expect(res).toEqual("google.com/123/456")
|
||||
})
|
||||
|
||||
it("should handle multiple variable instances", function() {
|
||||
const state = fromJS({
|
||||
serverVariableValues: {
|
||||
"google.com/{foo}/{foo}/{bar}": {
|
||||
foo: "123",
|
||||
bar: "456"
|
||||
}
|
||||
}
|
||||
})
|
||||
const system = {
|
||||
// needed to handle `onlyOAS3` wrapper
|
||||
getSystem() {
|
||||
return {
|
||||
specSelectors: {
|
||||
specJson: () => {
|
||||
return fromJS({ openapi: "3.0.0" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the value with the selector
|
||||
const res = serverEffectiveValue(state, "google.com/{foo}/{foo}/{bar}")(system)
|
||||
|
||||
expect(res).toEqual("google.com/123/123/456")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
+2
-5
@@ -321,14 +321,11 @@ describe("utils", function() {
|
||||
}
|
||||
|
||||
it("should check the isOAS3 flag when validating parameters", function() {
|
||||
// This should "skip" validation because there is no `schema.type` property
|
||||
// This should "skip" validation because there is no `schema` property
|
||||
// and we are telling `validateParam` this is an OAS3 spec
|
||||
param = fromJS({
|
||||
value: "",
|
||||
required: true,
|
||||
schema: {
|
||||
notTheTypeProperty: "string"
|
||||
}
|
||||
required: true
|
||||
})
|
||||
result = validateParam( param, false, true )
|
||||
expect( result ).toEqual( [] )
|
||||
|
||||
Reference in New Issue
Block a user