Merge branch 'master' into zopflipng
This commit is contained in:
8
.babelrc
8
.babelrc
@@ -9,6 +9,10 @@
|
|||||||
[
|
[
|
||||||
"module-alias",
|
"module-alias",
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
"expose": "root",
|
||||||
|
"src": "."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"expose": "components",
|
"expose": "components",
|
||||||
"src": "src/core/components"
|
"src": "src/core/components"
|
||||||
@@ -17,6 +21,10 @@
|
|||||||
"expose": "core",
|
"expose": "core",
|
||||||
"src": "src/core"
|
"src": "src/core"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"expose": "plugins",
|
||||||
|
"src": "src/plugins"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"expose": "img",
|
"expose": "img",
|
||||||
"src": "src/img"
|
"src": "src/img"
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2017 SmartBear Software
|
Copyright 2018 SmartBear Software
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -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.7.0 | 2017-12-15 | 2.0, 3.0 | [tag v3.7.0](https://github.com/swagger-api/swagger-ui/tree/v3.7.0)
|
3.8.0 | 2017-12-15 | 2.0, 3.0 | [tag v3.8.1](https://github.com/swagger-api/swagger-ui/tree/v3.8.1)
|
||||||
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)
|
||||||
|
|||||||
30
dist/swagger-ui-bundle.js
vendored
30
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
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
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
@@ -19,7 +19,9 @@ A plugin return value may contain any of these keys, where `myStateKey` is a nam
|
|||||||
},
|
},
|
||||||
components: {},
|
components: {},
|
||||||
wrapComponents: {},
|
wrapComponents: {},
|
||||||
fn: {}
|
rootInjects: {},
|
||||||
|
afterLoad: (system) => {},
|
||||||
|
fn: {},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -363,7 +365,55 @@ const MyWrapComponentPlugin = function(system) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### `rootInjects`
|
||||||
|
|
||||||
|
The `rootInjects` interface allows you to inject values at the top level of the system.
|
||||||
|
|
||||||
|
This interface takes an object, which will be merged in with the top-level system object at runtime.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const MyRootInjectsPlugin = function(system) {
|
||||||
|
return {
|
||||||
|
rootInjects: {
|
||||||
|
myConstant: 123,
|
||||||
|
myMethod: (...params) => console.log(...params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### `afterLoad`
|
||||||
|
|
||||||
|
The `afterLoad` plugin method allows you to get a reference to the system after your plugin has been registered.
|
||||||
|
|
||||||
|
This interface is used in the core code to attach methods that are driven by bound selectors or actions. You can also use it to execute logic that requires your plugin to already be ready, for example fetching initial data from a remote endpoint and passing it to an action your plugin creates.
|
||||||
|
|
||||||
|
The plugin context, which is bound to `this`, is undocumented, but below is an example of how to attach a bound action as a top-level method:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const MyMethodProvidingPlugin = function() {
|
||||||
|
return {
|
||||||
|
afterLoad(system) {
|
||||||
|
// at this point in time, your actions have been bound into the system
|
||||||
|
// so you can do things with them
|
||||||
|
this.rootInjects = this.rootInjects || {}
|
||||||
|
this.rootInjects.myMethod = system.exampleActions.updateFavoriteColor
|
||||||
|
},
|
||||||
|
statePlugins: {
|
||||||
|
example: {
|
||||||
|
actions: {
|
||||||
|
updateFavoriteColor: (str) => {
|
||||||
|
return {
|
||||||
|
type: "EXAMPLE_SET_FAV_COLOR",
|
||||||
|
payload: str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
##### fn
|
##### fn
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "swagger-ui",
|
"name": "swagger-ui",
|
||||||
"version": "3.7.0",
|
"version": "3.8.1",
|
||||||
"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": [
|
||||||
@@ -67,6 +67,7 @@
|
|||||||
"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-immutable-pure-component": "^1.1.1",
|
||||||
"react-markdown": "^2.5.0",
|
"react-markdown": "^2.5.0",
|
||||||
"react-motion": "^0.5.2",
|
"react-motion": "^0.5.2",
|
||||||
"react-object-inspector": "0.2.1",
|
"react-object-inspector": "0.2.1",
|
||||||
@@ -81,7 +82,7 @@
|
|||||||
"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.4.2",
|
"swagger-client": "^3.4.4",
|
||||||
"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",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
|
||||||
const propStyle = { color: "#999", fontStyle: "italic" }
|
const propStyle = { color: "#999", fontStyle: "italic" }
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ export default class ArrayModel extends Component {
|
|||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
required: PropTypes.bool,
|
required: PropTypes.bool,
|
||||||
expandDepth: PropTypes.number,
|
expandDepth: PropTypes.number,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
depth: PropTypes.number
|
depth: PropTypes.number
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +49,17 @@ export default class ArrayModel extends Component {
|
|||||||
!description ? null :
|
!description ? null :
|
||||||
<Markdown source={ description } />
|
<Markdown source={ description } />
|
||||||
}
|
}
|
||||||
<span><Model { ...this.props } getConfigs={ getConfigs } specPath={[...specPath, "items"]} name={null} schema={ items } required={ false } depth={ depth + 1 } /></span>
|
<span>
|
||||||
|
<Model
|
||||||
|
{ ...this.props }
|
||||||
|
getConfigs={ getConfigs }
|
||||||
|
specPath={specPath.push("items")}
|
||||||
|
name={null}
|
||||||
|
schema={ items }
|
||||||
|
required={ false }
|
||||||
|
depth={ depth + 1 }
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
]
|
]
|
||||||
</ModelCollapse>
|
</ModelCollapse>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
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 ModelExample extends React.Component {
|
export default class ModelExample extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -9,7 +10,7 @@ export default class ModelExample extends React.Component {
|
|||||||
example: PropTypes.any.isRequired,
|
example: PropTypes.any.isRequired,
|
||||||
isExecute: PropTypes.bool,
|
isExecute: PropTypes.bool,
|
||||||
getConfigs: PropTypes.func.isRequired,
|
getConfigs: PropTypes.func.isRequired,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React, { PureComponent } from "react"
|
import React from "react"
|
||||||
|
import ImmutablePureComponent from "react-immutable-pure-component"
|
||||||
import ImPropTypes from "react-immutable-proptypes"
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
export default class Model extends PureComponent {
|
export default class Model extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
schema: ImPropTypes.orderedMap.isRequired,
|
schema: ImPropTypes.orderedMap.isRequired,
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
@@ -13,7 +14,7 @@ export default class Model extends PureComponent {
|
|||||||
required: PropTypes.bool,
|
required: PropTypes.bool,
|
||||||
expandDepth: PropTypes.number,
|
expandDepth: PropTypes.number,
|
||||||
depth: PropTypes.number,
|
depth: PropTypes.number,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
getModelName =( ref )=> {
|
getModelName =( ref )=> {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
|
import Im from "immutable"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
|
||||||
export default class Models extends Component {
|
export default class Models extends Component {
|
||||||
@@ -37,7 +38,7 @@ export default class Models extends Component {
|
|||||||
<ModelWrapper name={ name }
|
<ModelWrapper name={ name }
|
||||||
expandDepth={ defaultModelsExpandDepth }
|
expandDepth={ defaultModelsExpandDepth }
|
||||||
schema={ model }
|
schema={ model }
|
||||||
specPath={[...specPathBase, name]}
|
specPath={Im.List([...specPathBase, name])}
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specSelectors={ specSelectors }
|
specSelectors={ specSelectors }
|
||||||
getConfigs = {getConfigs}
|
getConfigs = {getConfigs}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { Component, } from "react"
|
import React, { Component, } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import { List } from "immutable"
|
import { List } from "immutable"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
|
||||||
const braceOpen = "{"
|
const braceOpen = "{"
|
||||||
const braceClose = "}"
|
const braceClose = "}"
|
||||||
@@ -17,7 +18,7 @@ export default class ObjectModel extends Component {
|
|||||||
isRef: PropTypes.bool,
|
isRef: PropTypes.bool,
|
||||||
expandDepth: PropTypes.number,
|
expandDepth: PropTypes.number,
|
||||||
depth: PropTypes.number,
|
depth: PropTypes.number,
|
||||||
specPath: PropTypes.object.isRequired
|
specPath: ImPropTypes.list.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
@@ -102,7 +103,7 @@ export default class ObjectModel extends Component {
|
|||||||
<Model key={ `object-${name}-${key}_${value}` } { ...otherProps }
|
<Model key={ `object-${name}-${key}_${value}` } { ...otherProps }
|
||||||
required={ isRequired }
|
required={ isRequired }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specPath={[...specPath, "properties", key]}
|
specPath={specPath.push("properties", key)}
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
schema={ value }
|
schema={ value }
|
||||||
depth={ depth + 1 } />
|
depth={ depth + 1 } />
|
||||||
@@ -141,7 +142,7 @@ export default class ObjectModel extends Component {
|
|||||||
<td>
|
<td>
|
||||||
<Model { ...otherProps } required={ false }
|
<Model { ...otherProps } required={ false }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specPath={[...specPath, "additionalProperties"]}
|
specPath={specPath.push("additionalProperties")}
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
schema={ additionalProperties }
|
schema={ additionalProperties }
|
||||||
depth={ depth + 1 } />
|
depth={ depth + 1 } />
|
||||||
@@ -156,7 +157,7 @@ export default class ObjectModel extends Component {
|
|||||||
{anyOf.map((schema, k) => {
|
{anyOf.map((schema, k) => {
|
||||||
return <div key={k}><Model { ...otherProps } required={ false }
|
return <div key={k}><Model { ...otherProps } required={ false }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specPath={[...specPath, "anyOf", k]}
|
specPath={specPath.push("anyOf", k)}
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
schema={ schema }
|
schema={ schema }
|
||||||
depth={ depth + 1 } /></div>
|
depth={ depth + 1 } /></div>
|
||||||
@@ -172,7 +173,7 @@ export default class ObjectModel extends Component {
|
|||||||
{oneOf.map((schema, k) => {
|
{oneOf.map((schema, k) => {
|
||||||
return <div key={k}><Model { ...otherProps } required={ false }
|
return <div key={k}><Model { ...otherProps } required={ false }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specPath={[...specPath, "oneOf", k]}
|
specPath={specPath.push("oneOf", k)}
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
schema={ schema }
|
schema={ schema }
|
||||||
depth={ depth + 1 } /></div>
|
depth={ depth + 1 } /></div>
|
||||||
@@ -189,7 +190,7 @@ export default class ObjectModel extends Component {
|
|||||||
<Model { ...otherProps }
|
<Model { ...otherProps }
|
||||||
required={ false }
|
required={ false }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specPath={[...specPath, "not"]}
|
specPath={specPath.push("not")}
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
schema={ not }
|
schema={ not }
|
||||||
depth={ depth + 1 } />
|
depth={ depth + 1 } />
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ 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 { getExtensions, sanitizeUrl } from "core/utils"
|
import { getExtensions, sanitizeUrl } from "core/utils"
|
||||||
import { Iterable } from "immutable"
|
import { Iterable, List } from "immutable"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
|
|
||||||
export default class Operation extends PureComponent {
|
export default class Operation extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
operation: PropTypes.instanceOf(Iterable).isRequired,
|
operation: PropTypes.instanceOf(Iterable).isRequired,
|
||||||
response: PropTypes.instanceOf(Iterable),
|
response: PropTypes.instanceOf(Iterable),
|
||||||
request: PropTypes.instanceOf(Iterable),
|
request: PropTypes.instanceOf(Iterable),
|
||||||
@@ -33,7 +34,7 @@ export default class Operation extends PureComponent {
|
|||||||
operation: null,
|
operation: null,
|
||||||
response: null,
|
response: null,
|
||||||
request: null,
|
request: null,
|
||||||
specPath: []
|
specPath: List()
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -174,7 +175,7 @@ export default class Operation extends PureComponent {
|
|||||||
|
|
||||||
<Parameters
|
<Parameters
|
||||||
parameters={parameters}
|
parameters={parameters}
|
||||||
specPath={[...specPath, "parameters"]}
|
specPath={specPath.push("parameters")}
|
||||||
operation={operation}
|
operation={operation}
|
||||||
onChangeKey={onChangeKey}
|
onChangeKey={onChangeKey}
|
||||||
onTryoutClick = { onTryoutClick }
|
onTryoutClick = { onTryoutClick }
|
||||||
@@ -248,7 +249,7 @@ export default class Operation extends PureComponent {
|
|||||||
specActions={ specActions }
|
specActions={ specActions }
|
||||||
produces={ produces }
|
produces={ produces }
|
||||||
producesValue={ operation.get("produces_value") }
|
producesValue={ operation.get("produces_value") }
|
||||||
specPath={[...specPath, "responses"]}
|
specPath={specPath.push("responses")}
|
||||||
path={ path }
|
path={ path }
|
||||||
method={ method }
|
method={ method }
|
||||||
displayRequestDuration={ displayRequestDuration }
|
displayRequestDuration={ displayRequestDuration }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import Im from "immutable"
|
||||||
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
|
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
|
||||||
|
|
||||||
const SWAGGER2_OPERATION_METHODS = [
|
const SWAGGER2_OPERATION_METHODS = [
|
||||||
@@ -119,7 +120,7 @@ export default class Operations extends React.Component {
|
|||||||
operations.map( op => {
|
operations.map( op => {
|
||||||
const path = op.get("path")
|
const path = op.get("path")
|
||||||
const method = op.get("method")
|
const method = op.get("method")
|
||||||
const specPath = ["paths", path, method]
|
const specPath = Im.List(["paths", path, method])
|
||||||
|
|
||||||
|
|
||||||
// FIXME: (someday) this logic should probably be in a selector,
|
// FIXME: (someday) this logic should probably be in a selector,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
import { Map } from "immutable"
|
import { Map } from "immutable"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
import win from "core/window"
|
import win from "core/window"
|
||||||
import { getExtensions } from "core/utils"
|
import { getExtensions } from "core/utils"
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ export default class ParameterRow extends Component {
|
|||||||
specSelectors: PropTypes.object.isRequired,
|
specSelectors: PropTypes.object.isRequired,
|
||||||
pathMethod: PropTypes.array.isRequired,
|
pathMethod: PropTypes.array.isRequired,
|
||||||
getConfigs: PropTypes.func.isRequired,
|
getConfigs: PropTypes.func.isRequired,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
@@ -139,7 +140,7 @@ export default class ParameterRow extends Component {
|
|||||||
|
|
||||||
{
|
{
|
||||||
bodyParam && schema ? <ModelExample getComponent={ getComponent }
|
bodyParam && schema ? <ModelExample getComponent={ getComponent }
|
||||||
specPath={[...specPath, "schema"]}
|
specPath={specPath.push("schema")}
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
isExecute={ isExecute }
|
isExecute={ isExecute }
|
||||||
specSelectors={ specSelectors }
|
specSelectors={ specSelectors }
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default class Parameters extends Component {
|
|||||||
onChangeKey: PropTypes.array,
|
onChangeKey: PropTypes.array,
|
||||||
pathMethod: PropTypes.array.isRequired,
|
pathMethod: PropTypes.array.isRequired,
|
||||||
getConfigs: PropTypes.func.isRequired,
|
getConfigs: PropTypes.func.isRequired,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ export default class Parameters extends Component {
|
|||||||
eachMap(parameters, (parameter, i) => (
|
eachMap(parameters, (parameter, i) => (
|
||||||
<ParameterRow
|
<ParameterRow
|
||||||
fn={ fn }
|
fn={ fn }
|
||||||
specPath={[...specPath, i]}
|
specPath={specPath.push(i.toString())}
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
param={ parameter }
|
param={ parameter }
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import { fromJS, Seq, Iterable } from "immutable"
|
import { fromJS, Seq, Iterable, List } from "immutable"
|
||||||
import { getSampleSchema, fromJSOrdered } from "core/utils"
|
import { getSampleSchema, fromJSOrdered } from "core/utils"
|
||||||
|
|
||||||
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
|
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
|
||||||
@@ -47,7 +48,7 @@ export default class Response extends React.Component {
|
|||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
getConfigs: PropTypes.func.isRequired,
|
getConfigs: PropTypes.func.isRequired,
|
||||||
specSelectors: PropTypes.object.isRequired,
|
specSelectors: PropTypes.object.isRequired,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
fn: PropTypes.object.isRequired,
|
fn: PropTypes.object.isRequired,
|
||||||
contentType: PropTypes.string,
|
contentType: PropTypes.string,
|
||||||
controlsAcceptHeader: PropTypes.bool,
|
controlsAcceptHeader: PropTypes.bool,
|
||||||
@@ -99,7 +100,7 @@ export default class Response extends React.Component {
|
|||||||
var schema, specPathWithPossibleSchema
|
var schema, specPathWithPossibleSchema
|
||||||
|
|
||||||
if(isOAS3()) {
|
if(isOAS3()) {
|
||||||
const schemaPath = ["content", this.state.responseContentType, "schema"]
|
const schemaPath = List(["content", this.state.responseContentType, "schema"])
|
||||||
const oas3SchemaForContentType = response.getIn(schemaPath)
|
const oas3SchemaForContentType = response.getIn(schemaPath)
|
||||||
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
|
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
|
||||||
includeReadOnly: true
|
includeReadOnly: true
|
||||||
@@ -108,7 +109,7 @@ export default class Response extends React.Component {
|
|||||||
specPathWithPossibleSchema = oas3SchemaForContentType ? schemaPath : specPath
|
specPathWithPossibleSchema = oas3SchemaForContentType ? schemaPath : specPath
|
||||||
} else {
|
} else {
|
||||||
schema = inferSchema(response.toJS()) // TODO: don't convert back and forth. Lets just stick with immutable for inferSchema
|
schema = inferSchema(response.toJS()) // TODO: don't convert back and forth. Lets just stick with immutable for inferSchema
|
||||||
specPathWithPossibleSchema = response.has("schema") ? [...specPath, "schema"] : specPath
|
specPathWithPossibleSchema = response.has("schema") ? specPath.push("schema") : specPath
|
||||||
sampleResponse = schema ? getSampleSchema(schema, contentType, {
|
sampleResponse = schema ? getSampleSchema(schema, contentType, {
|
||||||
includeReadOnly: true,
|
includeReadOnly: true,
|
||||||
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0
|
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
|
||||||
import { fromJS, Iterable } from "immutable"
|
import { fromJS, Iterable } from "immutable"
|
||||||
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
import { defaultStatusCode, getAcceptControllingResponse } from "core/utils"
|
import { defaultStatusCode, getAcceptControllingResponse } from "core/utils"
|
||||||
|
|
||||||
export default class Responses extends React.Component {
|
export default class Responses extends React.Component {
|
||||||
@@ -17,7 +18,7 @@ export default class Responses extends React.Component {
|
|||||||
specSelectors: PropTypes.object.isRequired,
|
specSelectors: PropTypes.object.isRequired,
|
||||||
specActions: PropTypes.object.isRequired,
|
specActions: PropTypes.object.isRequired,
|
||||||
oas3Actions: PropTypes.object.isRequired,
|
oas3Actions: PropTypes.object.isRequired,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
fn: PropTypes.object.isRequired
|
fn: PropTypes.object.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ export default class Responses extends React.Component {
|
|||||||
let className = tryItOutResponse && tryItOutResponse.get("status") == code ? "response_current" : ""
|
let className = tryItOutResponse && tryItOutResponse.get("status") == code ? "response_current" : ""
|
||||||
return (
|
return (
|
||||||
<Response key={ code }
|
<Response key={ code }
|
||||||
specPath={[...specPath, code]}
|
specPath={specPath.push(code)}
|
||||||
isDefault={defaultCode === code}
|
isDefault={defaultCode === code}
|
||||||
fn={fn}
|
fn={fn}
|
||||||
className={ className }
|
className={ className }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { PureComponent } from "react"
|
import React, { PureComponent } from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
|
import ImPropTypes from "react-immutable-proptypes"
|
||||||
import { helpers } from "swagger-client"
|
import { helpers } from "swagger-client"
|
||||||
import { Iterable, fromJS } from "immutable"
|
import { Iterable, fromJS } from "immutable"
|
||||||
|
|
||||||
@@ -31,8 +32,7 @@ export default class OperationContainer extends PureComponent {
|
|||||||
request: PropTypes.instanceOf(Iterable),
|
request: PropTypes.instanceOf(Iterable),
|
||||||
security: PropTypes.instanceOf(Iterable),
|
security: PropTypes.instanceOf(Iterable),
|
||||||
isDeepLinkingEnabled: PropTypes.bool.isRequired,
|
isDeepLinkingEnabled: PropTypes.bool.isRequired,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
|
|
||||||
getComponent: PropTypes.func.isRequired,
|
getComponent: PropTypes.func.isRequired,
|
||||||
authActions: PropTypes.object,
|
authActions: PropTypes.object,
|
||||||
oas3Actions: PropTypes.object,
|
oas3Actions: PropTypes.object,
|
||||||
|
|||||||
@@ -92,6 +92,20 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
}, constructorConfig.initialState)
|
}, constructorConfig.initialState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(constructorConfig.initialState) {
|
||||||
|
// if the user sets a key as `undefined`, that signals to us that we
|
||||||
|
// should delete the key entirely.
|
||||||
|
// known usage: Swagger-Editor validate plugin tests
|
||||||
|
for (var key in constructorConfig.initialState) {
|
||||||
|
if(
|
||||||
|
constructorConfig.initialState.hasOwnProperty(key)
|
||||||
|
&& constructorConfig.initialState[key] === undefined
|
||||||
|
) {
|
||||||
|
delete storeConfigs.state[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let inlinePlugin = ()=> {
|
let inlinePlugin = ()=> {
|
||||||
return {
|
return {
|
||||||
fn: constructorConfig.fn,
|
fn: constructorConfig.fn,
|
||||||
@@ -105,8 +119,6 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
|
|
||||||
var system = store.getSystem()
|
var system = store.getSystem()
|
||||||
|
|
||||||
system.initOAuth = system.authActions.configureAuth
|
|
||||||
|
|
||||||
const downloadSpec = (fetchedConfig) => {
|
const downloadSpec = (fetchedConfig) => {
|
||||||
if(typeof constructorConfig !== "object") {
|
if(typeof constructorConfig !== "object") {
|
||||||
return system
|
return system
|
||||||
@@ -138,6 +150,9 @@ module.exports = function SwaggerUI(opts) {
|
|||||||
} else if(mergedConfig.dom_id) {
|
} else if(mergedConfig.dom_id) {
|
||||||
let domNode = document.querySelector(mergedConfig.dom_id)
|
let domNode = document.querySelector(mergedConfig.dom_id)
|
||||||
system.render(domNode, "App")
|
system.render(domNode, "App")
|
||||||
|
} else if(mergedConfig.dom_id === null || mergedConfig.domNode === null) {
|
||||||
|
// do nothing
|
||||||
|
// this is useful for testing that does not need to do any rendering
|
||||||
} else {
|
} else {
|
||||||
console.error("Skipped rendering: no `dom_id` or `domNode` was specified")
|
console.error("Skipped rendering: no `dom_id` or `domNode` was specified")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import * as specWrapActionReplacements from "./spec-wrap-actions"
|
|||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
return {
|
return {
|
||||||
|
afterLoad(system) {
|
||||||
|
this.rootInjects = this.rootInjects || {}
|
||||||
|
this.rootInjects.initOAuth = system.authActions.configureAuth
|
||||||
|
},
|
||||||
statePlugins: {
|
statePlugins: {
|
||||||
auth: {
|
auth: {
|
||||||
reducers,
|
reducers,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import YAML from "js-yaml"
|
import YAML from "js-yaml"
|
||||||
import yamlConfig from "../../../swagger-config.yaml"
|
import yamlConfig from "root/swagger-config.yaml"
|
||||||
import * as actions from "./actions"
|
import * as actions from "./actions"
|
||||||
import * as selectors from "./selectors"
|
import * as selectors from "./selectors"
|
||||||
import reducers from "./reducers"
|
import reducers from "./reducers"
|
||||||
@@ -1,26 +1,13 @@
|
|||||||
import reduce from "lodash/reduce"
|
import reduce from "lodash/reduce"
|
||||||
let request = require.context("./transformers/", true, /\.js$/)
|
import * as NotOfType from "./transformers/not-of-type"
|
||||||
let errorTransformers = []
|
import * as ParameterOneOf from "./transformers/parameter-oneof"
|
||||||
|
import * as StripInstance from "./transformers/strip-instance"
|
||||||
|
|
||||||
request.keys().forEach( function( key ){
|
const errorTransformers = [
|
||||||
if( key === "./hook.js" ) {
|
NotOfType,
|
||||||
return
|
ParameterOneOf,
|
||||||
}
|
StripInstance
|
||||||
|
]
|
||||||
if( !key.match(/js$/) ) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if( key.slice(2).indexOf("/") > -1) {
|
|
||||||
// skip files in subdirs
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
errorTransformers.push({
|
|
||||||
name: toTitleCase(key).replace(".js", "").replace("./", ""),
|
|
||||||
transform: request(key).transform
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function transformErrors (errors, system) {
|
export default function transformErrors (errors, system) {
|
||||||
let inputs = {
|
let inputs = {
|
||||||
@@ -47,10 +34,3 @@ export default function transformErrors (errors, system) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toTitleCase(str) {
|
|
||||||
return str
|
|
||||||
.split("-")
|
|
||||||
.map(substr => substr[0].toUpperCase() + substr.slice(1))
|
|
||||||
.join("")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const RequestBody = ({
|
|||||||
expandDepth={1}
|
expandDepth={1}
|
||||||
isExecute={isExecute}
|
isExecute={isExecute}
|
||||||
schema={mediaTypeValue.get("schema")}
|
schema={mediaTypeValue.get("schema")}
|
||||||
specPath={[...specPath, "content", contentType]}
|
specPath={specPath.push("content", contentType)}
|
||||||
example={<RequestBodyEditor
|
example={<RequestBodyEditor
|
||||||
requestBody={requestBody}
|
requestBody={requestBody}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
|||||||
@@ -72,10 +72,10 @@ export const servers = onlyOAS3(createSelector(
|
|||||||
|
|
||||||
export const isOAS3 = (ori, system) => () => {
|
export const isOAS3 = (ori, system) => () => {
|
||||||
const spec = system.getSystem().specSelectors.specJson()
|
const spec = system.getSystem().specSelectors.specJson()
|
||||||
return isOAS3Helper(spec)
|
return isOAS3Helper(Map.isMap(spec) ? spec : Map())
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isSwagger2 = (ori, system) => () => {
|
export const isSwagger2 = (ori, system) => () => {
|
||||||
const spec = system.getSystem().specSelectors.specJson()
|
const spec = system.getSystem().specSelectors.specJson()
|
||||||
return isSwagger2Helper(spec)
|
return isSwagger2Helper(Map.isMap(spec) ? spec : Map())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class Parameters extends Component {
|
|||||||
fn: PropTypes.object.isRequired,
|
fn: PropTypes.object.isRequired,
|
||||||
tryItOutEnabled: PropTypes.bool,
|
tryItOutEnabled: PropTypes.bool,
|
||||||
allowTryItOut: PropTypes.bool,
|
allowTryItOut: PropTypes.bool,
|
||||||
specPath: PropTypes.array.isRequired,
|
specPath: ImPropTypes.list.isRequired,
|
||||||
onTryoutClick: PropTypes.func,
|
onTryoutClick: PropTypes.func,
|
||||||
onCancelClick: PropTypes.func,
|
onCancelClick: PropTypes.func,
|
||||||
onChangeKey: PropTypes.array,
|
onChangeKey: PropTypes.array,
|
||||||
@@ -107,7 +107,7 @@ class Parameters extends Component {
|
|||||||
const { isOAS3 } = specSelectors
|
const { isOAS3 } = specSelectors
|
||||||
|
|
||||||
const requestBody = operation.get("requestBody")
|
const requestBody = operation.get("requestBody")
|
||||||
const requestBodySpecPath = [...specPath.slice(0, -1), "requestBody"] // remove the "parameters" part
|
const requestBodySpecPath = specPath.slice(0, -1).push("requestBody") // remove the "parameters" part
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="opblock-section">
|
<div className="opblock-section">
|
||||||
@@ -143,7 +143,7 @@ class Parameters extends Component {
|
|||||||
eachMap(parameters, (parameter, i) => (
|
eachMap(parameters, (parameter, i) => (
|
||||||
<ParameterRow fn={ fn }
|
<ParameterRow fn={ fn }
|
||||||
getComponent={ getComponent }
|
getComponent={ getComponent }
|
||||||
specPath={[...specPath, i]}
|
specPath={specPath.push(i)}
|
||||||
getConfigs={ getConfigs }
|
getConfigs={ getConfigs }
|
||||||
param={ parameter }
|
param={ parameter }
|
||||||
key={ parameter.get( "name" ) }
|
key={ parameter.get( "name" ) }
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export const parseToJson = (str) => ({specActions, specSelectors, errActions}) =
|
|||||||
line: e.mark && e.mark.line ? e.mark.line + 1 : undefined
|
line: e.mark && e.mark.line ? e.mark.line + 1 : undefined
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if(json) {
|
if(json && typeof json === "object") {
|
||||||
return specActions.updateJsonSpec(json)
|
return specActions.updateJsonSpec(json)
|
||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
@@ -105,8 +105,7 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio
|
|||||||
errActions.clear({
|
errActions.clear({
|
||||||
type: "thrown"
|
type: "thrown"
|
||||||
})
|
})
|
||||||
|
if(Array.isArray(errors) && errors.length > 0) {
|
||||||
if(errors.length > 0) {
|
|
||||||
let preparedErrors = errors
|
let preparedErrors = errors
|
||||||
.map(err => {
|
.map(err => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ import { fromJS, Set, Map, OrderedMap, List } from "immutable"
|
|||||||
|
|
||||||
const DEFAULT_TAG = "default"
|
const DEFAULT_TAG = "default"
|
||||||
|
|
||||||
|
const OPERATION_METHODS = [
|
||||||
|
"get", "put", "post", "delete", "options", "head", "patch", "trace"
|
||||||
|
]
|
||||||
|
|
||||||
const state = state => {
|
const state = state => {
|
||||||
return state || Map()
|
return state || Map()
|
||||||
}
|
}
|
||||||
@@ -95,6 +99,9 @@ export const operations = createSelector(
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
path.forEach((operation, method) => {
|
path.forEach((operation, method) => {
|
||||||
|
if(OPERATION_METHODS.indexOf(method) < 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
list = list.push(fromJS({
|
list = list.push(fromJS({
|
||||||
path: pathName,
|
path: pathName,
|
||||||
method,
|
method,
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import { pascalCaseFilename } from "core/utils"
|
|
||||||
|
|
||||||
const request = require.context(".", true, /\.jsx?$/)
|
|
||||||
|
|
||||||
request.keys().forEach( function( key ){
|
|
||||||
if( key === "./index.js" ) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// if( key.slice(2).indexOf("/") > -1) {
|
|
||||||
// // skip files in subdirs
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
let mod = request(key)
|
|
||||||
module.exports[pascalCaseFilename(key)] = mod.default ? mod.default : mod
|
|
||||||
})
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as components from "./components"
|
import SplitPaneMode from "./components/split-pane-mode"
|
||||||
|
|
||||||
export default function SplitPaneModePlugin() {
|
export default function SplitPaneModePlugin() {
|
||||||
return {
|
return {
|
||||||
// statePlugins: {
|
// statePlugins: {
|
||||||
@@ -9,6 +8,8 @@ export default function SplitPaneModePlugin() {
|
|||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
|
|
||||||
components,
|
components: {
|
||||||
|
SplitPaneMode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +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 configsPlugin from "core/plugins/configs"
|
||||||
import deepLinkingPlugin from "core/plugins/deep-linking"
|
import deepLinkingPlugin from "core/plugins/deep-linking"
|
||||||
|
|
||||||
import OperationContainer from "core/containers/OperationContainer"
|
import OperationContainer from "core/containers/OperationContainer"
|
||||||
|
|||||||
@@ -68,6 +68,12 @@ export default class Store {
|
|||||||
if(rebuild) {
|
if(rebuild) {
|
||||||
this.buildSystem()
|
this.buildSystem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const needAnotherRebuild = callAfterLoad.call(this.system, plugins, this.getSystem())
|
||||||
|
|
||||||
|
if(needAnotherRebuild) {
|
||||||
|
this.buildSystem()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildSystem(buildReducer=true) {
|
buildSystem(buildReducer=true) {
|
||||||
@@ -170,7 +176,7 @@ export default class Store {
|
|||||||
if(!isFn(newAction)) {
|
if(!isFn(newAction)) {
|
||||||
throw new TypeError("wrapActions needs to return a function that returns a new function (ie the wrapped action)")
|
throw new TypeError("wrapActions needs to return a function that returns a new function (ie the wrapped action)")
|
||||||
}
|
}
|
||||||
return newAction
|
return wrapWithTryCatch(newAction)
|
||||||
}, action || Function.prototype)
|
}, action || Function.prototype)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -250,11 +256,11 @@ export default class Store {
|
|||||||
|
|
||||||
return objMap(obj, (fn) => {
|
return objMap(obj, (fn) => {
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
let res = fn.apply(null, [getNestedState(), ...args])
|
let res = wrapWithTryCatch(fn).apply(null, [getNestedState(), ...args])
|
||||||
|
|
||||||
// If a selector returns a function, give it the system - for advanced usage
|
// If a selector returns a function, give it the system - for advanced usage
|
||||||
if(typeof(res) === "function")
|
if(typeof(res) === "function")
|
||||||
res = res(getSystem())
|
res = wrapWithTryCatch(res)(getSystem())
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@@ -320,6 +326,25 @@ function combinePlugins(plugins, toolbox) {
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function callAfterLoad(plugins, system, { hasLoaded } = {}) {
|
||||||
|
let calledSomething = hasLoaded
|
||||||
|
if(isObject(plugins) && !isArray(plugins)) {
|
||||||
|
if(typeof plugins.afterLoad === "function") {
|
||||||
|
calledSomething = true
|
||||||
|
wrapWithTryCatch(plugins.afterLoad).call(this, system)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isFunc(plugins))
|
||||||
|
return callAfterLoad.call(this, plugins(system), system, { hasLoaded: calledSomething })
|
||||||
|
|
||||||
|
if(isArray(plugins)) {
|
||||||
|
return plugins.map(plugin => callAfterLoad.call(this, plugin, system, { hasLoaded: calledSomething }))
|
||||||
|
}
|
||||||
|
|
||||||
|
return calledSomething
|
||||||
|
}
|
||||||
|
|
||||||
// Wraps deepExtend, to account for certain fields, being wrappers.
|
// Wraps deepExtend, to account for certain fields, being wrappers.
|
||||||
// Ie: we need to convert some fields into arrays, and append to them.
|
// Ie: we need to convert some fields into arrays, and append to them.
|
||||||
// Rather than overwrite
|
// Rather than overwrite
|
||||||
@@ -411,14 +436,36 @@ function makeReducer(reducerObj) {
|
|||||||
if(!reducerObj)
|
if(!reducerObj)
|
||||||
return state
|
return state
|
||||||
|
|
||||||
let redFn = reducerObj[action.type]
|
let redFn = (reducerObj[action.type])
|
||||||
if(redFn) {
|
if(redFn) {
|
||||||
return redFn(state, action)
|
const res = wrapWithTryCatch(redFn)(state, action)
|
||||||
|
// If the try/catch wrapper kicks in, we'll get null back...
|
||||||
|
// in that case, we want to avoid making any changes to state
|
||||||
|
return res === null ? state : res
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wrapWithTryCatch(fn, {
|
||||||
|
logErrors = true
|
||||||
|
} = {}) {
|
||||||
|
if(typeof fn !== "function") {
|
||||||
|
return fn
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(...args) {
|
||||||
|
try {
|
||||||
|
return fn.call(this, ...args)
|
||||||
|
} catch(e) {
|
||||||
|
if(logErrors) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function configureStore(rootReducer, initialState, getSystem) {
|
function configureStore(rootReducer, initialState, getSystem) {
|
||||||
const store = createStoreWithMiddleware(rootReducer, initialState, getSystem)
|
const store = createStoreWithMiddleware(rootReducer, initialState, getSystem)
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
import { pascalCaseFilename } from "js/utils"
|
import Configs from "./configs"
|
||||||
|
import Topbar from "./topbar"
|
||||||
|
|
||||||
const request = require.context(".", true, /\.jsx?$/)
|
export default {
|
||||||
|
Configs,
|
||||||
request.keys().forEach( function( key ){
|
Topbar
|
||||||
if( key === "./index.js" ) {
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// if( key.slice(2).indexOf("/") > -1) {
|
|
||||||
// // skip files in subdirs
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
let mod = request(key)
|
|
||||||
module.exports[pascalCaseFilename(key)] = mod.default ? mod.default : mod
|
|
||||||
})
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import StandaloneLayout from "./layout"
|
import StandaloneLayout from "./layout"
|
||||||
import TopbarPlugin from "plugins/topbar"
|
import TopbarPlugin from "plugins/topbar"
|
||||||
import ConfigsPlugin from "plugins/configs"
|
import ConfigsPlugin from "corePlugins/configs"
|
||||||
|
|
||||||
// the Standalone preset
|
// the Standalone preset
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import expect from "expect"
|
import expect from "expect"
|
||||||
import { shallow } from "enzyme"
|
import { shallow } from "enzyme"
|
||||||
import { fromJS } from "immutable"
|
import { fromJS, List } from "immutable"
|
||||||
import ObjectModel from "components/object-model"
|
import ObjectModel from "components/object-model"
|
||||||
import ModelExample from "components/model-example"
|
import ModelExample from "components/model-example"
|
||||||
import Immutable from "immutable"
|
import Immutable from "immutable"
|
||||||
@@ -25,7 +25,7 @@ describe("<ObjectModel />", function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
isRef : false,
|
isRef : false,
|
||||||
specPath: [],
|
specPath: List(),
|
||||||
schema: Immutable.fromJS(
|
schema: Immutable.fromJS(
|
||||||
{
|
{
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -571,116 +571,411 @@ describe("bound system", function(){
|
|||||||
// Then
|
// Then
|
||||||
expect(renderedComponent.text()).toEqual("This came from mapStateToProps and this came from the system and this came from my own props")
|
expect(renderedComponent.text()).toEqual("This came from mapStateToProps and this came from the system and this came from my own props")
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it("should catch errors thrown inside of React Component Class render methods", function() {
|
describe("afterLoad", function() {
|
||||||
|
it("should call a plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||||
// Given
|
// Given
|
||||||
// eslint-disable-next-line react/require-render-return
|
|
||||||
class BrokenComponent extends React.Component {
|
|
||||||
render() {
|
|
||||||
throw new Error("This component is broken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const system = new System({
|
const system = new System({
|
||||||
plugins: [
|
plugins: [
|
||||||
ViewPlugin,
|
|
||||||
{
|
{
|
||||||
components: {
|
afterLoad(system) {
|
||||||
BrokenComponent
|
this.rootInjects.wow = system.dogeSelectors.wow
|
||||||
|
},
|
||||||
|
statePlugins: {
|
||||||
|
doge: {
|
||||||
|
selectors: {
|
||||||
|
wow: () => (system) => {
|
||||||
|
return "so selective"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var Component = system.getSystem().getComponent("BrokenComponent")
|
var res = system.getSystem().wow()
|
||||||
const renderedComponent = render(<Component />)
|
expect(res).toEqual("so selective")
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
|
||||||
})
|
})
|
||||||
|
it("should call a preset plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||||
it("should catch errors thrown inside of pure component render methods", function() {
|
|
||||||
// Given
|
// Given
|
||||||
// eslint-disable-next-line react/require-render-return
|
const MyPlugin = {
|
||||||
class BrokenComponent extends PureComponent {
|
afterLoad(system) {
|
||||||
render() {
|
this.rootInjects.wow = system.dogeSelectors.wow
|
||||||
throw new Error("This component is broken")
|
},
|
||||||
|
statePlugins: {
|
||||||
|
doge: {
|
||||||
|
selectors: {
|
||||||
|
wow: () => (system) => {
|
||||||
|
return "so selective"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const system = new System({
|
const system = new System({
|
||||||
plugins: [
|
plugins: [
|
||||||
ViewPlugin,
|
[MyPlugin]
|
||||||
{
|
|
||||||
components: {
|
|
||||||
BrokenComponent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var Component = system.getSystem().getComponent("BrokenComponent")
|
var res = system.getSystem().wow()
|
||||||
const renderedComponent = render(<Component />)
|
expect(res).toEqual("so selective")
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
|
||||||
})
|
})
|
||||||
|
it("should call a function preset plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||||
it("should catch errors thrown inside of stateless component functions", function() {
|
|
||||||
// Given
|
// Given
|
||||||
// eslint-disable-next-line react/require-render-return
|
const MyPlugin = {
|
||||||
let BrokenComponent = function BrokenComponent() { throw new Error("This component is broken") }
|
afterLoad(system) {
|
||||||
const system = new System({
|
this.rootInjects.wow = system.dogeSelectors.wow
|
||||||
plugins: [
|
},
|
||||||
ViewPlugin,
|
statePlugins: {
|
||||||
{
|
doge: {
|
||||||
components: {
|
selectors: {
|
||||||
BrokenComponent
|
wow: () => (system) => {
|
||||||
|
return "so selective"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
// When
|
|
||||||
var Component = system.getSystem().getComponent("BrokenComponent")
|
|
||||||
const renderedComponent = render(<Component />)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(renderedComponent.text().startsWith("😱 Could not render")).toEqual(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should catch errors thrown inside of container components", function() {
|
|
||||||
// Given
|
|
||||||
// eslint-disable-next-line react/require-render-return
|
|
||||||
class BrokenComponent extends React.Component {
|
|
||||||
render() {
|
|
||||||
throw new Error("This component is broken")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const system = new System({
|
const system = new System({
|
||||||
plugins: [
|
plugins: [
|
||||||
ViewPlugin,
|
() => {
|
||||||
{
|
return [MyPlugin]
|
||||||
components: {
|
|
||||||
BrokenComponent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
// When
|
// When
|
||||||
var Component = system.getSystem().getComponent("BrokenComponent", true)
|
var res = system.getSystem().wow()
|
||||||
const renderedComponent = render(
|
expect(res).toEqual("so selective")
|
||||||
<Provider store={system.getStore()}>
|
})
|
||||||
<Component />
|
it("should call a registered plugin's `afterLoad` method after the plugin is loaded", function() {
|
||||||
</Provider>
|
// Given
|
||||||
)
|
const MyPlugin = {
|
||||||
|
afterLoad(system) {
|
||||||
|
this.rootInjects.wow = system.dogeSelectors.wow
|
||||||
|
},
|
||||||
|
statePlugins: {
|
||||||
|
doge: {
|
||||||
|
selectors: {
|
||||||
|
wow: () => (system) => {
|
||||||
|
return "so selective"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Then
|
const system = new System({
|
||||||
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
plugins: []
|
||||||
|
})
|
||||||
|
|
||||||
|
system.register([MyPlugin])
|
||||||
|
|
||||||
|
// When
|
||||||
|
var res = system.getSystem().wow()
|
||||||
|
expect(res).toEqual("so selective")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("error catching", function() {
|
||||||
|
it("should encapsulate thrown errors in an afterLoad method", function() {
|
||||||
|
// Given
|
||||||
|
const ThrowyPlugin = {
|
||||||
|
afterLoad(system) {
|
||||||
|
throw new Error("afterLoad BREAKS STUFF!")
|
||||||
|
},
|
||||||
|
statePlugins: {
|
||||||
|
doge: {
|
||||||
|
selectors: {
|
||||||
|
wow: () => (system) => {
|
||||||
|
return "so selective"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const system = new System({
|
||||||
|
plugins: []
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// When
|
||||||
|
expect(function() {
|
||||||
|
system.register([ThrowyPlugin])
|
||||||
|
// var resSystem = system.getSystem()
|
||||||
|
}).toNotThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should encapsulate thrown errors in an action creator", function(){
|
||||||
|
|
||||||
|
// Given
|
||||||
|
const system = new System({
|
||||||
|
plugins: {
|
||||||
|
statePlugins: {
|
||||||
|
throw: {
|
||||||
|
actions: {
|
||||||
|
func() {
|
||||||
|
throw new Error("this action creator THROWS!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(function() {
|
||||||
|
// TODO: fix existing action error catcher that creates THROWN ERR actions
|
||||||
|
system.getSystem().throwActions.func()
|
||||||
|
}).toNotThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should encapsulate thrown errors in a reducer", function(){
|
||||||
|
|
||||||
|
// Given
|
||||||
|
const system = new System({
|
||||||
|
plugins: {
|
||||||
|
statePlugins: {
|
||||||
|
throw: {
|
||||||
|
actions: {
|
||||||
|
func: () => {
|
||||||
|
return {
|
||||||
|
type: "THROW_FUNC",
|
||||||
|
payload: "BOOM!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
"THROW_FUNC": (state, action) => {
|
||||||
|
throw new Error("this reducer EXPLODES!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(function() {
|
||||||
|
system.getSystem().throwActions.func()
|
||||||
|
}).toNotThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should encapsulate thrown errors in a selector", function(){
|
||||||
|
|
||||||
|
// Given
|
||||||
|
const system = new System({
|
||||||
|
plugins: {
|
||||||
|
statePlugins: {
|
||||||
|
throw: {
|
||||||
|
selectors: {
|
||||||
|
func: (state, arg1) => {
|
||||||
|
throw new Error("this selector THROWS!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(system.getSystem().throwSelectors.func).toNotThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should encapsulate thrown errors in a complex selector", function(){
|
||||||
|
|
||||||
|
// Given
|
||||||
|
const system = new System({
|
||||||
|
plugins: {
|
||||||
|
statePlugins: {
|
||||||
|
throw: {
|
||||||
|
selectors: {
|
||||||
|
func: (state, arg1) => system => {
|
||||||
|
throw new Error("this selector THROWS!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(system.getSystem().throwSelectors.func).toNotThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should encapsulate thrown errors in a wrapAction", function(){
|
||||||
|
|
||||||
|
// Given
|
||||||
|
const system = new System({
|
||||||
|
plugins: {
|
||||||
|
statePlugins: {
|
||||||
|
throw: {
|
||||||
|
actions: {
|
||||||
|
func: () => {
|
||||||
|
return {
|
||||||
|
type: "THROW_FUNC",
|
||||||
|
payload: "this original action does NOT throw"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wrapActions: {
|
||||||
|
func: (ori) => (...args) => {
|
||||||
|
throw new Error("this wrapAction UNRAVELS EVERYTHING!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(system.getSystem().throwActions.func).toNotThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should encapsulate thrown errors in a wrapSelector", function(){
|
||||||
|
|
||||||
|
// Given
|
||||||
|
const system = new System({
|
||||||
|
plugins: {
|
||||||
|
statePlugins: {
|
||||||
|
throw: {
|
||||||
|
selectors: {
|
||||||
|
func: (state, arg1) => {
|
||||||
|
return 123
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wrapSelectors: {
|
||||||
|
func: (ori) => (...props) => {
|
||||||
|
return ori(...props)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(system.getSystem().throwSelectors.func).toNotThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("components", function() {
|
||||||
|
it("should catch errors thrown inside of React Component Class render methods", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
class BrokenComponent extends React.Component {
|
||||||
|
render() {
|
||||||
|
throw new Error("This component is broken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent")
|
||||||
|
const renderedComponent = render(<Component />)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should catch errors thrown inside of pure component render methods", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
class BrokenComponent extends PureComponent {
|
||||||
|
render() {
|
||||||
|
throw new Error("This component is broken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent")
|
||||||
|
const renderedComponent = render(<Component />)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should catch errors thrown inside of stateless component functions", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
let BrokenComponent = function BrokenComponent() { throw new Error("This component is broken") }
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent")
|
||||||
|
const renderedComponent = render(<Component />)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text().startsWith("😱 Could not render")).toEqual(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should catch errors thrown inside of container components", function() {
|
||||||
|
// Given
|
||||||
|
// eslint-disable-next-line react/require-render-return
|
||||||
|
class BrokenComponent extends React.Component {
|
||||||
|
render() {
|
||||||
|
throw new Error("This component is broken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const system = new System({
|
||||||
|
plugins: [
|
||||||
|
ViewPlugin,
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
BrokenComponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// When
|
||||||
|
var Component = system.getSystem().getComponent("BrokenComponent", true)
|
||||||
|
const renderedComponent = render(
|
||||||
|
<Provider store={system.getStore()}>
|
||||||
|
<Component />
|
||||||
|
</Provider>
|
||||||
|
)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect(renderedComponent.text()).toEqual("😱 Could not render BrokenComponent, see the console.")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user