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 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'. 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`. 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 ### 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 webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin') var ExtractTextPlugin = require('extract-text-webpack-plugin')
var deepExtend = require('deep-extend') var deepExtend = require('deep-extend')
var autoprefixer = require('autoprefixer')
const {gitDescribeSync} = require('git-describe'); const {gitDescribeSync} = require('git-describe');
var loadersByExtension = require('./build-tools/loadersByExtension')
var pkg = require('./package.json') var pkg = require('./package.json')
let gitInfo 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 // Special options, that have logic in this file
// ...with defaults // ...with defaults
@@ -33,23 +50,11 @@ module.exports = function(options) {
sourcemaps: false, sourcemaps: false,
}, options._special) }, 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 = [] var plugins = []
if( specialOptions.separateStylesheets ) { if( specialOptions.separateStylesheets ) {
plugins.push(new ExtractTextPlugin('[name].css' + (specialOptions.longTermCaching ? '?[contenthash]' : ''), { plugins.push(new ExtractTextPlugin({
filename: '[name].css' + (specialOptions.longTermCaching ? '?[contenthash]' : ''),
allChunks: true allChunks: true
})) }))
} }
@@ -58,14 +63,16 @@ module.exports = function(options) {
plugins.push( plugins.push(
new webpack.optimize.UglifyJsPlugin({ new webpack.optimize.UglifyJsPlugin({
compressor: { sourceMap: true,
warnings: false
}
}), }),
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' delete options._special
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
}
var completeConfig = deepExtend({ var completeConfig = deepExtend({
entry: {}, entry: {},
@@ -130,11 +110,11 @@ module.exports = function(options) {
}, },
module: { module: {
loaders: loaders, rules: commonRules.concat(rules),
}, },
resolveLoader: { resolveLoader: {
root: path.join(__dirname, 'node_modules'), modules: [path.join(__dirname, 'node_modules')],
}, },
externals: { externals: {
@@ -142,19 +122,16 @@ module.exports = function(options) {
}, },
resolve: { resolve: {
root: path.join(__dirname, './src'), modules: [
modulesDirectories: ['node_modules'], path.join(__dirname, './src'),
extensions: ["", ".web.js", ".js", ".jsx", ".json", ".less"], 'node_modules'
packageAlias: 'browser', ],
extensions: [".web.js", ".js", ".jsx", ".json", ".less"],
alias: { alias: {
base: "getbase/src/less/base", base: "getbase/src/less/base",
} }
}, },
postcss: function() {
return [autoprefixer]
},
devtool: specialOptions.sourcemaps ? 'cheap-module-source-map' : null, devtool: specialOptions.sourcemaps ? 'cheap-module-source-map' : null,
plugins, plugins,

View File

@@ -48,6 +48,7 @@
"matcher": "^0.1.2", "matcher": "^0.1.2",
"memoizee": "0.4.1", "memoizee": "0.4.1",
"promise-worker": "^1.1.1", "promise-worker": "^1.1.1",
"prop-types": "^15.5.10",
"react": "^15.4.0", "react": "^15.4.0",
"react-addons-perf": "0.14.8", "react-addons-perf": "0.14.8",
"react-addons-shallow-compare": "0.14.8", "react-addons-shallow-compare": "0.14.8",
@@ -77,10 +78,10 @@
"yaml-js": "0.2.0" "yaml-js": "0.2.0"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "6.6.1", "autoprefixer": "7.1.1",
"babel-core": "^6.23.1", "babel-core": "^6.23.1",
"babel-eslint": "^7.1.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-module-alias": "^1.6.0",
"babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.22.0", "babel-preset-es2015": "^6.22.0",
@@ -88,42 +89,43 @@
"babel-preset-react": "^6.23.0", "babel-preset-react": "^6.23.0",
"babel-preset-stage-0": "^6.22.0", "babel-preset-stage-0": "^6.22.0",
"babel-runtime": "^6.23.0", "babel-runtime": "^6.23.0",
"css-loader": "0.22.0", "css-loader": "0.28.4",
"deep-extend": "^0.4.1", "deep-extend": "^0.5.0",
"deepmerge": "^1.3.2", "deepmerge": "^1.3.2",
"enzyme": "^2.7.1", "enzyme": "^2.7.1",
"eslint": "^2.13.1", "eslint": "^4.1.1",
"eslint-plugin-react": "^6.10.3", "eslint-plugin-import": "^2.6.0",
"extract-text-webpack-plugin": "0.8.2", "eslint-plugin-react": "^7.1.0",
"file-loader": "0.8.4", "extract-text-webpack-plugin": "^2.1.2",
"file-loader": "0.11.2",
"git-describe": "^4.0.1", "git-describe": "^4.0.1",
"html-webpack-plugin": "^2.28.0", "html-webpack-plugin": "^2.28.0",
"imports-loader": "0.6.5", "imports-loader": "0.7.1",
"json-loader": "0.5.3", "json-loader": "0.5.4",
"karma": "^0.13.22", "karma": "^1.7.0",
"karma-chrome-launcher": "^0.2.3", "karma-chrome-launcher": "^2.2.0",
"karma-mocha": "^0.2.2", "karma-mocha": "^1.3.0",
"karma-sourcemap-loader": "^0.3.7", "karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "1.8.0", "karma-webpack": "2.0.3",
"less": "2.5.3", "less": "2.7.2",
"less-loader": "2.2.1", "less-loader": "4.0.4",
"license-checker": "^8.0.4", "license-checker": "^11.0.0",
"mocha": "^2.5.3", "mocha": "^3.4.2",
"node-sass": "^4.5.0", "node-sass": "^4.5.0",
"npm-run-all": "3.1.1", "npm-run-all": "4.0.2",
"null-loader": "0.1.1", "null-loader": "0.1.1",
"open": "0.0.5", "open": "0.0.5",
"postcss-loader": "0.7.0", "postcss-loader": "2.0.6",
"raw-loader": "0.5.1", "raw-loader": "0.5.1",
"react-hot-loader": "^1.3.1", "react-hot-loader": "^1.3.1",
"react-test-renderer": "^15.5.4", "react-test-renderer": "^15.5.4",
"rimraf": "^2.6.0", "rimraf": "^2.6.0",
"sass-loader": "^6.0.2", "sass-loader": "^6.0.2",
"standard": "^8.6.0", "standard": "^10.0.2",
"standard-loader": "^5.0.0", "standard-loader": "^6.0.1",
"style-loader": "0.13.0", "style-loader": "0.18.2",
"url-loader": "0.5.6", "url-loader": "0.5.9",
"webpack": "^1.14.0", "webpack": "^2.6.1",
"webpack-bundle-size-analyzer": "^2.5.0" "webpack-bundle-size-analyzer": "^2.5.0"
}, },
"config": { "config": {
@@ -135,6 +137,6 @@
"IE 11" "IE 11"
], ],
"optionalDependencies": { "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 { export default class App extends React.Component {
@@ -6,7 +7,7 @@ export default class App extends React.Component {
let { getComponent, layoutSelectors } = this.props let { getComponent, layoutSelectors } = this.props
const layoutName = layoutSelectors.current() const layoutName = layoutSelectors.current()
const Component = getComponent(layoutName, true) 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() { 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" } 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 { export default class ApiKeyAuth extends React.Component {
static propTypes = { 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 { export default class AuthorizationPopup extends React.Component {
close =() => { 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 { export default class AuthorizeBtn extends React.Component {
static propTypes = { 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" import ImPropTypes from "react-immutable-proptypes"
export default class AuthorizeOperationBtn extends React.Component { 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" import ImPropTypes from "react-immutable-proptypes"
export default class Auths extends React.Component { 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" import ImPropTypes from "react-immutable-proptypes"
export default class BasicAuth extends React.Component { 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 { 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" import oauth2Authorize from "core/oauth2-authorize"
const IMPLICIT = "implicit" 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 { 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 ImPropTypes from "react-immutable-proptypes"
import { fromJS } from "immutable" 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" import curlify from "core/curlify"
export default class Curl extends React.Component { 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 Collapse from "react-collapse"
import { presets } from "react-motion" import { presets } from "react-motion"
import ObjectInspector from "react-object-inspector" 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 { List } from "immutable"
import Collapse from "react-collapse" 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 { 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" import Im from "immutable"
export default class Headers extends React.Component { 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" import { highlight } from "core/utils"
export default class HighlightCode extends Component { export default class HighlightCode extends Component {
@@ -8,17 +9,21 @@ export default class HighlightCode extends Component {
} }
componentDidMount() { componentDidMount() {
highlight(this.refs.el) highlight(this.el)
} }
componentDidUpdate() { componentDidUpdate() {
highlight(this.refs.el) highlight(this.el)
}
initializeComponent = (c) => {
this.el = c
} }
render () { render () {
let { value, className } = this.props let { value, className } = this.props
className = className || "" 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 { fromJS } from "immutable"
import ImPropTypes from "react-immutable-proptypes" 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" import OriCollapse from "react-collapse"
function xclass(...args) { 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 { 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 { 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" import ImPropTypes from "react-immutable-proptypes"
const Headers = ( { headers } )=>{ const Headers = ( { headers } )=>{
@@ -8,28 +9,40 @@ const Headers = ( { headers } )=>{
<pre>{headers}</pre> <pre>{headers}</pre>
</div>) </div>)
} }
Headers.propTypes = { Headers.propTypes = {
headers: PropTypes.array.isRequired 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 { export default class LiveResponse extends React.Component {
static propTypes = { static propTypes = {
response: PropTypes.object.isRequired, response: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired getComponent: PropTypes.func.isRequired,
displayRequestDuration: PropTypes.bool.isRequired
} }
render() { render() {
const { request, response, getComponent } = this.props const { request, response, getComponent, displayRequestDuration } = this.props
const status = response.get("status") const status = response.get("status")
const url = response.get("url") const url = response.get("url")
const headers = response.get("headers").toJS() const headers = response.get("headers").toJS()
const notDocumented = response.get("notDocumented") const notDocumented = response.get("notDocumented")
const isError = response.get("error") const isError = response.get("error")
const body = response.get("text")
const body = isError ? response.get("response").get("text") : response.get("text") const duration = response.get("duration")
const headersKeys = Object.keys(headers) const headersKeys = Object.keys(headers)
const contentType = headers["content-type"] const contentType = headers["content-type"]
@@ -80,6 +93,9 @@ export default class LiveResponse extends React.Component {
{ {
hasHeaders ? <Headers headers={ returnObject }/> : null hasHeaders ? <Headers headers={ returnObject }/> : null
} }
{
displayRequestDuration && duration ? <Duration duration={ duration } /> : null
}
</td> </td>
</tr> </tr>
</tbody> </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 { export default class ModelExample extends React.Component {
static propTypes = { 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 { export default class ModelComponent extends Component {
static propTypes = { 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 { export default class Model extends Component {
static propTypes = { 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 { export default class Models extends Component {
static propTypes = { static propTypes = {
@@ -30,7 +31,6 @@ export default class Models extends Component {
<Collapse isOpened={showModels} animated> <Collapse isOpened={showModels} animated>
{ {
definitions.entrySeq().map( ( [ name, model ])=>{ definitions.entrySeq().map( ( [ name, model ])=>{
console.log("model", name, model)
return <div className="model-container" key={ `models-section-${name}` }> return <div className="model-container" key={ `models-section-${name}` }>
<ModelWrapper name={ name } <ModelWrapper name={ name }
schema={ model } 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" import { List } from "immutable"
const braceOpen = "{" 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 { export default class OnlineValidatorBadge extends React.Component {
static propTypes = { 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 { getList } from "core/utils"
import * as CustomPropTypes from "core/proptypes" import * as CustomPropTypes from "core/proptypes"
@@ -17,6 +18,7 @@ export default class Operation extends PureComponent {
allowTryItOut: PropTypes.bool, allowTryItOut: PropTypes.bool,
displayOperationId: PropTypes.bool, displayOperationId: PropTypes.bool,
displayRequestDuration: PropTypes.bool,
response: PropTypes.object, response: PropTypes.object,
request: PropTypes.object, request: PropTypes.object,
@@ -37,6 +39,7 @@ export default class Operation extends PureComponent {
response: null, response: null,
allowTryItOut: true, allowTryItOut: true,
displayOperationId: false, displayOperationId: false,
displayRequestDuration: false
} }
constructor(props, context) { constructor(props, context) {
@@ -107,7 +110,7 @@ export default class Operation extends PureComponent {
request, request,
allowTryItOut, allowTryItOut,
displayOperationId, displayOperationId,
displayRequestDuration,
fn, fn,
getComponent, getComponent,
specActions, specActions,
@@ -126,6 +129,7 @@ export default class Operation extends PureComponent {
let schemes = operation.get("schemes") let schemes = operation.get("schemes")
let parameters = getList(operation, ["parameters"]) let parameters = getList(operation, ["parameters"])
let operationId = operation.get("__originalOperationId") let operationId = operation.get("__originalOperationId")
let operationScheme = specSelectors.operationScheme(path, method)
const Responses = getComponent("responses") const Responses = getComponent("responses")
const Parameters = getComponent( "parameters" ) const Parameters = getComponent( "parameters" )
@@ -211,7 +215,8 @@ export default class Operation extends PureComponent {
<Schemes schemes={ schemes } <Schemes schemes={ schemes }
path={ path } path={ path }
method={ method } method={ method }
specActions={ specActions }/> specActions={ specActions }
operationScheme={ operationScheme } />
</div> : null </div> : null
} }
@@ -250,6 +255,7 @@ export default class Operation extends PureComponent {
produces={ produces } produces={ produces }
producesValue={ operation.get("produces_value") } producesValue={ operation.get("produces_value") }
pathMethod={ [path, method] } pathMethod={ [path, method] }
displayRequestDuration={ displayRequestDuration }
fn={fn} /> fn={fn} />
} }
</div> </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 { export default class Operations extends React.Component {
@@ -32,7 +33,7 @@ export default class Operations extends React.Component {
const Collapse = getComponent("Collapse") const Collapse = getComponent("Collapse")
let showSummary = layoutSelectors.showSummary() let showSummary = layoutSelectors.showSummary()
let { docExpansion, displayOperationId } = getConfigs() let { docExpansion, displayOperationId, displayRequestDuration } = getConfigs()
return ( return (
<div> <div>
@@ -87,6 +88,7 @@ export default class Operations extends React.Component {
allowTryItOut={allowTryItOut} allowTryItOut={allowTryItOut}
displayOperationId={displayOperationId} displayOperationId={displayOperationId}
displayRequestDuration={displayRequestDuration}
specActions={ specActions } specActions={ specActions }
specSelectors={ specSelectors } 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" import { Link } from "core/components/layout-utils"
export default class Overview extends React.Component { 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 { fromJS, List } from "immutable"
import { getSampleSchema } from "core/utils" 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" import win from "core/window"
export default class ParameterRow extends Component { export default class ParameterRow extends Component {
static propTypes = { static propTypes = {
onChange: PropTypes.func.isRequired, 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 ImPropTypes from "react-immutable-proptypes"
import Im from "immutable" 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" } 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 Remarkable from "react-remarkable"
import sanitize from "sanitize-html" 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 { formatXml } from "core/utils"
import lowerCase from "lodash/lowerCase" import lowerCase from "lodash/lowerCase"
@@ -6,7 +7,7 @@ export default class ResponseBody extends React.Component {
static propTypes = { static propTypes = {
content: PropTypes.any.isRequired, content: PropTypes.any.isRequired,
contentType: PropTypes.string.isRequired, contentType: PropTypes.string,
getComponent: PropTypes.func.isRequired, getComponent: PropTypes.func.isRequired,
headers: PropTypes.object, headers: PropTypes.object,
url: PropTypes.string 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 { fromJS } from "immutable"
import { getSampleSchema } from "core/utils" 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 { fromJS } from "immutable"
import { defaultStatusCode } from "core/utils" import { defaultStatusCode } from "core/utils"
@@ -14,19 +15,21 @@ export default class Responses extends React.Component {
specSelectors: PropTypes.object.isRequired, specSelectors: PropTypes.object.isRequired,
specActions: PropTypes.object.isRequired, specActions: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired, pathMethod: PropTypes.array.isRequired,
displayRequestDuration: PropTypes.bool.isRequired,
fn: PropTypes.object.isRequired fn: PropTypes.object.isRequired
} }
static defaultProps = { static defaultProps = {
request: null, request: null,
tryItOutResponse: null, tryItOutResponse: null,
produces: fromJS(["application/json"]) produces: fromJS(["application/json"]),
displayRequestDuration: false
} }
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val) onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val)
render() { 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 ) let defaultCode = defaultStatusCode( responses )
const ContentType = getComponent( "contentType" ) const ContentType = getComponent( "contentType" )
@@ -53,7 +56,8 @@ export default class Responses extends React.Component {
: <div> : <div>
<LiveResponse request={ request } <LiveResponse request={ request }
response={ tryItOutResponse } response={ tryItOutResponse }
getComponent={ getComponent } /> getComponent={ getComponent }
displayRequestDuration={ displayRequestDuration } />
<h4>Responses</h4> <h4>Responses</h4>
</div> </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 { export default class Schemes extends React.Component {
@@ -6,7 +7,8 @@ export default class Schemes extends React.Component {
specActions: PropTypes.object.isRequired, specActions: PropTypes.object.isRequired,
schemes: PropTypes.object.isRequired, schemes: PropTypes.object.isRequired,
path: PropTypes.string, path: PropTypes.string,
method: PropTypes.string method: PropTypes.string,
operationScheme: PropTypes.string
} }
componentWillMount() { componentWillMount() {
@@ -16,11 +18,18 @@ export default class Schemes extends React.Component {
this.setScheme(schemes.first()) 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 ) => { onChange =( e ) => {
this.setScheme( e.target.value ) this.setScheme( e.target.value )
} }
setScheme =( value ) => { setScheme = ( value ) => {
let { path, method, specActions } = this.props let { path, method, specActions } = this.props
specActions.setScheme( value, path, method ) specActions.setScheme( value, path, method )

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 { 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", const CONFIGS = [ "url", "urls", "urls.primaryName", "spec", "validatorUrl", "onComplete", "onFailure", "authorizations", "docExpansion",
"apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl", "apisSorter", "operationsSorter", "supportedSubmitMethods", "dom_id", "defaultModelRendering", "oauth2RedirectUrl",
"showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" ] "showRequestHeaders", "custom", "modelPropertyMacro", "parameterMacro", "displayOperationId" , "displayRequestDuration"]
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION } = buildInfo
@@ -30,6 +30,7 @@ module.exports = function SwaggerUI(opts) {
configs: {}, configs: {},
custom: {}, custom: {},
displayOperationId: false, 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. // 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. // 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 { List, fromJS } from "immutable"
//import "less/json-schema-form" //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) specActions.setRequest(req.pathName, req.method, parsedRequest)
// track duration of request
const startTime = Date.now()
return fn.execute(req) 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) } ) ) .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 } } ) =>{ [SET_RESPONSE]: (state, { payload: { res, path, method } } ) =>{
let result let result
if ( res.error ) { 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 { } else {
result = res result = res
} }
@@ -86,7 +91,7 @@ export default {
let newState = state.setIn( [ "responses", path, method ], fromJSOrdered(result) ) let newState = state.setIn( [ "responses", path, method ], fromJSOrdered(result) )
// ImmutableJS messes up Blob. Needs to reset its value. // 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) newState = newState.setIn( [ "responses", path, method, "text" ], res.data)
} }
return newState 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 SplitPane from "react-split-pane"
import "./split-pane-mode.less" import "./split-pane-mode.less"
@@ -23,9 +24,13 @@ export default class SplitPaneMode extends React.Component {
children: [], children: [],
}; };
initializeComponent = (c) => {
this.splitPane = c
}
onDragFinished = () => { onDragFinished = () => {
let { threshold, layoutActions } = this.props let { threshold, layoutActions } = this.props
let { position, draggedSize } = this.refs.splitPane.state let { position, draggedSize } = this.splitPane.state
this.draggedSize = draggedSize this.draggedSize = draggedSize
let nearLeftEdge = position <= threshold let nearLeftEdge = position <= threshold
@@ -62,7 +67,7 @@ export default class SplitPaneMode extends React.Component {
return ( return (
<SplitPane <SplitPane
disabledClass={""} disabledClass={""}
ref={"splitPane"} ref={this.initializeComponent}
split='vertical' split='vertical'
defaultSize={"50%"} defaultSize={"50%"}
primary="second" primary="second"

View File

@@ -65,11 +65,11 @@ export const render = (getSystem, getStore, getComponent, getComponents, dom) =>
} }
// Render try/catch wrapper // Render try/catch wrapper
const createClass = component => React.createClass({ const createClass = component => class extends Component {
render() { render() {
return component(this.props) return component(this.props)
} }
}) }
const Fallback = ({ name }) => <div style={{ // eslint-disable-line react/prop-types const Fallback = ({ name }) => <div style={{ // eslint-disable-line react/prop-types
padding: "1em", 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 }) // Takes a list and proptype, and returns a PropType.shape({ [item]: propType })
const mapListToPropTypeShape = (list, propType) => PropTypes.shape( 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) } action = {type: NEW_THROWN_ERR, error: true, payload: serializeError(e) }
} }
finally{ finally{
return action return action // eslint-disable-line no-unsafe-finally
} }
} }

View File

@@ -343,7 +343,7 @@ export function highlight (el) {
while (![ while (![
1, // 0: whitespace 1, // 0: whitespace
// 1: operator or braces // 1: operator or braces
/[\/{}[(\-+*=<>:;|\\.,?!&@~]/[test](chr), /[\/{}[(\-+*=<>:;|\\.,?!&@~]/[test](chr), // eslint-disable-line no-useless-escape
/[\])]/[test](chr), // 2: closing brace /[\])]/[test](chr), // 2: closing brace
/[$\w]/[test](chr), // 3: (key)word /[$\w]/[test](chr), // 3: (key)word
chr == "/" && // 4: regex chr == "/" && // 4: regex
@@ -450,15 +450,15 @@ export const propChecker = (props, nextProps, objectList=[], ignoreList=[]) => {
|| objectList.some( objectPropName => !eq(props[objectPropName], nextProps[objectPropName]))) || objectList.some( objectPropName => !eq(props[objectPropName], nextProps[objectPropName])))
} }
const validateNumber = ( val ) => { export const validateNumber = ( val ) => {
if ( !/^-?\d+(.?\d+)?$/.test(val)) { if ( !/^-?\d+(\.?\d+)?$/.test(val)) {
return "Value must be a number" return "Value must be a number"
} }
} }
const validateInteger = ( val ) => { export const validateInteger = ( val ) => {
if ( !/^-?\d+$/.test(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 required = param.get("required")
let type = param.get("type") 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") errors.push("Required field is not provided")
return errors return errors
} }
if ( !value ) return errors
if ( type === "number" ) { if ( type === "number" ) {
let err = validateNumber(value) let err = validateNumber(value)
if (!err) return errors 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 "./topbar.less"
import Logo from "./logo_small.png" 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 { export default class StandaloneLayout extends React.Component {

View File

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

View File

@@ -1,3 +1,4 @@
/* eslint-disable no-useless-escape */
import expect from "expect" import expect from "expect"
import { fromJS } from "immutable" import { fromJS } from "immutable"
import { transform } from "corePlugins/err/error-transformers/transformers/parameter-oneof" 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()) 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 */ /* eslint-env mocha */
import expect from "expect" import expect from "expect"
import { fromJS } from "immutable" import { fromJS } from "immutable"
import { mapToList } from "core/utils" import { mapToList, validateNumber, validateInteger, validateParam } from "core/utils"
describe("utils", function(){ describe("utils", function(){
@@ -67,9 +67,181 @@ describe("utils", function(){
// Then // Then
expect(aList.toJS()).toEqual([]) 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 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')(rules, {
module.exports = require('./make-webpack-config.js')({
_special: { _special: {
separateStylesheets: false, separateStylesheets: false,
minimize: true, minimize: true,
sourcemaps: true, sourcemaps: true,
loaders: {
"worker.js": ["worker-loader?inline=true&name=[name].js", "babel"]
}
}, },
entry: { entry: {

View File

@@ -1,14 +1,59 @@
var path = require('path') 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: { _special: {
separateStylesheets: false, separateStylesheets: false,
minimize: true, minimize: true,
sourcemaps: true, sourcemaps: true,
loaders: {
"worker.js": ["worker-loader?inline=true&name=[name].js", "babel"]
}
}, },
entry: { entry: {

View File

@@ -1,15 +1,70 @@
const path = require("path") var path = require('path')
const fs = require("fs") var fs = require('fs')
const nodeModules = fs.readdirSync("node_modules").filter(function(x) { return x !== ".bin" }) 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: { _special: {
separateStylesheets: true, separateStylesheets: true,
minimize: true, minimize: true,
sourcemaps: true, sourcemaps: true,
loaders: {
"worker.js": ["worker-loader?inline=true&name=[name].js", "babel"]
}
}, },
entry: { entry: {

View File

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