Merge branch 'master' of github.com:swagger-api/swagger-ui into bug/3102-unguarded-expressions

# Conflicts:
#	src/core/components/model.jsx
#	src/core/components/models.jsx
This commit is contained in:
Owen Conti
2017-07-03 16:12:31 -06:00
74 changed files with 811 additions and 395 deletions

View File

@@ -143,6 +143,7 @@ parameterMacro | MUST be a function. Function to set default value to parameters
modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable
docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'.
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
### Plugins

View File

@@ -1,28 +0,0 @@
function extsToRegExp(exts) {
return new RegExp("\\.(" + exts.map(function(ext) {
return ext.replace(/\./g, "\\.");
}).join("|") + ")(\\?.*)?$");
}
module.exports = function loadersByExtension(obj) {
var loaders = [];
Object.keys(obj).forEach(function(key) {
var exts = key.split("|");
var value = obj[key];
var entry = {
extensions: exts,
test: extsToRegExp(exts)
};
if(Array.isArray(value)) {
entry.loaders = value;
} else if(typeof value === "string") {
entry.loader = value;
} else {
Object.keys(value).forEach(function(valueKey) {
entry[valueKey] = value[valueKey];
});
}
loaders.push(entry);
});
return loaders;
};

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AA+4CA;;;;;;AAoIA;AAy2FA;AA8iCA;AA6lJA;AA81IA;AAwuGA;AA01FA;AAkjFA;AAs3FA;AAi+CA;AA29CA;AAmtCA;AAuyEA;;;;;AAwiDA;AA8zJA;;;;;;;;;;;;;;AAyoFA;AA+lIA;AA4oJA;AAqvHA;AA8nGA;AA+iEA;AAw3DA;AA4nDA;AAknBA;;;;;;AAg1FA;AAggGA;;;;;AA23CA;AAgsFA;AA6kDA;AA01CA;AA8yFA;AA61CA;AA0jFA;;;;;;;;;AA6pEA;AA2zIA;AAu7FA;AAmrFA;AAq/EA","sourceRoot":""}
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;AAsyKA;;;;;;AAmqEA;;;;;;;;;;;;;;;;;;;;;;;;;;AA6nTA;;;;;;;;;;;;;;AAu8JA;;;;;;;;;AA8/mBA;;;;;AA6/PA;;;;;;AAqpVA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA+tEA;AAo7GA;AAw0FA;;;;;;AAmZA;AAivFA;AAu+CA;AAo+CA;AAirCA;AAuyEA","sourceRoot":""}
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA40CA;;;;;;AA4kFA","sourceRoot":""}

5
dist/swagger-ui.css vendored

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"swagger-ui.css","sources":[],"mappings":"","sourceRoot":""}
{"version":3,"file":"swagger-ui.css","sources":[],"mappings":";;;","sourceRoot":""}

11
dist/swagger-ui.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;AA+nEA;;;;;;AAmgBA;AA2pHA;AA0pIA;AA09FA;AA0+CA;AAs0CA;AAgvCA","sourceRoot":""}
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAkoaA","sourceRoot":""}

View File

@@ -3,11 +3,8 @@ var path = require('path')
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var deepExtend = require('deep-extend')
var autoprefixer = require('autoprefixer')
const {gitDescribeSync} = require('git-describe');
var loadersByExtension = require('./build-tools/loadersByExtension')
var pkg = require('./package.json')
let gitInfo
@@ -21,7 +18,27 @@ try {
}
}
module.exports = function(options) {
var commonRules = [
{ test: /\.(js(x)?)(\?.*)?$/,
use: [{
loader: 'babel-loader',
options: {
retainLines: true
}
}],
include: [ path.join(__dirname, 'src') ]
},
{ test: /\.(txt|yaml)(\?.*)?$/,
loader: 'raw-loader' },
{ test: /\.(png|jpg|jpeg|gif|svg)(\?.*)?$/,
loader: 'url-loader?limit=10000' },
{ test: /\.(woff|woff2)(\?.*)?$/,
loader: 'url-loader?limit=100000' },
{ test: /\.(ttf|eot)(\?.*)?$/,
loader: 'file-loader' }
]
module.exports = function(rules, options) {
// Special options, that have logic in this file
// ...with defaults
@@ -33,23 +50,11 @@ module.exports = function(options) {
sourcemaps: false,
}, options._special)
var loadersMap = {
'js(x)?': {
loader: 'babel?retainLines=true',
include: [ path.join(__dirname, 'src') ],
},
'json': 'json-loader',
'txt|yaml': 'raw-loader',
'png|jpg|jpeg|gif|svg': specialOptions.disableAssets ? 'null-loader' : 'url-loader?limit=10000',
'woff|woff2': specialOptions.disableAssets ? 'null-loader' : 'url-loader?limit=100000',
'ttf|eot': specialOptions.disableAssets ? 'null-loader' : 'file-loader',
"worker.js": ["worker-loader?inline=true", "babel"]
}
var plugins = []
if( specialOptions.separateStylesheets ) {
plugins.push(new ExtractTextPlugin('[name].css' + (specialOptions.longTermCaching ? '?[contenthash]' : ''), {
plugins.push(new ExtractTextPlugin({
filename: '[name].css' + (specialOptions.longTermCaching ? '?[contenthash]' : ''),
allChunks: true
}))
}
@@ -58,14 +63,16 @@ module.exports = function(options) {
plugins.push(
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
sourceMap: true,
}),
new webpack.optimize.DedupePlugin()
new webpack.LoaderOptionsPlugin({
options: {
context: __dirname
}
})
)
plugins.push( new webpack.NoErrorsPlugin())
plugins.push( new webpack.NoEmitOnErrorsPlugin())
}
@@ -83,34 +90,7 @@ module.exports = function(options) {
})
}))
var cssLoader = 'css-loader!postcss-loader'
var completeStylesheetLoaders = deepExtend({
'css': cssLoader,
'scss': cssLoader + '!' + 'sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true',
'less': cssLoader + '!' + 'less-loader',
}, specialOptions.stylesheetLoaders)
if(specialOptions.cssModules) {
cssLoader = cssLoader + '?module' + (specialOptions.minimize ? '' : '&localIdentName=[path][name]---[local]---[hash:base64:5]')
}
Object.keys(completeStylesheetLoaders).forEach(function(ext) {
var ori = completeStylesheetLoaders[ext]
if(specialOptions.separateStylesheets) {
completeStylesheetLoaders[ext] = ExtractTextPlugin.extract('style-loader', ori)
} else {
completeStylesheetLoaders[ext] = 'style-loader!' + ori
}
})
var loaders = loadersByExtension(deepExtend({}, loadersMap, specialOptions.loaders, completeStylesheetLoaders))
var extraLoaders = (options.module || {} ).loaders
if(Array.isArray(extraLoaders)) {
loaders = loaders.concat(extraLoaders)
delete options.module.loaders
}
delete options._special
var completeConfig = deepExtend({
entry: {},
@@ -130,11 +110,11 @@ module.exports = function(options) {
},
module: {
loaders: loaders,
rules: commonRules.concat(rules),
},
resolveLoader: {
root: path.join(__dirname, 'node_modules'),
modules: [path.join(__dirname, 'node_modules')],
},
externals: {
@@ -142,19 +122,16 @@ module.exports = function(options) {
},
resolve: {
root: path.join(__dirname, './src'),
modulesDirectories: ['node_modules'],
extensions: ["", ".web.js", ".js", ".jsx", ".json", ".less"],
packageAlias: 'browser',
modules: [
path.join(__dirname, './src'),
'node_modules'
],
extensions: [".web.js", ".js", ".jsx", ".json", ".less"],
alias: {
base: "getbase/src/less/base",
}
},
postcss: function() {
return [autoprefixer]
},
devtool: specialOptions.sourcemaps ? 'cheap-module-source-map' : null,
plugins,

View File

@@ -48,6 +48,7 @@
"matcher": "^0.1.2",
"memoizee": "0.4.1",
"promise-worker": "^1.1.1",
"prop-types": "^15.5.10",
"react": "^15.4.0",
"react-addons-perf": "0.14.8",
"react-addons-shallow-compare": "0.14.8",
@@ -77,10 +78,10 @@
"yaml-js": "0.2.0"
},
"devDependencies": {
"autoprefixer": "6.6.1",
"autoprefixer": "7.1.1",
"babel-core": "^6.23.1",
"babel-eslint": "^7.1.1",
"babel-loader": "^6.3.2",
"babel-loader": "^7.1.0",
"babel-plugin-module-alias": "^1.6.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.22.0",
@@ -88,42 +89,43 @@
"babel-preset-react": "^6.23.0",
"babel-preset-stage-0": "^6.22.0",
"babel-runtime": "^6.23.0",
"css-loader": "0.22.0",
"deep-extend": "^0.4.1",
"css-loader": "0.28.4",
"deep-extend": "^0.5.0",
"deepmerge": "^1.3.2",
"enzyme": "^2.7.1",
"eslint": "^2.13.1",
"eslint-plugin-react": "^6.10.3",
"extract-text-webpack-plugin": "0.8.2",
"file-loader": "0.8.4",
"eslint": "^4.1.1",
"eslint-plugin-import": "^2.6.0",
"eslint-plugin-react": "^7.1.0",
"extract-text-webpack-plugin": "^2.1.2",
"file-loader": "0.11.2",
"git-describe": "^4.0.1",
"html-webpack-plugin": "^2.28.0",
"imports-loader": "0.6.5",
"json-loader": "0.5.3",
"karma": "^0.13.22",
"karma-chrome-launcher": "^0.2.3",
"karma-mocha": "^0.2.2",
"imports-loader": "0.7.1",
"json-loader": "0.5.4",
"karma": "^1.7.0",
"karma-chrome-launcher": "^2.2.0",
"karma-mocha": "^1.3.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "1.8.0",
"less": "2.5.3",
"less-loader": "2.2.1",
"license-checker": "^8.0.4",
"mocha": "^2.5.3",
"karma-webpack": "2.0.3",
"less": "2.7.2",
"less-loader": "4.0.4",
"license-checker": "^11.0.0",
"mocha": "^3.4.2",
"node-sass": "^4.5.0",
"npm-run-all": "3.1.1",
"npm-run-all": "4.0.2",
"null-loader": "0.1.1",
"open": "0.0.5",
"postcss-loader": "0.7.0",
"postcss-loader": "2.0.6",
"raw-loader": "0.5.1",
"react-hot-loader": "^1.3.1",
"react-test-renderer": "^15.5.4",
"rimraf": "^2.6.0",
"sass-loader": "^6.0.2",
"standard": "^8.6.0",
"standard-loader": "^5.0.0",
"style-loader": "0.13.0",
"url-loader": "0.5.6",
"webpack": "^1.14.0",
"standard": "^10.0.2",
"standard-loader": "^6.0.1",
"style-loader": "0.18.2",
"url-loader": "0.5.9",
"webpack": "^2.6.1",
"webpack-bundle-size-analyzer": "^2.5.0"
},
"config": {
@@ -135,6 +137,6 @@
"IE 11"
],
"optionalDependencies": {
"webpack-dev-server": "1.14.0"
"webpack-dev-server": "2.5.0"
}
}

1
postcss.config.js Normal file
View File

@@ -0,0 +1 @@
module.exports = {};

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class App extends React.Component {
@@ -6,7 +7,7 @@ export default class App extends React.Component {
let { getComponent, layoutSelectors } = this.props
const layoutName = layoutSelectors.current()
const Component = getComponent(layoutName, true)
return Component ? Component : ()=> <h1> No layout defined for "{layoutName}" </h1>
return Component ? Component : ()=> <h1> No layout defined for &quot;{layoutName}&quot; </h1>
}
render() {

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
const propStyle = { color: "#999", fontStyle: "italic" }

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class ApiKeyAuth extends React.Component {
static propTypes = {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class AuthorizationPopup extends React.Component {
close =() => {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class AuthorizeBtn extends React.Component {
static propTypes = {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
export default class AuthorizeOperationBtn extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
export default class Auths extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
export default class BasicAuth extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class AuthError extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import oauth2Authorize from "core/oauth2-authorize"
const IMPLICIT = "implicit"

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
export default class Clear extends Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import { fromJS } from "immutable"

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import curlify from "core/curlify"
export default class Curl extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import Collapse from "react-collapse"
import { presets } from "react-motion"
import ObjectInspector from "react-object-inspector"

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import { List } from "immutable"
import Collapse from "react-collapse"

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
export default class Execute extends Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import Im from "immutable"
export default class Headers extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
import { highlight } from "core/utils"
export default class HighlightCode extends Component {
@@ -8,17 +9,21 @@ export default class HighlightCode extends Component {
}
componentDidMount() {
highlight(this.refs.el)
highlight(this.el)
}
componentDidUpdate() {
highlight(this.refs.el)
highlight(this.el)
}
initializeComponent = (c) => {
this.el = c
}
render () {
let { value, className } = this.props
className = className || ""
return <pre ref="el" className={className + " microlight"}>{ value }</pre>
return <pre ref={this.initializeComponent} className={className + " microlight"}>{ value }</pre>
}
}

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import { fromJS } from "immutable"
import ImPropTypes from "react-immutable-proptypes"

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import OriCollapse from "react-collapse"
function xclass(...args) {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class BaseLayout extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class XPane extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
const Headers = ( { headers } )=>{
@@ -8,28 +9,40 @@ const Headers = ( { headers } )=>{
<pre>{headers}</pre>
</div>)
}
Headers.propTypes = {
headers: PropTypes.array.isRequired
}
const Duration = ( { duration } ) => {
return (
<div>
<h5>Request duration</h5>
<pre>{duration} ms</pre>
</div>
)
}
Duration.propTypes = {
duration: PropTypes.number.isRequired
}
export default class LiveResponse extends React.Component {
static propTypes = {
response: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired
getComponent: PropTypes.func.isRequired,
displayRequestDuration: PropTypes.bool.isRequired
}
render() {
const { request, response, getComponent } = this.props
const { request, response, getComponent, displayRequestDuration } = this.props
const status = response.get("status")
const url = response.get("url")
const headers = response.get("headers").toJS()
const notDocumented = response.get("notDocumented")
const isError = response.get("error")
const body = isError ? response.get("response").get("text") : response.get("text")
const body = response.get("text")
const duration = response.get("duration")
const headersKeys = Object.keys(headers)
const contentType = headers["content-type"]
@@ -80,6 +93,9 @@ export default class LiveResponse extends React.Component {
{
hasHeaders ? <Headers headers={ returnObject }/> : null
}
{
displayRequestDuration && duration ? <Duration duration={ duration } /> : null
}
</td>
</tr>
</tbody>

View File

@@ -1,5 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class ModelExample extends React.Component {
static propTypes = {

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component, } from "react"
import PropTypes from "prop-types"
export default class ModelComponent extends Component {
static propTypes = {

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
export default class Model extends Component {
static propTypes = {

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
export default class Models extends Component {
static propTypes = {
@@ -30,7 +31,6 @@ export default class Models extends Component {
<Collapse isOpened={showModels} animated>
{
definitions.entrySeq().map( ( [ name, model ])=>{
console.log("model", name, model)
return <div className="model-container" key={ `models-section-${name}` }>
<ModelWrapper name={ name }
schema={ model }

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component, } from "react"
import PropTypes from "prop-types"
import { List } from "immutable"
const braceOpen = "{"

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class OnlineValidatorBadge extends React.Component {
static propTypes = {

View File

@@ -1,4 +1,5 @@
import React, { PureComponent, PropTypes } from "react"
import React, { PureComponent } from "react"
import PropTypes from "prop-types"
import { getList } from "core/utils"
import * as CustomPropTypes from "core/proptypes"
@@ -17,6 +18,7 @@ export default class Operation extends PureComponent {
allowTryItOut: PropTypes.bool,
displayOperationId: PropTypes.bool,
displayRequestDuration: PropTypes.bool,
response: PropTypes.object,
request: PropTypes.object,
@@ -37,6 +39,7 @@ export default class Operation extends PureComponent {
response: null,
allowTryItOut: true,
displayOperationId: false,
displayRequestDuration: false
}
constructor(props, context) {
@@ -107,7 +110,7 @@ export default class Operation extends PureComponent {
request,
allowTryItOut,
displayOperationId,
displayRequestDuration,
fn,
getComponent,
specActions,
@@ -126,6 +129,7 @@ export default class Operation extends PureComponent {
let schemes = operation.get("schemes")
let parameters = getList(operation, ["parameters"])
let operationId = operation.get("__originalOperationId")
let operationScheme = specSelectors.operationScheme(path, method)
const Responses = getComponent("responses")
const Parameters = getComponent( "parameters" )
@@ -211,7 +215,8 @@ export default class Operation extends PureComponent {
<Schemes schemes={ schemes }
path={ path }
method={ method }
specActions={ specActions }/>
specActions={ specActions }
operationScheme={ operationScheme } />
</div> : null
}
@@ -250,6 +255,7 @@ export default class Operation extends PureComponent {
produces={ produces }
producesValue={ operation.get("produces_value") }
pathMethod={ [path, method] }
displayRequestDuration={ displayRequestDuration }
fn={fn} />
}
</div>

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class Operations extends React.Component {
@@ -32,7 +33,7 @@ export default class Operations extends React.Component {
const Collapse = getComponent("Collapse")
let showSummary = layoutSelectors.showSummary()
let { docExpansion, displayOperationId } = getConfigs()
let { docExpansion, displayOperationId, displayRequestDuration } = getConfigs()
return (
<div>
@@ -87,6 +88,7 @@ export default class Operations extends React.Component {
allowTryItOut={allowTryItOut}
displayOperationId={displayOperationId}
displayRequestDuration={displayRequestDuration}
specActions={ specActions }
specSelectors={ specSelectors }

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import { Link } from "core/components/layout-utils"
export default class Overview extends React.Component {

View File

@@ -1,4 +1,5 @@
import React, { PureComponent, PropTypes } from "react"
import React, { PureComponent } from "react"
import PropTypes from "prop-types"
import { fromJS, List } from "immutable"
import { getSampleSchema } from "core/utils"

View File

@@ -1,7 +1,7 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
import win from "core/window"
export default class ParameterRow extends Component {
static propTypes = {
onChange: PropTypes.func.isRequired,

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import Im from "immutable"

View File

@@ -1,4 +1,5 @@
import React, { Component, PropTypes } from "react"
import React, { Component } from "react"
import PropTypes from "prop-types"
const propStyle = { color: "#999", fontStyle: "italic" }

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import Remarkable from "react-remarkable"
import sanitize from "sanitize-html"

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import { formatXml } from "core/utils"
import lowerCase from "lodash/lowerCase"
@@ -6,7 +7,7 @@ export default class ResponseBody extends React.Component {
static propTypes = {
content: PropTypes.any.isRequired,
contentType: PropTypes.string.isRequired,
contentType: PropTypes.string,
getComponent: PropTypes.func.isRequired,
headers: PropTypes.object,
url: PropTypes.string

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import { fromJS } from "immutable"
import { getSampleSchema } from "core/utils"

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import { fromJS } from "immutable"
import { defaultStatusCode } from "core/utils"
@@ -14,19 +15,21 @@ export default class Responses extends React.Component {
specSelectors: PropTypes.object.isRequired,
specActions: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired,
displayRequestDuration: PropTypes.bool.isRequired,
fn: PropTypes.object.isRequired
}
static defaultProps = {
request: null,
tryItOutResponse: null,
produces: fromJS(["application/json"])
produces: fromJS(["application/json"]),
displayRequestDuration: false
}
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val)
render() {
let { responses, request, tryItOutResponse, getComponent, specSelectors, fn, producesValue } = this.props
let { responses, request, tryItOutResponse, getComponent, specSelectors, fn, producesValue, displayRequestDuration } = this.props
let defaultCode = defaultStatusCode( responses )
const ContentType = getComponent( "contentType" )
@@ -53,7 +56,8 @@ export default class Responses extends React.Component {
: <div>
<LiveResponse request={ request }
response={ tryItOutResponse }
getComponent={ getComponent } />
getComponent={ getComponent }
displayRequestDuration={ displayRequestDuration } />
<h4>Responses</h4>
</div>

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class Schemes extends React.Component {
@@ -6,7 +7,8 @@ export default class Schemes extends React.Component {
specActions: PropTypes.object.isRequired,
schemes: PropTypes.object.isRequired,
path: PropTypes.string,
method: PropTypes.string
method: PropTypes.string,
operationScheme: PropTypes.string
}
componentWillMount() {
@@ -16,6 +18,13 @@ export default class Schemes extends React.Component {
this.setScheme(schemes.first())
}
componentWillReceiveProps(nextProps) {
if ( this.props.operationScheme && !nextProps.schemes.has(this.props.operationScheme) ) {
//fire 'change' event if our selected scheme is no longer an option
this.setScheme(nextProps.schemes.first())
}
}
onChange =( e ) => {
this.setScheme( e.target.value )
}

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class TryItOutButton extends React.Component {

View File

@@ -8,7 +8,7 @@ import { parseSeach, filterConfigs } from "core/utils"
const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
"apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" ]
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" , "displayRequestDuration"]
// eslint-disable-next-line no-undef
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
@@ -30,6 +30,7 @@ module.exports = function SwaggerUI(opts) {
configs: {},
custom: {},
displayOperationId: false,
displayRequestDuration: false,
// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.

View File

@@ -1,4 +1,5 @@
import React, { PropTypes, PureComponent, Component } from "react"
import React, { PureComponent, Component } from "react"
import PropTypes from "prop-types"
import { List, fromJS } from "immutable"
//import "less/json-schema-form"

View File

@@ -207,8 +207,14 @@ export const executeRequest = (req) => ({fn, specActions, specSelectors}) => {
specActions.setRequest(req.pathName, req.method, parsedRequest)
// track duration of request
const startTime = Date.now()
return fn.execute(req)
.then( res => specActions.setResponse(req.pathName, req.method, res))
.then( res => {
res.duration = Date.now() - startTime
specActions.setResponse(req.pathName, req.method, res)
} )
.catch( err => specActions.setResponse(req.pathName, req.method, { error: true, err: serializeError(err) } ) )
}

View File

@@ -75,7 +75,12 @@ export default {
[SET_RESPONSE]: (state, { payload: { res, path, method } } ) =>{
let result
if ( res.error ) {
result = Object.assign({error: true}, res.err)
result = Object.assign({
error: true,
name: res.err.name,
message: res.err.message,
statusCode: res.err.statusCode
}, res.err.response)
} else {
result = res
}
@@ -86,7 +91,7 @@ export default {
let newState = state.setIn( [ "responses", path, method ], fromJSOrdered(result) )
// ImmutableJS messes up Blob. Needs to reset its value.
if (res.data instanceof win.Blob) {
if (win.Blob && res.data instanceof win.Blob) {
newState = newState.setIn( [ "responses", path, method, "text" ], res.data)
}
return newState

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
import SplitPane from "react-split-pane"
import "./split-pane-mode.less"
@@ -23,9 +24,13 @@ export default class SplitPaneMode extends React.Component {
children: [],
};
initializeComponent = (c) => {
this.splitPane = c
}
onDragFinished = () => {
let { threshold, layoutActions } = this.props
let { position, draggedSize } = this.refs.splitPane.state
let { position, draggedSize } = this.splitPane.state
this.draggedSize = draggedSize
let nearLeftEdge = position <= threshold
@@ -62,7 +67,7 @@ export default class SplitPaneMode extends React.Component {
return (
<SplitPane
disabledClass={""}
ref={"splitPane"}
ref={this.initializeComponent}
split='vertical'
defaultSize={"50%"}
primary="second"

View File

@@ -65,11 +65,11 @@ export const render = (getSystem, getStore, getComponent, getComponents, dom) =>
}
// Render try/catch wrapper
const createClass = component => React.createClass({
const createClass = component => class extends Component {
render() {
return component(this.props)
}
})
}
const Fallback = ({ name }) => <div style={{ // eslint-disable-line react/prop-types
padding: "1em",

View File

@@ -1,4 +1,4 @@
import { PropTypes } from "react"
import PropTypes from "prop-types"
// Takes a list and proptype, and returns a PropType.shape({ [item]: propType })
const mapListToPropTypeShape = (list, propType) => PropTypes.shape(

View File

@@ -240,7 +240,7 @@ export default class Store {
action = {type: NEW_THROWN_ERR, error: true, payload: serializeError(e) }
}
finally{
return action
return action // eslint-disable-line no-unsafe-finally
}
}

View File

@@ -343,7 +343,7 @@ export function highlight (el) {
while (![
1, // 0: whitespace
// 1: operator or braces
/[\/{}[(\-+*=<>:;|\\.,?!&@~]/[test](chr),
/[\/{}[(\-+*=<>:;|\\.,?!&@~]/[test](chr), // eslint-disable-line no-useless-escape
/[\])]/[test](chr), // 2: closing brace
/[$\w]/[test](chr), // 3: (key)word
chr == "/" && // 4: regex
@@ -450,15 +450,15 @@ export const propChecker = (props, nextProps, objectList=[], ignoreList=[]) => {
|| objectList.some( objectPropName => !eq(props[objectPropName], nextProps[objectPropName])))
}
const validateNumber = ( val ) => {
if ( !/^-?\d+(.?\d+)?$/.test(val)) {
export const validateNumber = ( val ) => {
if ( !/^-?\d+(\.?\d+)?$/.test(val)) {
return "Value must be a number"
}
}
const validateInteger = ( val ) => {
export const validateInteger = ( val ) => {
if ( !/^-?\d+$/.test(val)) {
return "Value must be integer"
return "Value must be an integer"
}
}
@@ -469,13 +469,14 @@ export const validateParam = (param, isXml) => {
let required = param.get("required")
let type = param.get("type")
if ( required && (!value || (type==="array" && Array.isArray(value) && !value.length ))) {
let stringCheck = type === "string" && !value
let arrayCheck = type === "array" && Array.isArray(value) && !value.length
let listCheck = type === "array" && Im.List.isList(value) && !value.count()
if ( required && (stringCheck || arrayCheck || listCheck) ) {
errors.push("Required field is not provided")
return errors
}
if ( !value ) return errors
if ( type === "number" ) {
let err = validateNumber(value)
if (!err) return errors

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
//import "./topbar.less"
import Logo from "./logo_small.png"

View File

@@ -1,4 +1,5 @@
import React, { PropTypes } from "react"
import React from "react"
import PropTypes from "prop-types"
export default class StandaloneLayout extends React.Component {

View File

@@ -95,14 +95,7 @@ section.models
h4
{
margin: 0 0 5px 0;
border-bottom: 1px solid rgba(#3b4151, .3);
svg
{
transform: rotate(90deg);
}
}
}
h4

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-useless-escape */
import expect from "expect"
import { fromJS } from "immutable"
import { transform } from "corePlugins/err/error-transformers/transformers/parameter-oneof"

View File

@@ -69,4 +69,56 @@ describe("spec plugin - reducer", function(){
expect(result.toJS()).toEqual(state.toJS())
})
})
describe("set response value", function() {
it("should combine the response and error objects", () => {
const setResponse = reducer["spec_set_response"]
const path = "/pet/post"
const method = "POST"
const state = fromJS({})
const result = setResponse(state, {
payload: {
path: path,
method: method,
res: {
error: true,
err: {
message: "Not Found",
name: "Error",
response: {
data: "response data",
headers: {
key: "value"
},
ok: false,
status: 404,
statusText: "Not Found"
},
status: 404,
statusCode: 404
}
}
}
})
let expectedResult = {
error: true,
message: "Not Found",
name: "Error",
data: "response data",
headers: {
key: "value"
},
ok: false,
status: 404,
statusCode: 404,
statusText: "Not Found"
}
const response = result.getIn(["responses", path, method]).toJS()
expect(response).toEqual(expectedResult)
})
})
})

View File

@@ -1,7 +1,7 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS } from "immutable"
import { mapToList } from "core/utils"
import { mapToList, validateNumber, validateInteger, validateParam } from "core/utils"
describe("utils", function(){
@@ -67,9 +67,181 @@ describe("utils", function(){
// Then
expect(aList.toJS()).toEqual([])
})
})
describe("validateNumber", function() {
let errorMessage = "Value must be a number"
it("doesn't return for whole numbers", function() {
expect(validateNumber(0)).toBeFalsy()
expect(validateNumber(1)).toBeFalsy()
expect(validateNumber(20)).toBeFalsy()
expect(validateNumber(5000000)).toBeFalsy()
expect(validateNumber("1")).toBeFalsy()
expect(validateNumber("2")).toBeFalsy()
expect(validateNumber(-1)).toBeFalsy()
expect(validateNumber(-20)).toBeFalsy()
expect(validateNumber(-5000000)).toBeFalsy()
})
it("doesn't return for negative numbers", function() {
expect(validateNumber(-1)).toBeFalsy()
expect(validateNumber(-20)).toBeFalsy()
expect(validateNumber(-5000000)).toBeFalsy()
})
it("doesn't return for decimal numbers", function() {
expect(validateNumber(1.1)).toBeFalsy()
expect(validateNumber(2.5)).toBeFalsy()
expect(validateNumber(-30.99)).toBeFalsy()
})
it("returns a message for strings", function() {
expect(validateNumber("")).toEqual(errorMessage)
expect(validateNumber(" ")).toEqual(errorMessage)
expect(validateNumber("test")).toEqual(errorMessage)
})
it("returns a message for invalid input", function() {
expect(validateNumber(undefined)).toEqual(errorMessage)
expect(validateNumber(null)).toEqual(errorMessage)
expect(validateNumber({})).toEqual(errorMessage)
expect(validateNumber([])).toEqual(errorMessage)
expect(validateNumber(true)).toEqual(errorMessage)
expect(validateNumber(false)).toEqual(errorMessage)
})
})
describe("validateInteger", function() {
let errorMessage = "Value must be an integer"
it("doesn't return for positive integers", function() {
expect(validateInteger(0)).toBeFalsy()
expect(validateInteger(1)).toBeFalsy()
expect(validateInteger(20)).toBeFalsy()
expect(validateInteger(5000000)).toBeFalsy()
expect(validateInteger("1")).toBeFalsy()
expect(validateInteger("2")).toBeFalsy()
expect(validateInteger(-1)).toBeFalsy()
expect(validateInteger(-20)).toBeFalsy()
expect(validateInteger(-5000000)).toBeFalsy()
})
it("doesn't return for negative integers", function() {
expect(validateInteger(-1)).toBeFalsy()
expect(validateInteger(-20)).toBeFalsy()
expect(validateInteger(-5000000)).toBeFalsy()
})
it("returns a message for decimal values", function() {
expect(validateInteger(1.1)).toEqual(errorMessage)
expect(validateInteger(2.5)).toEqual(errorMessage)
expect(validateInteger(-30.99)).toEqual(errorMessage)
})
it("returns a message for strings", function() {
expect(validateInteger("")).toEqual(errorMessage)
expect(validateInteger(" ")).toEqual(errorMessage)
expect(validateInteger("test")).toEqual(errorMessage)
})
it("returns a message for invalid input", function() {
expect(validateInteger(undefined)).toEqual(errorMessage)
expect(validateInteger(null)).toEqual(errorMessage)
expect(validateInteger({})).toEqual(errorMessage)
expect(validateInteger([])).toEqual(errorMessage)
expect(validateInteger(true)).toEqual(errorMessage)
expect(validateInteger(false)).toEqual(errorMessage)
})
})
describe("validateParam", function() {
let param = null
let result = null
it("validates required strings", function() {
param = fromJS({
required: true,
type: "string",
value: ""
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )
})
it("validates required arrays", function() {
param = fromJS({
required: true,
type: "array",
value: []
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )
param = fromJS({
required: true,
type: "array",
value: []
})
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )
})
it("validates numbers", function() {
param = fromJS({
required: false,
type: "number",
value: "test"
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be a number"] )
})
it("validates integers", function() {
param = fromJS({
required: false,
type: "integer",
value: "test"
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be an integer"] )
})
it("validates arrays", function() {
// empty array
param = fromJS({
required: false,
type: "array",
value: []
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
// numbers
param = fromJS({
required: false,
type: "array",
value: ["number"],
items: {
type: "number"
}
})
result = validateParam( param, false )
expect( result ).toEqual( [{index: 0, error: "Value must be a number"}] )
// integers
param = fromJS({
required: false,
type: "array",
value: ["not", "numbers"],
items: {
type: "integer"
}
})
result = validateParam( param, false )
expect( result ).toEqual( [{index: 0, error: "Value must be an integer"}, {index: 1, error: "Value must be an integer"}] )
})
})
})

View File

@@ -1,14 +1,58 @@
var path = require('path')
var rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
options: {
inline: true,
name: '[name].js'
}
},
{ loader: 'babel-loader' }
]
},
{ test: /\.(css)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
},
{ test: /\.(scss)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{ loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true,
sourceMapContents: 'true'
}
}
]
},
{ test: /\.(less)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
]
}
]
module.exports = require('./make-webpack-config.js')({
module.exports = require('./make-webpack-config.js')(rules, {
_special: {
separateStylesheets: false,
minimize: true,
sourcemaps: true,
loaders: {
"worker.js": ["worker-loader?inline=true&name=[name].js", "babel"]
}
},
entry: {

View File

@@ -1,14 +1,59 @@
var path = require('path')
var rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
options: {
inline: true,
name: '[name].js'
}
},
{ loader: 'babel-loader' }
]
},
{ test: /\.(css)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
},
{ test: /\.(scss)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{ loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true,
sourceMapContents: 'true'
}
}
]
},
{ test: /\.(less)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
]
}
]
module.exports = require('./make-webpack-config.js')({
module.exports = require('./make-webpack-config.js')(rules, {
_special: {
separateStylesheets: false,
minimize: true,
sourcemaps: true,
loaders: {
"worker.js": ["worker-loader?inline=true&name=[name].js", "babel"]
}
},
entry: {

View File

@@ -1,15 +1,70 @@
const path = require("path")
const fs = require("fs")
var path = require('path')
var fs = require('fs')
const nodeModules = fs.readdirSync("node_modules").filter(function(x) { return x !== ".bin" })
var ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = require("./make-webpack-config.js")({
var rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
options: {
inline: true,
name: '[name].js'
}
},
{ loader: 'babel-loader' }
]
},
{ test: /\.(css)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'postcss-loader'
]
})
},
{ test: /\.(scss)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: { minimize: true }
},
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{ loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true,
sourceMapContents: 'true'
}
}
]
})
},
{ test: /\.(less)(\?.*)?$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
]
})
}
]
module.exports = require('./make-webpack-config.js')(rules, {
_special: {
separateStylesheets: true,
minimize: true,
sourcemaps: true,
loaders: {
"worker.js": ["worker-loader?inline=true&name=[name].js", "babel"]
}
},
entry: {

View File

@@ -1,10 +1,61 @@
var path = require('path')
module.exports = require("./make-webpack-config")({
_special: {
loaders: {
'jsx': [ "react-hot-loader", "babel" ]
var rules = [
{ test: /\.(worker\.js)(\?.*)?$/,
use: [
{
loader: 'worker-loader',
options: {
inline: true
}
},
{ loader: 'babel-loader' }
]
},
{ test: /\.(jsx)(\?.*)?$/,
use: [
{ loader: 'react-hot-loader' },
{ loader: 'babel-loader' }
]
},
{ test: /\.(css)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
},
{ test: /\.(scss)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{ loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true,
sourceMapContents: 'true'
}
}
]
},
{ test: /\.(less)(\?.*)?$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
},
'less-loader'
]
}
]
module.exports = require("./make-webpack-config")(rules, {
_special: {
separateStylesheets: false,
},
devtool: "eval",
@@ -14,14 +65,12 @@ module.exports = require("./make-webpack-config")({
'./src/core/index.js'
],
'swagger-ui-standalone-preset': [
'webpack/hot/dev-server',
'./src/polyfills',
'./src/standalone/index.js',
]
},
output: {
pathinfo: true,
debug: true,
filename: '[name].js',
library: "[name]",
libraryTarget: "umd",
@@ -29,10 +78,9 @@ module.exports = require("./make-webpack-config")({
},
devServer: {
port: 3200,
path: path.join(__dirname, 'dev-helpers'),
contentBase: path.join(__dirname, 'dev-helpers'),
publicPath: "/",
noInfo: true,
colors: true,
hot: true,
stats: {
colors: true