Merge branch 'master' into uri-encoded-scopes-fix
This commit is contained in:
3
.github/issue_template.md
vendored
3
.github/issue_template.md
vendored
@@ -1,6 +1,9 @@
|
|||||||
<!---
|
<!---
|
||||||
Thanks for filing an issue 😄 ! Before you submit, please read the following:
|
Thanks for filing an issue 😄 ! Before you submit, please read the following:
|
||||||
|
|
||||||
|
If you're here to report a security issue, please STOP writing an issue and contact us
|
||||||
|
at security@swagger.io instead!
|
||||||
|
|
||||||
Search open/closed issues before submitting since someone might have asked the same thing before!
|
Search open/closed issues before submitting since someone might have asked the same thing before!
|
||||||
|
|
||||||
Issues on GitHub are only related to problems of Swagger-UI itself. We'll try to offer support
|
Issues on GitHub are only related to problems of Swagger-UI itself. We'll try to offer support
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,6 +2,7 @@ node_modules
|
|||||||
.idea
|
.idea
|
||||||
.deps_check
|
.deps_check
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.nyc_output
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
.eslintcache
|
.eslintcache
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- '6.9'
|
- '6.9'
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- node_modules
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
|
||||||
|
install: "npm i && npm update"
|
||||||
before_deploy:
|
before_deploy:
|
||||||
- npm run build
|
- npm run build
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ We love contributions from our community of users! This document explains our gu
|
|||||||
|
|
||||||
#### Environment setup
|
#### Environment setup
|
||||||
|
|
||||||
0. Install Node.js (4 or newer) and npm (3 or newer).
|
0. Install Node.js (6 or newer) and npm (3 or newer).
|
||||||
1. Make a fork of Swagger-UI on GitHub, then clone your fork to your machine.
|
1. Make a fork of Swagger-UI on GitHub, then clone your fork to your machine.
|
||||||
2. Run `npm install` in your Swagger-UI directory.
|
2. Run `npm install` in your Swagger-UI directory.
|
||||||
3. Run `npm run dev`. `localhost:3200` should open automatically.
|
3. Run `npm run dev`. `localhost:3200` should open automatically.
|
||||||
|
|||||||
@@ -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
|
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
|
||||||
------------------ | ------------ | -------------------------- | -----
|
------------------ | ------------ | -------------------------- | -----
|
||||||
3.4.1 | 2017-10-20 | 2.0, 3.0 | [tag v3.4.1](https://github.com/swagger-api/swagger-ui/tree/v3.4.1)
|
3.4.4 | 2017-11-03 | 2.0, 3.0 | [tag v3.4.4](https://github.com/swagger-api/swagger-ui/tree/v3.4.4)
|
||||||
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
|
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.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)
|
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)
|
||||||
|
|||||||
104
dist/swagger-ui-bundle.js
vendored
104
dist/swagger-ui-bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui-bundle.js.map
vendored
2
dist/swagger-ui-bundle.js.map
vendored
File diff suppressed because one or more lines are too long
6
dist/swagger-ui-standalone-preset.js
vendored
6
dist/swagger-ui-standalone-preset.js
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui-standalone-preset.js.map
vendored
2
dist/swagger-ui-standalone-preset.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui.css
vendored
2
dist/swagger-ui.css
vendored
File diff suppressed because one or more lines are too long
4
dist/swagger-ui.js
vendored
4
dist/swagger-ui.js
vendored
File diff suppressed because one or more lines are too long
2
dist/swagger-ui.js.map
vendored
2
dist/swagger-ui.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -20,8 +20,8 @@ Some distinct identifiers to Swagger-UI 3.X:
|
|||||||
|
|
||||||
If you've determined this is the version you have, to find the exact version:
|
If you've determined this is the version you have, to find the exact version:
|
||||||
- Open your browser's web console (changes between browsers)
|
- Open your browser's web console (changes between browsers)
|
||||||
- Type `versions` in the console and execute the call.
|
- Type `JSON.stringify(versions)` in the console and execute the call.
|
||||||
- You might need to expand the result, until you get a string similar to `swaggerUi : Object { version: "3.1.6", gitRevision: "g786cd47", gitDirty: true, … }`.
|
- The result should look similar to `swaggerUi : Object { version: "3.1.6", gitRevision: "g786cd47", gitDirty: true, … }`.
|
||||||
- The version taken from that example would be `3.1.6`.
|
- The version taken from that example would be `3.1.6`.
|
||||||
|
|
||||||
Note: This functionality was added in 3.0.8. If you're unable to execute it, you're likely to use an older version, and in that case the first step would be to upgrade.
|
Note: This functionality was added in 3.0.8. If you're unable to execute it, you're likely to use an older version, and in that case the first step would be to upgrade.
|
||||||
@@ -51,4 +51,4 @@ If you've determined this is the version you have, to find the exact version:
|
|||||||
* @link http://swagger.io
|
* @link http://swagger.io
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
```
|
```
|
||||||
|
|||||||
24
package.json
24
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "swagger-ui",
|
"name": "swagger-ui",
|
||||||
"version": "3.4.1",
|
"version": "3.4.4",
|
||||||
"main": "dist/swagger-ui.js",
|
"main": "dist/swagger-ui.js",
|
||||||
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
"repository": "git@github.com:swagger-api/swagger-ui.git",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -33,12 +33,14 @@
|
|||||||
"test-in-node": "npm run lint-errors && npm run just-test-in-node",
|
"test-in-node": "npm run lint-errors && npm run just-test-in-node",
|
||||||
"just-test": "karma start --config karma.conf.js",
|
"just-test": "karma start --config karma.conf.js",
|
||||||
"just-test-in-node": "mocha --recursive --compilers js:babel-core/register test/core test/components test/bugs test/swagger-ui-dist-package test/xss",
|
"just-test-in-node": "mocha --recursive --compilers js:babel-core/register test/core test/components test/bugs test/swagger-ui-dist-package test/xss",
|
||||||
|
"just-check-coverage": "nyc npm run just-test-in-node",
|
||||||
"test-e2e": "sleep 3 && nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json",
|
"test-e2e": "sleep 3 && nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json",
|
||||||
"e2e-initial-render": "nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json --group initial-render",
|
"e2e-initial-render": "nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json --group initial-render",
|
||||||
"mock-api": "json-server --watch test/e2e/db.json --port 3204",
|
"mock-api": "json-server --watch test/e2e/db.json --port 3204",
|
||||||
"e2e": "npm-run-all --parallel -r hot-server mock-api test-e2e"
|
"e2e": "npm-run-all --parallel -r hot-server mock-api test-e2e"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@braintree/sanitize-url": "^2.0.2",
|
||||||
"base64-js": "^1.2.0",
|
"base64-js": "^1.2.0",
|
||||||
"brace": "0.7.0",
|
"brace": "0.7.0",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
@@ -55,17 +57,17 @@
|
|||||||
"memoizee": "0.4.1",
|
"memoizee": "0.4.1",
|
||||||
"promise-worker": "^1.1.1",
|
"promise-worker": "^1.1.1",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"react": "^15.4.0",
|
"react": "^15.6.2",
|
||||||
"react-addons-perf": "^15.4.0",
|
"react-addons-perf": "^15.4.0",
|
||||||
"react-addons-shallow-compare": "0.14.8",
|
"react-addons-shallow-compare": "0.14.8",
|
||||||
"react-addons-test-utils": "^15.4.0",
|
"react-addons-test-utils": "^15.6.2",
|
||||||
"react-collapse": "2.3.1",
|
"react-collapse": "^4.0.3",
|
||||||
"react-dom": "^15.4.0",
|
"react-dom": "^15.6.2",
|
||||||
"react-height": "^2.0.0",
|
"react-height": "^2.0.0",
|
||||||
"react-hot-loader": "1.3.1",
|
"react-hot-loader": "1.3.1",
|
||||||
"react-immutable-proptypes": "2.1.0",
|
"react-immutable-proptypes": "2.1.0",
|
||||||
"react-markdown": "^2.5.0",
|
"react-markdown": "^2.5.0",
|
||||||
"react-motion": "0.4.4",
|
"react-motion": "^0.5.2",
|
||||||
"react-object-inspector": "0.2.1",
|
"react-object-inspector": "0.2.1",
|
||||||
"react-redux": "^4.x.x",
|
"react-redux": "^4.x.x",
|
||||||
"react-split-pane": "0.1.57",
|
"react-split-pane": "0.1.57",
|
||||||
@@ -78,11 +80,12 @@
|
|||||||
"scroll-to-element": "^2.0.0",
|
"scroll-to-element": "^2.0.0",
|
||||||
"serialize-error": "2.0.0",
|
"serialize-error": "2.0.0",
|
||||||
"shallowequal": "0.2.2",
|
"shallowequal": "0.2.2",
|
||||||
"swagger-client": "^3.3.1",
|
"swagger-client": "^3.3.3",
|
||||||
"url-parse": "^1.1.8",
|
"url-parse": "^1.1.8",
|
||||||
"whatwg-fetch": "0.11.1",
|
"whatwg-fetch": "0.11.1",
|
||||||
"worker-loader": "^0.7.1",
|
"worker-loader": "^0.7.1",
|
||||||
"xml": "1.0.1",
|
"xml": "1.0.1",
|
||||||
|
"xml-but-prettier": "^1.0.1",
|
||||||
"yaml-js": "0.2.0"
|
"yaml-js": "0.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -125,6 +128,7 @@
|
|||||||
"node-sass": "^4.5.0",
|
"node-sass": "^4.5.0",
|
||||||
"npm-run-all": "4.0.2",
|
"npm-run-all": "4.0.2",
|
||||||
"null-loader": "0.1.1",
|
"null-loader": "0.1.1",
|
||||||
|
"nyc": "^11.3.0",
|
||||||
"open": "0.0.5",
|
"open": "0.0.5",
|
||||||
"postcss-loader": "2.0.6",
|
"postcss-loader": "2.0.6",
|
||||||
"raw-loader": "0.5.1",
|
"raw-loader": "0.5.1",
|
||||||
@@ -150,5 +154,11 @@
|
|||||||
],
|
],
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"webpack-dev-server": "2.5.0"
|
"webpack-dev-server": "2.5.0"
|
||||||
|
},
|
||||||
|
"nyc": {
|
||||||
|
"all": true,
|
||||||
|
"include": [
|
||||||
|
"**/src/core/plugins/**.js"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,24 +24,23 @@ export default class ArrayModel extends Component {
|
|||||||
const Markdown = getComponent("Markdown")
|
const Markdown = getComponent("Markdown")
|
||||||
const ModelCollapse = getComponent("ModelCollapse")
|
const ModelCollapse = getComponent("ModelCollapse")
|
||||||
const Model = getComponent("Model")
|
const Model = getComponent("Model")
|
||||||
|
const Property = getComponent("Property")
|
||||||
|
|
||||||
const titleEl = title &&
|
const titleEl = title &&
|
||||||
<span className="model-title">
|
<span className="model-title">
|
||||||
<span className="model-title__text">{ title }</span>
|
<span className="model-title__text">{ title }</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Note: we set `name={null}` in <Model> below because we don't want
|
Note: we set `name={null}` in <Model> below because we don't want
|
||||||
the name of the current Model passed (and displayed) as the name of the array element Model
|
the name of the current Model passed (and displayed) as the name of the array element Model
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return <span className="model">
|
return <span className="model">
|
||||||
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent="[...]">
|
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent="[...]">
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }>
|
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <Property key={`${key}-${v}`} propKey={ key } propVal={ v } propStyle={ propStyle } />) : null
|
||||||
<br />{ key }: { String(v) }</span>)
|
|
||||||
: null
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!description ? null :
|
!description ? null :
|
||||||
|
|||||||
@@ -1,25 +1,23 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import ImPropTypes from "react-immutable-proptypes"
|
|
||||||
|
|
||||||
export default class AuthorizeOperationBtn extends React.Component {
|
export default class AuthorizeOperationBtn extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
isAuthorized: PropTypes.bool.isRequired,
|
||||||
|
onClick: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
onClick =(e) => {
|
onClick =(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
let { onClick } = this.props
|
||||||
|
|
||||||
let { security, authActions, authSelectors } = this.props
|
if(onClick) {
|
||||||
let definitions = authSelectors.getDefinitionsByNames(security)
|
onClick()
|
||||||
|
}
|
||||||
authActions.showDefinitions(definitions)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { security, authSelectors } = this.props
|
let { isAuthorized } = this.props
|
||||||
|
|
||||||
let isAuthorized = authSelectors.isAuthorized(security)
|
|
||||||
|
|
||||||
if(isAuthorized === null) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button className={isAuthorized ? "authorization__btn locked" : "authorization__btn unlocked"} onClick={ this.onClick }>
|
<button className={isAuthorized ? "authorization__btn locked" : "authorization__btn unlocked"} onClick={ this.onClick }>
|
||||||
@@ -30,10 +28,4 @@ export default class AuthorizeOperationBtn extends React.Component {
|
|||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
authSelectors: PropTypes.object.isRequired,
|
|
||||||
authActions: PropTypes.object.isRequired,
|
|
||||||
security: ImPropTypes.iterable.isRequired
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default class ContentType extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ "content-type-wrapper " + ( className || "" ) }>
|
<div className={ "content-type-wrapper " + ( className || "" ) }>
|
||||||
<select className="content-type" value={value} onChange={this.onChangeWrapper} >
|
<select className="content-type" value={value || ""} onChange={this.onChangeWrapper} >
|
||||||
{ contentTypes.map( (val) => {
|
{ contentTypes.map( (val) => {
|
||||||
return <option key={ val } value={ val }>{ val }</option>
|
return <option key={ val } value={ val }>{ val }</option>
|
||||||
}).toArray()}
|
}).toArray()}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import Collapse from "react-collapse"
|
import { Collapse } from "react-collapse"
|
||||||
import { presets } from "react-motion"
|
import { presets } from "react-motion"
|
||||||
import ObjectInspector from "react-object-inspector"
|
import ObjectInspector from "react-object-inspector"
|
||||||
import Perf from "react-addons-perf"
|
import Perf from "react-addons-perf"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { List } from "immutable"
|
import { List } from "immutable"
|
||||||
import Collapse from "react-collapse"
|
import { Collapse } from "react-collapse"
|
||||||
|
|
||||||
export default class Errors extends React.Component {
|
export default class Errors extends React.Component {
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ const SpecErrorItem = ( { error, jumpToLine } ) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toTitleCase(str) {
|
function toTitleCase(str) {
|
||||||
return str
|
return (str || "")
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map(substr => substr[0].toUpperCase() + substr.slice(1))
|
.map(substr => substr[0].toUpperCase() + substr.slice(1))
|
||||||
.join(" ")
|
.join(" ")
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from "react"
|
|||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { fromJS } from "immutable"
|
import { fromJS } from "immutable"
|
||||||
import ImPropTypes from "react-immutable-proptypes"
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
import { sanitizeUrl } from "core/utils"
|
||||||
|
|
||||||
|
|
||||||
class Path extends React.Component {
|
class Path extends React.Component {
|
||||||
@@ -35,9 +36,9 @@ class Contact extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ url && <div><a href={ url } target="_blank">{ name } - Website</a></div> }
|
{ url && <div><a href={ sanitizeUrl(url) } target="_blank">{ name } - Website</a></div> }
|
||||||
{ email &&
|
{ email &&
|
||||||
<a href={`mailto:${email}`}>
|
<a href={sanitizeUrl(`mailto:${email}`)}>
|
||||||
{ url ? `Send email to ${name}` : `Contact ${name}`}
|
{ url ? `Send email to ${name}` : `Contact ${name}`}
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@@ -59,7 +60,7 @@ class License extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
url ? <a target="_blank" href={ url }>{ name }</a>
|
url ? <a target="_blank" href={ sanitizeUrl(url) }>{ name }</a>
|
||||||
: <span>{ name }</span>
|
: <span>{ name }</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -97,7 +98,7 @@ export default class Info extends React.Component {
|
|||||||
{ version && <VersionStamp version={version}></VersionStamp> }
|
{ version && <VersionStamp version={version}></VersionStamp> }
|
||||||
</h2>
|
</h2>
|
||||||
{ host || basePath ? <Path host={ host } basePath={ basePath } /> : null }
|
{ host || basePath ? <Path host={ host } basePath={ basePath } /> : null }
|
||||||
{ url && <a target="_blank" href={ url }><span className="url"> { url } </span></a> }
|
{ url && <a target="_blank" href={ sanitizeUrl(url) }><span className="url"> { url } </span></a> }
|
||||||
</hgroup>
|
</hgroup>
|
||||||
|
|
||||||
<div className="description">
|
<div className="description">
|
||||||
@@ -106,14 +107,14 @@ export default class Info extends React.Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
termsOfService && <div>
|
termsOfService && <div>
|
||||||
<a target="_blank" href={ termsOfService }>Terms of service</a>
|
<a target="_blank" href={ sanitizeUrl(termsOfService) }>Terms of service</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{ contact && contact.size ? <Contact data={ contact } /> : null }
|
{ contact && contact.size ? <Contact data={ contact } /> : null }
|
||||||
{ license && license.size ? <License license={ license } /> : null }
|
{ license && license.size ? <License license={ license } /> : null }
|
||||||
{ externalDocsUrl ?
|
{ externalDocsUrl ?
|
||||||
<a target="_blank" href={externalDocsUrl}>{externalDocsDescription || externalDocsUrl}</a>
|
<a target="_blank" href={sanitizeUrl(externalDocsUrl)}>{externalDocsDescription || externalDocsUrl}</a>
|
||||||
: null }
|
: null }
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import OriCollapse from "react-collapse"
|
import { Collapse as OriCollapse } from "react-collapse"
|
||||||
|
|
||||||
function xclass(...args) {
|
function xclass(...args) {
|
||||||
return args.filter(a => !!a).join(" ").trim()
|
return args.filter(a => !!a).join(" ").trim()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from "react"
|
import React, { PureComponent } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
export default class Model extends Component {
|
export default class Model extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
schema: PropTypes.object.isRequired,
|
schema: PropTypes.object.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
@@ -35,7 +35,7 @@ export default class Model extends Component {
|
|||||||
const PrimitiveModel = getComponent("PrimitiveModel")
|
const PrimitiveModel = getComponent("PrimitiveModel")
|
||||||
let type = "object"
|
let type = "object"
|
||||||
let $$ref = schema && schema.get("$$ref")
|
let $$ref = schema && schema.get("$$ref")
|
||||||
|
|
||||||
// If we weren't passed a `name` but have a ref, grab the name from the ref
|
// If we weren't passed a `name` but have a ref, grab the name from the ref
|
||||||
if ( !name && $$ref ) {
|
if ( !name && $$ref ) {
|
||||||
name = this.getModelName( $$ref )
|
name = this.getModelName( $$ref )
|
||||||
@@ -44,11 +44,11 @@ export default class Model extends Component {
|
|||||||
if ( !schema && $$ref ) {
|
if ( !schema && $$ref ) {
|
||||||
schema = this.getRefSchema( name )
|
schema = this.getRefSchema( name )
|
||||||
}
|
}
|
||||||
|
|
||||||
const deprecated = specSelectors.isOAS3() && schema.get("deprecated")
|
const deprecated = specSelectors.isOAS3() && schema.get("deprecated")
|
||||||
isRef = isRef !== undefined ? isRef : !!$$ref
|
isRef = isRef !== undefined ? isRef : !!$$ref
|
||||||
type = schema && schema.get("type") || type
|
type = schema && schema.get("type") || type
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case "object":
|
case "object":
|
||||||
return <ObjectModel
|
return <ObjectModel
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ export default class ObjectModel extends Component {
|
|||||||
let { specSelectors } = otherProps
|
let { specSelectors } = otherProps
|
||||||
let { isOAS3 } = specSelectors
|
let { isOAS3 } = specSelectors
|
||||||
|
|
||||||
|
if(!schema) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
let description = schema.get("description")
|
let description = schema.get("description")
|
||||||
let properties = schema.get("properties")
|
let properties = schema.get("properties")
|
||||||
let additionalProperties = schema.get("additionalProperties")
|
let additionalProperties = schema.get("additionalProperties")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import { sanitizeUrl } from "core/utils"
|
||||||
|
|
||||||
export default class OnlineValidatorBadge extends React.Component {
|
export default class OnlineValidatorBadge extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -32,6 +33,8 @@ export default class OnlineValidatorBadge extends React.Component {
|
|||||||
let { getConfigs } = this.props
|
let { getConfigs } = this.props
|
||||||
let { spec } = getConfigs()
|
let { spec } = getConfigs()
|
||||||
|
|
||||||
|
let sanitizedValidatorUrl = sanitizeUrl(this.state.validatorUrl)
|
||||||
|
|
||||||
if ( typeof spec === "object" && Object.keys(spec).length) return null
|
if ( typeof spec === "object" && Object.keys(spec).length) return null
|
||||||
|
|
||||||
if (!this.state.url || !this.state.validatorUrl || this.state.url.indexOf("localhost") >= 0
|
if (!this.state.url || !this.state.validatorUrl || this.state.url.indexOf("localhost") >= 0
|
||||||
@@ -40,8 +43,8 @@ export default class OnlineValidatorBadge extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (<span style={{ float: "right"}}>
|
return (<span style={{ float: "right"}}>
|
||||||
<a target="_blank" href={`${ this.state.validatorUrl }/debug?url=${ this.state.url }`}>
|
<a target="_blank" href={`${ sanitizedValidatorUrl }/debug?url=${ this.state.url }`}>
|
||||||
<ValidatorImage src={`${ this.state.validatorUrl }?url=${ this.state.url }`} alt="Online validator badge"/>
|
<ValidatorImage src={`${ sanitizedValidatorUrl }?url=${ this.state.url }`} alt="Online validator badge"/>
|
||||||
</a>
|
</a>
|
||||||
</span>)
|
</span>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { PureComponent } from "react"
|
|||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { getList } from "core/utils"
|
import { getList } from "core/utils"
|
||||||
import * as CustomPropTypes from "core/proptypes"
|
import * as CustomPropTypes from "core/proptypes"
|
||||||
|
import { sanitizeUrl } from "core/utils"
|
||||||
|
|
||||||
//import "less/opblock"
|
//import "less/opblock"
|
||||||
|
|
||||||
@@ -11,8 +12,10 @@ export default class Operation extends PureComponent {
|
|||||||
method: PropTypes.string.isRequired,
|
method: PropTypes.string.isRequired,
|
||||||
operation: PropTypes.object.isRequired,
|
operation: PropTypes.object.isRequired,
|
||||||
showSummary: PropTypes.bool,
|
showSummary: PropTypes.bool,
|
||||||
|
isShown: PropTypes.bool.isRequired,
|
||||||
|
|
||||||
isShownKey: CustomPropTypes.arrayOrString.isRequired,
|
tagKey: PropTypes.string,
|
||||||
|
operationKey: PropTypes.string,
|
||||||
jumpToKey: CustomPropTypes.arrayOrString.isRequired,
|
jumpToKey: CustomPropTypes.arrayOrString.isRequired,
|
||||||
|
|
||||||
allowTryItOut: PropTypes.bool,
|
allowTryItOut: PropTypes.bool,
|
||||||
@@ -51,38 +54,16 @@ export default class Operation extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
const defaultContentType = "application/json"
|
|
||||||
let { specActions, path, method, operation } = nextProps
|
|
||||||
let producesValue = operation.get("produces_value")
|
|
||||||
let produces = operation.get("produces")
|
|
||||||
let consumes = operation.get("consumes")
|
|
||||||
let consumesValue = operation.get("consumes_value")
|
|
||||||
|
|
||||||
if(nextProps.response !== this.props.response) {
|
if(nextProps.response !== this.props.response) {
|
||||||
this.setState({ executeInProgress: false })
|
this.setState({ executeInProgress: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (producesValue === undefined) {
|
|
||||||
producesValue = produces && produces.size ? produces.first() : defaultContentType
|
|
||||||
specActions.changeProducesValue([path, method], producesValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consumesValue === undefined) {
|
|
||||||
consumesValue = consumes && consumes.size ? consumes.first() : defaultContentType
|
|
||||||
specActions.changeConsumesValue([path, method], consumesValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleShown =() => {
|
toggleShown =() => {
|
||||||
let { layoutActions, isShownKey } = this.props
|
let { layoutActions, tagKey, operationKey, isShown } = this.props
|
||||||
layoutActions.show(isShownKey, !this.isShown())
|
const isShownKey = ["operations", tagKey, operationKey]
|
||||||
}
|
|
||||||
|
|
||||||
isShown =() => {
|
layoutActions.show(isShownKey, !isShown)
|
||||||
let { layoutSelectors, isShownKey, getConfigs } = this.props
|
|
||||||
let { docExpansion } = getConfigs()
|
|
||||||
|
|
||||||
return layoutSelectors.isShown(isShownKey, docExpansion === "full" ) // Here is where we set the default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onTryoutClick =() => {
|
onTryoutClick =() => {
|
||||||
@@ -101,7 +82,9 @@ export default class Operation extends PureComponent {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {
|
let {
|
||||||
isShownKey,
|
operationKey,
|
||||||
|
tagKey,
|
||||||
|
isShown,
|
||||||
jumpToKey,
|
jumpToKey,
|
||||||
path,
|
path,
|
||||||
method,
|
method,
|
||||||
@@ -155,18 +138,17 @@ export default class Operation extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let { tryItOutEnabled } = this.state
|
let { tryItOutEnabled } = this.state
|
||||||
let shown = this.isShown()
|
|
||||||
let onChangeKey = [ path, method ] // Used to add values to _this_ operation ( indexed by path and method )
|
let onChangeKey = [ path, method ] // Used to add values to _this_ operation ( indexed by path and method )
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={deprecated ? "opblock opblock-deprecated" : shown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={isShownKey.join("-")} >
|
<div className={deprecated ? "opblock opblock-deprecated" : isShown ? `opblock opblock-${method} is-open` : `opblock opblock-${method}`} id={`operations-${tagKey}-${operationKey}`} >
|
||||||
<div className={`opblock-summary opblock-summary-${method}`} onClick={this.toggleShown} >
|
<div className={`opblock-summary opblock-summary-${method}`} onClick={this.toggleShown} >
|
||||||
<span className="opblock-summary-method">{method.toUpperCase()}</span>
|
<span className="opblock-summary-method">{method.toUpperCase()}</span>
|
||||||
<span className={ deprecated ? "opblock-summary-path__deprecated" : "opblock-summary-path" } >
|
<span className={ deprecated ? "opblock-summary-path__deprecated" : "opblock-summary-path" } >
|
||||||
<a
|
<a
|
||||||
className="nostyle"
|
className="nostyle"
|
||||||
onClick={isDeepLinkingEnabled ? (e) => e.preventDefault() : null}
|
onClick={isDeepLinkingEnabled ? (e) => e.preventDefault() : null}
|
||||||
href={isDeepLinkingEnabled ? `#/${isShownKey[1]}/${isShownKey[2]}` : null}>
|
href={isDeepLinkingEnabled ? `#/${tagKey}/${operationKey}` : null}>
|
||||||
<span>{path}</span>
|
<span>{path}</span>
|
||||||
</a>
|
</a>
|
||||||
<JumpToPath path={jumpToKey} />
|
<JumpToPath path={jumpToKey} />
|
||||||
@@ -182,13 +164,17 @@ export default class Operation extends PureComponent {
|
|||||||
|
|
||||||
{
|
{
|
||||||
(!security || !security.count()) ? null :
|
(!security || !security.count()) ? null :
|
||||||
<AuthorizeOperationBtn authActions={ authActions }
|
<AuthorizeOperationBtn
|
||||||
security={ security }
|
isAuthorized={ authSelectors.isAuthorized(security) }
|
||||||
authSelectors={ authSelectors }/>
|
onClick={() => {
|
||||||
|
const applicableDefinitions = authSelectors.definitionsForRequirements(security)
|
||||||
|
authActions.showDefinitions(applicableDefinitions)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Collapse isOpened={shown}>
|
<Collapse isOpened={isShown}>
|
||||||
<div className="opblock-body">
|
<div className="opblock-body">
|
||||||
{ deprecated && <h4 className="opblock-title_normal"> Warning: Deprecated</h4>}
|
{ deprecated && <h4 className="opblock-title_normal"> Warning: Deprecated</h4>}
|
||||||
{ description &&
|
{ description &&
|
||||||
@@ -206,7 +192,7 @@ export default class Operation extends PureComponent {
|
|||||||
<span className="opblock-external-docs__description">
|
<span className="opblock-external-docs__description">
|
||||||
<Markdown source={ externalDocs.get("description") } />
|
<Markdown source={ externalDocs.get("description") } />
|
||||||
</span>
|
</span>
|
||||||
<a className="opblock-external-docs__link" href={ externalDocs.get("url") }>{ externalDocs.get("url") }</a>
|
<a className="opblock-external-docs__link" href={ sanitizeUrl(externalDocs.get("url")) }>{ externalDocs.get("url") }</a>
|
||||||
</div>
|
</div>
|
||||||
</div> : null
|
</div> : null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { helpers } from "swagger-client"
|
import { helpers } from "swagger-client"
|
||||||
import { createDeepLinkPath } from "core/utils"
|
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
|
||||||
const { opId } = helpers
|
const { opId } = helpers
|
||||||
|
|
||||||
export default class Operations extends React.Component {
|
export default class Operations extends React.Component {
|
||||||
@@ -101,7 +101,7 @@ export default class Operations extends React.Component {
|
|||||||
{ tagExternalDocsUrl ? ": " : null }
|
{ tagExternalDocsUrl ? ": " : null }
|
||||||
{ tagExternalDocsUrl ?
|
{ tagExternalDocsUrl ?
|
||||||
<a
|
<a
|
||||||
href={tagExternalDocsUrl}
|
href={sanitizeUrl(tagExternalDocsUrl)}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
target={"_blank"}
|
target={"_blank"}
|
||||||
>{tagExternalDocsUrl}</a> : null
|
>{tagExternalDocsUrl}</a> : null
|
||||||
@@ -127,7 +127,8 @@ export default class Operations extends React.Component {
|
|||||||
|
|
||||||
const operationId =
|
const operationId =
|
||||||
op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id")
|
op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id")
|
||||||
const isShownKey = ["operations", createDeepLinkPath(tag), createDeepLinkPath(operationId)]
|
const tagKey = createDeepLinkPath(tag)
|
||||||
|
const operationKey = createDeepLinkPath(operationId)
|
||||||
|
|
||||||
const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method"))
|
const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method"))
|
||||||
const response = specSelectors.responseFor(op.get("path"), op.get("method"))
|
const response = specSelectors.responseFor(op.get("path"), op.get("method"))
|
||||||
@@ -135,11 +136,12 @@ export default class Operations extends React.Component {
|
|||||||
|
|
||||||
return <Operation
|
return <Operation
|
||||||
{...op.toObject()}
|
{...op.toObject()}
|
||||||
|
tagKey={tagKey}
|
||||||
isShownKey={isShownKey}
|
operationKey={operationKey}
|
||||||
|
isShown={layoutSelectors.isShown(["operations", tagKey, operationKey], docExpansion === "full")}
|
||||||
jumpToKey={jumpToKey}
|
jumpToKey={jumpToKey}
|
||||||
showSummary={showSummary}
|
showSummary={showSummary}
|
||||||
key={isShownKey}
|
key={tagKey + operationKey}
|
||||||
response={ response }
|
response={ response }
|
||||||
request={ request }
|
request={ request }
|
||||||
allowTryItOut={allowTryItOut}
|
allowTryItOut={allowTryItOut}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export default class Primitive extends Component {
|
|||||||
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
|
||||||
const Markdown = getComponent("Markdown")
|
const Markdown = getComponent("Markdown")
|
||||||
const EnumModel = getComponent("EnumModel")
|
const EnumModel = getComponent("EnumModel")
|
||||||
|
const Property = getComponent("Property")
|
||||||
|
|
||||||
return <span className="model">
|
return <span className="model">
|
||||||
<span className="prop">
|
<span className="prop">
|
||||||
@@ -35,9 +36,7 @@ export default class Primitive extends Component {
|
|||||||
<span className="prop-type">{ type }</span>
|
<span className="prop-type">{ type }</span>
|
||||||
{ format && <span className="prop-format">(${format})</span>}
|
{ format && <span className="prop-format">(${format})</span>}
|
||||||
{
|
{
|
||||||
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }>
|
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <Property key={`${key}-${v}`} propKey={ key } propVal={ v } propStyle={ propStyle } />) : null
|
||||||
<br />{ key }: { String(v) }</span>)
|
|
||||||
: null
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!description ? null :
|
!description ? null :
|
||||||
@@ -56,4 +55,4 @@ export default class Primitive extends Component {
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/core/components/property.jsx
Normal file
16
src/core/components/property.jsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import React from "react"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
|
export const Property = ({ propKey, propVal, propStyle }) => {
|
||||||
|
return (
|
||||||
|
<span style={ propStyle }>
|
||||||
|
<br />{ propKey }: { String(propVal) }</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Property.propTypes = {
|
||||||
|
propKey: PropTypes.string,
|
||||||
|
propVal: PropTypes.any,
|
||||||
|
propStyle: PropTypes.object
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Property
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { formatXml } from "core/utils"
|
import formatXml from "xml-but-prettier"
|
||||||
import lowerCase from "lodash/lowerCase"
|
import lowerCase from "lodash/lowerCase"
|
||||||
|
|
||||||
export default class ResponseBody extends React.Component {
|
export default class ResponseBody extends React.Component {
|
||||||
@@ -31,7 +31,10 @@ export default class ResponseBody extends React.Component {
|
|||||||
|
|
||||||
// XML
|
// XML
|
||||||
} else if (/xml/i.test(contentType)) {
|
} else if (/xml/i.test(contentType)) {
|
||||||
body = formatXml(content)
|
body = formatXml(content, {
|
||||||
|
textNodesOnSameLine: true,
|
||||||
|
indentor: " "
|
||||||
|
})
|
||||||
bodyEl = <HighlightCode value={ body } />
|
bodyEl = <HighlightCode value={ body } />
|
||||||
|
|
||||||
// HTML or Plain Text
|
// HTML or Plain Text
|
||||||
|
|||||||
@@ -58,13 +58,12 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
plugins: [
|
plugins: [
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// Initial state
|
||||||
|
initialState: { },
|
||||||
|
|
||||||
// Inline Plugin
|
// Inline Plugin
|
||||||
fn: { },
|
fn: { },
|
||||||
components: { },
|
components: { },
|
||||||
state: { },
|
|
||||||
|
|
||||||
// Override some core configs... at your own risk
|
|
||||||
store: { },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let queryConfig = parseSearch()
|
let queryConfig = parseSearch()
|
||||||
@@ -74,12 +73,12 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
|
|
||||||
const constructorConfig = deepExtend({}, defaults, opts, queryConfig)
|
const constructorConfig = deepExtend({}, defaults, opts, queryConfig)
|
||||||
|
|
||||||
const storeConfigs = deepExtend({}, constructorConfig.store, {
|
const storeConfigs = {
|
||||||
system: {
|
system: {
|
||||||
configs: constructorConfig.configs
|
configs: constructorConfig.configs
|
||||||
},
|
},
|
||||||
plugins: constructorConfig.presets,
|
plugins: constructorConfig.presets,
|
||||||
state: {
|
state: deepExtend({
|
||||||
layout: {
|
layout: {
|
||||||
layout: constructorConfig.layout,
|
layout: constructorConfig.layout,
|
||||||
filter: constructorConfig.filter
|
filter: constructorConfig.filter
|
||||||
@@ -88,8 +87,8 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
spec: "",
|
spec: "",
|
||||||
url: constructorConfig.url
|
url: constructorConfig.url
|
||||||
}
|
}
|
||||||
}
|
}, constructorConfig.initialState)
|
||||||
})
|
}
|
||||||
|
|
||||||
let inlinePlugin = ()=> {
|
let inlinePlugin = ()=> {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export class JsonSchema_string extends Component {
|
|||||||
if ( enumValue ) {
|
if ( enumValue ) {
|
||||||
const Select = getComponent("Select")
|
const Select = getComponent("Select")
|
||||||
return (<Select className={ errors.length ? "invalid" : ""}
|
return (<Select className={ errors.length ? "invalid" : ""}
|
||||||
|
title={ errors.length ? errors : ""}
|
||||||
allowedValues={ enumValue }
|
allowedValues={ enumValue }
|
||||||
value={ value }
|
value={ value }
|
||||||
allowEmptyValue={ !required }
|
allowEmptyValue={ !required }
|
||||||
@@ -67,10 +68,20 @@ export class JsonSchema_string extends Component {
|
|||||||
const isDisabled = schema["in"] === "formData" && !("FormData" in window)
|
const isDisabled = schema["in"] === "formData" && !("FormData" in window)
|
||||||
const Input = getComponent("Input")
|
const Input = getComponent("Input")
|
||||||
if (schema["type"] === "file") {
|
if (schema["type"] === "file") {
|
||||||
return <Input type="file" className={ errors.length ? "invalid" : ""} onChange={ this.onChange } disabled={isDisabled}/>
|
return (<Input type="file"
|
||||||
|
className={ errors.length ? "invalid" : ""}
|
||||||
|
title={ errors.length ? errors : ""}
|
||||||
|
onChange={ this.onChange }
|
||||||
|
disabled={isDisabled}/>)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return <Input type={ schema.format === "password" ? "password" : "text" } className={ errors.length ? "invalid" : ""} value={value} placeholder={description} onChange={ this.onChange } disabled={isDisabled}/>
|
return (<Input type={ schema.format === "password" ? "password" : "text" }
|
||||||
|
className={ errors.length ? "invalid" : ""}
|
||||||
|
title={ errors.length ? errors : ""}
|
||||||
|
value={value}
|
||||||
|
placeholder={description}
|
||||||
|
onChange={ this.onChange }
|
||||||
|
disabled={isDisabled}/>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,11 +145,12 @@ export class JsonSchema_array extends PureComponent {
|
|||||||
if ( enumValue ) {
|
if ( enumValue ) {
|
||||||
const Select = getComponent("Select")
|
const Select = getComponent("Select")
|
||||||
return (<Select className={ errors.length ? "invalid" : ""}
|
return (<Select className={ errors.length ? "invalid" : ""}
|
||||||
multiple={ true }
|
title={ errors.length ? errors : ""}
|
||||||
value={ value }
|
multiple={ true }
|
||||||
allowedValues={ enumValue }
|
value={ value }
|
||||||
allowEmptyValue={ !required }
|
allowedValues={ enumValue }
|
||||||
onChange={ this.onEnumChange }/>)
|
allowEmptyValue={ !required }
|
||||||
|
onChange={ this.onEnumChange }/>)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -175,6 +187,7 @@ export class JsonSchema_boolean extends Component {
|
|||||||
const Select = getComponent("Select")
|
const Select = getComponent("Select")
|
||||||
|
|
||||||
return (<Select className={ errors.length ? "invalid" : ""}
|
return (<Select className={ errors.length ? "invalid" : ""}
|
||||||
|
title={ errors.length ? errors : ""}
|
||||||
value={ String(value) }
|
value={ String(value) }
|
||||||
allowedValues={ fromJS(["true", "false"]) }
|
allowedValues={ fromJS(["true", "false"]) }
|
||||||
allowEmptyValue={ true }
|
allowEmptyValue={ true }
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const shownDefinitions = createSelector(
|
|||||||
export const definitionsToAuthorize = createSelector(
|
export const definitionsToAuthorize = createSelector(
|
||||||
state,
|
state,
|
||||||
() => ( { specSelectors } ) => {
|
() => ( { specSelectors } ) => {
|
||||||
let definitions = specSelectors.securityDefinitions()
|
let definitions = specSelectors.securityDefinitions() || Map({})
|
||||||
let list = List()
|
let list = List()
|
||||||
|
|
||||||
//todo refactor
|
//todo refactor
|
||||||
@@ -28,6 +28,7 @@ export const definitionsToAuthorize = createSelector(
|
|||||||
|
|
||||||
|
|
||||||
export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors } ) => {
|
export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors } ) => {
|
||||||
|
console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.")
|
||||||
let securityDefinitions = specSelectors.securityDefinitions()
|
let securityDefinitions = specSelectors.securityDefinitions()
|
||||||
let result = List()
|
let result = List()
|
||||||
|
|
||||||
@@ -58,6 +59,13 @@ export const getDefinitionsByNames = ( state, securities ) => ( { specSelectors
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const definitionsForRequirements = (state, securities = List()) => ({ authSelectors }) => {
|
||||||
|
const allDefinitions = authSelectors.definitionsToAuthorize() || List()
|
||||||
|
return allDefinitions.filter((def) => {
|
||||||
|
return securities.some(sec => sec.get(def.keySeq().first()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const authorized = createSelector(
|
export const authorized = createSelector(
|
||||||
state,
|
state,
|
||||||
auth => auth.get("authorized") || Map()
|
auth => auth.get("authorized") || Map()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import serializeError from "serialize-error"
|
|||||||
export const NEW_THROWN_ERR = "err_new_thrown_err"
|
export const NEW_THROWN_ERR = "err_new_thrown_err"
|
||||||
export const NEW_THROWN_ERR_BATCH = "err_new_thrown_err_batch"
|
export const NEW_THROWN_ERR_BATCH = "err_new_thrown_err_batch"
|
||||||
export const NEW_SPEC_ERR = "err_new_spec_err"
|
export const NEW_SPEC_ERR = "err_new_spec_err"
|
||||||
|
export const NEW_SPEC_ERR_BATCH = "err_new_spec_err_batch"
|
||||||
export const NEW_AUTH_ERR = "err_new_auth_err"
|
export const NEW_AUTH_ERR = "err_new_auth_err"
|
||||||
export const CLEAR = "err_clear"
|
export const CLEAR = "err_clear"
|
||||||
|
|
||||||
@@ -27,6 +28,13 @@ export function newSpecErr(err) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function newSpecErrBatch(errArray) {
|
||||||
|
return {
|
||||||
|
type: NEW_SPEC_ERR_BATCH,
|
||||||
|
payload: errArray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function newAuthErr(err) {
|
export function newAuthErr(err) {
|
||||||
return {
|
return {
|
||||||
type: NEW_AUTH_ERR,
|
type: NEW_AUTH_ERR,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
NEW_THROWN_ERR,
|
NEW_THROWN_ERR,
|
||||||
NEW_THROWN_ERR_BATCH,
|
NEW_THROWN_ERR_BATCH,
|
||||||
NEW_SPEC_ERR,
|
NEW_SPEC_ERR,
|
||||||
|
NEW_SPEC_ERR_BATCH,
|
||||||
NEW_AUTH_ERR,
|
NEW_AUTH_ERR,
|
||||||
CLEAR
|
CLEAR
|
||||||
} from "./actions"
|
} from "./actions"
|
||||||
@@ -45,6 +46,15 @@ export default function(system) {
|
|||||||
.update("errors", errors => transformErrors(errors, system.getSystem()))
|
.update("errors", errors => transformErrors(errors, system.getSystem()))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[NEW_SPEC_ERR_BATCH]: (state, { payload }) => {
|
||||||
|
payload = payload.map(err => {
|
||||||
|
return fromJS(Object.assign(DEFAULT_ERROR_STRUCTURE, err, { type: "spec" }))
|
||||||
|
})
|
||||||
|
return state
|
||||||
|
.update("errors", errors => (errors || List()).concat( fromJS( payload )) )
|
||||||
|
.update("errors", errors => transformErrors(errors, system.getSystem()))
|
||||||
|
},
|
||||||
|
|
||||||
[NEW_AUTH_ERR]: (state, { payload }) => {
|
[NEW_AUTH_ERR]: (state, { payload }) => {
|
||||||
let error = fromJS(Object.assign({}, payload))
|
let error = fromJS(Object.assign({}, payload))
|
||||||
|
|
||||||
|
|||||||
@@ -108,9 +108,6 @@ export default class HttpAuth extends React.Component {
|
|||||||
<Row>
|
<Row>
|
||||||
<Markdown source={ schema.get("description") } />
|
<Markdown source={ schema.get("description") } />
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
|
||||||
<p>In: <code>{ schema.get("in") }</code></p>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
<Row>
|
||||||
<label>Value:</label>
|
<label>Value:</label>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ RequestBody.propTypes = {
|
|||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
getConfigs: PropTypes.func.isRequired,
|
getConfigs: PropTypes.func.isRequired,
|
||||||
specSelectors: PropTypes.object.isRequired,
|
specSelectors: PropTypes.object.isRequired,
|
||||||
contentType: PropTypes.string.isRequired,
|
contentType: PropTypes.string,
|
||||||
isExecute: PropTypes.bool.isRequired,
|
isExecute: PropTypes.bool.isRequired,
|
||||||
onChange: PropTypes.func.isRequired
|
onChange: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ export const definitions = onlyOAS3(createSelector(
|
|||||||
spec => spec.getIn(["components", "schemas"]) || Map()
|
spec => spec.getIn(["components", "schemas"]) || Map()
|
||||||
))
|
))
|
||||||
|
|
||||||
|
export const hasHost = onlyOAS3((state) => {
|
||||||
|
return spec(state).hasIn(["servers", 0])
|
||||||
|
})
|
||||||
|
|
||||||
export const securityDefinitions = onlyOAS3(createSelector(
|
export const securityDefinitions = onlyOAS3(createSelector(
|
||||||
spec,
|
spec,
|
||||||
spec => spec.getIn(["components", "securitySchemes"]) || null
|
spec => spec.getIn(["components", "securitySchemes"]) || null
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class Parameters extends Component {
|
|||||||
specActions: PropTypes.object.isRequired,
|
specActions: PropTypes.object.isRequired,
|
||||||
operation: PropTypes.object.isRequired,
|
operation: PropTypes.object.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
|
getConfigs: PropTypes.func.isRequired,
|
||||||
specSelectors: PropTypes.object.isRequired,
|
specSelectors: PropTypes.object.isRequired,
|
||||||
oas3Actions: PropTypes.object.isRequired,
|
oas3Actions: PropTypes.object.isRequired,
|
||||||
oas3Selectors: PropTypes.object.isRequired,
|
oas3Selectors: PropTypes.object.isRequired,
|
||||||
@@ -86,6 +87,7 @@ class Parameters extends Component {
|
|||||||
|
|
||||||
fn,
|
fn,
|
||||||
getComponent,
|
getComponent,
|
||||||
|
getConfigs,
|
||||||
specSelectors,
|
specSelectors,
|
||||||
oas3Actions,
|
oas3Actions,
|
||||||
oas3Selectors,
|
oas3Selectors,
|
||||||
@@ -137,6 +139,7 @@ class Parameters extends Component {
|
|||||||
eachMap(parameters, (parameter) => (
|
eachMap(parameters, (parameter) => (
|
||||||
<ParameterRow fn={ fn }
|
<ParameterRow fn={ fn }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
|
getConfigs={ getConfigs }
|
||||||
param={ parameter }
|
param={ parameter }
|
||||||
key={ parameter.get( "name" ) }
|
key={ parameter.get( "name" ) }
|
||||||
onChange={ this.onChange }
|
onChange={ this.onChange }
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import auth from "core/plugins/auth"
|
|||||||
import util from "core/plugins/util"
|
import util from "core/plugins/util"
|
||||||
import SplitPaneModePlugin from "core/plugins/split-pane-mode"
|
import SplitPaneModePlugin from "core/plugins/split-pane-mode"
|
||||||
import downloadUrlPlugin from "core/plugins/download-url"
|
import downloadUrlPlugin from "core/plugins/download-url"
|
||||||
|
import configsPlugin from "plugins/configs"
|
||||||
import deepLinkingPlugin from "core/plugins/deep-linking"
|
import deepLinkingPlugin from "core/plugins/deep-linking"
|
||||||
|
|
||||||
import App from "core/components/app"
|
import App from "core/components/app"
|
||||||
@@ -52,6 +53,7 @@ import EnumModel from "core/components/enum-model"
|
|||||||
import ObjectModel from "core/components/object-model"
|
import ObjectModel from "core/components/object-model"
|
||||||
import ArrayModel from "core/components/array-model"
|
import ArrayModel from "core/components/array-model"
|
||||||
import PrimitiveModel from "core/components/primitive-model"
|
import PrimitiveModel from "core/components/primitive-model"
|
||||||
|
import Property from "core/components/property"
|
||||||
import TryItOutButton from "core/components/try-it-out-button"
|
import TryItOutButton from "core/components/try-it-out-button"
|
||||||
import VersionStamp from "core/components/version-stamp"
|
import VersionStamp from "core/components/version-stamp"
|
||||||
|
|
||||||
@@ -106,6 +108,7 @@ export default function() {
|
|||||||
ObjectModel,
|
ObjectModel,
|
||||||
ArrayModel,
|
ArrayModel,
|
||||||
PrimitiveModel,
|
PrimitiveModel,
|
||||||
|
Property,
|
||||||
TryItOutButton,
|
TryItOutButton,
|
||||||
Markdown,
|
Markdown,
|
||||||
BaseLayout,
|
BaseLayout,
|
||||||
@@ -122,6 +125,7 @@ export default function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
configsPlugin,
|
||||||
util,
|
util,
|
||||||
logs,
|
logs,
|
||||||
view,
|
view,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Im from "immutable"
|
import Im from "immutable"
|
||||||
|
import { sanitizeUrl as braintreeSanitizeUrl } from "@braintree/sanitize-url"
|
||||||
import camelCase from "lodash/camelCase"
|
import camelCase from "lodash/camelCase"
|
||||||
import upperFirst from "lodash/upperFirst"
|
import upperFirst from "lodash/upperFirst"
|
||||||
import _memoize from "lodash/memoize"
|
import _memoize from "lodash/memoize"
|
||||||
@@ -155,83 +155,6 @@ export function getList(iterable, keys) {
|
|||||||
return Im.List.isList(val) ? val : Im.List()
|
return Im.List.isList(val) ? val : Im.List()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapted from http://stackoverflow.com/a/2893259/454004
|
|
||||||
// Note: directly ported from CoffeeScript
|
|
||||||
export function formatXml (xml) {
|
|
||||||
var contexp, fn, formatted, indent, l, lastType, len, lines, ln, reg, transitions, wsexp
|
|
||||||
reg = /(>)(<)(\/*)/g
|
|
||||||
wsexp = /[ ]*(.*)[ ]+\n/g
|
|
||||||
contexp = /(<.+>)(.+\n)/g
|
|
||||||
xml = xml.replace(/\r\n/g, "\n").replace(reg, "$1\n$2$3").replace(wsexp, "$1\n").replace(contexp, "$1\n$2")
|
|
||||||
formatted = ""
|
|
||||||
lines = xml.split("\n")
|
|
||||||
indent = 0
|
|
||||||
lastType = "other"
|
|
||||||
transitions = {
|
|
||||||
"single->single": 0,
|
|
||||||
"single->closing": -1,
|
|
||||||
"single->opening": 0,
|
|
||||||
"single->other": 0,
|
|
||||||
"closing->single": 0,
|
|
||||||
"closing->closing": -1,
|
|
||||||
"closing->opening": 0,
|
|
||||||
"closing->other": 0,
|
|
||||||
"opening->single": 1,
|
|
||||||
"opening->closing": 0,
|
|
||||||
"opening->opening": 1,
|
|
||||||
"opening->other": 1,
|
|
||||||
"other->single": 0,
|
|
||||||
"other->closing": -1,
|
|
||||||
"other->opening": 0,
|
|
||||||
"other->other": 0
|
|
||||||
}
|
|
||||||
fn = function(ln) {
|
|
||||||
var fromTo, key, padding, type, types, value
|
|
||||||
types = {
|
|
||||||
single: Boolean(ln.match(/<.+\/>/)),
|
|
||||||
closing: Boolean(ln.match(/<\/.+>/)),
|
|
||||||
opening: Boolean(ln.match(/<[^!?].*>/))
|
|
||||||
}
|
|
||||||
type = ((function() {
|
|
||||||
var results
|
|
||||||
results = []
|
|
||||||
for (key in types) {
|
|
||||||
value = types[key]
|
|
||||||
if (value) {
|
|
||||||
results.push(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results
|
|
||||||
})())[0]
|
|
||||||
type = type === void 0 ? "other" : type
|
|
||||||
fromTo = lastType + "->" + type
|
|
||||||
lastType = type
|
|
||||||
padding = ""
|
|
||||||
indent += transitions[fromTo]
|
|
||||||
padding = ((function() {
|
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
var m, ref1, results, j
|
|
||||||
results = []
|
|
||||||
for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
|
|
||||||
results.push(" ")
|
|
||||||
}
|
|
||||||
/* eslint-enable no-unused-vars */
|
|
||||||
return results
|
|
||||||
})()).join("")
|
|
||||||
if (fromTo === "opening->closing") {
|
|
||||||
formatted = formatted.substr(0, formatted.length - 1) + ln + "\n"
|
|
||||||
} else {
|
|
||||||
formatted += padding + ln + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (l = 0, len = lines.length; l < len; l++) {
|
|
||||||
ln = lines[l]
|
|
||||||
fn(ln)
|
|
||||||
}
|
|
||||||
return formatted
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapted from http://github.com/asvd/microlight
|
* Adapted from http://github.com/asvd/microlight
|
||||||
* @copyright 2016 asvd <heliosframework@gmail.com>
|
* @copyright 2016 asvd <heliosframework@gmail.com>
|
||||||
@@ -536,6 +459,13 @@ export const validateMinLength = (val, min) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const validatePattern = (val, rxPattern) => {
|
||||||
|
var patt = new RegExp(rxPattern)
|
||||||
|
if (!patt.test(val)) {
|
||||||
|
return "Value must follow pattern " + rxPattern
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// validation of parameters before execute
|
// validation of parameters before execute
|
||||||
export const validateParam = (param, isXml, isOAS3 = false) => {
|
export const validateParam = (param, isXml, isOAS3 = false) => {
|
||||||
let errors = []
|
let errors = []
|
||||||
@@ -549,6 +479,8 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
|||||||
let format = paramDetails.get("format")
|
let format = paramDetails.get("format")
|
||||||
let maxLength = paramDetails.get("maxLength")
|
let maxLength = paramDetails.get("maxLength")
|
||||||
let minLength = paramDetails.get("minLength")
|
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)
|
If the parameter is required OR the parameter has a value (meaning optional, but filled in)
|
||||||
@@ -556,15 +488,25 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
|||||||
Only bother validating the parameter if the type was specified.
|
Only bother validating the parameter if the type was specified.
|
||||||
*/
|
*/
|
||||||
if ( type && (required || value) ) {
|
if ( type && (required || value) ) {
|
||||||
// These checks should evaluate to true if the parameter's value is valid
|
// These checks should evaluate to true if there is a parameter
|
||||||
let stringCheck = type === "string" && value && !validateString(value)
|
let stringCheck = type === "string" && value
|
||||||
let arrayCheck = type === "array" && Array.isArray(value) && value.length
|
let arrayCheck = type === "array" && Array.isArray(value) && value.length
|
||||||
let listCheck = type === "array" && Im.List.isList(value) && value.count()
|
let listCheck = type === "array" && Im.List.isList(value) && value.count()
|
||||||
let fileCheck = type === "file" && value instanceof win.File
|
let fileCheck = type === "file" && value instanceof win.File
|
||||||
let booleanCheck = type === "boolean" && !validateBoolean(value)
|
let booleanCheck = type === "boolean" && (value || value === false)
|
||||||
let numberCheck = type === "number" && !validateNumber(value) // validateNumber returns undefined if the value is a number
|
let numberCheck = type === "number" && (value || value === 0)
|
||||||
let integerCheck = type === "integer" && !validateInteger(value) // validateInteger returns undefined if the value is an integer
|
let integerCheck = type === "integer" && (value || value === 0)
|
||||||
|
|
||||||
|
if ( required && !(stringCheck || arrayCheck || listCheck || fileCheck || booleanCheck || numberCheck || integerCheck) ) {
|
||||||
|
errors.push("Required field is not provided")
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pattern) {
|
||||||
|
let err = validatePattern(value, pattern)
|
||||||
|
if (err) errors.push(err)
|
||||||
|
}
|
||||||
|
|
||||||
if (maxLength || maxLength === 0) {
|
if (maxLength || maxLength === 0) {
|
||||||
let err = validateMaxLength(value, maxLength)
|
let err = validateMaxLength(value, maxLength)
|
||||||
if (err) errors.push(err)
|
if (err) errors.push(err)
|
||||||
@@ -575,11 +517,6 @@ export const validateParam = (param, isXml, isOAS3 = false) => {
|
|||||||
if (err) errors.push(err)
|
if (err) errors.push(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( required && !(stringCheck || arrayCheck || listCheck || fileCheck || booleanCheck || numberCheck || integerCheck) ) {
|
|
||||||
errors.push("Required field is not provided")
|
|
||||||
return errors
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maximum || maximum === 0) {
|
if (maximum || maximum === 0) {
|
||||||
let err = validateMaximum(value, maximum)
|
let err = validateMaximum(value, maximum)
|
||||||
if (err) errors.push(err)
|
if (err) errors.push(err)
|
||||||
@@ -722,6 +659,14 @@ export const shallowEqualKeys = (a,b, keys) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sanitizeUrl(url) {
|
||||||
|
if(typeof url !== "string" || url === "") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return braintreeSanitizeUrl(url)
|
||||||
|
}
|
||||||
|
|
||||||
export function getAcceptControllingResponse(responses) {
|
export function getAcceptControllingResponse(responses) {
|
||||||
if(!Im.OrderedMap.isOrderedMap(responses)) {
|
if(!Im.OrderedMap.isOrderedMap(responses)) {
|
||||||
// wrong type!
|
// wrong type!
|
||||||
|
|||||||
20
src/plugins/configs/actions.js
Normal file
20
src/plugins/configs/actions.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export const UPDATE_CONFIGS = "configs_update"
|
||||||
|
export const TOGGLE_CONFIGS = "configs_toggle"
|
||||||
|
|
||||||
|
// Update the configs, with a merge ( not deep )
|
||||||
|
export function update(configName, configValue) {
|
||||||
|
return {
|
||||||
|
type: UPDATE_CONFIGS,
|
||||||
|
payload: {
|
||||||
|
[configName]: configValue
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle's the config, by name
|
||||||
|
export function toggle(configName) {
|
||||||
|
return {
|
||||||
|
type: TOGGLE_CONFIGS,
|
||||||
|
payload: configName,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,56 +1,66 @@
|
|||||||
import YAML from "js-yaml"
|
import YAML from "js-yaml"
|
||||||
import yamlConfig from "../../../swagger-config.yaml"
|
import yamlConfig from "../../../swagger-config.yaml"
|
||||||
|
import * as actions from "./actions"
|
||||||
|
import * as selectors from "./selectors"
|
||||||
|
import reducers from "./reducers"
|
||||||
|
|
||||||
const parseYamlConfig = (yaml, system) => {
|
const parseYamlConfig = (yaml, system) => {
|
||||||
try {
|
try {
|
||||||
return YAML.safeLoad(yaml)
|
return YAML.safeLoad(yaml)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (system) {
|
if (system) {
|
||||||
system.errActions.newThrownErr( new Error(e) )
|
system.errActions.newThrownErr( new Error(e) )
|
||||||
}
|
|
||||||
return {}
|
|
||||||
}
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function configPlugin (toolbox) {
|
const specActions = {
|
||||||
let { fn } = toolbox
|
downloadConfig: (url) => ({fn}) => {
|
||||||
|
let {fetch} = fn
|
||||||
const actions = {
|
return fetch(url)
|
||||||
downloadConfig: (url) => () => {
|
},
|
||||||
let {fetch} = fn
|
|
||||||
return fetch(url)
|
|
||||||
},
|
|
||||||
|
|
||||||
getConfigByUrl: (configUrl, cb)=> ({ specActions }) => {
|
|
||||||
if (configUrl) {
|
|
||||||
return specActions.downloadConfig(configUrl).then(next, next)
|
|
||||||
}
|
|
||||||
|
|
||||||
function next(res) {
|
|
||||||
if (res instanceof Error || res.status >= 400) {
|
|
||||||
specActions.updateLoadingStatus("failedConfig")
|
|
||||||
specActions.updateLoadingStatus("failedConfig")
|
|
||||||
specActions.updateUrl("")
|
|
||||||
console.error(res.statusText + " " + configUrl)
|
|
||||||
cb(null)
|
|
||||||
} else {
|
|
||||||
cb(parseYamlConfig(res.text))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
getConfigByUrl: (configUrl, cb)=> ({ specActions }) => {
|
||||||
|
if (configUrl) {
|
||||||
|
return specActions.downloadConfig(configUrl).then(next, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectors = {
|
function next(res) {
|
||||||
getLocalConfig: () => {
|
if (res instanceof Error || res.status >= 400) {
|
||||||
return parseYamlConfig(yamlConfig)
|
specActions.updateLoadingStatus("failedConfig")
|
||||||
}
|
specActions.updateLoadingStatus("failedConfig")
|
||||||
}
|
specActions.updateUrl("")
|
||||||
|
console.error(res.statusText + " " + configUrl)
|
||||||
return {
|
cb(null)
|
||||||
statePlugins: {
|
} else {
|
||||||
spec: { actions, selectors }
|
cb(parseYamlConfig(res.text))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const specSelectors = {
|
||||||
|
getLocalConfig: () => {
|
||||||
|
return parseYamlConfig(yamlConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function configsPlugin() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
statePlugins: {
|
||||||
|
spec: {
|
||||||
|
actions: specActions,
|
||||||
|
selectors: specSelectors,
|
||||||
|
},
|
||||||
|
configs: {
|
||||||
|
reducers,
|
||||||
|
actions,
|
||||||
|
selectors,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/plugins/configs/reducers.js
Normal file
20
src/plugins/configs/reducers.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { fromJS } from "immutable"
|
||||||
|
|
||||||
|
import {
|
||||||
|
UPDATE_CONFIGS,
|
||||||
|
TOGGLE_CONFIGS,
|
||||||
|
} from "./actions"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
[UPDATE_CONFIGS]: (state, action) => {
|
||||||
|
return state.merge(fromJS(action.payload))
|
||||||
|
},
|
||||||
|
|
||||||
|
[TOGGLE_CONFIGS]: (state, action) => {
|
||||||
|
const configName = action.payload
|
||||||
|
const oriVal = state.get(configName)
|
||||||
|
return state.set(configName, !oriVal)
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
4
src/plugins/configs/selectors.js
Normal file
4
src/plugins/configs/selectors.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Just get the config value ( it can possibly be an immutable object)
|
||||||
|
export const get = (state, path) => {
|
||||||
|
return state.getIn(Array.isArray(path) ? path : [path])
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from "react"
|
import React, { cloneElement } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
//import "./topbar.less"
|
//import "./topbar.less"
|
||||||
@@ -134,7 +134,7 @@ export default class Topbar extends React.Component {
|
|||||||
<span>swagger</span>
|
<span>swagger</span>
|
||||||
</Link>
|
</Link>
|
||||||
<form className="download-url-wrapper" onSubmit={formOnSubmit}>
|
<form className="download-url-wrapper" onSubmit={formOnSubmit}>
|
||||||
{control}
|
{control.map((el, i) => cloneElement(el, { key: i }))}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
|
|
||||||
border-bottom: 1px solid #ebebeb;
|
border-bottom: 1px solid $auth-container-border-color;
|
||||||
|
|
||||||
&:last-of-type
|
&:last-of-type
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
transition: all .3s;
|
transition: all .3s;
|
||||||
|
|
||||||
border: 2px solid #888;
|
border: 2px solid $btn-border-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
box-shadow: 0 1px 2px rgba(#000,.1);
|
box-shadow: 0 1px 2px rgba($btn-box-shadow-color,.1);
|
||||||
|
|
||||||
@include text_headline();
|
@include text_headline();
|
||||||
|
|
||||||
@@ -29,14 +29,14 @@
|
|||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
{
|
{
|
||||||
box-shadow: 0 0 5px rgba(#000,.3);
|
box-shadow: 0 0 5px rgba($btn-box-shadow-color,.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.cancel
|
&.cancel
|
||||||
{
|
{
|
||||||
border-color: #ff6060;
|
border-color: $btn-cancel-border-color;
|
||||||
|
background-color: $btn-cancel-background-color;
|
||||||
@include text_headline(#ff6060);
|
@include text_headline($btn-cancel-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.authorize
|
&.authorize
|
||||||
@@ -45,9 +45,9 @@
|
|||||||
|
|
||||||
display: inline;
|
display: inline;
|
||||||
|
|
||||||
color: $_color-post;
|
color: $btn-authorize-font-color;
|
||||||
border-color: $_color-post;
|
border-color: $btn-authorize-border-color;
|
||||||
|
background-color: $btn-authorize-background-color;
|
||||||
|
|
||||||
span
|
span
|
||||||
{
|
{
|
||||||
@@ -58,16 +58,17 @@
|
|||||||
|
|
||||||
svg
|
svg
|
||||||
{
|
{
|
||||||
fill: $_color-post;
|
fill: $btn-authorize-svg-fill-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.execute
|
&.execute
|
||||||
{
|
{
|
||||||
animation: swagger-ui-pulse 2s infinite;
|
animation: swagger-ui-pulse 2s infinite;
|
||||||
|
will-change: transform;
|
||||||
color: #fff;
|
background-color: $btn-execute-background-color;
|
||||||
border-color: #4990e2;
|
color: $btn-execute-font-color;
|
||||||
|
border-color: $btn-execute-border-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,21 +77,19 @@
|
|||||||
{
|
{
|
||||||
0%
|
0%
|
||||||
{
|
{
|
||||||
color: #fff;
|
color: $btn-execute-font-color;
|
||||||
background: #4990e2;
|
background: $btn-execute-background-color-alt;
|
||||||
box-shadow: 0 0 0 0 rgba(#4990e2, .8);
|
box-shadow: 0 0 0 0 rgba($btn-execute-background-color-alt, .8);
|
||||||
}
|
}
|
||||||
70%
|
70%
|
||||||
{
|
{
|
||||||
//color: #4990e2;
|
box-shadow: 0 0 0 5px rgba($btn-execute-background-color-alt, 0);
|
||||||
//background: transparent;
|
|
||||||
box-shadow: 0 0 0 5px rgba(#4990e2, 0);
|
|
||||||
}
|
}
|
||||||
100%
|
100%
|
||||||
{
|
{
|
||||||
color: #fff;
|
color: $btn-execute-font-color;
|
||||||
background: #4990e2;
|
background: $btn-execute-background-color-alt;
|
||||||
box-shadow: 0 0 0 0 rgba(#4990e2, 0);
|
box-shadow: 0 0 0 0 rgba($btn-execute-background-color-alt, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +154,7 @@
|
|||||||
{
|
{
|
||||||
svg
|
svg
|
||||||
{
|
{
|
||||||
fill: #444;
|
fill: $expand-methods-svg-fill-color-hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +162,7 @@
|
|||||||
{
|
{
|
||||||
transition: all .3s;
|
transition: all .3s;
|
||||||
|
|
||||||
fill: #777;
|
fill: $expand-methods-svg-fill-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
small
|
small
|
||||||
{
|
{
|
||||||
color: #666;
|
color: $errors-wrapper-errors-small-font-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ select
|
|||||||
|
|
||||||
padding: 5px 40px 5px 10px;
|
padding: 5px 40px 5px 10px;
|
||||||
|
|
||||||
border: 2px solid #41444e;
|
border: 2px solid $form-select-border-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #f7f7f7 url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+ICAgIDxwYXRoIGQ9Ik0xMy40MTggNy44NTljLjI3MS0uMjY4LjcwOS0uMjY4Ljk3OCAwIC4yNy4yNjguMjcyLjcwMSAwIC45NjlsLTMuOTA4IDMuODNjLS4yNy4yNjgtLjcwNy4yNjgtLjk3OSAwbC0zLjkwOC0zLjgzYy0uMjctLjI2Ny0uMjctLjcwMSAwLS45NjkuMjcxLS4yNjguNzA5LS4yNjguOTc4IDBMMTAgMTFsMy40MTgtMy4xNDF6Ii8+PC9zdmc+) right 10px center no-repeat;
|
background: $form-select-background-color url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+ICAgIDxwYXRoIGQ9Ik0xMy40MTggNy44NTljLjI3MS0uMjY4LjcwOS0uMjY4Ljk3OCAwIC4yNy4yNjguMjcyLjcwMSAwIC45NjlsLTMuOTA4IDMuODNjLS4yNy4yNjgtLjcwNy4yNjgtLjk3OSAwbC0zLjkwOC0zLjgzYy0uMjctLjI2Ny0uMjctLjcwMSAwLS45NjkuMjcxLS4yNjguNzA5LS4yNjguOTc4IDBMMTAgMTFsMy40MTgtMy4xNDF6Ii8+PC9zdmc+) right 10px center no-repeat;
|
||||||
background-size: 20px;
|
background-size: 20px;
|
||||||
box-shadow: 0 1px 2px 0 rgba(0,0,0,.25);
|
box-shadow: 0 1px 2px 0 rgba($form-select-box-shadow-color, .25);
|
||||||
|
|
||||||
@include text_headline();
|
@include text_headline();
|
||||||
appearance: none;
|
appearance: none;
|
||||||
@@ -19,7 +19,7 @@ select
|
|||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
|
||||||
background: #f7f7f7;
|
background: $form-select-background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.invalid {
|
&.invalid {
|
||||||
@@ -57,9 +57,9 @@ input[type=file]
|
|||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
|
|
||||||
border: 1px solid #d9d9d9;
|
border: 1px solid $form-input-border-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #fff;
|
background: $form-input-background-color;
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
max-width: 175px;
|
max-width: 175px;
|
||||||
}
|
}
|
||||||
@@ -110,13 +110,13 @@ textarea
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
outline: none;
|
outline: none;
|
||||||
background: rgba(#fff,.8);
|
background: rgba($form-textarea-background-color,.8);
|
||||||
|
|
||||||
@include text_code();
|
@include text_code();
|
||||||
|
|
||||||
&:focus
|
&:focus
|
||||||
{
|
{
|
||||||
border: 2px solid $_color-get;
|
border: 2px solid $form-textarea-focus-border-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.curl
|
&.curl
|
||||||
@@ -130,9 +130,9 @@ textarea
|
|||||||
resize: none;
|
resize: none;
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #41444e;
|
background: $form-textarea-curl-background-color;
|
||||||
|
|
||||||
@include text_code(#fff);
|
@include text_code($form-textarea-curl-font-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ textarea
|
|||||||
|
|
||||||
transition: opacity .5s;
|
transition: opacity .5s;
|
||||||
|
|
||||||
color: #333;
|
color: $form-checkbox-label-font-color;
|
||||||
|
|
||||||
label
|
label
|
||||||
{
|
{
|
||||||
@@ -179,8 +179,8 @@ textarea
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
background: #e8e8e8;
|
background: $form-checkbox-background-color;
|
||||||
box-shadow: 0 0 0 2px #e8e8e8;
|
box-shadow: 0 0 0 2px $form-checkbox-box-shadow-color;
|
||||||
|
|
||||||
flex: none;
|
flex: none;
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ textarea
|
|||||||
|
|
||||||
&:checked + label > .item
|
&:checked + label > .item
|
||||||
{
|
{
|
||||||
background: #e8e8e8 url(data:image/svg+xml,%0A%3Csvg%20width%3D%2210px%22%20height%3D%228px%22%20viewBox%3D%223%207%2010%208%22%20version%3D%221.1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%3E%0A%20%20%20%20%3C%21--%20Generator%3A%20Sketch%2042%20%2836781%29%20-%20http%3A//www.bohemiancoding.com/sketch%20--%3E%0A%20%20%20%20%3Cdesc%3ECreated%20with%20Sketch.%3C/desc%3E%0A%20%20%20%20%3Cdefs%3E%3C/defs%3E%0A%20%20%20%20%3Cpolygon%20id%3D%22Rectangle-34%22%20stroke%3D%22none%22%20fill%3D%22%2341474E%22%20fill-rule%3D%22evenodd%22%20points%3D%226.33333333%2015%203%2011.6666667%204.33333333%2010.3333333%206.33333333%2012.3333333%2011.6666667%207%2013%208.33333333%22%3E%3C/polygon%3E%0A%3C/svg%3E) center center no-repeat;
|
background: $form-checkbox-background-color url(data:image/svg+xml,%0A%3Csvg%20width%3D%2210px%22%20height%3D%228px%22%20viewBox%3D%223%207%2010%208%22%20version%3D%221.1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%3E%0A%20%20%20%20%3C%21--%20Generator%3A%20Sketch%2042%20%2836781%29%20-%20http%3A//www.bohemiancoding.com/sketch%20--%3E%0A%20%20%20%20%3Cdesc%3ECreated%20with%20Sketch.%3C/desc%3E%0A%20%20%20%20%3Cdefs%3E%3C/defs%3E%0A%20%20%20%20%3Cpolygon%20id%3D%22Rectangle-34%22%20stroke%3D%22none%22%20fill%3D%22%2341474E%22%20fill-rule%3D%22evenodd%22%20points%3D%226.33333333%2015%203%2011.6666667%204.33333333%2010.3333333%206.33333333%2012.3333333%2011.6666667%207%2013%208.33333333%22%3E%3C/polygon%3E%0A%3C/svg%3E) center center no-repeat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
padding: 3px 5px;
|
padding: 3px 5px;
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(#000,.05);
|
background: rgba($info-code-background-color,.05);
|
||||||
|
|
||||||
@include text_code(#9012fe);
|
@include text_code($info-code-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
a
|
a
|
||||||
@@ -41,11 +41,11 @@
|
|||||||
|
|
||||||
transition: all .4s;
|
transition: all .4s;
|
||||||
|
|
||||||
@include text_body(#4990e2);
|
@include text_body($info-link-font-color);
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
{
|
{
|
||||||
color: darken(#4990e2, 15%);
|
color: darken($info-link-font-color-hover, 15%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
> div
|
> div
|
||||||
@@ -86,13 +86,13 @@
|
|||||||
vertical-align: super;
|
vertical-align: super;
|
||||||
|
|
||||||
border-radius: 57px;
|
border-radius: 57px;
|
||||||
background: #7d8492;
|
background: $info-title-small-background-color;
|
||||||
|
|
||||||
pre
|
pre
|
||||||
{
|
{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
@include text_headline(#fff);
|
@include text_headline($info-title-small-pre-font-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,11 +34,11 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
|
|
||||||
border-bottom: 1px solid rgba(#3b4151, .3);
|
border-bottom: 1px solid rgba($opblock-tag-border-bottom-color, .3);
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
{
|
{
|
||||||
background: rgba(#000,.02);
|
background: rgba($opblock-tag-background-color-hover,.02);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,9 +127,9 @@
|
|||||||
{
|
{
|
||||||
margin: 0 0 15px 0;
|
margin: 0 0 15px 0;
|
||||||
|
|
||||||
border: 1px solid #000;
|
border: 1px solid $opblock-border-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 3px rgba(#000,.19);
|
box-shadow: 0 0 3px rgba($opblock-box-shadow-color,.19);
|
||||||
|
|
||||||
.tab-header
|
.tab-header
|
||||||
{
|
{
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
content: '';
|
content: '';
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
|
|
||||||
background: #888;
|
background: $opblock-tab-header-tab-item-active-h4-span-after-background-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
{
|
{
|
||||||
.opblock-summary
|
.opblock-summary
|
||||||
{
|
{
|
||||||
border-bottom: 1px solid #000;
|
border-bottom: 1px solid $opblock-isopen-summary-border-bottom-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,8 +194,8 @@
|
|||||||
|
|
||||||
min-height: 50px;
|
min-height: 50px;
|
||||||
|
|
||||||
background: rgba(#fff,.8);
|
background: rgba($opblock-isopen-section-header-background-color,.8);
|
||||||
box-shadow: 0 1px 2px rgba(#000,.1);
|
box-shadow: 0 1px 2px rgba($opblock-isopen-section-header-box-shadow-color,.1);
|
||||||
|
|
||||||
label
|
label
|
||||||
{
|
{
|
||||||
@@ -239,10 +239,10 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: #000;
|
background: $opblock-summary-method-background-color;
|
||||||
text-shadow: 0 1px 0 rgba(#000,.1);
|
text-shadow: 0 1px 0 rgba($opblock-summary-method-text-shadow-color,.1);
|
||||||
|
|
||||||
@include text_headline(#fff);
|
@include text_headline($opblock-summary-method-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.opblock-summary-path,
|
.opblock-summary-path,
|
||||||
@@ -377,7 +377,7 @@
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
padding: 10px 10px;
|
padding: 10px 10px;
|
||||||
|
|
||||||
border: 2px solid #d8dde7;
|
border: 2px solid $operational-filter-input-border-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +420,7 @@
|
|||||||
|
|
||||||
content: '';
|
content: '';
|
||||||
|
|
||||||
background: rgba(#000,.2);
|
background: rgba($tab-list-item-first-background-color,.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +525,7 @@
|
|||||||
{
|
{
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
|
||||||
@include text_code(#999);
|
@include text_code($response-col-status-undocumented-font-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +541,7 @@
|
|||||||
{
|
{
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
|
||||||
@include text_code(#999);
|
@include text_code($response-col-links-font-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,9 +558,9 @@
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #41444e;
|
background: $response-col-description-inner-markdown-background-color;
|
||||||
|
|
||||||
@include text_code(#fff);
|
@include text_code($response-col-description-inner-markdown-font-color);
|
||||||
|
|
||||||
p
|
p
|
||||||
{
|
{
|
||||||
@@ -569,10 +569,10 @@
|
|||||||
|
|
||||||
a
|
a
|
||||||
{
|
{
|
||||||
@include text_code(#89bf04);
|
@include text_code($response-col-description-inner-markdown-link-font-color);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #81b10c;
|
color: $response-col-description-inner-markdown-link-font-color-hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -593,13 +593,13 @@
|
|||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #41444e;
|
background: $opblock-body-background-color;
|
||||||
|
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
@include text_code(#fff);
|
@include text_code($opblock-body-font-color);
|
||||||
span
|
span
|
||||||
{
|
{
|
||||||
color: #fff !important;
|
color: $opblock-body-font-color !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.headerline
|
.headerline
|
||||||
@@ -613,8 +613,8 @@
|
|||||||
margin: 0 0 20px 0;
|
margin: 0 0 20px 0;
|
||||||
padding: 30px 0;
|
padding: 30px 0;
|
||||||
|
|
||||||
background: #fff;
|
background: $scheme-container-background-color;
|
||||||
box-shadow: 0 1px 2px 0 rgba(0,0,0,.15);
|
box-shadow: 0 1px 2px 0 rgba($scheme-container-box-shadow-color,.15);
|
||||||
|
|
||||||
.schemes
|
.schemes
|
||||||
{
|
{
|
||||||
@@ -648,14 +648,14 @@
|
|||||||
margin: 0 0 20px 0;
|
margin: 0 0 20px 0;
|
||||||
padding: 30px 0;
|
padding: 30px 0;
|
||||||
|
|
||||||
background: #fff;
|
background: $server-container-background-color;
|
||||||
box-shadow: 0 1px 2px 0 rgba(0,0,0,.15);
|
box-shadow: 0 1px 2px 0 rgba($server-container-box-shadow-color,.15);
|
||||||
|
|
||||||
.computed-url {
|
.computed-url {
|
||||||
margin: 2em 0;
|
margin: 2em 0;
|
||||||
|
|
||||||
code {
|
code {
|
||||||
color: grey;
|
color: $server-container-computed-url-code-font-color;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@@ -755,8 +755,8 @@
|
|||||||
animation: rotation 1s infinite linear, opacity .5s;
|
animation: rotation 1s infinite linear, opacity .5s;
|
||||||
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
border: 2px solid rgba(#555, .1);
|
border: 2px solid rgba($loading-container-before-border-color, .1);
|
||||||
border-top-color: rgba(#000, .6);
|
border-top-color: rgba($loading-container-before-border-top-color, .6);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
|
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
@@ -777,11 +777,11 @@
|
|||||||
|
|
||||||
&.controls-accept-header {
|
&.controls-accept-header {
|
||||||
select {
|
select {
|
||||||
border-color: green;
|
border-color: $response-content-type-controls-accept-header-select-border-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small {
|
||||||
color: green;
|
color: $response-content-type-controls-accept-header-small-font-color;
|
||||||
font-size: .7em;
|
font-size: .7em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
||||||
background: rgba(#000,.8);
|
background: rgba($dialog-ux-backdrop-background-color,.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-ux
|
.modal-ux
|
||||||
@@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
transform: translate(-50%,-50%);
|
transform: translate(-50%,-50%);
|
||||||
|
|
||||||
border: 1px solid #ebebeb;
|
border: 1px solid $dialog-ux-modal-border-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #fff;
|
background: $dialog-ux-modal-background-color;
|
||||||
box-shadow: 0 10px 30px 0 rgba(0,0,0,.20);
|
box-shadow: 0 10px 30px 0 rgba($dialog-ux-modal-box-shadow-color,.20);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-ux-content
|
.modal-ux-content
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
margin: 0 0 5px 0;
|
margin: 0 0 5px 0;
|
||||||
|
|
||||||
color: #41444e;
|
color: $dialog-ux-modal-content-font-color;
|
||||||
|
|
||||||
@include text_body();
|
@include text_body();
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
padding: 12px 0;
|
padding: 12px 0;
|
||||||
|
|
||||||
border-bottom: 1px solid #ebebeb;
|
border-bottom: 1px solid $dialog-ux-modal-header-border-bottom-color;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,16 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
|
|
||||||
|
@include text_code();
|
||||||
|
|
||||||
.deprecated
|
.deprecated
|
||||||
{
|
{
|
||||||
span, td {
|
span,
|
||||||
color: #aaa !important;
|
td
|
||||||
}
|
{
|
||||||
|
color: $model-deprecated-font-color !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include text_code();
|
|
||||||
&-toggle
|
&-toggle
|
||||||
{
|
{
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
@@ -82,12 +84,13 @@
|
|||||||
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
color: #ebebeb;
|
color: $model-hint-font-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(#000,.7);
|
background: rgba($model-hint-background-color,.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p
|
||||||
|
{
|
||||||
margin: 0 0 1em 0;
|
margin: 0 0 1em 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +100,7 @@ section.models
|
|||||||
{
|
{
|
||||||
margin: 30px 0;
|
margin: 30px 0;
|
||||||
|
|
||||||
border: 1px solid rgba(#3b4151, .3);
|
border: 1px solid rgba($section-models-border-color, .3);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
&.is-open
|
&.is-open
|
||||||
@@ -106,7 +109,8 @@ section.models
|
|||||||
h4
|
h4
|
||||||
{
|
{
|
||||||
margin: 0 0 5px 0;
|
margin: 0 0 5px 0;
|
||||||
border-bottom: 1px solid rgba(#3b4151, .3);
|
|
||||||
|
border-bottom: 1px solid rgba($section-models-isopen-h4-border-bottom-color, .3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h4
|
h4
|
||||||
@@ -114,6 +118,7 @@ section.models
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 10px 20px 10px 10px;
|
padding: 10px 20px 10px 10px;
|
||||||
@@ -121,8 +126,7 @@ section.models
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
|
|
||||||
@include text_headline(#777);
|
@include text_headline($section-models-h4-font-color);
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
svg
|
svg
|
||||||
{
|
{
|
||||||
@@ -136,7 +140,7 @@ section.models
|
|||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
{
|
{
|
||||||
background: rgba(#000,.02);
|
background: rgba($section-models-h4-background-color-hover,.02);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +150,7 @@ section.models
|
|||||||
|
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
|
|
||||||
@include text_headline(#777);
|
@include text_headline($section-models-h5-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.model-jump-to-path
|
.model-jump-to-path
|
||||||
@@ -162,11 +166,11 @@ section.models
|
|||||||
transition: all .5s;
|
transition: all .5s;
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(#000,.05);
|
background: rgba($section-models-model-container-background-color,.05);
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
{
|
{
|
||||||
background: rgba(#000,.07);
|
background: rgba($section-models-model-container-background-color,.07);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:first-of-type
|
&:first-of-type
|
||||||
@@ -192,7 +196,7 @@ section.models
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(#000,.1);
|
background: rgba($section-models-model-box-background-color,.1);
|
||||||
|
|
||||||
.model-jump-to-path
|
.model-jump-to-path
|
||||||
{
|
{
|
||||||
@@ -202,7 +206,7 @@ section.models
|
|||||||
|
|
||||||
&.deprecated
|
&.deprecated
|
||||||
{
|
{
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,21 +215,23 @@ section.models
|
|||||||
{
|
{
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
||||||
@include text_headline(#555);
|
@include text_headline($section-models-model-title-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.model-deprecated-warning
|
.model-deprecated-warning
|
||||||
{
|
{
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
|
|
||||||
@include text_headline($_color-delete);
|
@include text_headline($_color-delete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
span
|
span
|
||||||
{
|
{
|
||||||
> span.model
|
> span.model
|
||||||
{
|
{
|
||||||
.brace-close
|
.brace-close
|
||||||
{
|
{
|
||||||
@@ -237,13 +243,13 @@ span
|
|||||||
.prop-name
|
.prop-name
|
||||||
{
|
{
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
width: 8em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.prop-type
|
.prop-type
|
||||||
{
|
{
|
||||||
color: #55a;
|
color: $prop-type-font-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prop-enum
|
.prop-enum
|
||||||
@@ -252,5 +258,5 @@ span
|
|||||||
}
|
}
|
||||||
.prop-format
|
.prop-format
|
||||||
{
|
{
|
||||||
color: #999;
|
color: $prop-format-font-color;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ table
|
|||||||
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
border-bottom: 1px solid rgba(#3b4151, .2);
|
border-bottom: 1px solid rgba($table-thead-td-border-bottom-color, .2);
|
||||||
|
|
||||||
@include text_body();
|
@include text_body();
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ table
|
|||||||
|
|
||||||
content: 'required';
|
content: 'required';
|
||||||
|
|
||||||
color: rgba(#f00, .6);
|
color: rgba($table-parameter-name-required-font-color, .6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ table
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
|
||||||
@include text_code(#888);
|
@include text_code($table-parameter-in-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.parameter__deprecated
|
.parameter__deprecated
|
||||||
@@ -144,7 +144,7 @@ table
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
|
||||||
@include text_code(#f00);
|
@include text_code($table-parameter-deprecated-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
padding: 8px 0;
|
padding: 8px 0;
|
||||||
|
|
||||||
background-color: #89bf04;
|
background-color: $topbar-background-color;
|
||||||
.topbar-wrapper
|
.topbar-wrapper
|
||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
@include text_headline(#fff);
|
@include text_headline($topbar-link-font-color);
|
||||||
|
|
||||||
span
|
span
|
||||||
{
|
{
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
border: 2px solid #547f00;
|
border: 2px solid $topbar-download-url-wrapper-element-border-color;
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
border: 2px solid #547f00;
|
border: 2px solid $topbar-download-url-wrapper-element-border-color;
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
@@ -87,9 +87,9 @@
|
|||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0 4px 4px 0;
|
border-radius: 0 4px 4px 0;
|
||||||
background: #547f00;
|
background: $topbar-download-url-button-background-color;
|
||||||
|
|
||||||
@include text_headline(#fff);
|
@include text_headline($topbar-download-url-button-font-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
@mixin text_body($color: #3b4151)
|
@mixin text_body($color: $text-body-default-font-color)
|
||||||
{
|
{
|
||||||
font-family: 'Open Sans', sans-serif;
|
font-family: 'Open Sans', sans-serif;
|
||||||
|
|
||||||
color: $color;
|
color: $color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin text_code($color: #3b4151)
|
@mixin text_code($color: $text-code-default-font-color)
|
||||||
{
|
{
|
||||||
font-family: 'Source Code Pro', monospace;
|
font-family: 'Source Code Pro', monospace;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
color: $color;
|
color: $color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin text_headline($color: #3b4151)
|
@mixin text_headline($color: $text-headline-default-font-color)
|
||||||
{
|
{
|
||||||
font-family: 'Titillium Web', sans-serif;
|
font-family: 'Titillium Web', sans-serif;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,218 @@
|
|||||||
|
|
||||||
|
$gray-base: #000 !default;
|
||||||
|
$white: #fff !default;
|
||||||
|
$gray-50: #ebebeb !default;
|
||||||
|
$gray-100: #d8dde7 !default;
|
||||||
|
$gray-200: lighten($gray-base, 62.75%) !default; // #aaa
|
||||||
|
$gray-300: lighten($gray-base, 56.5%) !default; // #999
|
||||||
|
$gray-400: lighten($gray-base, 50%) !default; // #888
|
||||||
|
$gray-500: lighten($gray-base, 43.75%) !default; // #777
|
||||||
|
$gray-600: lighten($gray-base, 37.5%) !default; // #666
|
||||||
|
$gray-650: lighten($gray-base, 33.3%) !default; // ##555555
|
||||||
|
$gray-700: lighten($gray-base, 31.25%) !default; // #555
|
||||||
|
$gray-800: lighten($gray-base, 25%) !default; // #444
|
||||||
|
$gray-900: lighten($gray-base, 18.75%) !default; // #333
|
||||||
|
|
||||||
|
$gray-custom-1: #41444e !default;
|
||||||
|
$gray-custom-2: #3b4151 !default;
|
||||||
|
|
||||||
|
$color-primary: #89bf04 !default;
|
||||||
|
$color-secondary: #9012fe !default;
|
||||||
|
$color-info: #4990e2 !default;
|
||||||
|
$color-warning: #ff6060 !default;
|
||||||
|
$color-danger: #f00 !default;
|
||||||
|
|
||||||
|
$_color-post: #49cc90 !default;
|
||||||
|
$_color-get: #61affe !default;
|
||||||
|
$_color-put: #fca130 !default;
|
||||||
|
$_color-delete: #f93e3e !default;
|
||||||
|
$_color-head: #9012fe !default;
|
||||||
|
$_color-patch: #50e3c2 !default;
|
||||||
|
$_color-disabled: #ebebeb !default;
|
||||||
|
$_color-options: #0d5aa7 !default;
|
||||||
|
|
||||||
|
$color-green: #008000 !default;
|
||||||
|
|
||||||
|
$color-primary-hover: #81b10c !default;
|
||||||
|
|
||||||
|
// Authorize
|
||||||
|
|
||||||
|
$auth-container-border-color: $gray-50 !default;
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
|
||||||
|
$btn-background-color: transparent !default;
|
||||||
|
$btn-border-color: $gray-400 !default;
|
||||||
|
$btn-font-color: inherit !default;
|
||||||
|
$btn-box-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$btn-authorize-background-color: transparent !default;
|
||||||
|
$btn-authorize-border-color: $_color-post !default;
|
||||||
|
$btn-authorize-font-color: $_color-post !default;
|
||||||
|
$btn-authorize-svg-fill-color: $_color-post !default;
|
||||||
|
|
||||||
|
$btn-cancel-background-color: transparent !default;
|
||||||
|
$btn-cancel-border-color: $color-warning !default;
|
||||||
|
$btn-cancel-font-color: $color-warning !default;
|
||||||
|
|
||||||
|
$btn-execute-background-color: transparent !default;
|
||||||
|
$btn-execute-border-color: $color-info !default;
|
||||||
|
$btn-execute-font-color: $white !default;
|
||||||
|
$btn-execute-background-color-alt: $color-info !default;
|
||||||
|
|
||||||
|
$expand-methods-svg-fill-color: $gray-500 !default;
|
||||||
|
$expand-methods-svg-fill-color-hover: $gray-800 !default;
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
|
||||||
|
$errors-wrapper-background-color: $_color-delete !default;
|
||||||
|
$errors-wrapper-border-color: $_color-delete !default;
|
||||||
|
|
||||||
|
$errors-wrapper-errors-small-font-color: $gray-600 !default;
|
||||||
|
|
||||||
|
// Form
|
||||||
|
|
||||||
|
$form-select-background-color: #f7f7f7 !default;
|
||||||
|
$form-select-border-color: $gray-custom-1 !default;
|
||||||
|
$form-select-box-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$form-input-border-color: #d9d9d9 !default;
|
||||||
|
$form-input-background-color: $white !default;
|
||||||
|
|
||||||
|
$form-textarea-background-color: $white !default;
|
||||||
|
$form-textarea-focus-border-color: $_color-get !default;
|
||||||
|
|
||||||
|
$form-textarea-curl-background-color: $gray-custom-1 !default;
|
||||||
|
$form-textarea-curl-font-color: $white !default;
|
||||||
|
|
||||||
|
$form-checkbox-label-font-color: $gray-900 !default;
|
||||||
|
$form-checkbox-background-color: #e8e8e8 !default;
|
||||||
|
$form-checkbox-box-shadow-color: #e8e8e8 !default;
|
||||||
|
|
||||||
|
// Information
|
||||||
|
|
||||||
|
$info-code-background-color: $gray-base !default;
|
||||||
|
$info-code-font-color: $_color-head !default;
|
||||||
|
|
||||||
|
$info-link-font-color: $color-info !default;
|
||||||
|
$info-link-font-color-hover: $info-link-font-color !default;
|
||||||
|
|
||||||
|
$info-title-small-background-color: #7d8492 !default;
|
||||||
|
|
||||||
|
$info-title-small-pre-font-color: $white !default;
|
||||||
|
|
||||||
|
// Layout
|
||||||
|
|
||||||
|
$opblock-border-color: $gray-base !default;
|
||||||
|
$opblock-box-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$opblock-tag-border-bottom-color: $gray-custom-2 !default;
|
||||||
|
$opblock-tag-background-color-hover: $gray-base !default;
|
||||||
|
|
||||||
|
$opblock-tab-header-tab-item-active-h4-span-after-background-color: $gray-400 !default;
|
||||||
|
|
||||||
|
$opblock-isopen-summary-border-bottom-color: $gray-base !default;
|
||||||
|
|
||||||
|
$opblock-isopen-section-header-background-color: $white !default;
|
||||||
|
$opblock-isopen-section-header-box-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$opblock-summary-method-background-color: $gray-base !default;
|
||||||
|
$opblock-summary-method-font-color: $white !default;
|
||||||
|
$opblock-summary-method-text-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$operational-filter-input-border-color: #d8dde7 !default;
|
||||||
|
|
||||||
|
$tab-list-item-first-background-color: $gray-base !default;
|
||||||
|
|
||||||
|
$response-col-status-undocumented-font-color: $gray-300 !default;
|
||||||
|
|
||||||
|
$response-col-links-font-color: $gray-300 !default;
|
||||||
|
|
||||||
|
$response-col-description-inner-markdown-font-color: $white !default;
|
||||||
|
$response-col-description-inner-markdown-background-color: $gray-custom-1 !default;
|
||||||
|
|
||||||
|
$response-col-description-inner-markdown-link-font-color: $color-primary !default;
|
||||||
|
$response-col-description-inner-markdown-link-font-color-hover: $color-primary-hover !default;
|
||||||
|
|
||||||
|
$opblock-body-background-color: $gray-custom-1 !default;
|
||||||
|
$opblock-body-font-color: $white !default;
|
||||||
|
|
||||||
|
$scheme-container-background-color: $white !default;
|
||||||
|
$scheme-container-box-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$server-container-background-color: $white !default;
|
||||||
|
$server-container-box-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$server-container-computed-url-code-font-color: $gray-400 !default;
|
||||||
|
|
||||||
|
$loading-container-before-border-color: $gray-650 !default;
|
||||||
|
$loading-container-before-border-top-color: $gray-base !default;
|
||||||
|
|
||||||
|
$response-content-type-controls-accept-header-select-border-color: $color-green !default;
|
||||||
|
$response-content-type-controls-accept-header-small-font-color: $color-green !default;
|
||||||
|
|
||||||
|
// Modal
|
||||||
|
|
||||||
|
$dialog-ux-backdrop-background-color: $gray-base !default;
|
||||||
|
|
||||||
|
|
||||||
|
$dialog-ux-modal-background-color: $white !default;
|
||||||
|
$dialog-ux-modal-border-color: $gray-50 !default;
|
||||||
|
$dialog-ux-modal-box-shadow-color: $gray-base !default;
|
||||||
|
|
||||||
|
$dialog-ux-modal-content-font-color: $gray-custom-1 !default;
|
||||||
|
|
||||||
|
$dialog-ux-modal-header-border-bottom-color: $gray-50 !default;
|
||||||
|
|
||||||
|
// Models
|
||||||
|
|
||||||
|
$model-deprecated-font-color: $gray-200 !default;
|
||||||
|
|
||||||
|
$model-hint-font-color: $gray-50 !default;
|
||||||
|
$model-hint-background-color: $gray-base !default;
|
||||||
|
|
||||||
|
$section-models-border-color: $gray-custom-2 !default;
|
||||||
|
|
||||||
|
$section-models-isopen-h4-border-bottom-color: $section-models-border-color !default;
|
||||||
|
|
||||||
|
$section-models-h4-font-color: $gray-500 !default;
|
||||||
|
$section-models-h4-background-color-hover: $gray-base !default;
|
||||||
|
|
||||||
|
$section-models-h5-font-color: $gray-500 !default;
|
||||||
|
|
||||||
|
$section-models-model-container-background-color: $gray-base !default;
|
||||||
|
|
||||||
|
$section-models-model-box-background-color: $gray-base !default;
|
||||||
|
|
||||||
|
$section-models-model-title-font-color: $gray-700 !default;
|
||||||
|
|
||||||
|
$prop-type-font-color: #55a !default;
|
||||||
|
|
||||||
|
$prop-format-font-color: $gray-300 !default;
|
||||||
|
|
||||||
|
// Tables
|
||||||
|
|
||||||
|
$table-thead-td-border-bottom-color: $gray-custom-2 !default;
|
||||||
|
|
||||||
|
$table-parameter-name-required-font-color: $color-danger !default;
|
||||||
|
|
||||||
|
$table-parameter-in-font-color: $gray-400 !default;
|
||||||
|
|
||||||
|
$table-parameter-deprecated-font-color: $color-danger !default;
|
||||||
|
|
||||||
|
// Topbar
|
||||||
|
|
||||||
|
$topbar-background-color: $color-primary !default;
|
||||||
|
|
||||||
|
$topbar-link-font-color: $white !default;
|
||||||
|
|
||||||
|
$topbar-download-url-wrapper-element-border-color: #547f00 !default;
|
||||||
|
|
||||||
|
$topbar-download-url-button-background-color: #547f00 !default;
|
||||||
|
$topbar-download-url-button-font-color: $white !default;
|
||||||
|
|
||||||
|
// Type
|
||||||
|
|
||||||
|
$text-body-default-font-color: $gray-custom-2 !default;
|
||||||
|
$text-code-default-font-color: $gray-custom-2 !default;
|
||||||
|
$text-headline-default-font-color: $gray-custom-2 !default;
|
||||||
|
|||||||
63
test/components/object-model.js
Normal file
63
test/components/object-model.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import React from "react"
|
||||||
|
import expect from "expect"
|
||||||
|
import { shallow } from "enzyme"
|
||||||
|
import { fromJS } from "immutable"
|
||||||
|
import ObjectModel from "components/object-model"
|
||||||
|
import ModelExample from "components/model-example"
|
||||||
|
import Immutable from "immutable"
|
||||||
|
import Model from "components/model"
|
||||||
|
import ModelCollapse from "components/model-collapse"
|
||||||
|
import { inferSchema } from "corePlugins/samples/fn"
|
||||||
|
|
||||||
|
describe("<ObjectModel />", function() {
|
||||||
|
const dummyComponent = () => null
|
||||||
|
const components = {
|
||||||
|
"JumpToPath" : dummyComponent,
|
||||||
|
"Markdown" : dummyComponent,
|
||||||
|
"Model" : Model,
|
||||||
|
"ModelCollapse" : ModelCollapse
|
||||||
|
}
|
||||||
|
const props = {
|
||||||
|
getComponent: c => components[c],
|
||||||
|
isRef : false,
|
||||||
|
schema: Immutable.fromJS(
|
||||||
|
{
|
||||||
|
"properties": {
|
||||||
|
// Note reverse order: c, b, a
|
||||||
|
c: {
|
||||||
|
type: "integer",
|
||||||
|
name: "c"
|
||||||
|
},
|
||||||
|
b: {
|
||||||
|
type: "boolean",
|
||||||
|
name: "b"
|
||||||
|
},
|
||||||
|
a: {
|
||||||
|
type: "string",
|
||||||
|
name: "a"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
specSelectors: {
|
||||||
|
isOAS3(){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
className: "for-test"
|
||||||
|
}
|
||||||
|
it("renders a collapsible header", function(){
|
||||||
|
const wrapper = shallow(<ObjectModel {...props}/>)
|
||||||
|
const renderedModelCollapse = wrapper.find(ModelCollapse)
|
||||||
|
expect(renderedModelCollapse.length).toEqual(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("renders the object properties in order", function() {
|
||||||
|
const wrapper = shallow(<ObjectModel {...props}/>)
|
||||||
|
const renderedModel = wrapper.find(Model)
|
||||||
|
expect(renderedModel.length).toEqual(3)
|
||||||
|
expect(renderedModel.get(0).props.schema.get("name")).toEqual("c")
|
||||||
|
expect(renderedModel.get(1).props.schema.get("name")).toEqual("b")
|
||||||
|
expect(renderedModel.get(2).props.schema.get("name")).toEqual("a")
|
||||||
|
})
|
||||||
|
})
|
||||||
133
test/core/plugins/auth/selectors.js
Normal file
133
test/core/plugins/auth/selectors.js
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/* eslint-env mocha */
|
||||||
|
import expect from "expect"
|
||||||
|
import { fromJS } from "immutable"
|
||||||
|
import { definitionsToAuthorize, definitionsForRequirements } from "corePlugins/auth/selectors"
|
||||||
|
|
||||||
|
describe("auth plugin - selectors", () => {
|
||||||
|
describe("definitionsToAuthorize", () => {
|
||||||
|
it("should return securityDefinitions as a List", () => {
|
||||||
|
const securityDefinitions = {
|
||||||
|
"petstore_auth": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
|
||||||
|
"flow": "implicit",
|
||||||
|
"scopes": {
|
||||||
|
"write:pets": "modify pets in your account",
|
||||||
|
"read:pets": "read your pets"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"api_key": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"name": "api_key",
|
||||||
|
"in": "header"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const system = {
|
||||||
|
specSelectors: {
|
||||||
|
securityDefinitions() {
|
||||||
|
return fromJS(securityDefinitions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = definitionsToAuthorize({})(system)
|
||||||
|
|
||||||
|
expect(res.toJS()).toEqual([
|
||||||
|
{
|
||||||
|
"petstore_auth": securityDefinitions["petstore_auth"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": securityDefinitions["api_key"]
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should fail gracefully with bad data", () => {
|
||||||
|
const securityDefinitions = null
|
||||||
|
|
||||||
|
const system = {
|
||||||
|
specSelectors: {
|
||||||
|
securityDefinitions() {
|
||||||
|
return fromJS(securityDefinitions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = definitionsToAuthorize({})(system)
|
||||||
|
|
||||||
|
expect(res.toJS()).toEqual([])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("definitionsForRequirements", () => {
|
||||||
|
it("should return applicable securityDefinitions as a List", () => {
|
||||||
|
const securityDefinitions = {
|
||||||
|
"petstore_auth": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
|
||||||
|
"flow": "implicit",
|
||||||
|
"scopes": {
|
||||||
|
"write:pets": "modify pets in your account",
|
||||||
|
"read:pets": "read your pets"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"api_key": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"name": "api_key",
|
||||||
|
"in": "header"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const system = {
|
||||||
|
authSelectors: {
|
||||||
|
definitionsToAuthorize() {
|
||||||
|
return fromJS([
|
||||||
|
{
|
||||||
|
"petstore_auth": securityDefinitions["petstore_auth"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api_key": securityDefinitions["api_key"]
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const securities = fromJS([
|
||||||
|
{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const res = definitionsForRequirements({}, securities)(system)
|
||||||
|
|
||||||
|
expect(res.toJS()).toEqual([
|
||||||
|
{
|
||||||
|
"petstore_auth": securityDefinitions["petstore_auth"]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should fail gracefully with bad data", () => {
|
||||||
|
const securityDefinitions = null
|
||||||
|
|
||||||
|
const system = {
|
||||||
|
authSelectors: {
|
||||||
|
definitionsToAuthorize() {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const securities = null
|
||||||
|
|
||||||
|
const res = definitionsForRequirements({}, securities)(system)
|
||||||
|
|
||||||
|
expect(res.toJS()).toEqual([])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -3,6 +3,7 @@ import expect from "expect"
|
|||||||
import { fromJS, OrderedMap } from "immutable"
|
import { fromJS, OrderedMap } from "immutable"
|
||||||
import {
|
import {
|
||||||
mapToList,
|
mapToList,
|
||||||
|
validatePattern,
|
||||||
validateMinLength,
|
validateMinLength,
|
||||||
validateMaxLength,
|
validateMaxLength,
|
||||||
validateDateTime,
|
validateDateTime,
|
||||||
@@ -16,7 +17,8 @@ import {
|
|||||||
fromJSOrdered,
|
fromJSOrdered,
|
||||||
getAcceptControllingResponse,
|
getAcceptControllingResponse,
|
||||||
createDeepLinkPath,
|
createDeepLinkPath,
|
||||||
escapeDeepLinkPath
|
escapeDeepLinkPath,
|
||||||
|
sanitizeUrl
|
||||||
} from "core/utils"
|
} from "core/utils"
|
||||||
import win from "core/window"
|
import win from "core/window"
|
||||||
|
|
||||||
@@ -215,9 +217,9 @@ describe("utils", function() {
|
|||||||
expect(validateFile(1)).toEqual(errorMessage)
|
expect(validateFile(1)).toEqual(errorMessage)
|
||||||
expect(validateFile("string")).toEqual(errorMessage)
|
expect(validateFile("string")).toEqual(errorMessage)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("validateDateTime", function() {
|
describe("validateDateTime", function() {
|
||||||
let errorMessage = "Value must be a DateTime"
|
let errorMessage = "Value must be a DateTime"
|
||||||
|
|
||||||
it("doesn't return for valid dates", function() {
|
it("doesn't return for valid dates", function() {
|
||||||
@@ -228,7 +230,7 @@ describe("utils", function() {
|
|||||||
expect(validateDateTime(null)).toEqual(errorMessage)
|
expect(validateDateTime(null)).toEqual(errorMessage)
|
||||||
expect(validateDateTime("string")).toEqual(errorMessage)
|
expect(validateDateTime("string")).toEqual(errorMessage)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("validateGuid", function() {
|
describe("validateGuid", function() {
|
||||||
let errorMessage = "Value must be a Guid"
|
let errorMessage = "Value must be a Guid"
|
||||||
@@ -242,9 +244,9 @@ describe("utils", function() {
|
|||||||
expect(validateGuid(1)).toEqual(errorMessage)
|
expect(validateGuid(1)).toEqual(errorMessage)
|
||||||
expect(validateGuid("string")).toEqual(errorMessage)
|
expect(validateGuid("string")).toEqual(errorMessage)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("validateMaxLength", function() {
|
describe("validateMaxLength", function() {
|
||||||
let errorMessage = "Value must be less than MaxLength"
|
let errorMessage = "Value must be less than MaxLength"
|
||||||
|
|
||||||
it("doesn't return for valid guid", function() {
|
it("doesn't return for valid guid", function() {
|
||||||
@@ -257,9 +259,9 @@ describe("utils", function() {
|
|||||||
expect(validateMaxLength("abc", 1)).toEqual(errorMessage)
|
expect(validateMaxLength("abc", 1)).toEqual(errorMessage)
|
||||||
expect(validateMaxLength("abc", 2)).toEqual(errorMessage)
|
expect(validateMaxLength("abc", 2)).toEqual(errorMessage)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("validateMinLength", function() {
|
describe("validateMinLength", function() {
|
||||||
let errorMessage = "Value must be greater than MinLength"
|
let errorMessage = "Value must be greater than MinLength"
|
||||||
|
|
||||||
it("doesn't return for valid guid", function() {
|
it("doesn't return for valid guid", function() {
|
||||||
@@ -271,7 +273,29 @@ describe("utils", function() {
|
|||||||
expect(validateMinLength("abc", 5)).toEqual(errorMessage)
|
expect(validateMinLength("abc", 5)).toEqual(errorMessage)
|
||||||
expect(validateMinLength("abc", 8)).toEqual(errorMessage)
|
expect(validateMinLength("abc", 8)).toEqual(errorMessage)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("validatePattern", function() {
|
||||||
|
let rxPattern = "^(red|blue)"
|
||||||
|
let errorMessage = "Value must follow pattern " + rxPattern
|
||||||
|
|
||||||
|
it("doesn't return for a match", function() {
|
||||||
|
expect(validatePattern("red", rxPattern)).toBeFalsy()
|
||||||
|
expect(validatePattern("blue", rxPattern)).toBeFalsy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns a message for invalid pattern", function() {
|
||||||
|
expect(validatePattern("pink", rxPattern)).toEqual(errorMessage)
|
||||||
|
expect(validatePattern("123", rxPattern)).toEqual(errorMessage)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("fails gracefully when an invalid regex value is passed", function() {
|
||||||
|
expect(() => validatePattern("aValue", "---")).toNotThrow()
|
||||||
|
expect(() => validatePattern("aValue", 1234)).toNotThrow()
|
||||||
|
expect(() => validatePattern("aValue", null)).toNotThrow()
|
||||||
|
expect(() => validatePattern("aValue", [])).toNotThrow()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("validateParam", function() {
|
describe("validateParam", function() {
|
||||||
let param = null
|
let param = null
|
||||||
@@ -524,7 +548,7 @@ describe("utils", function() {
|
|||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: "test string"
|
value: "test string"
|
||||||
}
|
}
|
||||||
assertValidateParam(param, ["Required field is not provided"])
|
assertValidateParam(param, ["Value must be a boolean"])
|
||||||
|
|
||||||
// valid boolean value
|
// valid boolean value
|
||||||
param = {
|
param = {
|
||||||
@@ -584,7 +608,7 @@ describe("utils", function() {
|
|||||||
type: "number",
|
type: "number",
|
||||||
value: "test"
|
value: "test"
|
||||||
}
|
}
|
||||||
assertValidateParam(param, ["Required field is not provided"])
|
assertValidateParam(param, ["Value must be a number"])
|
||||||
|
|
||||||
// invalid number, undefined value
|
// invalid number, undefined value
|
||||||
param = {
|
param = {
|
||||||
@@ -666,7 +690,7 @@ describe("utils", function() {
|
|||||||
type: "integer",
|
type: "integer",
|
||||||
value: "test"
|
value: "test"
|
||||||
}
|
}
|
||||||
assertValidateParam(param, ["Required field is not provided"])
|
assertValidateParam(param, ["Value must be an integer"])
|
||||||
|
|
||||||
// invalid integer, undefined value
|
// invalid integer, undefined value
|
||||||
param = {
|
param = {
|
||||||
@@ -676,6 +700,14 @@ describe("utils", function() {
|
|||||||
}
|
}
|
||||||
assertValidateParam(param, ["Required field is not provided"])
|
assertValidateParam(param, ["Required field is not provided"])
|
||||||
|
|
||||||
|
// valid integer, but 0 is falsy in JS
|
||||||
|
param = {
|
||||||
|
required: true,
|
||||||
|
type: "integer",
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
assertValidateParam(param, [])
|
||||||
|
|
||||||
// valid integer
|
// valid integer
|
||||||
param = {
|
param = {
|
||||||
required: true,
|
required: true,
|
||||||
@@ -885,4 +917,44 @@ describe("utils", function() {
|
|||||||
expect(result).toEqual("hello\\#world")
|
expect(result).toEqual("hello\\#world")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("sanitizeUrl", function() {
|
||||||
|
it("should sanitize a `javascript:` url", function() {
|
||||||
|
const res = sanitizeUrl("javascript:alert('bam!')")
|
||||||
|
|
||||||
|
expect(res).toEqual("about:blank")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should sanitize a `data:` url", function() {
|
||||||
|
const res = sanitizeUrl(`data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGV
|
||||||
|
sbG8iKTs8L3NjcmlwdD4=`)
|
||||||
|
|
||||||
|
expect(res).toEqual("about:blank")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should not modify a `http:` url", function() {
|
||||||
|
const res = sanitizeUrl(`http://swagger.io/`)
|
||||||
|
|
||||||
|
expect(res).toEqual("http://swagger.io/")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should not modify a `https:` url", function() {
|
||||||
|
const res = sanitizeUrl(`https://swagger.io/`)
|
||||||
|
|
||||||
|
expect(res).toEqual("https://swagger.io/")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should gracefully handle empty strings", function() {
|
||||||
|
expect(sanitizeUrl("")).toEqual("")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should gracefully handle non-string values", function() {
|
||||||
|
expect(sanitizeUrl(123)).toEqual("")
|
||||||
|
expect(sanitizeUrl(null)).toEqual("")
|
||||||
|
expect(sanitizeUrl(undefined)).toEqual("")
|
||||||
|
expect(sanitizeUrl([])).toEqual("")
|
||||||
|
expect(sanitizeUrl({})).toEqual("")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ module.exports = {
|
|||||||
petAPIWrapperBar: {
|
petAPIWrapperBar: {
|
||||||
selector: ".swagger-ui .opblock-tag-section:nth-child(1) .opblock-tag"
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) .opblock-tag"
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post pet/ api
|
* Post pet/ api
|
||||||
*/
|
*/
|
||||||
@@ -141,6 +142,7 @@ module.exports = {
|
|||||||
petOperationPostStatus: {
|
petOperationPostStatus: {
|
||||||
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(70)"
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(70)"
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put pet/ api
|
* Put pet/ api
|
||||||
*/
|
*/
|
||||||
@@ -189,8 +191,9 @@ module.exports = {
|
|||||||
petOperationPutStatus: {
|
petOperationPutStatus: {
|
||||||
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(70)"
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(70)"
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get pet/
|
* Get /pet/findByTags
|
||||||
*/
|
*/
|
||||||
petOperationGetByTagContainer: {
|
petOperationGetByTagContainer: {
|
||||||
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags"
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags"
|
||||||
@@ -237,6 +240,34 @@ module.exports = {
|
|||||||
petOperationGetByTagStatus: {
|
petOperationGetByTagStatus: {
|
||||||
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(70)"
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(70)"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get /pet/{petId}
|
||||||
|
*/
|
||||||
|
petOperationGetByIdContainer: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-getPetById"
|
||||||
|
},
|
||||||
|
petOperationGetByIdTitle: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-getPetById .opblock-summary-get span.opblock-summary-path span"
|
||||||
|
},
|
||||||
|
petOperationGetByIdCollpase: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-getPetById .opblock-summary-get"
|
||||||
|
},
|
||||||
|
petOperationGetByIdCollapseContainer: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-getPetById .ReactCollapse--collapse"
|
||||||
|
},
|
||||||
|
petOperationGetByIdTryBtn: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-getPetById button.try-out__btn"
|
||||||
|
},
|
||||||
|
petOperationGetByIdExecuteBtn: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-getPetById button.execute"
|
||||||
|
},
|
||||||
|
petOperationGetByIdParameter: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-pet-getPetById div.parameters-col_description input"
|
||||||
|
},
|
||||||
|
petOperationGetByIdResultsBox: {
|
||||||
|
selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-getPetById pre.microlight"
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete pet/
|
* Delete pet/
|
||||||
@@ -497,9 +528,5 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ describe("render pet api container", function () {
|
|||||||
|
|
||||||
client.end()
|
client.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Testing put /pet api Mock data", function (client) {
|
it("Testing put /pet api Mock data", function (client) {
|
||||||
apiWrapper.waitForElementVisible("@petOperationPutContainer", 5000)
|
apiWrapper.waitForElementVisible("@petOperationPutContainer", 5000)
|
||||||
.click("@petOperationPutCollpase")
|
.click("@petOperationPutCollpase")
|
||||||
@@ -137,6 +138,38 @@ describe("render pet api container", function () {
|
|||||||
|
|
||||||
client.end()
|
client.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("render get by ID /pet/{petId} api container", function (client) {
|
||||||
|
apiWrapper.waitForElementVisible("@petOperationGetByIdContainer", 5000)
|
||||||
|
.assert.containsText("@petOperationGetByIdTitle", "/pet/{petId}")
|
||||||
|
.click("@petOperationGetByIdCollpase")
|
||||||
|
.waitForElementVisible("@petOperationGetByIdCollapseContainer", 3000)
|
||||||
|
.click("@petOperationGetByIdTryBtn")
|
||||||
|
.waitForElementVisible("@petOperationGetByTagExecuteBtn", 1000)
|
||||||
|
.click("@petOperationGetByTagTryBtn")
|
||||||
|
.assert.cssClassNotPresent("@petOperationGetByTagTryBtn", "cancel")
|
||||||
|
|
||||||
|
client.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("render get by ID /pet/{petId} api Mock data", function (client) {
|
||||||
|
apiWrapper.waitForElementVisible("@petOperationGetByIdContainer", 5000)
|
||||||
|
.assert.containsText("@petOperationGetByIdTitle", "/pet/{petId}")
|
||||||
|
.click("@petOperationGetByIdCollpase")
|
||||||
|
.waitForElementVisible("@petOperationGetByIdCollapseContainer", 3000)
|
||||||
|
.click("@petOperationGetByIdTryBtn")
|
||||||
|
.waitForElementVisible("@petOperationGetByTagExecuteBtn", 1000)
|
||||||
|
.setValue("@petOperationGetByIdParameter", "abc")
|
||||||
|
.click("@petOperationGetByIdExecuteBtn")
|
||||||
|
.waitForElementVisible("@petOperationGetByIdResultsBox")
|
||||||
|
.assert.containsText("@petOperationGetByIdParameter", "abc")
|
||||||
|
.assert.cssClassPresent("@petOperationGetByIdParameter", "invalid")
|
||||||
|
.assert.attributeEquals("@petOperationGetByIdParameter", "title", "Value must be an integer")
|
||||||
|
.click("@petOperationGetByTagTryBtn")
|
||||||
|
.assert.cssClassNotPresent("@petOperationGetByTagTryBtn", "cancel")
|
||||||
|
|
||||||
|
client.end()
|
||||||
|
})
|
||||||
|
|
||||||
it("render delete /pet api container", function (client) {
|
it("render delete /pet api container", function (client) {
|
||||||
apiWrapper.waitForElementVisible("@petOperationDeleteContainer")
|
apiWrapper.waitForElementVisible("@petOperationDeleteContainer")
|
||||||
@@ -150,6 +183,7 @@ describe("render pet api container", function () {
|
|||||||
|
|
||||||
client.end()
|
client.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("Testing delete /pet api Mock data", function (client) {
|
it("Testing delete /pet api Mock data", function (client) {
|
||||||
apiWrapper.waitForElementVisible("@petOperationDeleteContainer", 3000)
|
apiWrapper.waitForElementVisible("@petOperationDeleteContainer", 3000)
|
||||||
.click("@petOperationDeleteCollpase")
|
.click("@petOperationDeleteCollpase")
|
||||||
|
|||||||
Reference in New Issue
Block a user