diff --git a/.agignore b/.agignore
new file mode 100644
index 00000000..849ddff3
--- /dev/null
+++ b/.agignore
@@ -0,0 +1 @@
+dist/
diff --git a/docs/customization/plugin-api.md b/docs/customization/plugin-api.md
index db88ca71..245b5a14 100644
--- a/docs/customization/plugin-api.md
+++ b/docs/customization/plugin-api.md
@@ -293,7 +293,7 @@ const MyWrapSelectorsPlugin = function(system) {
Wrap Components allow you to override a component registered within the system.
-Wrap Components are function factories with the signature `(OriginalComponent, system) => props => ReactElement`.
+Wrap Components are function factories with the signature `(OriginalComponent, system) => props => ReactElement`. If you'd prefer to provide a React component class, `(OriginalComponent, system) => ReactClass` works as well.
```javascript
const MyWrapBuiltinComponentPlugin = function(system) {
@@ -310,9 +310,12 @@ const MyWrapBuiltinComponentPlugin = function(system) {
}
```
-```javascript
-// Overriding a component from a plugin
+Here's another example that includes a code sample of a component that will be wrapped:
+```javascript
+///// Overriding a component from a plugin
+
+// Here's our normal, unmodified component.
const MyNumberDisplayPlugin = function(system) {
return {
components: {
@@ -321,6 +324,7 @@ const MyNumberDisplayPlugin = function(system) {
}
}
+// Here's a component wrapper defined as a function.
const MyWrapComponentPlugin = function(system) {
return {
wrapComponents: {
@@ -328,6 +332,7 @@ const MyWrapComponentPlugin = function(system) {
if(props.number > 10) {
return
Warning! Big number ahead.
+
} else {
return
@@ -336,8 +341,30 @@ const MyWrapComponentPlugin = function(system) {
}
}
}
+
+// Alternatively, here's the same component wrapper defined as a class.
+const MyWrapComponentPlugin = function(system) {
+ return {
+ wrapComponents: {
+ NumberDisplay: (Original, system) => class WrappedNumberDisplay extends React.component {
+ render() {
+ if(props.number > 10) {
+ return
+
Warning! Big number ahead.
+
+
+ } else {
+ return
+ }
+ }
+ }
+ }
+ }
+}
```
+
+
##### fn
The fn interface allows you to add helper functions to the system for use elsewhere.
diff --git a/docs/usage/installation.md b/docs/usage/installation.md
index 63f7d233..e4fd09d2 100644
--- a/docs/usage/installation.md
+++ b/docs/usage/installation.md
@@ -49,7 +49,7 @@ const ui = SwaggerUIBundle({
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
- ]
+ ],
layout: "StandaloneLayout"
})
```
@@ -86,7 +86,7 @@ This will serve Swagger UI at `/swagger` instead of `/`.
You can embed Swagger-UI's code directly in your HTML by using unkpg's interface:
```html
-
```
diff --git a/src/core/components/deep-link.jsx b/src/core/components/deep-link.jsx
new file mode 100644
index 00000000..44aa08bb
--- /dev/null
+++ b/src/core/components/deep-link.jsx
@@ -0,0 +1,20 @@
+import React from "react"
+import PropTypes from "prop-types"
+
+export const DeepLink = ({ enabled, path, text }) => {
+ return (
+ e.preventDefault() : null}
+ href={enabled ? `#/${path}` : null}>
+ {text}
+
+ )
+}
+DeepLink.propTypes = {
+ enabled: PropTypes.bool,
+ isShown: PropTypes.bool,
+ path: PropTypes.string,
+ text: PropTypes.string
+}
+
+export default DeepLink
diff --git a/src/core/components/operation.jsx b/src/core/components/operation.jsx
index 37ec4d16..7063cf22 100644
--- a/src/core/components/operation.jsx
+++ b/src/core/components/operation.jsx
@@ -102,12 +102,13 @@ export default class Operation extends PureComponent {
const Schemes = getComponent( "schemes" )
const OperationServers = getComponent( "OperationServers" )
const OperationExt = getComponent( "OperationExt" )
+ const DeepLink = getComponent( "DeepLink" )
const { showExtensions } = getConfigs()
// Merge in Live Response
if(responses && response && response.size > 0) {
- let notDocumented = !responses.get(String(response.get("status")))
+ let notDocumented = !responses.get(String(response.get("status"))) && !responses.get("default")
response = response.set("notDocumented", notDocumented)
}
@@ -120,12 +121,11 @@ export default class Operation extends PureComponent {
and pulled in with getComponent */}
{method.toUpperCase()}
- e.preventDefault() : null}
- href={isDeepLinkingEnabled ? `#/${isShownKey.join("/")}` : null}>
- {path}
-
+
{/*TODO: use wrapComponents here, swagger-ui doesn't care about jumpToPath */}
diff --git a/src/core/components/operations.jsx b/src/core/components/operations.jsx
index 46a04cc9..6500587e 100644
--- a/src/core/components/operations.jsx
+++ b/src/core/components/operations.jsx
@@ -37,6 +37,7 @@ export default class Operations extends React.Component {
const OperationContainer = getComponent("OperationContainer", true)
const Collapse = getComponent("Collapse")
const Markdown = getComponent("Markdown")
+ const DeepLink = getComponent("DeepLink")
let {
docExpansion,
@@ -79,12 +80,11 @@ export default class Operations extends React.Component {
onClick={() => layoutActions.show(isShownKey, !showTag)}
className={!tagDescription ? "opblock-tag no-desc" : "opblock-tag" }
id={isShownKey.join("-")}>
- e.preventDefault() : null}
- href= {isDeepLinkingEnabled ? `#/${tag}` : null}>
- {tag}
-
+
{ !tagDescription ? null :
diff --git a/src/core/components/param-body.jsx b/src/core/components/param-body.jsx
index 980ef490..13a4377f 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")) : {}
+ let parameter = specSelectors ? specSelectors.getParameter(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")
diff --git a/src/core/components/response-body.jsx b/src/core/components/response-body.jsx
index 1e48f4e5..e239c258 100644
--- a/src/core/components/response-body.jsx
+++ b/src/core/components/response-body.jsx
@@ -43,7 +43,11 @@ export default class ResponseBody extends React.Component {
// Image
} else if (/^image\//i.test(contentType)) {
- bodyEl =
+ if(contentType.includes("svg")) {
+ bodyEl = { content }
+ } else {
+ bodyEl =
+ }
// Audio
} else if (/^audio\//i.test(contentType)) {
diff --git a/src/core/oauth2-authorize.js b/src/core/oauth2-authorize.js
index c5521aaf..0de353d2 100644
--- a/src/core/oauth2-authorize.js
+++ b/src/core/oauth2-authorize.js
@@ -46,7 +46,7 @@ export default function authorize ( { auth, authActions, errActions, configs, au
authId: name,
source: "validation",
level: "error",
- message: "oauth2RedirectUri configuration is not passed. Oauth2 authorization cannot be performed."
+ message: "oauth2RedirectUrl configuration is not passed. Oauth2 authorization cannot be performed."
})
return
}
diff --git a/src/core/plugins/ast/ast.js b/src/core/plugins/ast/ast.js
index d067e80f..880cdb38 100644
--- a/src/core/plugins/ast/ast.js
+++ b/src/core/plugins/ast/ast.js
@@ -103,30 +103,30 @@ export function positionRangeForPath(yaml, path) {
let ast = cachedCompose(yaml)
- // simply walks the tree using current path recursively to the point that
+ // simply walks the tree using astValue path recursively to the point that
// path is empty.
return find(ast)
- function find(current) {
- if (current.tag === MAP_TAG) {
- for (i = 0; i < current.value.length; i++) {
- var pair = current.value[i]
+ function find(astValue, astKeyValue) {
+ if (astValue.tag === MAP_TAG) {
+ for (i = 0; i < astValue.value.length; i++) {
+ var pair = astValue.value[i]
var key = pair[0]
var value = pair[1]
if (key.value === path[0]) {
path.shift()
- return find(value)
+ return find(value, key)
}
}
}
- if (current.tag === SEQ_TAG) {
- var item = current.value[path[0]]
+ if (astValue.tag === SEQ_TAG) {
+ var item = astValue.value[path[0]]
if (item && item.tag) {
path.shift()
- return find(item)
+ return find(item, astKeyValue)
}
}
@@ -135,17 +135,35 @@ export function positionRangeForPath(yaml, path) {
return invalidRange
}
- return {
- /* jshint camelcase: false */
+ const range = {
start: {
- line: current.start_mark.line,
- column: current.start_mark.column
+ line: astValue.start_mark.line,
+ column: astValue.start_mark.column,
+ pointer: astValue.start_mark.pointer,
},
end: {
- line: current.end_mark.line,
- column: current.end_mark.column
+ line: astValue.end_mark.line,
+ column: astValue.end_mark.column,
+ pointer: astValue.end_mark.pointer,
}
}
+
+ if(astKeyValue) {
+ // eslint-disable-next-line camelcase
+ range.key_start = {
+ line: astKeyValue.start_mark.line,
+ column: astKeyValue.start_mark.column,
+ pointer: astKeyValue.start_mark.pointer,
+ }
+ // eslint-disable-next-line camelcase
+ range.key_end = {
+ line: astKeyValue.end_mark.line,
+ column: astKeyValue.end_mark.column,
+ pointer: astKeyValue.end_mark.pointer,
+ }
+ }
+
+ return range
}
}
diff --git a/src/core/plugins/spec/actions.js b/src/core/plugins/spec/actions.js
index b332f953..6ec1ed9c 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 isString from "lodash/isString"
import { isJSONObject } from "core/utils"
// Actions conform to FSA (flux-standard-actions)
@@ -22,22 +23,16 @@ export const UPDATE_OPERATION_VALUE = "spec_update_operation_value"
export const UPDATE_RESOLVED = "spec_update_resolved"
export const SET_SCHEME = "set_scheme"
-export function updateSpec(spec) {
- if(spec instanceof Error) {
- return {type: UPDATE_SPEC, error: true, payload: spec}
- }
+const toStr = (str) => isString(str) ? str : ""
+export function updateSpec(spec) {
+ const cleanSpec = (toStr(spec)).replace(/\t/g, " ")
if(typeof spec === "string") {
return {
type: UPDATE_SPEC,
- payload: spec.replace(/\t/g, " ") || ""
+ payload: cleanSpec
}
}
-
- return {
- type: UPDATE_SPEC,
- payload: ""
- }
}
export function updateResolved(spec) {
@@ -52,9 +47,6 @@ export function updateUrl(url) {
}
export function updateJsonSpec(json) {
- if(!json || typeof json !== "object") {
- throw new Error("updateJson must only accept a simple JSON object")
- }
return {type: UPDATE_JSON, payload: json}
}
@@ -76,7 +68,10 @@ export const parseToJson = (str) => ({specActions, specSelectors, errActions}) =
line: e.mark && e.mark.line ? e.mark.line + 1 : undefined
})
}
- return specActions.updateJsonSpec(json)
+ if(json) {
+ return specActions.updateJsonSpec(json)
+ }
+ return {}
}
export const resolveSpec = (json, url) => ({specActions, specSelectors, errActions, fn: { fetch, resolve, AST }, getConfigs}) => {
@@ -130,18 +125,6 @@ export const resolveSpec = (json, url) => ({specActions, specSelectors, errActio
})
}
-export const formatIntoYaml = () => ({specActions, specSelectors}) => {
- let { specStr } = specSelectors
- let { updateSpec } = specActions
-
- try {
- let yaml = YAML.safeDump(YAML.safeLoad(specStr()), {indent: 2})
- updateSpec(yaml)
- } catch(e) {
- updateSpec(e)
- }
-}
-
export function changeParam( path, paramName, paramIn, value, isXml ){
return {
type: UPDATE_PARAM,
diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js
index 71914c7d..ba35abc2 100644
--- a/src/core/plugins/spec/selectors.js
+++ b/src/core/plugins/spec/selectors.js
@@ -256,10 +256,11 @@ export const allowTryItOutFor = () => {
// Get the parameter value by parameter name
export function getParameter(state, pathMethod, name, inType) {
+ pathMethod = pathMethod || []
let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([]))
- return params.filter( (p) => {
+ return params.find( (p) => {
return Map.isMap(p) && p.get("name") === name && p.get("in") === inType
- }).first()
+ }) || Map() // Always return a map
}
export const hasHost = createSelector(
@@ -272,6 +273,7 @@ export const hasHost = createSelector(
// Get the parameter values, that the user filled out
export function parameterValues(state, pathMethod, isXml) {
+ pathMethod = pathMethod || []
let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([]))
return params.reduce( (hash, p) => {
let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value")
@@ -295,6 +297,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({}))
const parameters = op.get("parameters") || new List()
@@ -313,6 +316,7 @@ 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({}))
}
@@ -329,6 +333,7 @@ export const canExecuteScheme = ( state, path, method ) => {
}
export const validateBeforeExecute = ( state, pathMethod ) => {
+ pathMethod = pathMethod || []
let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([]))
let isValid = true
diff --git a/src/core/presets/base.js b/src/core/presets/base.js
index 133df134..1521fa28 100644
--- a/src/core/presets/base.js
+++ b/src/core/presets/base.js
@@ -61,6 +61,7 @@ import PrimitiveModel from "core/components/primitive-model"
import Property from "core/components/property"
import TryItOutButton from "core/components/try-it-out-button"
import VersionStamp from "core/components/version-stamp"
+import DeepLink from "core/components/deep-link"
import Markdown from "core/components/providers/markdown"
@@ -121,7 +122,8 @@ export default function() {
OperationExt,
OperationExtRow,
ParameterExt,
- OperationContainer
+ OperationContainer,
+ DeepLink
}
}
diff --git a/test/components/operations.js b/test/components/operations.js
index 8a6a7506..bfcbed4f 100644
--- a/test/components/operations.js
+++ b/test/components/operations.js
@@ -3,11 +3,13 @@ import React from "react"
import expect, { createSpy } from "expect"
import { render } from "enzyme"
import { fromJS } from "immutable"
+import DeepLink from "components/deep-link"
import Operations from "components/operations"
import {Collapse} from "components/layout-utils"
const components = {
Collapse,
+ DeepLink,
OperationContainer: ({ path, method }) =>
}