Merge branch 'master' into bug/2903-wrong-font-for-error
This commit is contained in:
@@ -146,6 +146,7 @@ displayOperationId | Controls the display of operationId in operations list. The
|
|||||||
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
|
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
|
||||||
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
|
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
|
||||||
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
|
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
|
||||||
|
deepLinking | If set to `true`, enables dynamic deep linking for tags and operations. [Docs](https://github.com/swagger-api/swagger-ui/blob/master/docs/deep-linking.md)
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
|
|
||||||
@@ -235,6 +236,10 @@ Access-Control-Allow-Headers: Content-Type, api_key, Authorization
|
|||||||
|
|
||||||
Only headers with these names will be allowed to be sent by Swagger-UI.
|
Only headers with these names will be allowed to be sent by Swagger-UI.
|
||||||
|
|
||||||
|
## Security contact
|
||||||
|
|
||||||
|
Please disclose any security-related issues or vulnerabilities by emailing [security@swagger.io](mailto:security@swagger.io), instead of using the public issue tracker.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright 2017 SmartBear Software
|
Copyright 2017 SmartBear Software
|
||||||
|
|||||||
1
dist/index.html
vendored
1
dist/index.html
vendored
@@ -76,6 +76,7 @@ window.onload = function() {
|
|||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: "http://petstore.swagger.io/v2/swagger.json",
|
url: "http://petstore.swagger.io/v2/swagger.json",
|
||||||
dom_id: '#swagger-ui',
|
dom_id: '#swagger-ui',
|
||||||
|
deepLinking: true,
|
||||||
presets: [
|
presets: [
|
||||||
SwaggerUIBundle.presets.apis,
|
SwaggerUIBundle.presets.apis,
|
||||||
SwaggerUIStandalonePreset
|
SwaggerUIStandalonePreset
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ module.exports = function(rules, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( specialOptions.minimize ) {
|
if( specialOptions.minimize ) {
|
||||||
|
|
||||||
plugins.push(
|
plugins.push(
|
||||||
new webpack.optimize.UglifyJsPlugin({
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
|
|||||||
@@ -109,7 +109,6 @@
|
|||||||
"karma-sourcemap-loader": "^0.3.7",
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
"karma-webpack": "2.0.3",
|
"karma-webpack": "2.0.3",
|
||||||
"less": "2.7.2",
|
"less": "2.7.2",
|
||||||
"less-loader": "4.0.4",
|
|
||||||
"license-checker": "^11.0.0",
|
"license-checker": "^11.0.0",
|
||||||
"mocha": "^3.4.2",
|
"mocha": "^3.4.2",
|
||||||
"node-sass": "^4.5.0",
|
"node-sass": "^4.5.0",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class Path extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<pre className="base-url">
|
<pre className="base-url">
|
||||||
[ Base url: {host}{basePath}]
|
[ Base URL: {host}{basePath} ]
|
||||||
</pre>
|
</pre>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,8 @@ export class Select extends React.Component {
|
|||||||
value: PropTypes.any,
|
value: PropTypes.any,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
multiple: PropTypes.bool,
|
multiple: PropTypes.bool,
|
||||||
allowEmptyValue: PropTypes.bool
|
allowEmptyValue: PropTypes.bool,
|
||||||
|
className: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -142,7 +143,7 @@ export class Select extends React.Component {
|
|||||||
|
|
||||||
let value
|
let value
|
||||||
|
|
||||||
if (props.value !== undefined) {
|
if (props.value) {
|
||||||
value = props.value
|
value = props.value
|
||||||
} else {
|
} else {
|
||||||
value = props.multiple ? [""] : ""
|
value = props.multiple ? [""] : ""
|
||||||
@@ -178,7 +179,7 @@ export class Select extends React.Component {
|
|||||||
let value = this.state.value.toJS ? this.state.value.toJS() : this.state.value
|
let value = this.state.value.toJS ? this.state.value.toJS() : this.state.value
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<select multiple={ multiple } value={ value } onChange={ this.onChange } >
|
<select className={this.props.className} multiple={ multiple } value={ value } onChange={ this.onChange } >
|
||||||
{ allowEmptyValue ? <option value="">--</option> : null }
|
{ allowEmptyValue ? <option value="">--</option> : null }
|
||||||
{
|
{
|
||||||
allowedValues.map(function (item, key) {
|
allowedValues.map(function (item, key) {
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ export default class Models extends Component {
|
|||||||
return <section className={ showModels ? "models is-open" : "models"}>
|
return <section className={ showModels ? "models is-open" : "models"}>
|
||||||
<h4 onClick={() => layoutActions.show("models", !showModels)}>
|
<h4 onClick={() => layoutActions.show("models", !showModels)}>
|
||||||
<span>Models</span>
|
<span>Models</span>
|
||||||
<svg width="20" height="20">
|
<svg className="arrow" width="20" height="20">
|
||||||
<use xlinkHref="#large-arrow" />
|
<use xlinkHref={showModels ? "#large-arrow-down" : "#large-arrow"} />
|
||||||
</svg>
|
</svg>
|
||||||
</h4>
|
</h4>
|
||||||
<Collapse isOpened={showModels}>
|
<Collapse isOpened={showModels}>
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ export default class Schemes extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
if ( this.props.operationScheme && !nextProps.schemes.has(this.props.operationScheme) ) {
|
if ( !this.props.operationScheme || !nextProps.schemes.has(this.props.operationScheme) ) {
|
||||||
//fire 'change' event if our selected scheme is no longer an option
|
// if we don't have a selected operationScheme or if our selected scheme is no longer an option,
|
||||||
|
// then fire 'change' event and select the first scheme in the list of options
|
||||||
this.setScheme(nextProps.schemes.first())
|
this.setScheme(nextProps.schemes.first())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ export class JsonSchema_string extends Component {
|
|||||||
|
|
||||||
if ( enumValue ) {
|
if ( enumValue ) {
|
||||||
const Select = getComponent("Select")
|
const Select = getComponent("Select")
|
||||||
return (<Select allowedValues={ enumValue }
|
return (<Select className={ errors.length ? "invalid" : ""}
|
||||||
|
allowedValues={ enumValue }
|
||||||
value={ value }
|
value={ value }
|
||||||
allowEmptyValue={ !required }
|
allowEmptyValue={ !required }
|
||||||
onChange={ this.onEnumChange }/>)
|
onChange={ this.onEnumChange }/>)
|
||||||
@@ -121,6 +122,7 @@ export class JsonSchema_array extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
let { getComponent, required, schema, fn } = this.props
|
let { getComponent, required, schema, fn } = this.props
|
||||||
|
|
||||||
|
let errors = schema.errors || []
|
||||||
let itemSchema = fn.inferSchema(schema.items)
|
let itemSchema = fn.inferSchema(schema.items)
|
||||||
|
|
||||||
const JsonSchemaForm = getComponent("JsonSchemaForm")
|
const JsonSchemaForm = getComponent("JsonSchemaForm")
|
||||||
@@ -131,19 +133,17 @@ export class JsonSchema_array extends PureComponent {
|
|||||||
|
|
||||||
if ( enumValue ) {
|
if ( enumValue ) {
|
||||||
const Select = getComponent("Select")
|
const Select = getComponent("Select")
|
||||||
return (<Select multiple={ true }
|
return (<Select className={ errors.length ? "invalid" : ""}
|
||||||
|
multiple={ true }
|
||||||
value={ value }
|
value={ value }
|
||||||
allowedValues={ enumValue }
|
allowedValues={ enumValue }
|
||||||
allowEmptyValue={ !required }
|
allowEmptyValue={ !required }
|
||||||
onChange={ this.onEnumChange }/>)
|
onChange={ this.onEnumChange }/>)
|
||||||
}
|
}
|
||||||
|
|
||||||
let errors = schema.errors || []
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ !value || value.count() < 1 ?
|
{ !value || value.count() < 1 ? null :
|
||||||
(errors.length ? <span style={{ color: "red", fortWeight: "bold" }}>{ errors[0] }</span> : null) :
|
|
||||||
value.map( (item,i) => {
|
value.map( (item,i) => {
|
||||||
let schema = Object.assign({}, itemSchema)
|
let schema = Object.assign({}, itemSchema)
|
||||||
if ( errors.length ) {
|
if ( errors.length ) {
|
||||||
@@ -153,12 +153,12 @@ export class JsonSchema_array extends PureComponent {
|
|||||||
return (
|
return (
|
||||||
<div key={i} className="json-schema-form-item">
|
<div key={i} className="json-schema-form-item">
|
||||||
<JsonSchemaForm fn={fn} getComponent={getComponent} value={item} onChange={(val) => this.onItemChange(val, i)} schema={schema} />
|
<JsonSchemaForm fn={fn} getComponent={getComponent} value={item} onChange={(val) => this.onItemChange(val, i)} schema={schema} />
|
||||||
<Button className="json-schema-form-item-remove" onClick={()=> this.removeItem(i)} > - </Button>
|
<Button className="btn btn-sm json-schema-form-item-remove" onClick={()=> this.removeItem(i)} > - </Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}).toArray()
|
}).toArray()
|
||||||
}
|
}
|
||||||
<Button className="json-schema-form-item-add" onClick={this.addItem}> Add item </Button>
|
<Button className={`btn btn-sm json-schema-form-item-add ${errors.length ? "invalid" : null}`} onClick={this.addItem}> Add item </Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -170,12 +170,14 @@ export class JsonSchema_boolean extends Component {
|
|||||||
|
|
||||||
onEnumChange = (val) => this.props.onChange(val)
|
onEnumChange = (val) => this.props.onChange(val)
|
||||||
render() {
|
render() {
|
||||||
let { getComponent, required, value } = this.props
|
let { getComponent, value, schema } = this.props
|
||||||
|
let errors = schema.errors || []
|
||||||
const Select = getComponent("Select")
|
const Select = getComponent("Select")
|
||||||
|
|
||||||
return (<Select value={ String(value) }
|
return (<Select className={ errors.length ? "invalid" : ""}
|
||||||
|
value={ String(value) }
|
||||||
allowedValues={ fromJS(["true", "false"]) }
|
allowedValues={ fromJS(["true", "false"]) }
|
||||||
allowEmptyValue={ !required }
|
allowEmptyValue={true}
|
||||||
onChange={ this.onEnumChange }/>)
|
onChange={ this.onEnumChange }/>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
import get from "lodash/get"
|
|
||||||
|
|
||||||
export function transformPathToArray(property, jsSpec) {
|
|
||||||
if(property.slice(0,9) === "instance.") {
|
|
||||||
var str = property.slice(9)
|
|
||||||
} else { // eslint-disable-next-line no-redeclare
|
|
||||||
var str = property
|
|
||||||
}
|
|
||||||
|
|
||||||
var pathArr = []
|
|
||||||
|
|
||||||
str
|
|
||||||
.split(".")
|
|
||||||
.map(item => {
|
|
||||||
// "key[0]" becomes ["key", "0"]
|
|
||||||
if(item.includes("[")) {
|
|
||||||
let index = parseInt(item.match(/\[(.*)\]/)[1])
|
|
||||||
let keyName = item.slice(0, item.indexOf("["))
|
|
||||||
return [keyName, index.toString()]
|
|
||||||
} else {
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.reduce(function(a, b) {
|
|
||||||
// flatten!
|
|
||||||
return a.concat(b)
|
|
||||||
}, [])
|
|
||||||
.concat([""]) // add an empty item into the array, so we don't get stuck with something in our buffer below
|
|
||||||
.reduce((buffer, curr) => {
|
|
||||||
let obj = pathArr.length ? get(jsSpec, pathArr) : jsSpec
|
|
||||||
|
|
||||||
if(get(obj, makeAccessArray(buffer, curr))) {
|
|
||||||
if(buffer.length) {
|
|
||||||
pathArr.push(buffer)
|
|
||||||
}
|
|
||||||
if(curr.length) {
|
|
||||||
pathArr.push(curr)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
} else {
|
|
||||||
// attach key to buffer
|
|
||||||
return `${buffer}${buffer.length ? "." : ""}${curr}`
|
|
||||||
}
|
|
||||||
}, "")
|
|
||||||
|
|
||||||
if(typeof get(jsSpec, pathArr) !== "undefined") {
|
|
||||||
return pathArr
|
|
||||||
} else {
|
|
||||||
// if our path is not correct (there is no value at the path),
|
|
||||||
// return null
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeAccessArray(buffer, curr) {
|
|
||||||
let arr = []
|
|
||||||
|
|
||||||
if(buffer.length) {
|
|
||||||
arr.push(buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(curr.length) {
|
|
||||||
arr.push(curr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
@@ -73,7 +73,7 @@ export const authorizePassword = ( auth ) => ( { authActions } ) => {
|
|||||||
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
|
let { schema, name, username, password, passwordType, clientId, clientSecret } = auth
|
||||||
let form = {
|
let form = {
|
||||||
grant_type: "password",
|
grant_type: "password",
|
||||||
scopes: encodeURIComponent(auth.scopes.join(scopeSeparator))
|
scope: encodeURIComponent(auth.scopes.join(scopeSeparator))
|
||||||
}
|
}
|
||||||
let query = {}
|
let query = {}
|
||||||
let headers = {}
|
let headers = {}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import SplitPane from "react-split-pane"
|
import SplitPane from "react-split-pane"
|
||||||
import "./split-pane-mode.less"
|
|
||||||
|
|
||||||
const MODE_KEY = ["split-pane-mode"]
|
const MODE_KEY = ["split-pane-mode"]
|
||||||
const MODE_LEFT = "left"
|
const MODE_LEFT = "left"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
.swagger-ui {
|
|
||||||
.Resizer.vertical.disabled {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import { shallowEqualKeys } from "core/utils"
|
import { shallowEqualKeys } from "core/utils"
|
||||||
import { transformPathToArray } from "core/path-translator"
|
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
return {
|
return {
|
||||||
fn: { shallowEqualKeys, transformPathToArray }
|
fn: { shallowEqualKeys }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function fromJSOrdered (js) {
|
|||||||
return !isObject(js) ? js :
|
return !isObject(js) ? js :
|
||||||
Array.isArray(js) ?
|
Array.isArray(js) ?
|
||||||
Im.Seq(js).map(fromJSOrdered).toList() :
|
Im.Seq(js).map(fromJSOrdered).toList() :
|
||||||
Im.Seq(js).map(fromJSOrdered).toOrderedMap()
|
Im.OrderedMap(js).map(fromJSOrdered)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bindToState(obj, state) {
|
export function bindToState(obj, state) {
|
||||||
@@ -468,6 +468,18 @@ export const validateFile = ( val ) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const validateBoolean = ( val ) => {
|
||||||
|
if ( !(val === "true" || val === "false" || val === true || val === false) ) {
|
||||||
|
return "Value must be a boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const validateString = ( val ) => {
|
||||||
|
if ( val && typeof val !== "string" ) {
|
||||||
|
return "Value must be a string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// validation of parameters before execute
|
// validation of parameters before execute
|
||||||
export const validateParam = (param, isXml) => {
|
export const validateParam = (param, isXml) => {
|
||||||
let errors = []
|
let errors = []
|
||||||
@@ -475,21 +487,32 @@ 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")
|
||||||
|
|
||||||
let stringCheck = type === "string" && !value
|
// If the parameter is required OR the parameter has a value (meaning optional, but filled in)
|
||||||
let arrayCheck = type === "array" && Array.isArray(value) && !value.length
|
// then we should do our validation routine
|
||||||
let listCheck = type === "array" && Im.List.isList(value) && !value.count()
|
if ( required || value ) {
|
||||||
let fileCheck = type === "file" && !(value instanceof win.File)
|
// These checks should evaluate to true if the parameter's value is valid
|
||||||
|
let stringCheck = type === "string" && value && !validateString(value)
|
||||||
|
let arrayCheck = type === "array" && Array.isArray(value) && value.length
|
||||||
|
let listCheck = type === "array" && Im.List.isList(value) && value.count()
|
||||||
|
let fileCheck = type === "file" && value instanceof win.File
|
||||||
|
let booleanCheck = type === "boolean" && !validateBoolean(value)
|
||||||
|
let numberCheck = type === "number" && !validateNumber(value) // validateNumber returns undefined if the value is a number
|
||||||
|
let integerCheck = type === "integer" && !validateInteger(value) // validateInteger returns undefined if the value is an integer
|
||||||
|
|
||||||
if ( required && (stringCheck || arrayCheck || listCheck || fileCheck) ) {
|
if ( required && !(stringCheck || arrayCheck || listCheck || fileCheck || booleanCheck || numberCheck || integerCheck) ) {
|
||||||
errors.push("Required field is not provided")
|
errors.push("Required field is not provided")
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( value === null || value === undefined ) {
|
if ( type === "string" ) {
|
||||||
return errors
|
let err = validateString(value)
|
||||||
}
|
if (!err) return errors
|
||||||
|
errors.push(err)
|
||||||
if ( type === "number" ) {
|
} else if ( type === "boolean" ) {
|
||||||
|
let err = validateBoolean(value)
|
||||||
|
if (!err) return errors
|
||||||
|
errors.push(err)
|
||||||
|
} else if ( type === "number" ) {
|
||||||
let err = validateNumber(value)
|
let err = validateNumber(value)
|
||||||
if (!err) return errors
|
if (!err) return errors
|
||||||
errors.push(err)
|
errors.push(err)
|
||||||
@@ -511,6 +534,8 @@ export const validateParam = (param, isXml) => {
|
|||||||
err = validateNumber(item)
|
err = validateNumber(item)
|
||||||
} else if (itemType === "integer") {
|
} else if (itemType === "integer") {
|
||||||
err = validateInteger(item)
|
err = validateInteger(item)
|
||||||
|
} else if (itemType === "string") {
|
||||||
|
err = validateString(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( err ) {
|
if ( err ) {
|
||||||
@@ -522,6 +547,7 @@ export const validateParam = (param, isXml) => {
|
|||||||
if (!err) return errors
|
if (!err) return errors
|
||||||
errors.push(err)
|
errors.push(err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ SwaggerUI({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Or if you're updating the core plugins.. you'll add it to [src/js/bootstrap-plugin](https://github.com/SmartBear/swagger-ux/blob/master/src/js/bootstrap-plugin.js)
|
Or if you're updating the core plugins.. you'll add it to the base preset: [src/core/presets/base.js](https://github.com/swagger-api/swagger-ui/blob/master/src/core/presets/base.js)
|
||||||
|
|
||||||
Each Plugin is a function that returns an object. That object will get merged with the `system` and later bound to the state.
|
Each Plugin is a function that returns an object. That object will get merged with the `system` and later bound to the state.
|
||||||
Here is an example of each `type`
|
Here is an example of each `type`
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export default class Topbar extends React.Component {
|
|||||||
<div className="wrapper">
|
<div className="wrapper">
|
||||||
<div className="topbar-wrapper">
|
<div className="topbar-wrapper">
|
||||||
<Link href="#" title="Swagger UX">
|
<Link href="#" title="Swagger UX">
|
||||||
<img height="30" width="30" src={ Logo } alt="Swagger UX"/>
|
<img height="30" width="30" src={ Logo } alt="Swagger UI"/>
|
||||||
<span>swagger</span>
|
<span>swagger</span>
|
||||||
</Link>
|
</Link>
|
||||||
<form className="download-url-wrapper" onSubmit={formOnSubmit}>
|
<form className="download-url-wrapper" onSubmit={formOnSubmit}>
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
.swagger-ui {
|
|
||||||
.topbar {
|
|
||||||
background-color: #89bf04;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topbar-wrapper {
|
|
||||||
padding: 0.7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topbar-logo__img {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topbar-logo__title {
|
|
||||||
display: inline-block;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.5em;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 0.15em 0 0 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.download-url-wrapper {
|
|
||||||
text-align: right;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topbar .download-url__text {
|
|
||||||
width: 28em;
|
|
||||||
height: 2em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.download-url__btn {
|
|
||||||
background-color: #547f00;
|
|
||||||
border-color: #547f00;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 0.2em 0.3em;
|
|
||||||
color: white;
|
|
||||||
border-radius: 0.1em;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
&:extend(.download-url__btn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-700 {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
width: 45em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
import StandaloneLayout from "./layout"
|
import StandaloneLayout from "./layout"
|
||||||
import "../style/main.scss"
|
|
||||||
|
|
||||||
import TopbarPlugin from "plugins/topbar"
|
import TopbarPlugin from "plugins/topbar"
|
||||||
import ConfigsPlugin from "plugins/configs"
|
import ConfigsPlugin from "plugins/configs"
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
@include text_headline();
|
@include text_headline();
|
||||||
|
|
||||||
|
&.btn-sm {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 4px 23px;
|
||||||
|
}
|
||||||
|
|
||||||
&[disabled]
|
&[disabled]
|
||||||
{
|
{
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
@@ -165,6 +170,9 @@
|
|||||||
button
|
button
|
||||||
{
|
{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
|
&.invalid {
|
||||||
|
@include invalidFormElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ select
|
|||||||
|
|
||||||
background: #f7f7f7;
|
background: #f7f7f7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.invalid {
|
||||||
|
@include invalidFormElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.opblock-body select
|
.opblock-body select
|
||||||
@@ -53,12 +57,8 @@ input[type=file]
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
||||||
&.invalid
|
&.invalid {
|
||||||
{
|
@include invalidFormElement();
|
||||||
animation: shake .4s 1;
|
|
||||||
|
|
||||||
border-color: $_color-delete;
|
|
||||||
background: lighten($_color-delete, 35%);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -490,6 +490,15 @@
|
|||||||
{
|
{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a
|
||||||
|
{
|
||||||
|
@include text_code(#89bf04);
|
||||||
|
text-decoration: underline;
|
||||||
|
&:hover {
|
||||||
|
color: #81b10c;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,3 +166,9 @@ $browser-context: 16;
|
|||||||
@warn 'Breakpoint mixin supports: tablet, mobile, desktop';
|
@warn 'Breakpoint mixin supports: tablet, mobile, desktop';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin invalidFormElement() {
|
||||||
|
animation: shake .4s 1;
|
||||||
|
border-color: $_color-delete;
|
||||||
|
background: lighten($_color-delete, 35%);
|
||||||
|
}
|
||||||
|
|||||||
3
src/style/_split-pane-mode.scss
Normal file
3
src/style/_split-pane-mode.scss
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.Resizer.vertical.disabled {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
@@ -97,6 +97,10 @@ table
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 340px;
|
max-width: 340px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.parameter__name
|
.parameter__name
|
||||||
|
|||||||
@@ -14,6 +14,6 @@
|
|||||||
@import 'information';
|
@import 'information';
|
||||||
@import 'authorize';
|
@import 'authorize';
|
||||||
@import 'errors';
|
@import 'errors';
|
||||||
|
|
||||||
@include text_body();
|
@include text_body();
|
||||||
|
@import 'split-pane-mode';
|
||||||
}
|
}
|
||||||
|
|||||||
41
test/components/schemes.js
Normal file
41
test/components/schemes.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
/* eslint-env mocha */
|
||||||
|
import React from "react"
|
||||||
|
import expect, { createSpy } from "expect"
|
||||||
|
import { shallow } from "enzyme"
|
||||||
|
import { fromJS } from "immutable"
|
||||||
|
import Schemes from "components/schemes"
|
||||||
|
|
||||||
|
describe("<Schemes/>", function(){
|
||||||
|
it("calls props.specActions.setScheme() when no operationScheme is selected", function(){
|
||||||
|
|
||||||
|
// Given
|
||||||
|
let props = {
|
||||||
|
specActions: {
|
||||||
|
setScheme: createSpy()
|
||||||
|
},
|
||||||
|
schemes: fromJS([
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
]),
|
||||||
|
operationScheme: undefined,
|
||||||
|
path: "/test",
|
||||||
|
method: "get"
|
||||||
|
}
|
||||||
|
|
||||||
|
// When
|
||||||
|
let wrapper = shallow(<Schemes {...props}/>)
|
||||||
|
|
||||||
|
// Then operationScheme should default to first scheme in options list
|
||||||
|
expect(props.specActions.setScheme).toHaveBeenCalledWith("http", "/test" , "get")
|
||||||
|
|
||||||
|
// When the operationScheme is no longer in the list of options
|
||||||
|
props.schemes = fromJS([
|
||||||
|
"https"
|
||||||
|
])
|
||||||
|
wrapper.setProps(props)
|
||||||
|
|
||||||
|
// Then operationScheme should default to first scheme in options list
|
||||||
|
expect(props.specActions.setScheme).toHaveBeenCalledWith("https", "/test", "get")
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
/* eslint-env mocha */
|
|
||||||
import expect from "expect"
|
|
||||||
import { transformPathToArray } from "core/path-translator"
|
|
||||||
|
|
||||||
describe("validation plugin - path translator", function(){
|
|
||||||
|
|
||||||
describe("string paths", function(){
|
|
||||||
|
|
||||||
it("should translate a simple string path to an array", function(){
|
|
||||||
// Given
|
|
||||||
let jsSpec = {
|
|
||||||
one: {
|
|
||||||
a: "a thing",
|
|
||||||
b: "another thing",
|
|
||||||
c: "one more thing"
|
|
||||||
},
|
|
||||||
two: 2
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "instance.one.a"
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(transformPathToArray(path, jsSpec)).toEqual(["one", "a"])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should translate an ambiguous string path to an array", function(){
|
|
||||||
// Since JSONSchema uses periods to mark different properties,
|
|
||||||
// a key with a period in it is ambiguous, because it can mean at least two things.
|
|
||||||
// In our case, the path can mean:
|
|
||||||
// ["google", "com", "a"] or ["google.com", "a"]
|
|
||||||
|
|
||||||
// Given
|
|
||||||
let jsSpec = {
|
|
||||||
"google.com": {
|
|
||||||
a: "a thing",
|
|
||||||
b: "another thing",
|
|
||||||
c: "one more thing"
|
|
||||||
},
|
|
||||||
"gmail.com": {
|
|
||||||
d: "more stuff",
|
|
||||||
e: "even more stuff"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "instance.google.com.a"
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a"])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should translate an doubly ambiguous string path to an array", function(){
|
|
||||||
// Since JSONSchema uses periods to mark different properties,
|
|
||||||
// a key with two periods in it (like "www.google.com") is doubly ambiguous,
|
|
||||||
// because it can mean at least three things.
|
|
||||||
|
|
||||||
|
|
||||||
// Given
|
|
||||||
let jsSpec = {
|
|
||||||
"www.google.com": {
|
|
||||||
a: "a thing",
|
|
||||||
b: "another thing",
|
|
||||||
c: "one more thing"
|
|
||||||
},
|
|
||||||
"gmail.com": {
|
|
||||||
d: "more stuff",
|
|
||||||
e: "even more stuff"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "instance.www.google.com.a"
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(transformPathToArray(path, jsSpec)).toEqual(["www.google.com", "a"])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should return null for an invalid path", function(){
|
|
||||||
|
|
||||||
// Given
|
|
||||||
let jsSpec = {
|
|
||||||
"google.com": {
|
|
||||||
a: "a thing",
|
|
||||||
b: "another thing",
|
|
||||||
c: "one more thing"
|
|
||||||
},
|
|
||||||
"gmail.com": {
|
|
||||||
d: "more stuff",
|
|
||||||
e: "even more stuff"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "instance.google.net.a"
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(transformPathToArray(path, jsSpec)).toEqual(null)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should return inline array indices in their own value", function(){
|
|
||||||
// "a[1]" => ["a", "1"]
|
|
||||||
|
|
||||||
// Given
|
|
||||||
let jsSpec = {
|
|
||||||
"google.com": {
|
|
||||||
a: [
|
|
||||||
"hello",
|
|
||||||
"here is the target"
|
|
||||||
],
|
|
||||||
b: "another thing",
|
|
||||||
c: "one more thing"
|
|
||||||
},
|
|
||||||
"gmail.com": {
|
|
||||||
d: "more stuff",
|
|
||||||
e: "even more stuff"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "instance.google.com.a[1]"
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a", "1"])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should return the correct path when the last part is ambiguous", function(){
|
|
||||||
|
|
||||||
// Given
|
|
||||||
let jsSpec = {
|
|
||||||
"google.com": {
|
|
||||||
a: [
|
|
||||||
"hello",
|
|
||||||
{
|
|
||||||
"gmail.com": 1234
|
|
||||||
}
|
|
||||||
],
|
|
||||||
b: "another thing",
|
|
||||||
c: "one more thing"
|
|
||||||
},
|
|
||||||
"gmail.com": {
|
|
||||||
d: "more stuff",
|
|
||||||
e: "even more stuff"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "instance.google.com.a[1].gmail.com"
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a", "1", "gmail.com"])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should return the correct path when the last part is doubly ambiguous", function(){
|
|
||||||
|
|
||||||
// Given
|
|
||||||
let jsSpec = {
|
|
||||||
"google.com": {
|
|
||||||
a: [
|
|
||||||
"hello",
|
|
||||||
{
|
|
||||||
"www.gmail.com": 1234
|
|
||||||
}
|
|
||||||
],
|
|
||||||
b: "another thing",
|
|
||||||
c: "one more thing"
|
|
||||||
},
|
|
||||||
"gmail.com": {
|
|
||||||
d: "more stuff",
|
|
||||||
e: "even more stuff"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "instance.google.com.a[1].www.gmail.com"
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(transformPathToArray(path, jsSpec)).toEqual(["google.com", "a", "1", "www.gmail.com"])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
@@ -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, validateNumber, validateInteger, validateParam, validateFile } from "core/utils"
|
import { mapToList, validateNumber, validateInteger, validateParam, validateFile, fromJSOrdered } from "core/utils"
|
||||||
import win from "core/window"
|
import win from "core/window"
|
||||||
|
|
||||||
describe("utils", function() {
|
describe("utils", function() {
|
||||||
@@ -176,6 +176,7 @@ describe("utils", function(){
|
|||||||
let result = null
|
let result = null
|
||||||
|
|
||||||
it("validates required strings", function() {
|
it("validates required strings", function() {
|
||||||
|
// invalid string
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: true,
|
required: true,
|
||||||
type: "string",
|
type: "string",
|
||||||
@@ -183,9 +184,39 @@ describe("utils", function(){
|
|||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// valid string
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "string",
|
||||||
|
value: "test string"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates optional strings", function() {
|
||||||
|
// valid (empty) string
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "string",
|
||||||
|
value: ""
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// valid string
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "string",
|
||||||
|
value: "test"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required files", function() {
|
it("validates required files", function() {
|
||||||
|
// invalid file
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: true,
|
required: true,
|
||||||
type: "file",
|
type: "file",
|
||||||
@@ -193,9 +224,48 @@ describe("utils", function(){
|
|||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// valid file
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "file",
|
||||||
|
value: new win.File()
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates optional files", function() {
|
||||||
|
// invalid file
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "file",
|
||||||
|
value: "not a file"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Value must be a file"] )
|
||||||
|
|
||||||
|
// valid (empty) file
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "file",
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// valid file
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "file",
|
||||||
|
value: new win.File()
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates required arrays", function() {
|
it("validates required arrays", function() {
|
||||||
|
// invalid (empty) array
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: true,
|
required: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
@@ -204,75 +274,51 @@ describe("utils", function(){
|
|||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// invalid (not an array)
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: true,
|
required: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: []
|
value: undefined
|
||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( ["Required field is not provided"] )
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
})
|
|
||||||
|
|
||||||
it("validates numbers", function() {
|
// invalid array, items do not match correct type
|
||||||
// string instead of a number
|
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: false,
|
required: true,
|
||||||
type: "number",
|
type: "array",
|
||||||
value: "test"
|
value: [1],
|
||||||
|
items: {
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( ["Value must be a number"] )
|
expect( result ).toEqual( [{index: 0, error: "Value must be a string"}] )
|
||||||
|
|
||||||
// undefined value
|
// valid array, with no 'type' for items
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: false,
|
required: true,
|
||||||
type: "number",
|
type: "array",
|
||||||
value: undefined
|
value: ["1"]
|
||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( [] )
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
// null value
|
// valid array, items match type
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: false,
|
required: true,
|
||||||
type: "number",
|
type: "array",
|
||||||
value: null
|
value: ["1"],
|
||||||
|
items: {
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( [] )
|
expect( result ).toEqual( [] )
|
||||||
})
|
})
|
||||||
|
|
||||||
it("validates integers", function() {
|
it("validates optional arrays", function() {
|
||||||
// string instead of integer
|
// valid, empty array
|
||||||
param = fromJS({
|
|
||||||
required: false,
|
|
||||||
type: "integer",
|
|
||||||
value: "test"
|
|
||||||
})
|
|
||||||
result = validateParam( param, false )
|
|
||||||
expect( result ).toEqual( ["Value must be an integer"] )
|
|
||||||
|
|
||||||
// undefined value
|
|
||||||
param = fromJS({
|
|
||||||
required: false,
|
|
||||||
type: "integer",
|
|
||||||
value: undefined
|
|
||||||
})
|
|
||||||
result = validateParam( param, false )
|
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
|
|
||||||
// null value
|
|
||||||
param = fromJS({
|
|
||||||
required: false,
|
|
||||||
type: "integer",
|
|
||||||
value: null
|
|
||||||
})
|
|
||||||
result = validateParam( param, false )
|
|
||||||
expect( result ).toEqual( [] )
|
|
||||||
})
|
|
||||||
|
|
||||||
it("validates arrays", function() {
|
|
||||||
// empty array
|
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: false,
|
required: false,
|
||||||
type: "array",
|
type: "array",
|
||||||
@@ -281,7 +327,7 @@ describe("utils", function(){
|
|||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( [] )
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
// numbers
|
// invalid, items do not match correct type
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: false,
|
required: false,
|
||||||
type: "array",
|
type: "array",
|
||||||
@@ -293,17 +339,236 @@ describe("utils", function(){
|
|||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( [{index: 0, error: "Value must be a number"}] )
|
expect( result ).toEqual( [{index: 0, error: "Value must be a number"}] )
|
||||||
|
|
||||||
// integers
|
// valid
|
||||||
param = fromJS({
|
param = fromJS({
|
||||||
required: false,
|
required: false,
|
||||||
type: "array",
|
type: "array",
|
||||||
value: ["not", "numbers"],
|
value: ["test"],
|
||||||
items: {
|
items: {
|
||||||
type: "integer"
|
type: "string"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
result = validateParam( param, false )
|
result = validateParam( param, false )
|
||||||
expect( result ).toEqual( [{index: 0, error: "Value must be an integer"}, {index: 1, error: "Value must be an integer"}] )
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates required booleans", function() {
|
||||||
|
// invalid boolean value
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "boolean",
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// invalid boolean value (not a boolean)
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "boolean",
|
||||||
|
value: "test string"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// valid boolean value
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "boolean",
|
||||||
|
value: "true"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// valid boolean value
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates optional booleans", function() {
|
||||||
|
// valid (empty) boolean value
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "boolean",
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// invalid boolean value (not a boolean)
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "boolean",
|
||||||
|
value: "test string"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Value must be a boolean"] )
|
||||||
|
|
||||||
|
// valid boolean value
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "boolean",
|
||||||
|
value: "true"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// valid boolean value
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates required numbers", function() {
|
||||||
|
// invalid number, string instead of a number
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "number",
|
||||||
|
value: "test"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// invalid number, undefined value
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "number",
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// valid number
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "number",
|
||||||
|
value: 10
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates optional numbers", function() {
|
||||||
|
// invalid number, string instead of a number
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "number",
|
||||||
|
value: "test"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Value must be a number"] )
|
||||||
|
|
||||||
|
// valid (empty) number
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "number",
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// valid number
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "number",
|
||||||
|
value: 10
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates required integers", function() {
|
||||||
|
// invalid integer, string instead of an integer
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "integer",
|
||||||
|
value: "test"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// invalid integer, undefined value
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "integer",
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Required field is not provided"] )
|
||||||
|
|
||||||
|
// valid integer
|
||||||
|
param = fromJS({
|
||||||
|
required: true,
|
||||||
|
type: "integer",
|
||||||
|
value: 10
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("validates optional integers", function() {
|
||||||
|
// invalid integer, string instead of an integer
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "integer",
|
||||||
|
value: "test"
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( ["Value must be an integer"] )
|
||||||
|
|
||||||
|
// valid (empty) integer
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "integer",
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
|
||||||
|
// valid number
|
||||||
|
param = fromJS({
|
||||||
|
required: false,
|
||||||
|
type: "integer",
|
||||||
|
value: 10
|
||||||
|
})
|
||||||
|
result = validateParam( param, false )
|
||||||
|
expect( result ).toEqual( [] )
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("fromJSOrdered", () => {
|
||||||
|
it("should create an OrderedMap from an object", () => {
|
||||||
|
const param = {
|
||||||
|
value: "test"
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = fromJSOrdered(param).toJS()
|
||||||
|
expect( result ).toEqual( { value: "test" } )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should not use an object's length property for Map size", () => {
|
||||||
|
const param = {
|
||||||
|
length: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = fromJSOrdered(param).toJS()
|
||||||
|
expect( result ).toEqual( { length: 5 } )
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should create an OrderedMap from an array", () => {
|
||||||
|
const param = [1, 1, 2, 3, 5, 8]
|
||||||
|
|
||||||
|
const result = fromJSOrdered(param).toJS()
|
||||||
|
expect( result ).toEqual( [1, 1, 2, 3, 5, 8] )
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,64 +1,32 @@
|
|||||||
var path = require('path')
|
const path = require("path")
|
||||||
var rules = [
|
const styleRules = require("./webpack.dist-style.config.js")
|
||||||
|
|
||||||
|
let rules = [
|
||||||
{ test: /\.(worker\.js)(\?.*)?$/,
|
{ test: /\.(worker\.js)(\?.*)?$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'worker-loader',
|
loader: "worker-loader",
|
||||||
options: {
|
options: {
|
||||||
inline: true,
|
inline: true,
|
||||||
name: '[name].js'
|
name: "[name].js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: 'babel-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.js')(rules, {
|
module.exports = require("./make-webpack-config.js")(rules, {
|
||||||
_special: {
|
_special: {
|
||||||
separateStylesheets: false,
|
separateStylesheets: true,
|
||||||
minimize: true,
|
minimize: true,
|
||||||
sourcemaps: true,
|
sourcemaps: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
entry: {
|
entry: {
|
||||||
'swagger-ui-bundle': [
|
"swagger-ui-bundle": [
|
||||||
'./src/polyfills',
|
"./src/polyfills",
|
||||||
'./src/core/index.js'
|
"./src/core/index.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +1,32 @@
|
|||||||
var path = require('path')
|
const path = require("path")
|
||||||
|
const styleRules = require("./webpack.dist-style.config.js")
|
||||||
|
|
||||||
var rules = [
|
let rules = [
|
||||||
{ test: /\.(worker\.js)(\?.*)?$/,
|
{ test: /\.(worker\.js)(\?.*)?$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'worker-loader',
|
loader: "worker-loader",
|
||||||
options: {
|
options: {
|
||||||
inline: true,
|
inline: true,
|
||||||
name: '[name].js'
|
name: "[name].js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: 'babel-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.js')(rules, {
|
module.exports = require("./make-webpack-config.js")(rules, {
|
||||||
_special: {
|
_special: {
|
||||||
separateStylesheets: false,
|
separateStylesheets: true,
|
||||||
minimize: true,
|
minimize: true,
|
||||||
sourcemaps: true,
|
sourcemaps: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
entry: {
|
entry: {
|
||||||
'swagger-ui-standalone-preset': [
|
"swagger-ui-standalone-preset": [
|
||||||
'./src/polyfills',
|
"./src/polyfills",
|
||||||
'./src/standalone/index.js'
|
"./src/standalone/index.js"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +1,25 @@
|
|||||||
var path = require('path')
|
const path = require("path")
|
||||||
var fs = require('fs')
|
const 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')
|
const styleRules = require("./webpack.dist-style.config.js")
|
||||||
|
|
||||||
var rules = [
|
let rules = [
|
||||||
{ test: /\.(worker\.js)(\?.*)?$/,
|
{ test: /\.(worker\.js)(\?.*)?$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'worker-loader',
|
loader: "worker-loader",
|
||||||
options: {
|
options: {
|
||||||
inline: true,
|
inline: true,
|
||||||
name: '[name].js'
|
name: "[name].js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: 'babel-loader' }
|
{ 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'
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
rules = rules.concat(styleRules)
|
||||||
|
|
||||||
module.exports = require('./make-webpack-config.js')(rules, {
|
module.exports = require("./make-webpack-config.js")(rules, {
|
||||||
_special: {
|
_special: {
|
||||||
separateStylesheets: true,
|
separateStylesheets: true,
|
||||||
minimize: true,
|
minimize: true,
|
||||||
|
|||||||
@@ -1,56 +1,46 @@
|
|||||||
var path = require('path')
|
const path = require("path")
|
||||||
|
|
||||||
var rules = [
|
const rules = [
|
||||||
{ test: /\.(worker\.js)(\?.*)?$/,
|
{ test: /\.(worker\.js)(\?.*)?$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'worker-loader',
|
loader: "worker-loader",
|
||||||
options: {
|
options: {
|
||||||
inline: true
|
inline: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ loader: 'babel-loader' }
|
{ loader: "babel-loader" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ test: /\.(jsx)(\?.*)?$/,
|
{ test: /\.(jsx)(\?.*)?$/,
|
||||||
use: [
|
use: [
|
||||||
{ loader: 'react-hot-loader' },
|
{ loader: "react-hot-loader" },
|
||||||
{ loader: 'babel-loader' }
|
{ loader: "babel-loader" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ test: /\.(css)(\?.*)?$/,
|
{ test: /\.(css)(\?.*)?$/,
|
||||||
use: [
|
use: [
|
||||||
'style-loader',
|
"style-loader",
|
||||||
'css-loader',
|
"css-loader",
|
||||||
'postcss-loader'
|
"postcss-loader"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ test: /\.(scss)(\?.*)?$/,
|
{ test: /\.(scss)(\?.*)?$/,
|
||||||
use: [
|
use: [
|
||||||
'style-loader',
|
"style-loader",
|
||||||
'css-loader',
|
"css-loader",
|
||||||
{
|
{
|
||||||
loader: 'postcss-loader',
|
loader: "postcss-loader",
|
||||||
options: { sourceMap: true }
|
options: { sourceMap: true }
|
||||||
},
|
},
|
||||||
{ loader: 'sass-loader',
|
{ loader: "sass-loader",
|
||||||
options: {
|
options: {
|
||||||
outputStyle: 'expanded',
|
outputStyle: "expanded",
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
sourceMapContents: 'true'
|
sourceMapContents: "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{ test: /\.(less)(\?.*)?$/,
|
|
||||||
use: [
|
|
||||||
'style-loader',
|
|
||||||
'css-loader',
|
|
||||||
{
|
|
||||||
loader: 'postcss-loader',
|
|
||||||
},
|
|
||||||
'less-loader'
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -60,25 +50,26 @@ module.exports = require("./make-webpack-config")(rules, {
|
|||||||
},
|
},
|
||||||
devtool: "eval",
|
devtool: "eval",
|
||||||
entry: {
|
entry: {
|
||||||
'swagger-ui-bundle': [
|
"swagger-ui-bundle": [
|
||||||
'./src/polyfills',
|
"./src/polyfills",
|
||||||
'./src/core/index.js'
|
"./src/core/index.js"
|
||||||
],
|
],
|
||||||
'swagger-ui-standalone-preset': [
|
"swagger-ui-standalone-preset": [
|
||||||
'./src/polyfills',
|
"./src/style/main.scss",
|
||||||
'./src/standalone/index.js',
|
"./src/polyfills",
|
||||||
|
"./src/standalone/index.js",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
pathinfo: true,
|
pathinfo: true,
|
||||||
filename: '[name].js',
|
filename: "[name].js",
|
||||||
library: "[name]",
|
library: "[name]",
|
||||||
libraryTarget: "umd",
|
libraryTarget: "umd",
|
||||||
chunkFilename: "[id].js"
|
chunkFilename: "[id].js"
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
port: 3200,
|
port: 3200,
|
||||||
contentBase: path.join(__dirname, 'dev-helpers'),
|
contentBase: path.join(__dirname, "dev-helpers"),
|
||||||
publicPath: "/",
|
publicPath: "/",
|
||||||
noInfo: true,
|
noInfo: true,
|
||||||
hot: true,
|
hot: true,
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
var config = require("./webpack-dist.config.js")
|
const config = require("./webpack-dist.config.js")
|
||||||
|
|
||||||
module.exports = config
|
module.exports = config
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
const webpack = require('webpack')
|
const path = require("path")
|
||||||
const path = require('path')
|
const deepMerge = require("deepmerge")
|
||||||
const deepMerge = require('deepmerge')
|
const webpackConfig = require("./webpack-dist-bundle.config.js")
|
||||||
const webpackConfig = require('./webpack-dist-bundle.config.js')
|
const DEPS_CHECK_DIR = require("./package.json").config.deps_check_dir
|
||||||
const DEPS_CHECK_DIR = require('./package.json').config.deps_check_dir
|
|
||||||
|
|
||||||
module.exports = deepMerge(
|
module.exports = deepMerge(
|
||||||
webpackConfig, {
|
webpackConfig, {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module.exports = require("./make-webpack-config")({
|
module.exports = require("./make-webpack-config")({
|
||||||
|
|
||||||
});
|
})
|
||||||
34
webpack.dist-style.config.js
Normal file
34
webpack.dist-style.config.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
const ExtractTextPlugin = require("extract-text-webpack-plugin")
|
||||||
|
|
||||||
|
module.exports = [{
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}]
|
||||||
Reference in New Issue
Block a user