From 5bd9846006ef7fdf6acbc008128ce658554594f8 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 25 Jan 2018 17:53:02 -0800 Subject: [PATCH 01/25] default to empty `ImmutableMap` when grabbing op metadata --- src/core/plugins/spec/reducers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index bf8dadf5e33..bdeabc04490 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -52,7 +52,7 @@ export default { }, [VALIDATE_PARAMS]: ( state, { payload: { pathMethod, isOAS3 } } ) => { - let meta = state.getIn( [ "meta", "paths", ...pathMethod ] ) + let meta = state.getIn( [ "meta", "paths", ...pathMethod ], fromJS({}) ) let isXml = /xml/i.test(meta.get("consumes_value")) return state.updateIn( [ "resolved", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { From 573028811205d0e46c33351ac3f9d15b8cc09d6d Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 25 Jan 2018 17:54:25 -0800 Subject: [PATCH 02/25] pass `errors` into JsonSchema components --- src/core/components/parameter-row.jsx | 3 ++- src/core/json-schema-components.js | 34 +++++++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/core/components/parameter-row.jsx b/src/core/components/parameter-row.jsx index 653914171b4..42f45bd9b48 100644 --- a/src/core/components/parameter-row.jsx +++ b/src/core/components/parameter-row.jsx @@ -158,7 +158,7 @@ export default class ParameterRow extends Component { Available values: " + paramItemsEnum.map(function(item) { return item - }).toArray().join(", ")}/> + }).toArray().join(", ")}/> : null } @@ -181,6 +181,7 @@ export default class ParameterRow extends Component { required={ required } description={param.get("description") ? `${param.get("name")} - ${param.get("description")}` : `${param.get("name")}`} onChange={ this.onChangeWrapper } + errors={ param.get("errors") } schema={ isOAS3 && isOAS3() ? param.get("schema") : param }/> } diff --git a/src/core/json-schema-components.js b/src/core/json-schema-components.js index 07fcada2e23..1edf2b12110 100644 --- a/src/core/json-schema-components.js +++ b/src/core/json-schema-components.js @@ -11,6 +11,7 @@ const JsonSchemaPropShape = { keyName: PropTypes.any, fn: PropTypes.object.isRequired, schema: PropTypes.object, + errors: PropTypes.array, required: PropTypes.bool, description: PropTypes.any } @@ -20,7 +21,8 @@ const JsonSchemaDefaultProps = { onChange: noop, schema: {}, keyName: "", - required: false + required: false, + errors: [] } export class JsonSchemaForm extends Component { @@ -29,7 +31,7 @@ export class JsonSchemaForm extends Component { static defaultProps = JsonSchemaDefaultProps render() { - let { schema, value, onChange, getComponent, fn } = this.props + let { schema, errors, value, onChange, getComponent, fn } = this.props if(schema.toJS) schema = schema.toJS() @@ -37,7 +39,7 @@ export class JsonSchemaForm extends Component { let { type, format="" } = schema let Comp = (format ? getComponent(`JsonSchema_${type}_${format}`) : getComponent(`JsonSchema_${type}`)) || getComponent("JsonSchema_string") - return + return } } @@ -51,14 +53,15 @@ export class JsonSchema_string extends Component { } onEnumChange = (val) => this.props.onChange(val) render() { - let { getComponent, value, schema, required, description } = this.props + let { getComponent, value, schema, errors, required, description } = this.props let enumValue = schema["enum"] - let errors = schema.errors || [] + + errors = errors || [] if ( enumValue ) { const Select = getComponent("Select") return ( err.index === i) - if (err.length) schema.errors = [ err[0].error + i ] + if (err.length) errors = [ err[0].error + i ] } return (
@@ -182,12 +186,12 @@ export class JsonSchema_boolean extends Component { onEnumChange = (val) => this.props.onChange(val) render() { - let { getComponent, value, schema } = this.props - let errors = schema.errors || [] + let { getComponent, value, errors, schema } = this.props + errors = errors || [] const Select = getComponent("Select") return ( Date: Thu, 8 Feb 2018 21:03:24 -0800 Subject: [PATCH 05/25] Add lazy resolving spec state extensions --- src/core/plugins/spec/actions.js | 69 ++++++++++++++++++++++++++++ src/core/plugins/spec/reducers.js | 6 +++ src/core/plugins/spec/selectors.js | 4 ++ src/core/plugins/swagger-js/index.js | 1 + 4 files changed, 80 insertions(+) diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js index 0d0d853a0e3..abd224c962d 100644 --- a/src/core/plugins/spec/actions.js +++ b/src/core/plugins/spec/actions.js @@ -1,6 +1,7 @@ import YAML from "js-yaml" import parseUrl from "url-parse" import serializeError from "serialize-error" +import { Map } from "immutable" import isString from "lodash/isString" import { isJSONObject } from "core/utils" @@ -21,6 +22,7 @@ export const CLEAR_REQUEST = "spec_clear_request" export const CLEAR_VALIDATE_PARAMS = "spec_clear_validate_param" export const UPDATE_OPERATION_META_VALUE = "spec_update_operation_meta_value" export const UPDATE_RESOLVED = "spec_update_resolved" +export const UPDATE_RESOLVED_SUBTREE = "spec_update_resolved_subtree" export const SET_SCHEME = "set_scheme" const toStr = (str) => isString(str) ? str : "" @@ -74,7 +76,14 @@ export const parseToJson = (str) => ({specActions, specSelectors, errActions}) = return {} } +let hasWarnedAboutResolveSpecDeprecation = false + export const resolveSpec = (json, url) => ({specActions, specSelectors, errActions, fn: { fetch, resolve, AST }, getConfigs}) => { + if(!hasWarnedAboutResolveSpecDeprecation) { + console.warn(`specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use resolveIn instead!`) + hasWarnedAboutResolveSpecDeprecation = true + } + const { modelPropertyMacro, parameterMacro, @@ -124,6 +133,49 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio }) } +export const requestResolvedSubtree = path => system => { + const { + errActions, + fn: { + resolveSubtree, + AST: { getLineNumberForPath } + }, + specSelectors, + specActions, + } = system + + const specStr = specSelectors.specStr() + + if(!resolveSubtree) { + console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing.") + return + } + + return resolveSubtree(specSelectors.specJson().toJS(), path) + .then(({ spec, errors }) => { + errActions.clear({ + type: "thrown" + }) + if(Array.isArray(errors) && errors.length > 0) { + let preparedErrors = errors + .map(err => { + console.error(err) + err.line = err.fullPath ? getLineNumberForPath(specStr, err.fullPath) : null + err.path = err.fullPath ? err.fullPath.join(".") : null + err.level = "error" + err.type = "thrown" + err.source = "resolver" + Object.defineProperty(err, "message", { enumerable: true, value: err.message }) + return err + }) + errActions.newThrownErrBatch(preparedErrors) + } + + return specActions.updateResolvedSubtree(path, spec) + }) + .catch(e => console.error(e)) +} + export function changeParam( path, paramName, paramIn, value, isXml ){ return { type: UPDATE_PARAM, @@ -131,6 +183,23 @@ export function changeParam( path, paramName, paramIn, value, isXml ){ } } +export const updateResolvedSubtree = (path, value) => { + return { + type: UPDATE_RESOLVED_SUBTREE, + payload: { path, value } + } +} + +export const invalidateResolvedSubtreeCache = () => { + return { + type: UPDATE_RESOLVED_SUBTREE, + payload: { + path: [], + value: Map() + } + } +} + export const validateParams = ( payload, isOAS3 ) =>{ return { type: VALIDATE_PARAMS, diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index f49519e0a68..51fce4ce254 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -12,6 +12,7 @@ import { SET_REQUEST, SET_MUTATED_REQUEST, UPDATE_RESOLVED, + UPDATE_RESOLVED_SUBTREE, UPDATE_OPERATION_META_VALUE, CLEAR_RESPONSE, CLEAR_REQUEST, @@ -39,6 +40,11 @@ export default { return state.setIn(["resolved"], fromJSOrdered(action.payload)) }, + [UPDATE_RESOLVED_SUBTREE]: (state, action) => { + const { value, path } = action.payload + return state.setIn(["resolvedSubtrees", ...path], fromJSOrdered(value)) + }, + [UPDATE_PARAM]: ( state, {payload} ) => { let { path, paramName, paramIn, value, isXml } = payload diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index e19c590c31b..5aa5263c29d 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -42,6 +42,10 @@ export const specResolved = createSelector( spec => spec.get("resolved", Map()) ) +export const specResolvedSubtree = (state, path) => { + return state.getIn(["resolvedSubtrees", ...path], undefined) +} + // Default Spec ( as an object ) export const spec = state => { let res = specResolved(state) diff --git a/src/core/plugins/swagger-js/index.js b/src/core/plugins/swagger-js/index.js index d8744c19922..90ceeca3619 100644 --- a/src/core/plugins/swagger-js/index.js +++ b/src/core/plugins/swagger-js/index.js @@ -7,6 +7,7 @@ module.exports = function({ configs }) { buildRequest: Swagger.buildRequest, execute: Swagger.execute, resolve: Swagger.resolve, + resolveSubtree: Swagger.resolveSubtree, serializeRes: Swagger.serializeRes, opId: Swagger.helpers.opId } From d642b57ddba38dee9c806780c6691795636d2cb9 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 8 Feb 2018 21:10:53 -0800 Subject: [PATCH 06/25] TEMPORARY: disable conventional resolved spec --- src/core/plugins/spec/reducers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index 51fce4ce254..eec435ba8dd 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -37,6 +37,7 @@ export default { }, [UPDATE_RESOLVED]: (state, action) => { + return state return state.setIn(["resolved"], fromJSOrdered(action.payload)) }, From 22a64fdedc0f69a337df442a00bfd566eeb4b8ba Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Fri, 9 Feb 2018 20:11:33 -0800 Subject: [PATCH 07/25] WIP --- src/core/plugins/spec/selectors.js | 2 +- test/core/plugins/spec/actions.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index 5aa5263c29d..96f4688ab6c 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -48,7 +48,7 @@ export const specResolvedSubtree = (state, path) => { // Default Spec ( as an object ) export const spec = state => { - let res = specResolved(state) + let res = specJson(state) return res } diff --git a/test/core/plugins/spec/actions.js b/test/core/plugins/spec/actions.js index 4a5846da924..58aec54eef1 100644 --- a/test/core/plugins/spec/actions.js +++ b/test/core/plugins/spec/actions.js @@ -177,6 +177,10 @@ describe("spec plugin - actions", function(){ }) }) + describe("requestResolvedSubtree", () => { + it("should return a promise ") + }) + it.skip("should call errActions.newErr, if the fn.execute rejects", function(){ }) From f31b6c0de8e0bce3d6593aab84ade65db9424c5a Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Sun, 11 Feb 2018 20:50:23 -0800 Subject: [PATCH 08/25] Use resolveSubtree in Operation display --- src/core/components/operation.jsx | 4 ++-- src/core/containers/OperationContainer.jsx | 11 +++++++---- src/core/plugins/spec/actions.js | 9 +++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/core/components/operation.jsx b/src/core/components/operation.jsx index 14f2122758a..bce484cb83d 100644 --- a/src/core/components/operation.jsx +++ b/src/core/components/operation.jsx @@ -81,9 +81,9 @@ export default class Operation extends PureComponent { deprecated, externalDocs, schemes - } = op.operation + } = op - let operation = operationProps.getIn(["op", "operation"]) + let operation = operationProps.getIn(["op"]) let security = operationProps.get("security") let responses = operation.get("responses") let produces = operation.get("produces") diff --git a/src/core/containers/OperationContainer.jsx b/src/core/containers/OperationContainer.jsx index 6364365af7a..edc2aa57d3a 100644 --- a/src/core/containers/OperationContainer.jsx +++ b/src/core/containers/OperationContainer.jsx @@ -2,7 +2,7 @@ import React, { PureComponent } from "react" import PropTypes from "prop-types" import ImPropTypes from "react-immutable-proptypes" import { helpers } from "swagger-client" -import { Iterable, fromJS } from "immutable" +import { Iterable, fromJS, Map } from "immutable" const { opId } = helpers @@ -88,7 +88,11 @@ export default class OperationContainer extends PureComponent { } toggleShown =() => { - let { layoutActions, tag, operationId, isShown } = this.props + let { layoutActions, specActions, tag, operationId, path, method, isShown } = this.props + if(!isShown) { + // transitioning from collapsed to expanded + specActions.requestResolvedSubtree(["paths", path, method]) + } layoutActions.show(["operations", tag, operationId], !isShown) } @@ -108,7 +112,6 @@ export default class OperationContainer extends PureComponent { render() { let { - op, tag, path, method, @@ -141,7 +144,7 @@ export default class OperationContainer extends PureComponent { const Operation = getComponent( "operation" ) const operationProps = fromJS({ - op, + op: specSelectors.specResolvedSubtree(["paths", path, method]) || Map(), tag, path, method, diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js index abd224c962d..c642e545b21 100644 --- a/src/core/plugins/spec/actions.js +++ b/src/core/plugins/spec/actions.js @@ -84,6 +84,8 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio hasWarnedAboutResolveSpecDeprecation = true } + return + const { modelPropertyMacro, parameterMacro, @@ -151,6 +153,13 @@ export const requestResolvedSubtree = path => system => { return } + const currentValue = specSelectors.specResolvedSubtree(path) + + if(currentValue) { + console.log(`DEV DEBUG: subtree already exists; not resolving again`) + return + } + return resolveSubtree(specSelectors.specJson().toJS(), path) .then(({ spec, errors }) => { errActions.clear({ From 13cf9b99502ebd23df777d9d1f7f97495bd094c0 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Sun, 11 Feb 2018 21:38:01 -0800 Subject: [PATCH 09/25] Freebie: short-circuit Markdown component if it is given plaintext --- src/core/components/providers/markdown.jsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/components/providers/markdown.jsx b/src/core/components/providers/markdown.jsx index 35ad0c5fc09..f80ccec0bda 100644 --- a/src/core/components/providers/markdown.jsx +++ b/src/core/components/providers/markdown.jsx @@ -3,7 +3,16 @@ import PropTypes from "prop-types" import Remarkable from "remarkable" import sanitize from "sanitize-html" +const isPlainText = (str) => /^[A-Z\s0-9!?\.]+$/gi.test(str) + function Markdown({ source }) { + if(isPlainText(source)) { + // If the source text is not Markdown, + // let's save some time and just render it. + return
+ {source} +
+ } const html = new Remarkable({ html: true, typographer: true, From ff90ef3e6894db580e9a9b7a7c911d2c4a335dbf Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 13 Feb 2018 13:09:08 -0800 Subject: [PATCH 10/25] NEW DEFAULT BEHAVIOR: `defaultModelsExpandDepth: 1` does not expand individual models --- src/core/components/models.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/components/models.jsx b/src/core/components/models.jsx index 1bd14a77145..74930c03feb 100644 --- a/src/core/components/models.jsx +++ b/src/core/components/models.jsx @@ -36,7 +36,7 @@ export default class Models extends Component { return
Date: Tue, 13 Feb 2018 22:10:09 -0800 Subject: [PATCH 11/25] Render faked Model expander to trigger resolution --- src/core/components/model-collapse.jsx | 27 +++++++++++-- src/core/components/models.jsx | 54 ++++++++++++++++++++------ src/style/_models.scss | 1 + 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/core/components/model-collapse.jsx b/src/core/components/model-collapse.jsx index 528ec09d0e0..30b1dabe4cd 100644 --- a/src/core/components/model-collapse.jsx +++ b/src/core/components/model-collapse.jsx @@ -8,14 +8,17 @@ export default class ModelCollapse extends Component { children: PropTypes.any, title: PropTypes.element, modelName: PropTypes.string, - onToggle: PropTypes.func + classes: PropTypes.string, + onToggle: PropTypes.func, + hideSelfOnExpand: PropTypes.bool, } static defaultProps = { collapsedContent: "{...}", expanded: false, title: null, - onToggle: () => {} + onToggle: () => {}, + hideSelfOnExpand: false } constructor(props, context) { @@ -29,6 +32,16 @@ export default class ModelCollapse extends Component { } } + componentDidMount() { + const { hideSelfOnExpand, expanded, modelName } = this.props + if(hideSelfOnExpand && expanded) { + // We just mounted pre-expanded, and we won't be going back.. + // So let's give our parent an `onToggle` call.. + // Since otherwise it will never be called. + this.props.onToggle(modelName, expanded) + } + } + componentWillReceiveProps(nextProps){ if(this.props.expanded!= nextProps.expanded){ @@ -50,9 +63,15 @@ export default class ModelCollapse extends Component { } render () { - const {title} = this.props + const { title, classes } = this.props + + if(this.state.expanded && this.props.hideSelfOnExpand) { + return + {this.props.children} + + } return ( - + { title && {title} } diff --git a/src/core/components/models.jsx b/src/core/components/models.jsx index 74930c03feb..cb585316865 100644 --- a/src/core/components/models.jsx +++ b/src/core/components/models.jsx @@ -6,11 +6,28 @@ export default class Models extends Component { static propTypes = { getComponent: PropTypes.func, specSelectors: PropTypes.object, + specActions: PropTypes.object.isRequired, layoutSelectors: PropTypes.object, layoutActions: PropTypes.object, getConfigs: PropTypes.func.isRequired } + getSchemaBasePath = () => { + const isOAS3 = this.props.specSelectors.isOAS3() + return isOAS3 ? ["components", "schemas"] : ["definitions"] + } + + getCollapsedContent = (name) => { + return " " + } + + handleToggle = (name, isExpanded) => { + console.log(`handleToggle`, name, isExpanded) + if(isExpanded) { + this.props.specActions.requestResolvedSubtree([...this.getSchemaBasePath(), name]) + } + } + render(){ let { specSelectors, getComponent, layoutSelectors, layoutActions, getConfigs } = this.props let definitions = specSelectors.definitions() @@ -18,10 +35,11 @@ export default class Models extends Component { if (!definitions.size || defaultModelsExpandDepth < 0) return null let showModels = layoutSelectors.isShown("models", defaultModelsExpandDepth > 0 && docExpansion !== "none") - const specPathBase = specSelectors.isOAS3() ? ["components", "schemas"] : ["definitions"] + const specPathBase = this.getSchemaBasePath() const ModelWrapper = getComponent("ModelWrapper") const Collapse = getComponent("Collapse") + const ModelCollapse = getComponent("ModelCollapse") return

layoutActions.show("models", !showModels)}> @@ -32,18 +50,32 @@ export default class Models extends Component {

{ - definitions.entrySeq().map( ( [ name, model ])=>{ + definitions.entrySeq().map( ( [ name ])=>{ + + const content = + + const title = + {name} + return
- + 1} + >{content}
}).toArray() } diff --git a/src/style/_models.scss b/src/style/_models.scss index 5b69b3fd159..2ee50c281ed 100644 --- a/src/style/_models.scss +++ b/src/style/_models.scss @@ -198,6 +198,7 @@ section.models .model-box { padding: 10px; + display: inline-block; border-radius: 4px; background: rgba($section-models-model-box-background-color,.1); From 860a868b57150edd58152e0c2932a5d88788bfb7 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 15 Feb 2018 21:22:10 -0800 Subject: [PATCH 12/25] Baseline support for Editor lifecycles --- src/core/components/model-collapse.jsx | 17 ++++++------- src/core/components/model-wrapper.jsx | 1 + src/core/components/models.jsx | 13 +++++++++- src/core/containers/OperationContainer.jsx | 10 +++++++- src/core/plugins/err/actions.js | 9 +++++++ src/core/plugins/err/reducers.js | 29 ++++++++++++++++++++-- src/core/plugins/layout/reducers.js | 1 + src/core/plugins/spec/reducers.js | 1 + src/core/plugins/spec/wrap-actions.js | 4 +-- 9 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/core/components/model-collapse.jsx b/src/core/components/model-collapse.jsx index 30b1dabe4cd..41ae29b94bb 100644 --- a/src/core/components/model-collapse.jsx +++ b/src/core/components/model-collapse.jsx @@ -43,16 +43,12 @@ export default class ModelCollapse extends Component { } componentWillReceiveProps(nextProps){ - - if(this.props.expanded!= nextProps.expanded){ + if(this.props.expanded !== nextProps.expanded){ this.setState({expanded: nextProps.expanded}) } - } toggleCollapsed=()=>{ - - if(this.props.onToggle){ this.props.onToggle(this.props.modelName,!this.state.expanded) } @@ -65,11 +61,14 @@ export default class ModelCollapse extends Component { render () { const { title, classes } = this.props - if(this.state.expanded && this.props.hideSelfOnExpand) { - return - {this.props.children} - + if(this.state.expanded ) { + if(this.props.hideSelfOnExpand) { + return + {this.props.children} + + } } + return ( { title && {title} } diff --git a/src/core/components/model-wrapper.jsx b/src/core/components/model-wrapper.jsx index 24d9020931f..00fec83bca8 100644 --- a/src/core/components/model-wrapper.jsx +++ b/src/core/components/model-wrapper.jsx @@ -25,6 +25,7 @@ export default class ModelWrapper extends Component { } render(){ + console.log(`rendering ModelWrapper`) let { getComponent, getConfigs } = this.props const Model = getComponent("Model") diff --git a/src/core/components/models.jsx b/src/core/components/models.jsx index cb585316865..5656efcf9df 100644 --- a/src/core/components/models.jsx +++ b/src/core/components/models.jsx @@ -22,13 +22,16 @@ export default class Models extends Component { } handleToggle = (name, isExpanded) => { + const { layoutActions } = this.props console.log(`handleToggle`, name, isExpanded) + layoutActions.show(["models", name], isExpanded) if(isExpanded) { this.props.specActions.requestResolvedSubtree([...this.getSchemaBasePath(), name]) } } render(){ + console.log(`rendering Models`) let { specSelectors, getComponent, layoutSelectors, layoutActions, getConfigs } = this.props let definitions = specSelectors.definitions() let { docExpansion, defaultModelsExpandDepth } = getConfigs() @@ -52,9 +55,17 @@ export default class Models extends Component { { definitions.entrySeq().map( ( [ name ])=>{ + const schema = specSelectors.specResolvedSubtree([...specPathBase, name]) + + if(layoutSelectors.isShown(["models", name], false) && schema === undefined) { + // Firing an action in a container render is not great, + // but it works for now. + this.props.specActions.requestResolvedSubtree([...this.getSchemaBasePath(), name]) + } + const content = true) { + // filter is a function + return { + type: CLEAR_BY, + payload: filter + } +} diff --git a/src/core/plugins/err/reducers.js b/src/core/plugins/err/reducers.js index 795f5dd59f7..963a082341b 100644 --- a/src/core/plugins/err/reducers.js +++ b/src/core/plugins/err/reducers.js @@ -4,7 +4,8 @@ import { NEW_SPEC_ERR, NEW_SPEC_ERR_BATCH, NEW_AUTH_ERR, - CLEAR + CLEAR, + CLEAR_BY, } from "./actions" import reject from "lodash/reject" @@ -69,7 +70,31 @@ export default function(system) { return } // TODO: Rework, to use immutable only, no need for lodash - let newErrors = Im.fromJS(reject((state.get("errors") || List()).toJS(), payload)) + // let newErrors = Im.fromJS(reject((state.get("errors") || List()).toJS(), payload)) + let newErrors = state.get("errors") + .filter(err => { + return err.keySeq().every(k => { + const errValue = err.get(k) + const filterValue = payload[k] + + if(!filterValue) return true + + return errValue !== filterValue + }) + }) + return state.merge({ + errors: newErrors + }) + }, + + [CLEAR_BY]: (state, { payload }) => { + if(!payload || typeof payload !== "function") { + return + } + let newErrors = state.get("errors") + .filter(err => { + return payload(err) + }) return state.merge({ errors: newErrors }) diff --git a/src/core/plugins/layout/reducers.js b/src/core/plugins/layout/reducers.js index aa067abdfd0..503119e0239 100644 --- a/src/core/plugins/layout/reducers.js +++ b/src/core/plugins/layout/reducers.js @@ -13,6 +13,7 @@ export default { [UPDATE_FILTER]: (state, action) => state.set("filter", action.payload), [SHOW]: (state, action) => { + console.log(`i said hey what's up hello`) const isShown = action.payload.shown // This is one way to serialize an array, another (preferred) is to convert to json-pointer // TODO: use json-pointer serilization instead of fromJS(...), for performance diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index eec435ba8dd..3e9ac3a2940 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -43,6 +43,7 @@ export default { [UPDATE_RESOLVED_SUBTREE]: (state, action) => { const { value, path } = action.payload + console.log(`updating resolved subtree:`, path, value.toJS ? value.toJS() : value) return state.setIn(["resolvedSubtrees", ...path], fromJSOrdered(value)) }, diff --git a/src/core/plugins/spec/wrap-actions.js b/src/core/plugins/spec/wrap-actions.js index a9c73f22baa..324ddda1d9c 100644 --- a/src/core/plugins/spec/wrap-actions.js +++ b/src/core/plugins/spec/wrap-actions.js @@ -5,7 +5,7 @@ export const updateSpec = (ori, {specActions}) => (...args) => { export const updateJsonSpec = (ori, {specActions}) => (...args) => { ori(...args) - specActions.resolveSpec(...args) + specActions.invalidateResolvedSubtreeCache() } // Log the request ( just for debugging, shouldn't affect prod ) @@ -16,4 +16,4 @@ export const executeRequest = (ori, { specActions }) => (req) => { export const validateParams = (ori, { specSelectors }) => (req) => { return ori(req, specSelectors.isOAS3()) -} \ No newline at end of file +} From e3514d52de18860841efb0ec2cb541011fbaa759 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 15 Feb 2018 22:24:30 -0800 Subject: [PATCH 13/25] Display operation summaries before the operation is resolved --- src/core/components/operation.jsx | 9 ++++++--- src/core/containers/OperationContainer.jsx | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/components/operation.jsx b/src/core/components/operation.jsx index bce484cb83d..c060e3853b9 100644 --- a/src/core/components/operation.jsx +++ b/src/core/components/operation.jsx @@ -9,6 +9,7 @@ export default class Operation extends PureComponent { static propTypes = { specPath: ImPropTypes.list.isRequired, operation: PropTypes.instanceOf(Iterable).isRequired, + summary: PropTypes.string, response: PropTypes.instanceOf(Iterable), request: PropTypes.instanceOf(Iterable), @@ -34,7 +35,8 @@ export default class Operation extends PureComponent { operation: null, response: null, request: null, - specPath: List() + specPath: List(), + summary: "" } render() { @@ -59,6 +61,7 @@ export default class Operation extends PureComponent { let operationProps = this.props.operation let { + summary, isShown, isAuthorized, path, @@ -76,7 +79,7 @@ export default class Operation extends PureComponent { } = operationProps.toJS() let { - summary, + summary: resolvedSummary, description, deprecated, externalDocs, @@ -132,7 +135,7 @@ export default class Operation extends PureComponent { { !showSummary ? null :
- { summary } + { resolvedSummary || summary }
} diff --git a/src/core/containers/OperationContainer.jsx b/src/core/containers/OperationContainer.jsx index d7befd0519e..9e7e536ff17 100644 --- a/src/core/containers/OperationContainer.jsx +++ b/src/core/containers/OperationContainer.jsx @@ -112,6 +112,7 @@ export default class OperationContainer extends PureComponent { render() { let { + op: unresolvedOp, tag, path, method, @@ -155,6 +156,7 @@ export default class OperationContainer extends PureComponent { op: resolvedSubtree || Map(), tag, path, + summary: unresolvedOp.getIn(["operation", "summary"]) || "", method, security, isAuthorized, From f76e92864b1302bd2bbd0bc02d3ff1b51bb47380 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 15 Feb 2018 22:24:44 -0800 Subject: [PATCH 14/25] Test migrations --- test/components/models.js | 3 ++- test/core/plugins/spec/selectors.js | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/test/components/models.js b/test/components/models.js index 0280e0fba49..11a8b7f4434 100644 --- a/test/components/models.js +++ b/test/components/models.js @@ -24,7 +24,8 @@ describe("", function(){ def1: {}, def2: {} }) - } + }, + specResolvedSubtree: () => {} }, layoutSelectors: { isShown: createSpy() diff --git a/test/core/plugins/spec/selectors.js b/test/core/plugins/spec/selectors.js index 824464899f9..a11699ef110 100644 --- a/test/core/plugins/spec/selectors.js +++ b/test/core/plugins/spec/selectors.js @@ -24,7 +24,7 @@ describe("spec plugin - selectors", function(){ // Given const spec = fromJS({ - resolved: { + json: { paths: { "/one": { get: { @@ -55,7 +55,7 @@ describe("spec plugin - selectors", function(){ it("should return { requestContentType, responseContentType } from an operation", function(){ // Given let state = fromJS({ - resolved: { + json: { paths: { "/one": { get: {} @@ -86,7 +86,7 @@ describe("spec plugin - selectors", function(){ it("should default to the first `produces` array value if current is not set", function(){ // Given let state = fromJS({ - resolved: { + json: { paths: { "/one": { get: { @@ -121,7 +121,7 @@ describe("spec plugin - selectors", function(){ it("should default to `application/json` if a default produces value is not available", function(){ // Given let state = fromJS({ - resolved: { + json: { paths: { "/one": { get: {} @@ -151,7 +151,7 @@ describe("spec plugin - selectors", function(){ it("should prioritize consumes value first from an operation", function(){ // Given let state = fromJS({ - resolved: { + json: { paths: { "/one": { get: { @@ -182,7 +182,7 @@ describe("spec plugin - selectors", function(){ it("should fallback to multipart/form-data if there is no consumes value but there is a file parameter", function(){ // Given let state = fromJS({ - resolved: { + json: { paths: { "/one": { get: { @@ -204,7 +204,7 @@ describe("spec plugin - selectors", function(){ it("should fallback to application/x-www-form-urlencoded if there is no consumes value, no file parameter, but there is a formData parameter", function(){ // Given let state = fromJS({ - resolved: { + json: { paths: { "/one": { get: { @@ -244,7 +244,7 @@ describe("spec plugin - selectors", function(){ // Given let state = fromJS({ url: "https://generator.swagger.io/api/swagger.json", - resolved: { + json: { paths: { "/one": { get: { From d1f235d5db2cdcc946f0aa58de359dd3bb2881a1 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Fri, 16 Feb 2018 19:26:07 -0800 Subject: [PATCH 15/25] WIP --- src/core/plugins/err/reducers.js | 6 +++--- src/core/plugins/spec/actions.js | 17 +++++++++++++++-- src/core/plugins/spec/reducers.js | 8 ++++---- src/core/plugins/spec/selectors.js | 16 +++++++++++++--- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/core/plugins/err/reducers.js b/src/core/plugins/err/reducers.js index 963a082341b..d2df95b32b0 100644 --- a/src/core/plugins/err/reducers.js +++ b/src/core/plugins/err/reducers.js @@ -66,8 +66,8 @@ export default function(system) { }, [CLEAR]: (state, { payload }) => { - if(!payload) { - return + if(!payload || !state.get("errors")) { + return state } // TODO: Rework, to use immutable only, no need for lodash // let newErrors = Im.fromJS(reject((state.get("errors") || List()).toJS(), payload)) @@ -89,7 +89,7 @@ export default function(system) { [CLEAR_BY]: (state, { payload }) => { if(!payload || typeof payload !== "function") { - return + return state } let newErrors = state.get("errors") .filter(err => { diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js index c642e545b21..eb34575a4ea 100644 --- a/src/core/plugins/spec/actions.js +++ b/src/core/plugins/spec/actions.js @@ -311,6 +311,8 @@ export const executeRequest = (req) => } } + console.log(req) + let parsedRequest = Object.assign({}, req) parsedRequest = fn.buildRequest(parsedRequest) @@ -329,6 +331,7 @@ export const executeRequest = (req) => // track duration of request const startTime = Date.now() + return fn.execute(req) .then( res => { res.duration = Date.now() - startTime @@ -344,14 +347,24 @@ export const executeRequest = (req) => // I'm using extras as a way to inject properties into the final, `execute` method - It's not great. Anyone have a better idea? @ponelat export const execute = ( { path, method, ...extras }={} ) => (system) => { + debugger let { fn:{fetch}, specSelectors, specActions } = system - let spec = specSelectors.spec().toJS() + let spec = specSelectors.specJsonWithResolvedSubtrees().toJS() let scheme = specSelectors.operationScheme(path, method) let { requestContentType, responseContentType } = specSelectors.contentTypeValues([path, method]).toJS() let isXml = /xml/i.test(requestContentType) let parameters = specSelectors.parameterValues([path, method], isXml).toJS() - return specActions.executeRequest({fetch, spec, pathName: path, method, parameters, requestContentType, scheme, responseContentType, ...extras }) + return specActions.executeRequest({ + ...extras, + fetch, + spec, + pathName: path, + method, parameters, + requestContentType, + scheme, + responseContentType + }) } export function clearResponse (path, method) { diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index 3e9ac3a2940..ca2e6aa01cc 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -50,7 +50,7 @@ export default { [UPDATE_PARAM]: ( state, {payload} ) => { let { path, paramName, paramIn, value, isXml } = payload - return state.updateIn( [ "resolved", "paths", ...path, "parameters" ], fromJS([]), parameters => { + return state.updateIn( [ "parameterValues", ...path, "parameters" ], fromJS([]), parameters => { const index = parameters.findIndex(p => p.get( "name" ) === paramName && p.get("in") === paramIn ) if (!(value instanceof win.File)) { value = fromJSOrdered( value ) @@ -63,7 +63,7 @@ export default { let meta = state.getIn( [ "meta", "paths", ...pathMethod ], fromJS({}) ) let isXml = /xml/i.test(meta.get("consumes_value")) - return state.updateIn( [ "resolved", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { + return state.updateIn( [ "parameterValues", ...pathMethod, "parameters" ], fromJS([]), parameters => { return parameters.withMutations( parameters => { for ( let i = 0, len = parameters.count(); i < len; i++ ) { let errors = validateParam(parameters.get(i), isXml, isOAS3) @@ -73,7 +73,7 @@ export default { }) }, [CLEAR_VALIDATE_PARAMS]: ( state, { payload: { pathMethod } } ) => { - return state.updateIn( [ "resolved", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { + return state.updateIn( [ "parameterValues", ...pathMethod, "parameters" ], fromJS([]), parameters => { return parameters.withMutations( parameters => { for ( let i = 0, len = parameters.count(); i < len; i++ ) { parameters.setIn([i, "errors"], fromJS([])) @@ -117,7 +117,7 @@ export default { [UPDATE_OPERATION_META_VALUE]: (state, { payload: { path, value, key } }) => { // path is a pathMethod tuple... can't change the name now. - let operationPath = ["resolved", "paths", ...path] + let operationPath = ["json", "paths", ...path] let metaPath = ["meta", "paths", ...path] if(!state.getIn(operationPath)) { diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index 96f4688ab6c..4d9d14e12c3 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -46,6 +46,11 @@ export const specResolvedSubtree = (state, path) => { return state.getIn(["resolvedSubtrees", ...path], undefined) } +export const specJsonWithResolvedSubtrees = createSelector( + state, + spec => Map().merge(spec.get("json"), spec.get("resolvedSubtrees")) +) + // Default Spec ( as an object ) export const spec = state => { let res = specJson(state) @@ -141,7 +146,10 @@ export const securityDefinitions = createSelector( export const findDefinition = ( state, name ) => { - return specResolved(state).getIn(["definitions", name], null) + // TODO: migrate + const resolvedRes = state.getIn(["resolvedSubtrees", "definitions", name], null) + const unresolvedRes = state.getIn(["json", "definitions", name], null) + return resolvedRes || unresolvedRes || null } export const definitions = createSelector( @@ -267,8 +275,9 @@ export const allowTryItOutFor = () => { // Get the parameter value by parameter name export function getParameter(state, pathMethod, name, inType) { + // TODO: migrate pathMethod = pathMethod || [] - let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) + let params = specJsonWithResolvedSubtrees(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) return params.find( (p) => { return Map.isMap(p) && p.get("name") === name && p.get("in") === inType }) || Map() // Always return a map @@ -284,8 +293,9 @@ export const hasHost = createSelector( // Get the parameter values, that the user filled out export function parameterValues(state, pathMethod, isXml) { + // TODO: migrate pathMethod = pathMethod || [] - let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) + let params = specJsonWithResolvedSubtrees(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("in")}.${p.get("name")}`, value) From 12359329aa1d76c4e38eebde92ce167bc60dcb02 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 20 Feb 2018 18:35:30 -0800 Subject: [PATCH 16/25] Swagger2 TIO Body params --- src/core/components/param-body.jsx | 4 +- src/core/components/parameter-row.jsx | 7 ++- src/core/components/parameters.jsx | 2 +- src/core/plugins/spec/reducers.js | 67 ++++++++++++++++++--------- src/core/plugins/spec/selectors.js | 51 ++++++++++++++++---- 5 files changed, 92 insertions(+), 39 deletions(-) diff --git a/src/core/components/param-body.jsx b/src/core/components/param-body.jsx index 13a4377f8c7..a6097c76ec2 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"), param.get("in")) : fromJS({}) + let parameter = specSelectors ? specSelectors.parameterWithMeta(pathMethod, param.get("name"), param.get("in")) : fromJS({}) let isXml = /xml/i.test(consumesValue) let isJson = /json/i.test(consumesValue) let paramValue = isXml ? parameter.get("value_xml") : parameter.get("value") @@ -107,7 +107,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.get("in")) : param + let parameter = specSelectors ? specSelectors.parameterWithMeta(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 42f45bd9b48..b3844574965 100644 --- a/src/core/components/parameter-row.jsx +++ b/src/core/components/parameter-row.jsx @@ -24,7 +24,7 @@ export default class ParameterRow extends Component { let { specSelectors, pathMethod, param } = props let defaultValue = param.get("default") - let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) + let parameter = specSelectors.parameterWithMeta(pathMethod, param.get("name"), param.get("in")) let value = parameter ? parameter.get("value") : "" if ( defaultValue !== undefined && value === undefined ) { this.onChangeWrapper(defaultValue) @@ -37,7 +37,7 @@ export default class ParameterRow extends Component { let example = param.get("example") let defaultValue = param.get("default") - let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) + let parameter = specSelectors.parameterWithMeta(pathMethod, param.get("name"), param.get("in")) let enumValue if(isOAS3()) { @@ -104,8 +104,7 @@ export default class ParameterRow extends Component { let isFormDataSupported = "FormData" in win let required = param.get("required") let itemType = param.getIn(isOAS3 && isOAS3() ? ["schema", "items", "type"] : ["items", "type"]) - let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) - let value = parameter ? parameter.get("value") : "" + let value = param ? param.get("value") : "" let extensions = getExtensions(param) diff --git a/src/core/components/parameters.jsx b/src/core/components/parameters.jsx index c1c6ded3082..c5b1e2293ad 100644 --- a/src/core/components/parameters.jsx +++ b/src/core/components/parameters.jsx @@ -101,7 +101,7 @@ export default class Parameters extends Component { specPath={specPath.push(i.toString())} getComponent={ getComponent } getConfigs={ getConfigs } - param={ parameter } + param={ specSelectors.parameterWithMeta(pathMethod, parameter.get("name"), parameter.get("in")) } key={ `${parameter.get( "in" )}.${parameter.get("name")}` } onChange={ this.onChange } onChangeConsumes={this.onChangeConsumesWrapper} diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index ca2e6aa01cc..159edecfb23 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -1,7 +1,12 @@ -import { fromJS } from "immutable" +import { fromJS, List } from "immutable" import { fromJSOrdered, validateParam } from "core/utils" import win from "../../window" +// selector-in-reducer is suboptimal, but `operationWithMeta` is more of a helper +import { + operationWithMeta +} from "./selectors" + import { UPDATE_SPEC, UPDATE_URL, @@ -48,37 +53,53 @@ export default { }, [UPDATE_PARAM]: ( state, {payload} ) => { - let { path, paramName, paramIn, value, isXml } = payload - - return state.updateIn( [ "parameterValues", ...path, "parameters" ], fromJS([]), parameters => { - const index = parameters.findIndex(p => p.get( "name" ) === paramName && p.get("in") === paramIn ) - if (!(value instanceof win.File)) { - value = fromJSOrdered( value ) - } - return parameters.setIn( [ index, isXml ? "value_xml" : "value" ], value) - }) + let { path: pathMethod, paramName, paramIn, value, isXml } = payload + + const valueKey = isXml ? "value_xml" : "value" + + return state.setIn( + ["meta", "paths", ...pathMethod, "parameters", `${paramName}.${paramIn}`, valueKey], + value + ) + + // TODO: delete + // return state.updateIn( [ "meta", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { + // const index = parameters.findIndex(p => p.get( "name" ) === paramName && p.get("in") === paramIn ) + // if (!(value instanceof win.File)) { + // value = fromJSOrdered( value ) + // } + // return parameters.setIn( [ index, isXml ? "value_xml" : "value" ], value) + // }) }, [VALIDATE_PARAMS]: ( state, { payload: { pathMethod, isOAS3 } } ) => { let meta = state.getIn( [ "meta", "paths", ...pathMethod ], fromJS({}) ) let isXml = /xml/i.test(meta.get("consumes_value")) - return state.updateIn( [ "parameterValues", ...pathMethod, "parameters" ], fromJS([]), parameters => { - return parameters.withMutations( parameters => { - for ( let i = 0, len = parameters.count(); i < len; i++ ) { - let errors = validateParam(parameters.get(i), isXml, isOAS3) - parameters.setIn([i, "errors"], fromJS(errors)) - } - }) + const op = operationWithMeta(state, ...pathMethod) + + debugger + + return state.updateIn(["meta", "paths", ...pathMethod, "parameters"], fromJS({}), paramMeta => { + return op.get("parameters", List()).reduce((res, param) => { + const errors = validateParam(param, isXml, isOAS3) + return res.setIn([`${param.get("name")}.${param.get("in")}`, "errors"], fromJS(errors)) + }, paramMeta) }) + + // return state.updateIn( [ "meta", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { + // return parameters.withMutations( parameters => { + // for ( let i = 0, len = parameters.count(); i < len; i++ ) { + // console.log("validateParams", parameters.get(i).toJS(), isXml, isOAS3) + // let errors = validateParam(parameters.get(i), isXml, isOAS3) + // parameters.setIn([i, "errors"], fromJS(errors)) + // } + // }) + // }) }, [CLEAR_VALIDATE_PARAMS]: ( state, { payload: { pathMethod } } ) => { - return state.updateIn( [ "parameterValues", ...pathMethod, "parameters" ], fromJS([]), parameters => { - return parameters.withMutations( parameters => { - for ( let i = 0, len = parameters.count(); i < len; i++ ) { - parameters.setIn([i, "errors"], fromJS([])) - } - }) + return state.updateIn( [ "meta", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { + return parameters.map(param => param.set("errors", fromJS([]))) }) }, diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index 4d9d14e12c3..f2398e6c50c 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -273,11 +273,41 @@ export const allowTryItOutFor = () => { return true } +export const operationWithMeta = (state, path, method) => { + const op = specJsonWithResolvedSubtrees(state).getIn(["paths", path, method], Map()) + const meta = state.getIn(["meta", "paths", path, method], Map()) + + const mergedParams = op.get("parameters", List()).map((param) => { + return Map().merge( + param, + meta.getIn(["parameters", `${param.get("name")}.${param.get("in")}`]) + ) + }) + + return Map() + .merge(op, meta) + .set("parameters", mergedParams) +} + +export const parameterWithMeta = (state, pathMethod, paramName, paramIn) => { + const opParams = specJsonWithResolvedSubtrees(state).getIn(["paths", ...pathMethod, "parameters"], Map()) + const metaParams = state.getIn(["meta", "paths", ...pathMethod, "parameters"], Map()) + + const mergedParams = opParams.map((param) => { + return Map().merge( + param, + metaParams.get(`${param.get("name")}.${param.get("in")}`) + ) + }) + + return mergedParams.find(param => param.get("in") === paramIn && param.get("name") === paramName, Map()) +} + // Get the parameter value by parameter name export function getParameter(state, pathMethod, name, inType) { // TODO: migrate pathMethod = pathMethod || [] - let params = specJsonWithResolvedSubtrees(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) + let params = state.getIn(["meta", "paths", ...pathMethod, "parameters"], fromJS([])) return params.find( (p) => { return Map.isMap(p) && p.get("name") === name && p.get("in") === inType }) || Map() // Always return a map @@ -293,10 +323,11 @@ export const hasHost = createSelector( // Get the parameter values, that the user filled out export function parameterValues(state, pathMethod, isXml) { - // TODO: migrate pathMethod = pathMethod || [] - let params = specJsonWithResolvedSubtrees(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) - return params.reduce( (hash, p) => { + // let paramValues = state.getIn(["meta", "paths", ...pathMethod, "parameters"], fromJS([])) + let paramValues = operationWithMeta(state, ...pathMethod).get("parameters", List()) + console.log("paramValues", paramValues.toJS()) + return paramValues.reduce( (hash, p) => { let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value") return hash.set(`${p.get("in")}.${p.get("name")}`, value) }, fromJS({})) @@ -319,7 +350,7 @@ export function parametersIncludeType(parameters, typeValue="") { // Get the consumes/produces value that the user selected export function contentTypeValues(state, pathMethod) { pathMethod = pathMethod || [] - let op = spec(state).getIn(["paths", ...pathMethod], fromJS({})) + let op = specJsonWithResolvedSubtrees(state).getIn(["paths", ...pathMethod], fromJS({})) let meta = state.getIn(["meta", "paths", ...pathMethod], fromJS({})) let producesValue = currentProducesFor(state, pathMethod) @@ -341,14 +372,14 @@ export function contentTypeValues(state, pathMethod) { // Get the consumes/produces by path export function operationConsumes(state, pathMethod) { pathMethod = pathMethod || [] - return spec(state).getIn(["paths", ...pathMethod, "consumes"], fromJS({})) + return state.getIn(["meta", ...pathMethod, "consumes"], fromJS({})) } // Get the currently selected produces value for an operation export function currentProducesFor(state, pathMethod) { pathMethod = pathMethod || [] - const operation = spec(state).getIn(["paths", ...pathMethod], null) + const operation = specJsonWithResolvedSubtrees(state).getIn(["meta", "paths", ...pathMethod], null) if(operation === null) { // return nothing if the operation does not exist @@ -376,10 +407,12 @@ export const canExecuteScheme = ( state, path, method ) => { export const validateBeforeExecute = ( state, pathMethod ) => { pathMethod = pathMethod || [] - let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([])) + let paramValues = state.getIn(["meta", "paths", ...pathMethod, "parameters"], fromJS([])) let isValid = true - params.forEach( (p) => { + debugger + + paramValues.forEach( (p) => { let errors = p.get("errors") if ( errors && errors.count() ) { isValid = false From 4e1a36eb11deaf31cccd78b79225e0cca2e18746 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 20 Feb 2018 18:36:21 -0800 Subject: [PATCH 17/25] a bit of cleanup --- src/core/plugins/spec/reducers.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index 159edecfb23..2e3f166fc09 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -61,15 +61,6 @@ export default { ["meta", "paths", ...pathMethod, "parameters", `${paramName}.${paramIn}`, valueKey], value ) - - // TODO: delete - // return state.updateIn( [ "meta", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { - // const index = parameters.findIndex(p => p.get( "name" ) === paramName && p.get("in") === paramIn ) - // if (!(value instanceof win.File)) { - // value = fromJSOrdered( value ) - // } - // return parameters.setIn( [ index, isXml ? "value_xml" : "value" ], value) - // }) }, [VALIDATE_PARAMS]: ( state, { payload: { pathMethod, isOAS3 } } ) => { @@ -86,16 +77,6 @@ export default { return res.setIn([`${param.get("name")}.${param.get("in")}`, "errors"], fromJS(errors)) }, paramMeta) }) - - // return state.updateIn( [ "meta", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { - // return parameters.withMutations( parameters => { - // for ( let i = 0, len = parameters.count(); i < len; i++ ) { - // console.log("validateParams", parameters.get(i).toJS(), isXml, isOAS3) - // let errors = validateParam(parameters.get(i), isXml, isOAS3) - // parameters.setIn([i, "errors"], fromJS(errors)) - // } - // }) - // }) }, [CLEAR_VALIDATE_PARAMS]: ( state, { payload: { pathMethod } } ) => { return state.updateIn( [ "meta", "paths", ...pathMethod, "parameters" ], fromJS([]), parameters => { From d35abfe6fb6d62191246316a26b2b1b6251a6b43 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 20 Feb 2018 21:00:23 -0800 Subject: [PATCH 18/25] Debounce string param inputs --- package.json | 1 + src/core/json-schema-components.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 96737f2d505..e3586a58142 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "react-addons-shallow-compare": "0.14.8", "react-addons-test-utils": "^15.6.2", "react-collapse": "^4.0.3", + "react-debounce-input": "^3.2.0", "react-dom": "^15.6.2", "react-height": "^2.0.0", "react-hot-loader": "1.3.1", diff --git a/src/core/json-schema-components.js b/src/core/json-schema-components.js index 087b617ca33..14998febd3d 100644 --- a/src/core/json-schema-components.js +++ b/src/core/json-schema-components.js @@ -2,6 +2,7 @@ import React, { PureComponent, Component } from "react" import PropTypes from "prop-types" import { List, fromJS } from "immutable" import ImPropTypes from "react-immutable-proptypes" +import DebounceInput from "react-debounce-input" //import "less/json-schema-form" const noop = ()=> {} @@ -79,10 +80,13 @@ export class JsonSchema_string extends Component { disabled={isDisabled}/>) } else { - return () From cd73087b8bc0f49dbbb152f436154bf81fd6c3db Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 20 Feb 2018 21:43:19 -0800 Subject: [PATCH 19/25] Reach into unresolved operation for deprecated flag, if available --- src/core/components/operation.jsx | 2 +- src/core/containers/OperationContainer.jsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/components/operation.jsx b/src/core/components/operation.jsx index c060e3853b9..358291823fc 100644 --- a/src/core/components/operation.jsx +++ b/src/core/components/operation.jsx @@ -62,6 +62,7 @@ export default class Operation extends PureComponent { let { summary, + deprecated, isShown, isAuthorized, path, @@ -81,7 +82,6 @@ export default class Operation extends PureComponent { let { summary: resolvedSummary, description, - deprecated, externalDocs, schemes } = op diff --git a/src/core/containers/OperationContainer.jsx b/src/core/containers/OperationContainer.jsx index 9e7e536ff17..43fe38879e7 100644 --- a/src/core/containers/OperationContainer.jsx +++ b/src/core/containers/OperationContainer.jsx @@ -144,7 +144,7 @@ export default class OperationContainer extends PureComponent { const Operation = getComponent( "operation" ) - const resolvedSubtree = specSelectors.specResolvedSubtree(["paths", path, method]) + const resolvedSubtree = specSelectors.specResolvedSubtree(["paths", path, method]) || Map() console.log(`OperationContainer for ${path} ${method}`, isShown, resolvedSubtree && resolvedSubtree.toJS ? resolvedSubtree.toJS() : resolvedSubtree) @@ -157,6 +157,7 @@ export default class OperationContainer extends PureComponent { tag, path, summary: unresolvedOp.getIn(["operation", "summary"]) || "", + deprecated: resolvedSubtree.get("deprecated") || unresolvedOp.getIn(["operation", "deprecated"]) || false, method, security, isAuthorized, From 762d8f1ea0bcbffd35ca86325c55da818a3b8290 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 20 Feb 2018 22:49:43 -0800 Subject: [PATCH 20/25] Fire subtree request outside of render --- src/core/containers/OperationContainer.jsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/containers/OperationContainer.jsx b/src/core/containers/OperationContainer.jsx index 43fe38879e7..a72c080f504 100644 --- a/src/core/containers/OperationContainer.jsx +++ b/src/core/containers/OperationContainer.jsx @@ -82,9 +82,16 @@ export default class OperationContainer extends PureComponent { } componentWillReceiveProps(nextProps) { - if(nextProps.response !== this.props.response) { + const { path, method, specActions, specSelectors, response, isShown } = nextProps + const resolvedSubtree = specSelectors.specResolvedSubtree(["paths", path, method]) + + if(response !== this.props.response) { this.setState({ executeInProgress: false }) } + + if(isShown && resolvedSubtree === undefined) { + specActions.requestResolvedSubtree(["paths", path, method]) + } } toggleShown =() => { @@ -148,10 +155,6 @@ export default class OperationContainer extends PureComponent { console.log(`OperationContainer for ${path} ${method}`, isShown, resolvedSubtree && resolvedSubtree.toJS ? resolvedSubtree.toJS() : resolvedSubtree) - if(isShown && resolvedSubtree === undefined) { - specActions.requestResolvedSubtree(["paths", path, method]) - } - const operationProps = fromJS({ op: resolvedSubtree || Map(), tag, From 579dfb94c164d98f1d0067fe95d205862ee47384 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Tue, 20 Feb 2018 22:57:34 -0800 Subject: [PATCH 21/25] Remove debugging flags --- src/core/components/model-wrapper.jsx | 1 - src/core/components/models.jsx | 2 -- src/core/containers/OperationContainer.jsx | 2 -- src/core/plugins/layout/reducers.js | 1 - src/core/plugins/spec/actions.js | 6 ------ src/core/plugins/spec/reducers.js | 3 --- src/core/plugins/spec/selectors.js | 3 --- 7 files changed, 18 deletions(-) diff --git a/src/core/components/model-wrapper.jsx b/src/core/components/model-wrapper.jsx index 00fec83bca8..24d9020931f 100644 --- a/src/core/components/model-wrapper.jsx +++ b/src/core/components/model-wrapper.jsx @@ -25,7 +25,6 @@ export default class ModelWrapper extends Component { } render(){ - console.log(`rendering ModelWrapper`) let { getComponent, getConfigs } = this.props const Model = getComponent("Model") diff --git a/src/core/components/models.jsx b/src/core/components/models.jsx index 5656efcf9df..6e043403f13 100644 --- a/src/core/components/models.jsx +++ b/src/core/components/models.jsx @@ -23,7 +23,6 @@ export default class Models extends Component { handleToggle = (name, isExpanded) => { const { layoutActions } = this.props - console.log(`handleToggle`, name, isExpanded) layoutActions.show(["models", name], isExpanded) if(isExpanded) { this.props.specActions.requestResolvedSubtree([...this.getSchemaBasePath(), name]) @@ -31,7 +30,6 @@ export default class Models extends Component { } render(){ - console.log(`rendering Models`) let { specSelectors, getComponent, layoutSelectors, layoutActions, getConfigs } = this.props let definitions = specSelectors.definitions() let { docExpansion, defaultModelsExpandDepth } = getConfigs() diff --git a/src/core/containers/OperationContainer.jsx b/src/core/containers/OperationContainer.jsx index a72c080f504..af2004a5d76 100644 --- a/src/core/containers/OperationContainer.jsx +++ b/src/core/containers/OperationContainer.jsx @@ -153,8 +153,6 @@ export default class OperationContainer extends PureComponent { const resolvedSubtree = specSelectors.specResolvedSubtree(["paths", path, method]) || Map() - console.log(`OperationContainer for ${path} ${method}`, isShown, resolvedSubtree && resolvedSubtree.toJS ? resolvedSubtree.toJS() : resolvedSubtree) - const operationProps = fromJS({ op: resolvedSubtree || Map(), tag, diff --git a/src/core/plugins/layout/reducers.js b/src/core/plugins/layout/reducers.js index 503119e0239..aa067abdfd0 100644 --- a/src/core/plugins/layout/reducers.js +++ b/src/core/plugins/layout/reducers.js @@ -13,7 +13,6 @@ export default { [UPDATE_FILTER]: (state, action) => state.set("filter", action.payload), [SHOW]: (state, action) => { - console.log(`i said hey what's up hello`) const isShown = action.payload.shown // This is one way to serialize an array, another (preferred) is to convert to json-pointer // TODO: use json-pointer serilization instead of fromJS(...), for performance diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js index eb34575a4ea..b5c719385a5 100644 --- a/src/core/plugins/spec/actions.js +++ b/src/core/plugins/spec/actions.js @@ -84,8 +84,6 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio hasWarnedAboutResolveSpecDeprecation = true } - return - const { modelPropertyMacro, parameterMacro, @@ -156,7 +154,6 @@ export const requestResolvedSubtree = path => system => { const currentValue = specSelectors.specResolvedSubtree(path) if(currentValue) { - console.log(`DEV DEBUG: subtree already exists; not resolving again`) return } @@ -311,8 +308,6 @@ export const executeRequest = (req) => } } - console.log(req) - let parsedRequest = Object.assign({}, req) parsedRequest = fn.buildRequest(parsedRequest) @@ -347,7 +342,6 @@ export const executeRequest = (req) => // I'm using extras as a way to inject properties into the final, `execute` method - It's not great. Anyone have a better idea? @ponelat export const execute = ( { path, method, ...extras }={} ) => (system) => { - debugger let { fn:{fetch}, specSelectors, specActions } = system let spec = specSelectors.specJsonWithResolvedSubtrees().toJS() let scheme = specSelectors.operationScheme(path, method) diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index 2e3f166fc09..9b9d1399530 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -48,7 +48,6 @@ export default { [UPDATE_RESOLVED_SUBTREE]: (state, action) => { const { value, path } = action.payload - console.log(`updating resolved subtree:`, path, value.toJS ? value.toJS() : value) return state.setIn(["resolvedSubtrees", ...path], fromJSOrdered(value)) }, @@ -69,8 +68,6 @@ export default { const op = operationWithMeta(state, ...pathMethod) - debugger - return state.updateIn(["meta", "paths", ...pathMethod, "parameters"], fromJS({}), paramMeta => { return op.get("parameters", List()).reduce((res, param) => { const errors = validateParam(param, isXml, isOAS3) diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index f2398e6c50c..fd50d267590 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -326,7 +326,6 @@ export function parameterValues(state, pathMethod, isXml) { pathMethod = pathMethod || [] // let paramValues = state.getIn(["meta", "paths", ...pathMethod, "parameters"], fromJS([])) let paramValues = operationWithMeta(state, ...pathMethod).get("parameters", List()) - console.log("paramValues", paramValues.toJS()) return paramValues.reduce( (hash, p) => { let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value") return hash.set(`${p.get("in")}.${p.get("name")}`, value) @@ -410,8 +409,6 @@ export const validateBeforeExecute = ( state, pathMethod ) => { let paramValues = state.getIn(["meta", "paths", ...pathMethod, "parameters"], fromJS([])) let isValid = true - debugger - paramValues.forEach( (p) => { let errors = p.get("errors") if ( errors && errors.count() ) { From 795a595fe3b9d68b2a04648a3c8fe7fd5bb4446b Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 22 Feb 2018 20:48:27 -0800 Subject: [PATCH 22/25] Fix logical errors in spec statePlugins --- src/core/plugins/spec/reducers.js | 4 ++-- src/core/plugins/spec/selectors.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index 9b9d1399530..245ebbcda5e 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -116,10 +116,10 @@ export default { [UPDATE_OPERATION_META_VALUE]: (state, { payload: { path, value, key } }) => { // path is a pathMethod tuple... can't change the name now. - let operationPath = ["json", "paths", ...path] + let operationPath = ["paths", ...path] let metaPath = ["meta", "paths", ...path] - if(!state.getIn(operationPath)) { + if(!state.getIn(["json", ...operationPath]) && !state.getIn(["resolved", ...operationPath])) { // do nothing if the operation does not exist return state } diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index fd50d267590..722939453b2 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -378,7 +378,7 @@ export function operationConsumes(state, pathMethod) { export function currentProducesFor(state, pathMethod) { pathMethod = pathMethod || [] - const operation = specJsonWithResolvedSubtrees(state).getIn(["meta", "paths", ...pathMethod], null) + const operation = specJsonWithResolvedSubtrees(state).getIn([ "paths", ...pathMethod], null) if(operation === null) { // return nothing if the operation does not exist From 9015026fdd5a00c5a3f556f63eaee9844ab403a0 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 22 Feb 2018 20:53:24 -0800 Subject: [PATCH 23/25] TODOs become TODONEs! --- src/core/plugins/err/reducers.js | 3 +-- src/core/plugins/spec/selectors.js | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/core/plugins/err/reducers.js b/src/core/plugins/err/reducers.js index d2df95b32b0..500e1508580 100644 --- a/src/core/plugins/err/reducers.js +++ b/src/core/plugins/err/reducers.js @@ -69,8 +69,7 @@ export default function(system) { if(!payload || !state.get("errors")) { return state } - // TODO: Rework, to use immutable only, no need for lodash - // let newErrors = Im.fromJS(reject((state.get("errors") || List()).toJS(), payload)) + let newErrors = state.get("errors") .filter(err => { return err.keySeq().every(k => { diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index 722939453b2..f8fa9a38df6 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -146,7 +146,6 @@ export const securityDefinitions = createSelector( export const findDefinition = ( state, name ) => { - // TODO: migrate const resolvedRes = state.getIn(["resolvedSubtrees", "definitions", name], null) const unresolvedRes = state.getIn(["json", "definitions", name], null) return resolvedRes || unresolvedRes || null @@ -305,7 +304,6 @@ export const parameterWithMeta = (state, pathMethod, paramName, paramIn) => { // Get the parameter value by parameter name export function getParameter(state, pathMethod, name, inType) { - // TODO: migrate pathMethod = pathMethod || [] let params = state.getIn(["meta", "paths", ...pathMethod, "parameters"], fromJS([])) return params.find( (p) => { From e419594f94c6529b4f7cf541a27872b1cd31ad8b Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Thu, 22 Feb 2018 23:40:39 -0800 Subject: [PATCH 24/25] Migrate deeplinking feature to non-resolved spec action --- src/core/plugins/deep-linking/spec-wrap-actions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/plugins/deep-linking/spec-wrap-actions.js b/src/core/plugins/deep-linking/spec-wrap-actions.js index d69fc46500f..398fbcbc282 100644 --- a/src/core/plugins/deep-linking/spec-wrap-actions.js +++ b/src/core/plugins/deep-linking/spec-wrap-actions.js @@ -4,7 +4,7 @@ import { escapeDeepLinkPath } from "core/utils" let hasHashBeenParsed = false //TODO this forces code to only run once which may prevent scrolling if page not refreshed -export const updateResolved = (ori, { layoutActions, getConfigs }) => (...args) => { +export const updateJsonSpec = (ori, { layoutActions, getConfigs }) => (...args) => { ori(...args) const isDeepLinkingEnabled = getConfigs().deepLinking From 496ed42996cc55b00630bddddaa2f6f7b2537582 Mon Sep 17 00:00:00 2001 From: Kyle Shockey Date: Fri, 23 Feb 2018 01:08:21 -0800 Subject: [PATCH 25/25] ESLint fixes --- src/core/components/models.jsx | 2 +- src/core/components/providers/markdown.jsx | 1 + src/core/plugins/err/reducers.js | 4 +--- src/core/plugins/oas3/spec-extensions/wrap-selectors.js | 2 +- src/core/plugins/spec/reducers.js | 1 - 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/components/models.jsx b/src/core/components/models.jsx index 6e043403f13..3bbe69eef5f 100644 --- a/src/core/components/models.jsx +++ b/src/core/components/models.jsx @@ -17,7 +17,7 @@ export default class Models extends Component { return isOAS3 ? ["components", "schemas"] : ["definitions"] } - getCollapsedContent = (name) => { + getCollapsedContent = () => { return " " } diff --git a/src/core/components/providers/markdown.jsx b/src/core/components/providers/markdown.jsx index 979b20010ce..a4cbf3f900e 100644 --- a/src/core/components/providers/markdown.jsx +++ b/src/core/components/providers/markdown.jsx @@ -3,6 +3,7 @@ import PropTypes from "prop-types" import Remarkable from "remarkable" import sanitize from "sanitize-html" +// eslint-disable-next-line no-useless-escape const isPlainText = (str) => /^[A-Z\s0-9!?\.]+$/gi.test(str) function Markdown({ source }) { diff --git a/src/core/plugins/err/reducers.js b/src/core/plugins/err/reducers.js index 500e1508580..8a9cbbbae22 100644 --- a/src/core/plugins/err/reducers.js +++ b/src/core/plugins/err/reducers.js @@ -8,9 +8,7 @@ import { CLEAR_BY, } from "./actions" -import reject from "lodash/reject" - -import Im, { fromJS, List } from "immutable" +import { fromJS, List } from "immutable" import transformErrors from "./error-transformers/hook" diff --git a/src/core/plugins/oas3/spec-extensions/wrap-selectors.js b/src/core/plugins/oas3/spec-extensions/wrap-selectors.js index 82c10f2196a..8109e2eff7f 100644 --- a/src/core/plugins/oas3/spec-extensions/wrap-selectors.js +++ b/src/core/plugins/oas3/spec-extensions/wrap-selectors.js @@ -20,7 +20,7 @@ const state = state => { return state || Map() } -const nullSelector = createSelector(() => null) +const nullSelector = createSelector(() => null) const OAS3NullSelector = onlyOAS3(nullSelector) diff --git a/src/core/plugins/spec/reducers.js b/src/core/plugins/spec/reducers.js index 245ebbcda5e..c4b9d96fd95 100644 --- a/src/core/plugins/spec/reducers.js +++ b/src/core/plugins/spec/reducers.js @@ -42,7 +42,6 @@ export default { }, [UPDATE_RESOLVED]: (state, action) => { - return state return state.setIn(["resolved"], fromJSOrdered(action.payload)) },