From fdb0d13089adc58bb30020e317950c823f7017e7 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Wed, 2 Aug 2017 22:07:48 -0600 Subject: [PATCH 01/61] Fixes #3511 - Update changeParameter calls to accept `in` value to identify parameters based on `name` plus `in` value --- src/core/components/param-body.jsx | 4 ++-- src/core/components/parameter-row.jsx | 8 ++++++-- src/core/components/parameters.jsx | 4 ++-- src/core/plugins/oas3/wrap-components/parameters.jsx | 2 +- src/core/plugins/spec/actions.js | 5 ++--- src/core/plugins/spec/reducers.js | 5 +++-- src/core/plugins/spec/selectors.js | 4 ++-- 7 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/core/components/param-body.jsx b/src/core/components/param-body.jsx index e64a65cc..a6fa893e 100644 --- a/src/core/components/param-body.jsx +++ b/src/core/components/param-body.jsx @@ -47,7 +47,7 @@ export default class ParamBody extends PureComponent { updateValues = (props) => { let { specSelectors, pathMethod, param, isExecute, consumesValue="" } = props - let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name")) : {} + let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) : {} let isXml = /xml/i.test(consumesValue) let isJson = /json/i.test(consumesValue) let paramValue = isXml ? parameter.get("value_xml") : parameter.get("value") @@ -105,7 +105,7 @@ export default class ParamBody extends PureComponent { const HighlightCode = getComponent("highlightCode") const ContentType = getComponent("contentType") // for domains where specSelectors not passed - let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name")) : param + let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) : param let errors = parameter.get("errors", List()) let consumesValue = specSelectors.contentTypeValues(pathMethod).get("requestContentType") let consumes = this.props.consumes && this.props.consumes.size ? this.props.consumes : ParamBody.defaultProp.consumes diff --git a/src/core/components/parameter-row.jsx b/src/core/components/parameter-row.jsx index 7db5e4ee..d8cf37b9 100644 --- a/src/core/components/parameter-row.jsx +++ b/src/core/components/parameter-row.jsx @@ -19,13 +19,17 @@ export default class ParameterRow extends Component { let { specSelectors, pathMethod, param } = props let defaultValue = param.get("default") - let parameter = specSelectors.getParameter(pathMethod, param.get("name")) + let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) let value = parameter ? parameter.get("value") : "" if ( defaultValue !== undefined && value === undefined ) { this.onChangeWrapper(defaultValue) } } + shouldComponentUpdate(nextProps) { + return nextProps.param !== this.props.param + } + componentWillReceiveProps(props) { let { specSelectors, pathMethod, param } = props let example = param.get("example") @@ -84,7 +88,7 @@ export default class ParameterRow extends Component { let isFormDataSupported = "FormData" in win let required = param.get("required") let itemType = param.getIn(["items", "type"]) - let parameter = specSelectors.getParameter(pathMethod, param.get("name")) + let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) let value = parameter ? parameter.get("value") : "" return ( diff --git a/src/core/components/parameters.jsx b/src/core/components/parameters.jsx index a6b981e6..c2cae178 100644 --- a/src/core/components/parameters.jsx +++ b/src/core/components/parameters.jsx @@ -37,7 +37,7 @@ export default class Parameters extends Component { onChangeKey, } = this.props - changeParam( onChangeKey, param.get("name"), value, isXml) + changeParam( onChangeKey, param.get("name"), param.get("in"), value, isXml) } onChangeConsumesWrapper = ( val ) => { @@ -94,7 +94,7 @@ export default class Parameters extends Component { { diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js index 31671b87..3372ad61 100644 --- a/src/core/plugins/spec/actions.js +++ b/src/core/plugins/spec/actions.js @@ -128,10 +128,10 @@ export const formatIntoYaml = () => ({specActions, specSelectors}) => { } } -export function changeParam( path, paramName, value, isXml ){ +export function changeParam( path, paramName, paramIn, value, isXml ){ return { type: UPDATE_PARAM, - payload:{ path, value, paramName, isXml } + payload:{ path, value, paramName, paramIn, isXml } } } @@ -195,7 +195,6 @@ export const executeRequest = (req) => ({fn, specActions, specSelectors}) => { // if url is relative, parseUrl makes it absolute by inferring from `window.location` req.contextUrl = parseUrl(specSelectors.url()).toString() - if(op && op.operationId) { req.operationId = op.operationId } else if(op && pathName && method) { diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index d9670d7b..3ea5a30a 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -39,9 +39,10 @@ export default { }, [UPDATE_PARAM]: ( state, {payload} ) => { - let { path, paramName, value, isXml } = payload + let { path, paramName, paramIn, value, isXml } = payload + return state.updateIn( [ "resolved", "paths", ...path, "parameters" ], fromJS([]), parameters => { - const index = parameters.findIndex(p => p.get( "name" ) === paramName ) + const index = parameters.findIndex(p => p.get( "name" ) === paramName && p.get("in") === paramIn ) if (!(value instanceof win.File)) { value = fromJSOrdered( value ) } diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index fbc12764..728caf56 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -251,10 +251,10 @@ export const allowTryItOutFor = () => { } // Get the parameter value by parameter name -export function getParameter(state, pathMethod, name) { +export function getParameter(state, pathMethod, name, inType) { let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) return params.filter( (p) => { - return Map.isMap(p) && p.get("name") === name + return Map.isMap(p) && p.get("name") === name && p.get("in") === inType }).first() } From 51016c33f4a9c6997d65c48e5bc4ff46e99a74f1 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Wed, 2 Aug 2017 22:37:31 -0600 Subject: [PATCH 02/61] Attach `in` value to parameters map so parameters with the same name from different `in` types do not override each other. --- src/core/plugins/spec/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index 728caf56..3a2cc39c 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -271,7 +271,7 @@ export function parameterValues(state, pathMethod, isXml) { let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) return params.reduce( (hash, p) => { let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value") - return hash.set(p.get("name"), value) + return hash.set(`${p.get("name")}-${p.get("in")}`, value) }, fromJS({})) } From ce8adb91a574ce20b91722b3c92ad88b3b0d9296 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Thu, 3 Aug 2017 07:14:03 -0600 Subject: [PATCH 03/61] Fix failing selector test --- test/core/plugins/spec/selectors.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/plugins/spec/selectors.js b/test/core/plugins/spec/selectors.js index 7519a42e..1816f16e 100644 --- a/test/core/plugins/spec/selectors.js +++ b/test/core/plugins/spec/selectors.js @@ -29,8 +29,8 @@ describe("spec plugin - selectors", function(){ "/one": { get: { parameters: [ - { name: "one", value: 1}, - { name: "two", value: "duos"} + { name: "one", in: "query", value: 1}, + { name: "two", in: "query", value: "duos"} ] } } @@ -43,8 +43,8 @@ describe("spec plugin - selectors", function(){ // Then expect(paramValues.toJS()).toEqual({ - one: 1, - two: "duos" + "one-query": 1, + "two-query": "duos" }) }) From 7a694e287a8e0f31b985090f488078e66ecc42a1 Mon Sep 17 00:00:00 2001 From: Owen Conti Date: Thu, 3 Aug 2017 19:29:49 -0600 Subject: [PATCH 04/61] Change name format to `in.name` and update tests --- src/core/components/parameters.jsx | 2 +- src/core/plugins/spec/selectors.js | 2 +- test/core/plugins/spec/selectors.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/components/parameters.jsx b/src/core/components/parameters.jsx index c2cae178..eff94f65 100644 --- a/src/core/components/parameters.jsx +++ b/src/core/components/parameters.jsx @@ -94,7 +94,7 @@ export default class Parameters extends Component { { let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value") - return hash.set(`${p.get("name")}-${p.get("in")}`, value) + return hash.set(`${p.get("in")}.${p.get("name")}`, value) }, fromJS({})) } diff --git a/test/core/plugins/spec/selectors.js b/test/core/plugins/spec/selectors.js index 1816f16e..df6b1c21 100644 --- a/test/core/plugins/spec/selectors.js +++ b/test/core/plugins/spec/selectors.js @@ -43,8 +43,8 @@ describe("spec plugin - selectors", function(){ // Then expect(paramValues.toJS()).toEqual({ - "one-query": 1, - "two-query": "duos" + "query.one": 1, + "query.two": "duos" }) }) From 54b383a7d2c6587663626fd5f29af7f02f98810d Mon Sep 17 00:00:00 2001 From: Matthew Seal Date: Tue, 15 Aug 2017 18:02:17 -0700 Subject: [PATCH 05/61] Updated docs for correct usage of SWAGGER_JSON --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c543541a..10d87701 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Will start nginx with swagger-ui on port 80. Or you can provide your own swagger.json on your host ``` -docker run -p 80:8080 -e "SWAGGER_JSON=/foo/swagger.json" -v /bar:/foo swaggerapi/swagger-ui +docker run -p 80:8080 -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui ``` ##### Prerequisites From 947953d087ec1ee883c6f7c9f5abca89d7f819b2 Mon Sep 17 00:00:00 2001 From: HelderSepu Date: Sat, 2 Sep 2017 19:59:18 -0400 Subject: [PATCH 06/61] fix #3624 --- dev-helpers/oauth2-redirect.html | 6 +++++- dist/oauth2-redirect.html | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dev-helpers/oauth2-redirect.html b/dev-helpers/oauth2-redirect.html index 00c7f014..a7eb162d 100644 --- a/dev-helpers/oauth2-redirect.html +++ b/dev-helpers/oauth2-redirect.html @@ -11,7 +11,11 @@ var redirectUrl = oauth2.redirectUrl; var isValid, qp, arr; - qp = (window.location.hash || location.search).substring(1); + if (/code|token|error/.test(window.location.hash)) { + qp = window.location.hash.substring(1); + } else { + qp = location.search.substring(1); + } arr = qp.split("&") arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';}) diff --git a/dist/oauth2-redirect.html b/dist/oauth2-redirect.html index 00c7f014..a7eb162d 100644 --- a/dist/oauth2-redirect.html +++ b/dist/oauth2-redirect.html @@ -11,7 +11,11 @@ var redirectUrl = oauth2.redirectUrl; var isValid, qp, arr; - qp = (window.location.hash || location.search).substring(1); + if (/code|token|error/.test(window.location.hash)) { + qp = window.location.hash.substring(1); + } else { + qp = location.search.substring(1); + } arr = qp.split("&") arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';}) From 7a2c7d2cdc7c58591a0ad11dd31c2e404c9bee44 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 5 Sep 2017 13:59:31 -0700 Subject: [PATCH 07/61] Squash commit: OAS3 Try-It-Out changes --- src/core/components/layouts/base.jsx | 29 +++- src/core/plugins/oas3/actions.js | 35 ++++ src/core/plugins/oas3/components/index.js | 4 + .../oas3/components/request-body-editor.jsx | 114 +++++++++++++ .../plugins/oas3/components/request-body.jsx | 25 ++- src/core/plugins/oas3/components/servers.jsx | 155 ++++++++++++++++++ src/core/plugins/oas3/index.js | 14 +- src/core/plugins/oas3/reducers.js | 23 +++ src/core/plugins/oas3/selectors.js | 54 ++++++ .../plugins/oas3/spec-extensions/selectors.js | 50 ++++++ .../{ => spec-extensions}/wrap-selectors.js | 7 +- .../plugins/oas3/wrap-components/index.js | 2 - .../oas3/wrap-components/parameters.jsx | 17 +- .../wrap-components/try-it-out-button.jsx | 5 - src/core/plugins/spec/actions.js | 85 ++++++---- src/style/_layout.scss | 71 ++++++++ 16 files changed, 631 insertions(+), 59 deletions(-) create mode 100644 src/core/plugins/oas3/actions.js create mode 100644 src/core/plugins/oas3/components/request-body-editor.jsx create mode 100644 src/core/plugins/oas3/components/servers.jsx create mode 100644 src/core/plugins/oas3/reducers.js create mode 100644 src/core/plugins/oas3/selectors.js create mode 100644 src/core/plugins/oas3/spec-extensions/selectors.js rename src/core/plugins/oas3/{ => spec-extensions}/wrap-selectors.js (92%) delete mode 100644 src/core/plugins/oas3/wrap-components/try-it-out-button.jsx diff --git a/src/core/components/layouts/base.jsx b/src/core/components/layouts/base.jsx index 268ef46c..6cd909bb 100644 --- a/src/core/components/layouts/base.jsx +++ b/src/core/components/layouts/base.jsx @@ -8,6 +8,8 @@ export default class BaseLayout extends React.Component { errActions: PropTypes.object.isRequired, specActions: PropTypes.object.isRequired, specSelectors: PropTypes.object.isRequired, + oas3Selectors: PropTypes.object.isRequired, + oas3Actions: PropTypes.object.isRequired, layoutSelectors: PropTypes.object.isRequired, layoutActions: PropTypes.object.isRequired, getComponent: PropTypes.func.isRequired @@ -19,7 +21,14 @@ export default class BaseLayout extends React.Component { } render() { - let { specSelectors, specActions, getComponent, layoutSelectors } = this.props + let { + specSelectors, + specActions, + getComponent, + layoutSelectors, + oas3Selectors, + oas3Actions + } = this.props let info = specSelectors.info() let url = specSelectors.url() @@ -28,6 +37,7 @@ export default class BaseLayout extends React.Component { let securityDefinitions = specSelectors.securityDefinitions() let externalDocs = specSelectors.externalDocs() let schemes = specSelectors.schemes() + let servers = specSelectors.servers() let Info = getComponent("info") let Operations = getComponent("operations", true) @@ -35,6 +45,7 @@ export default class BaseLayout extends React.Component { let AuthorizeBtn = getComponent("authorizeBtn", true) let Row = getComponent("Row") let Col = getComponent("Col") + let Servers = getComponent("Servers") let Errors = getComponent("errors", true) let isLoading = specSelectors.loadingStatus() === "loading" @@ -82,6 +93,22 @@ export default class BaseLayout extends React.Component { ) : null } + { servers && servers.size ? ( +
+ + + +
+ + ) : null} + { filter === null || filter === false ? null :
diff --git a/src/core/plugins/oas3/actions.js b/src/core/plugins/oas3/actions.js new file mode 100644 index 00000000..4a5bf9ac --- /dev/null +++ b/src/core/plugins/oas3/actions.js @@ -0,0 +1,35 @@ +// Actions conform to FSA (flux-standard-actions) +// {type: string,payload: Any|Error, meta: obj, error: bool} + +export const UPDATE_SELECTED_SERVER = "oas3_set_servers" +export const UPDATE_REQUEST_BODY_VALUE = "oas3_set_request_body_value" +export const UPDATE_REQUEST_CONTENT_TYPE = "oas3_set_request_content_type" +export const UPDATE_SERVER_VARIABLE_VALUE = "oas3_set_server_variable_value" + +export function setSelectedServer (selectedServerUrl) { + return { + type: UPDATE_SELECTED_SERVER, + payload: selectedServerUrl + } +} + +export function setRequestBodyValue ({ value, pathMethod }) { + return { + type: UPDATE_REQUEST_BODY_VALUE, + payload: { value, pathMethod } + } +} + +export function setRequestContentType ({ value, pathMethod }) { + return { + type: UPDATE_REQUEST_CONTENT_TYPE, + payload: { value, pathMethod } + } +} + +export function setServerVariableValue ({ server, key, val }) { + return { + type: UPDATE_SERVER_VARIABLE_VALUE, + payload: { server, key, val } + } +} diff --git a/src/core/plugins/oas3/components/index.js b/src/core/plugins/oas3/components/index.js index 8186ce8e..642c6689 100644 --- a/src/core/plugins/oas3/components/index.js +++ b/src/core/plugins/oas3/components/index.js @@ -1,9 +1,13 @@ import Callbacks from "./callbacks" import RequestBody from "./request-body" import OperationLink from "./operation-link.jsx" +import Servers from "./servers" +import RequestBodyEditor from "./request-body-editor" export default { Callbacks, RequestBody, + Servers, + RequestBodyEditor, operationLink: OperationLink } diff --git a/src/core/plugins/oas3/components/request-body-editor.jsx b/src/core/plugins/oas3/components/request-body-editor.jsx new file mode 100644 index 00000000..f277d7b4 --- /dev/null +++ b/src/core/plugins/oas3/components/request-body-editor.jsx @@ -0,0 +1,114 @@ +import React, { PureComponent } from "react" +import PropTypes from "prop-types" +import { fromJS, List } from "immutable" +import { getSampleSchema } from "core/utils" + +const NOOP = Function.prototype + +export default class RequestBodyEditor extends PureComponent { + + static propTypes = { + requestBody: PropTypes.object.isRequired, + mediaType: PropTypes.string.isRequired, + onChange: PropTypes.func, + getComponent: PropTypes.func.isRequired, + isExecute: PropTypes.bool, + specSelectors: PropTypes.object.isRequired, + }; + + static defaultProps = { + mediaType: "application/json", + requestBody: fromJS({}), + onChange: NOOP, + }; + + constructor(props, context) { + super(props, context) + + this.state = { + isEditBox: false, + value: "" + } + } + + componentDidMount() { + this.setValueToSample.call(this) + } + + componentWillReceiveProps(nextProps) { + if(this.props.mediaType !== nextProps.mediaType) { + // media type was changed + this.setValueToSample(nextProps.mediaType) + } + + if(!this.props.isExecute && nextProps.isExecute) { + // we just entered execute mode, + // so enable editing for convenience + this.setState({ isEditBox: true }) + } + } + + setValueToSample = (explicitMediaType) => { + this.onChange(this.sample(explicitMediaType)) + } + + sample = (explicitMediaType) => { + let { requestBody, mediaType } = this.props + let schema = requestBody.getIn(["content", explicitMediaType || mediaType, "schema"]).toJS() + + return getSampleSchema(schema, explicitMediaType || mediaType, { + includeWriteOnly: true + }) + } + + onChange = (value) => { + this.setState({value}) + this.props.onChange(value) + } + + handleOnChange = e => { + const { mediaType } = this.props + const isJson = /json/i.test(mediaType) + const inputValue = isJson ? e.target.value.trim() : e.target.value + + this.onChange(inputValue) + } + + toggleIsEditBox = () => this.setState( state => ({isEditBox: !state.isEditBox})) + + render() { + let { + isExecute, + getComponent, + } = this.props + + const Button = getComponent("Button") + const TextArea = getComponent("TextArea") + const HighlightCode = getComponent("highlightCode") + + let { value, isEditBox } = this.state + + return ( +
+ { + isEditBox && isExecute + ?