Merge branch 'master' into feature/headerfix
This commit is contained in:
54
CONTRIBUTING.md
Normal file
54
CONTRIBUTING.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
## Contributing to Swagger-UI
|
||||||
|
|
||||||
|
We love contributions from our community of users! This document explains our guidelines and workflows. Please take care to follow them, as it helps us keep things moving smoothly.
|
||||||
|
|
||||||
|
#### Environment setup
|
||||||
|
|
||||||
|
0. Install Node.js (4 or newer) and npm (3 or newer).
|
||||||
|
1. Make a fork of Swagger-UI on GitHub, then clone your fork to your machine.
|
||||||
|
2. Run `npm install` in your Swagger-UI directory.
|
||||||
|
3. Run `npm run dev`. `localhost:3200` should open automatically.
|
||||||
|
4. You're ready to go!
|
||||||
|
|
||||||
|
#### Branching model
|
||||||
|
|
||||||
|
Feature branches should be prefixed with `ft/`.
|
||||||
|
|
||||||
|
Bugfix branches should be prefixed with `bug/`.
|
||||||
|
|
||||||
|
Version branches should be prefixed with `v/`.
|
||||||
|
|
||||||
|
After the forward slash, include a short description of what you're fixing. For example: `bug/fix-everything-that-was-broken`. For versions, add the version that will be released via the branch, for example: `v/1.2.3`.
|
||||||
|
|
||||||
|
If there's an issue filed that you're addressing in your branch, include the issue number directly after the forward slash. For example: `bug/1234-fix-all-the-other-things`.
|
||||||
|
|
||||||
|
#### Filing issues
|
||||||
|
|
||||||
|
- **Do** include the Swagger-UI build you're using - you can find this by opening your console and checking `window.versions.swaggerUi`
|
||||||
|
- **Do** include a spec that demonstrates the issue you're experiencing.
|
||||||
|
- **Do** include screenshots, if needed. GIFs are even better!
|
||||||
|
- **Do** place code inside of a pre-formatted container by surrounding the code with triple backticks.
|
||||||
|
- **Don't** open tickets discussing issues with the Swagger/OpenAPI specification itself, or for issues with projects that use Swagger-UI.
|
||||||
|
- **Don't** open an issue without searching the issue tracker for duplicates first.
|
||||||
|
|
||||||
|
#### Committing
|
||||||
|
|
||||||
|
- Break your commits into logical atomic units. Well-segmented commits make it _much_ easier for others to step through your changes.
|
||||||
|
- Limit your subject (first) line to 50 characters (GitHub truncates more than 70).
|
||||||
|
- Provide a body if you'd like to explain your commit in detail.
|
||||||
|
- Capitalize the beginning of your subject line, and do not end the subject line with a period.
|
||||||
|
- Your subject line should complete this sentence: `If applied, this commit will [your subject line].`
|
||||||
|
- Don't use [magic GitHub words](https://help.github.com/articles/closing-issues-using-keywords/) in your commits to close issues - do that in the pull request for your code instead.
|
||||||
|
|
||||||
|
_Adapted from [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/#seven-rules)._
|
||||||
|
|
||||||
|
#### Making pull requests
|
||||||
|
|
||||||
|
- **Do** summarize your changes in the PR body. If in doubt, write a bullet-point list titled `This PR does the following:`.
|
||||||
|
- **Do** include references to issues that your PR solves, and use [magic GitHub words](https://help.github.com/articles/closing-issues-using-keywords/) to close those issues automatically when your PR is merged.
|
||||||
|
- **Do** include tests that cover new or changed functionality.
|
||||||
|
- **Do** be careful to follow our ESLint style rules. We recommend installing an ESLint plugin if you use a graphical code editor.
|
||||||
|
- **Do** make sure that tests and the linter are passing by running `npm test` locally, otherwise we can't merge your pull request.
|
||||||
|
- **Don't** include any changes to files in the `dist/` directory - we update those files only during releases.
|
||||||
|
- **Don't** mention maintainers in your original PR body - we probably would've seen it anyway, so it just increases the noise in our inboxes. Do feel free to ping maintainers if a week has passed and you've heard nothing from us.
|
||||||
|
- **Don't** open PRs for custom functionality that only serves a small subset of our users - custom functionality should be implemented outside of our codebase, via a plugin.
|
||||||
@@ -69,7 +69,9 @@ export default class ParamBody extends PureComponent {
|
|||||||
let { param, fn:{inferSchema} } = this.props
|
let { param, fn:{inferSchema} } = this.props
|
||||||
let schema = inferSchema(param.toJS())
|
let schema = inferSchema(param.toJS())
|
||||||
|
|
||||||
return getSampleSchema(schema, xml)
|
return getSampleSchema(schema, xml, {
|
||||||
|
includeWriteOnly: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange = (value, { isEditBox, isXml }) => {
|
onChange = (value, { isEditBox, isXml }) => {
|
||||||
|
|||||||
@@ -83,11 +83,16 @@ export default class Response extends React.Component {
|
|||||||
|
|
||||||
if(isOAS3()) {
|
if(isOAS3()) {
|
||||||
let oas3SchemaForContentType = response.getIn(["content", this.state.responseContentType, "schema"])
|
let oas3SchemaForContentType = response.getIn(["content", this.state.responseContentType, "schema"])
|
||||||
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, { includeReadOnly: true }) : null
|
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
|
||||||
|
includeReadOnly: true
|
||||||
|
}) : null
|
||||||
schema = oas3SchemaForContentType ? inferSchema(oas3SchemaForContentType.toJS()) : null
|
schema = oas3SchemaForContentType ? inferSchema(oas3SchemaForContentType.toJS()) : null
|
||||||
} else {
|
} else {
|
||||||
schema = inferSchema(response.toJS())
|
schema = inferSchema(response.toJS())
|
||||||
sampleResponse = schema ? getSampleSchema(schema, contentType, { includeReadOnly: true }) : null
|
sampleResponse = schema ? getSampleSchema(schema, contentType, {
|
||||||
|
includeReadOnly: true,
|
||||||
|
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0
|
||||||
|
}) : null
|
||||||
}
|
}
|
||||||
let example = getExampleComponent( sampleResponse, examples, HighlightCode )
|
let example = getExampleComponent( sampleResponse, examples, HighlightCode )
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default function curl( request ){
|
|||||||
if ( request.get("body") ){
|
if ( request.get("body") ){
|
||||||
|
|
||||||
if(type === "multipart/form-data" && request.get("method") === "POST") {
|
if(type === "multipart/form-data" && request.get("method") === "POST") {
|
||||||
for( let [ k,v ] of request.get("body").values()) {
|
for( let [ k,v ] of request.get("body").entrySeq()) {
|
||||||
curlified.push( "-F" )
|
curlified.push( "-F" )
|
||||||
if (v instanceof win.File) {
|
if (v instanceof win.File) {
|
||||||
curlified.push( `"${k}=@${v.name};type=${v.type}"` )
|
curlified.push( `"${k}=@${v.name};type=${v.type}"` )
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ const RequestBody = ({ requestBody, getComponent, specSelectors, contentType })
|
|||||||
|
|
||||||
const mediaTypeValue = requestBodyContent.get(contentType)
|
const mediaTypeValue = requestBodyContent.get(contentType)
|
||||||
|
|
||||||
const sampleSchema = getSampleSchema(mediaTypeValue.get("schema").toJS(), contentType)
|
const sampleSchema = getSampleSchema(mediaTypeValue.get("schema").toJS(), contentType, {
|
||||||
|
includeWriteOnly: true
|
||||||
|
})
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{ requestBodyDescription &&
|
{ requestBodyDescription &&
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const primitives = {
|
|||||||
"number": () => 0,
|
"number": () => 0,
|
||||||
"number_float": () => 0.0,
|
"number_float": () => 0.0,
|
||||||
"integer": () => 0,
|
"integer": () => 0,
|
||||||
"boolean": (schema) => typeof schema.default === "boolean" ? schema.default : true
|
"boolean": (schema) => typeof schema.default === "boolean" ? schema.default : true
|
||||||
}
|
}
|
||||||
|
|
||||||
const primitive = (schema) => {
|
const primitive = (schema) => {
|
||||||
@@ -27,7 +27,7 @@ const primitive = (schema) => {
|
|||||||
|
|
||||||
export const sampleFromSchema = (schema, config={}) => {
|
export const sampleFromSchema = (schema, config={}) => {
|
||||||
let { type, example, properties, additionalProperties, items } = objectify(schema)
|
let { type, example, properties, additionalProperties, items } = objectify(schema)
|
||||||
let { includeReadOnly } = config
|
let { includeReadOnly, includeWriteOnly } = config
|
||||||
|
|
||||||
if(example !== undefined)
|
if(example !== undefined)
|
||||||
return example
|
return example
|
||||||
@@ -46,16 +46,20 @@ export const sampleFromSchema = (schema, config={}) => {
|
|||||||
let props = objectify(properties)
|
let props = objectify(properties)
|
||||||
let obj = {}
|
let obj = {}
|
||||||
for (var name in props) {
|
for (var name in props) {
|
||||||
if ( !props[name].readOnly || includeReadOnly ) {
|
if ( props[name].readOnly && !includeReadOnly ) {
|
||||||
obj[name] = sampleFromSchema(props[name], { includeReadOnly: includeReadOnly })
|
continue
|
||||||
}
|
}
|
||||||
|
if ( props[name].writeOnly && !includeWriteOnly ) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
obj[name] = sampleFromSchema(props[name], config)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( additionalProperties === true ) {
|
if ( additionalProperties === true ) {
|
||||||
obj.additionalProp1 = {}
|
obj.additionalProp1 = {}
|
||||||
} else if ( additionalProperties ) {
|
} else if ( additionalProperties ) {
|
||||||
let additionalProps = objectify(additionalProperties)
|
let additionalProps = objectify(additionalProperties)
|
||||||
let additionalPropVal = sampleFromSchema(additionalProps, { includeReadOnly: includeReadOnly })
|
let additionalPropVal = sampleFromSchema(additionalProps, config)
|
||||||
|
|
||||||
for (let i = 1; i < 4; i++) {
|
for (let i = 1; i < 4; i++) {
|
||||||
obj["additionalProp" + i] = additionalPropVal
|
obj["additionalProp" + i] = additionalPropVal
|
||||||
@@ -65,7 +69,7 @@ export const sampleFromSchema = (schema, config={}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(type === "array") {
|
if(type === "array") {
|
||||||
return [ sampleFromSchema(items, { includeReadOnly: includeReadOnly }) ]
|
return [ sampleFromSchema(items, config) ]
|
||||||
}
|
}
|
||||||
|
|
||||||
if(schema["enum"]) {
|
if(schema["enum"]) {
|
||||||
@@ -96,7 +100,7 @@ export const inferSchema = (thing) => {
|
|||||||
export const sampleXmlFromSchema = (schema, config={}) => {
|
export const sampleXmlFromSchema = (schema, config={}) => {
|
||||||
let objectifySchema = objectify(schema)
|
let objectifySchema = objectify(schema)
|
||||||
let { type, properties, additionalProperties, items, example } = objectifySchema
|
let { type, properties, additionalProperties, items, example } = objectifySchema
|
||||||
let { includeReadOnly } = config
|
let { includeReadOnly, includeWriteOnly } = config
|
||||||
let defaultValue = objectifySchema.default
|
let defaultValue = objectifySchema.default
|
||||||
let res = {}
|
let res = {}
|
||||||
let _attr = {}
|
let _attr = {}
|
||||||
@@ -177,27 +181,32 @@ export const sampleXmlFromSchema = (schema, config={}) => {
|
|||||||
example = example || {}
|
example = example || {}
|
||||||
|
|
||||||
for (let propName in props) {
|
for (let propName in props) {
|
||||||
if ( !props[propName].readOnly || includeReadOnly ) {
|
if ( props[propName].readOnly && !includeReadOnly ) {
|
||||||
props[propName].xml = props[propName].xml || {}
|
continue
|
||||||
|
}
|
||||||
|
if ( props[propName].writeOnly && !includeWriteOnly ) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if (props[propName].xml.attribute) {
|
props[propName].xml = props[propName].xml || {}
|
||||||
let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]
|
|
||||||
let attrExample = props[propName].example
|
if (props[propName].xml.attribute) {
|
||||||
let attrDefault = props[propName].default
|
let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]
|
||||||
_attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample
|
let attrExample = props[propName].example
|
||||||
|| example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault
|
let attrDefault = props[propName].default
|
||||||
|| enumAttrVal || primitive(props[propName])
|
_attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample
|
||||||
|
|| example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault
|
||||||
|
|| enumAttrVal || primitive(props[propName])
|
||||||
|
} else {
|
||||||
|
props[propName].xml.name = props[propName].xml.name || propName
|
||||||
|
props[propName].example = props[propName].example !== undefined ? props[propName].example : example[propName]
|
||||||
|
let t = sampleXmlFromSchema(props[propName])
|
||||||
|
if (Array.isArray(t)) {
|
||||||
|
res[displayName] = res[displayName].concat(t)
|
||||||
} else {
|
} else {
|
||||||
props[propName].xml.name = props[propName].xml.name || propName
|
res[displayName].push(t)
|
||||||
props[propName].example = props[propName].example !== undefined ? props[propName].example : example[propName]
|
|
||||||
let t = sampleXmlFromSchema(props[propName])
|
|
||||||
if (Array.isArray(t)) {
|
|
||||||
res[displayName] = res[displayName].concat(t)
|
|
||||||
} else {
|
|
||||||
res[displayName].push(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,10 +132,10 @@ describe("curlify", function() {
|
|||||||
url: "http://example.com",
|
url: "http://example.com",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "content-type": "multipart/form-data" },
|
headers: { "content-type": "multipart/form-data" },
|
||||||
body: [
|
body: {
|
||||||
["id", "123"],
|
id: "123",
|
||||||
["name", "Sahar"]
|
name: "Sahar"
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let curlified = curl(Im.fromJS(req))
|
let curlified = curl(Im.fromJS(req))
|
||||||
@@ -152,10 +152,10 @@ describe("curlify", function() {
|
|||||||
url: "http://example.com",
|
url: "http://example.com",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "content-type": "multipart/form-data" },
|
headers: { "content-type": "multipart/form-data" },
|
||||||
body: [
|
body: {
|
||||||
["id", "123"],
|
id: "123",
|
||||||
["file", file]
|
file
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let curlified = curl(Im.fromJS(req))
|
let curlified = curl(Im.fromJS(req))
|
||||||
|
|||||||
@@ -1,6 +1,105 @@
|
|||||||
import { createXMLExample } from "corePlugins/samples/fn"
|
import { createXMLExample, sampleFromSchema } from "corePlugins/samples/fn"
|
||||||
import expect from "expect"
|
import expect from "expect"
|
||||||
|
|
||||||
|
describe("sampleFromSchema", function() {
|
||||||
|
it("returns object with no readonly fields for parameter", function () {
|
||||||
|
var definition = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "integer"
|
||||||
|
},
|
||||||
|
readOnlyDog: {
|
||||||
|
readOnly: true,
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xml: {
|
||||||
|
name: "animals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var expected = {
|
||||||
|
id: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns object with readonly fields for parameter, with includeReadOnly", function () {
|
||||||
|
var definition = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "integer"
|
||||||
|
},
|
||||||
|
readOnlyDog: {
|
||||||
|
readOnly: true,
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xml: {
|
||||||
|
name: "animals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var expected = {
|
||||||
|
id: 0,
|
||||||
|
readOnlyDog: "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sampleFromSchema(definition, { includeReadOnly: true })).toEqual(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns object without writeonly fields for parameter", function () {
|
||||||
|
var definition = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "integer"
|
||||||
|
},
|
||||||
|
writeOnlyDog: {
|
||||||
|
writeOnly: true,
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xml: {
|
||||||
|
name: "animals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var expected = {
|
||||||
|
id: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sampleFromSchema(definition)).toEqual(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns object with writeonly fields for parameter, with includeWriteOnly", function () {
|
||||||
|
var definition = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "integer"
|
||||||
|
},
|
||||||
|
writeOnlyDog: {
|
||||||
|
writeOnly: true,
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xml: {
|
||||||
|
name: "animals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var expected = {
|
||||||
|
id: 0,
|
||||||
|
writeOnlyDog: "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sampleFromSchema(definition, { includeWriteOnly: true })).toEqual(expected)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("createXMLExample", function () {
|
describe("createXMLExample", function () {
|
||||||
var sut = createXMLExample
|
var sut = createXMLExample
|
||||||
@@ -554,6 +653,69 @@ describe("createXMLExample", function () {
|
|||||||
expect(sut(definition, { includeReadOnly: false })).toEqual(expected)
|
expect(sut(definition, { includeReadOnly: false })).toEqual(expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("returns object with readonly fields for parameter, with includeReadOnly", function () {
|
||||||
|
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n\t<dog>string</dog>\n</animals>"
|
||||||
|
var definition = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "integer"
|
||||||
|
},
|
||||||
|
dog: {
|
||||||
|
readOnly: true,
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xml: {
|
||||||
|
name: "animals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sut(definition, { includeReadOnly: true })).toEqual(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns object without writeonly fields for parameter", function () {
|
||||||
|
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n</animals>"
|
||||||
|
var definition = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "integer"
|
||||||
|
},
|
||||||
|
dog: {
|
||||||
|
writeOnly: true,
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xml: {
|
||||||
|
name: "animals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sut(definition)).toEqual(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("returns object with writeonly fields for parameter, with includeWriteOnly", function () {
|
||||||
|
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n\t<dog>string</dog>\n</animals>"
|
||||||
|
var definition = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: "integer"
|
||||||
|
},
|
||||||
|
dog: {
|
||||||
|
writeOnly: true,
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xml: {
|
||||||
|
name: "animals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(sut(definition, { includeWriteOnly: true })).toEqual(expected)
|
||||||
|
})
|
||||||
|
|
||||||
it("returns object with passed property as attribute", function () {
|
it("returns object with passed property as attribute", function () {
|
||||||
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals id=\"0\">\n\t<dog>string</dog>\n</animals>"
|
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals id=\"0\">\n\t<dog>string</dog>\n</animals>"
|
||||||
var definition = {
|
var definition = {
|
||||||
|
|||||||
Reference in New Issue
Block a user