mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-08 14:14:56 +03:00
Merge pull request #1 from raha1923/master-with-console
WIP: Master with console
This commit is contained in:
commit
faef716b1a
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -36,3 +36,6 @@ cli/index.js
|
||||||
stats.json
|
stats.json
|
||||||
/package-lock.json
|
/package-lock.json
|
||||||
/.idea/
|
/.idea/
|
||||||
|
|
||||||
|
# npmrc for local npm
|
||||||
|
.npmrc
|
||||||
|
|
1
demo/.gitignore
vendored
Normal file
1
demo/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
intent.json
|
|
@ -38,8 +38,6 @@ info:
|
||||||
OAuth2 - an open protocol to allow secure authorization in a simple
|
OAuth2 - an open protocol to allow secure authorization in a simple
|
||||||
and standard method from web, mobile and desktop applications.
|
and standard method from web, mobile and desktop applications.
|
||||||
|
|
||||||
<SecurityDefinitions />
|
|
||||||
|
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
title: Swagger Petstore
|
title: Swagger Petstore
|
||||||
termsOfService: 'http://swagger.io/terms/'
|
termsOfService: 'http://swagger.io/terms/'
|
||||||
|
|
993
demo/petstore.json
Normal file
993
demo/petstore.json
Normal file
|
@ -0,0 +1,993 @@
|
||||||
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"title": "Swagger Petstore",
|
||||||
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
|
"contact": {
|
||||||
|
"email": "apiteam@swagger.io"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "Apache 2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"host": "petstore.swagger.io",
|
||||||
|
"basePath": "/v2",
|
||||||
|
"tags": [{
|
||||||
|
"name": "pet",
|
||||||
|
"description": "Everything about your Pets",
|
||||||
|
"externalDocs": {
|
||||||
|
"description": "Find out more",
|
||||||
|
"url": "http://swagger.io"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "store",
|
||||||
|
"description": "Access to Petstore orders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user",
|
||||||
|
"description": "Operations about user",
|
||||||
|
"externalDocs": {
|
||||||
|
"description": "Find out more about our store",
|
||||||
|
"url": "http://swagger.io"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http"
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/pet": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "Add a new pet to the store",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "addPet",
|
||||||
|
"consumes": [
|
||||||
|
"application/json",
|
||||||
|
"application/xml"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "Pet object that needs to be added to the store",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"405": {
|
||||||
|
"description": "Invalid input"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "Update an existing pet",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "updatePet",
|
||||||
|
"consumes": [
|
||||||
|
"application/json",
|
||||||
|
"application/xml"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "Pet object that needs to be added to the store",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid ID supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Pet not found"
|
||||||
|
},
|
||||||
|
"405": {
|
||||||
|
"description": "Validation exception"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/pet/findByStatus": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "Finds Pets by status",
|
||||||
|
"description": "Multiple status values can be provided with comma separated strings",
|
||||||
|
"operationId": "findPetsByStatus",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "status",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Status values that need to be considered for filter",
|
||||||
|
"required": true,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"available",
|
||||||
|
"pending",
|
||||||
|
"sold"
|
||||||
|
],
|
||||||
|
"default": "available"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid status value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/pet/findByTags": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "Finds Pets by tags",
|
||||||
|
"description": "Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
|
||||||
|
"operationId": "findPetsByTags",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "tags",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Tags to filter by",
|
||||||
|
"required": true,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid tag value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
"deprecated": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/pet/{petId}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "Find pet by ID",
|
||||||
|
"description": "Returns a single pet",
|
||||||
|
"operationId": "getPetById",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of pet to return",
|
||||||
|
"required": true,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Pet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid ID supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Pet not found"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"api_key": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "Updates a pet in the store with form data",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "updatePetWithForm",
|
||||||
|
"consumes": [
|
||||||
|
"application/x-www-form-urlencoded"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of pet that needs to be updated",
|
||||||
|
"required": true,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"in": "formData",
|
||||||
|
"description": "Updated name of the pet",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"in": "formData",
|
||||||
|
"description": "Updated status of the pet",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"405": {
|
||||||
|
"description": "Invalid input"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "Deletes a pet",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "deletePet",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "api_key",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "Pet id to delete",
|
||||||
|
"required": true,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid ID supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Pet not found"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/pet/{petId}/uploadImage": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"pet"
|
||||||
|
],
|
||||||
|
"summary": "uploads an image",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "uploadFile",
|
||||||
|
"consumes": [
|
||||||
|
"multipart/form-data"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of pet to update",
|
||||||
|
"required": true,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "additionalMetadata",
|
||||||
|
"in": "formData",
|
||||||
|
"description": "Additional data to pass to server",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "file",
|
||||||
|
"in": "formData",
|
||||||
|
"description": "file to upload",
|
||||||
|
"required": false,
|
||||||
|
"type": "file"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ApiResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"petstore_auth": [
|
||||||
|
"write:pets",
|
||||||
|
"read:pets"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/store/inventory": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"store"
|
||||||
|
],
|
||||||
|
"summary": "Returns pet inventories by status",
|
||||||
|
"description": "Returns a map of status codes to quantities",
|
||||||
|
"operationId": "getInventory",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [{
|
||||||
|
"api_key": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/store/order": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"store"
|
||||||
|
],
|
||||||
|
"summary": "Place an order for a pet",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "placeOrder",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "order placed for purchasing the pet",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Order"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Order"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid Order"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/store/order/{orderId}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"store"
|
||||||
|
],
|
||||||
|
"summary": "Find purchase order by ID",
|
||||||
|
"description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
|
||||||
|
"operationId": "getOrderById",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "orderId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of pet that needs to be fetched",
|
||||||
|
"required": true,
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 10.0,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"format": "int64"
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Order"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid ID supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Order not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"store"
|
||||||
|
],
|
||||||
|
"summary": "Delete purchase order by ID",
|
||||||
|
"description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
|
||||||
|
"operationId": "deleteOrder",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "orderId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of the order that needs to be deleted",
|
||||||
|
"required": true,
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1.0,
|
||||||
|
"format": "int64"
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid ID supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Order not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Create user",
|
||||||
|
"description": "This can only be done by the logged in user.",
|
||||||
|
"operationId": "createUser",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "Created user object",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"default": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user/createWithArray": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Creates list of users with given input array",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "createUsersWithArrayInput",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "List of user object",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"default": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user/createWithList": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Creates list of users with given input array",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "createUsersWithListInput",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "List of user object",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"default": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user/login": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Logs user into the system",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "loginUser",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "username",
|
||||||
|
"in": "query",
|
||||||
|
"description": "The user name for login",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password",
|
||||||
|
"in": "query",
|
||||||
|
"description": "The password for login in clear text",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"X-Rate-Limit": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"description": "calls per hour allowed by the user"
|
||||||
|
},
|
||||||
|
"X-Expires-After": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"description": "date in UTC when token expires"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid username/password supplied"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user/logout": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Logs out current logged in user session",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "logoutUser",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"default": {
|
||||||
|
"description": "successful operation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user/{username}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Get user by user name",
|
||||||
|
"description": "",
|
||||||
|
"operationId": "getUserByName",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "username",
|
||||||
|
"in": "path",
|
||||||
|
"description": "The name that needs to be fetched. Use user1 for testing. ",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "successful operation",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid username supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "User not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Updated user",
|
||||||
|
"description": "This can only be done by the logged in user.",
|
||||||
|
"operationId": "updateUser",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "username",
|
||||||
|
"in": "path",
|
||||||
|
"description": "name that need to be updated",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "Updated user object",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/User"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid user supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "User not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Delete user",
|
||||||
|
"description": "This can only be done by the logged in user.",
|
||||||
|
"operationId": "deleteUser",
|
||||||
|
"produces": [
|
||||||
|
"application/xml",
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"parameters": [{
|
||||||
|
"name": "username",
|
||||||
|
"in": "path",
|
||||||
|
"description": "The name that needs to be deleted",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}],
|
||||||
|
"responses": {
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid username supplied"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "User not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securityDefinitions": {
|
||||||
|
"petstore_auth": {
|
||||||
|
"type": "oauth2",
|
||||||
|
"authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
|
||||||
|
"flow": "implicit",
|
||||||
|
"scopes": {
|
||||||
|
"write:pets": "modify pets in your account",
|
||||||
|
"read:pets": "read your pets"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"api_key": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"name": "api_key",
|
||||||
|
"in": "header"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"Order": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"petId": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"quantity": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"shipDate": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Order Status",
|
||||||
|
"enum": [
|
||||||
|
"placed",
|
||||||
|
"approved",
|
||||||
|
"delivered"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"complete": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xml": {
|
||||||
|
"name": "Order"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"User": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"firstName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"lastName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"phone": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"userStatus": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"description": "User Status"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xml": {
|
||||||
|
"name": "User"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Category": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xml": {
|
||||||
|
"name": "Category"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Tag": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xml": {
|
||||||
|
"name": "Tag"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Pet": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"photoUrls"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"$ref": "#/definitions/Category"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "doggie"
|
||||||
|
},
|
||||||
|
"photoUrls": {
|
||||||
|
"type": "array",
|
||||||
|
"xml": {
|
||||||
|
"name": "photoUrl",
|
||||||
|
"wrapped": true
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"type": "array",
|
||||||
|
"xml": {
|
||||||
|
"name": "tag",
|
||||||
|
"wrapped": true
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Tag"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "pet status in the store",
|
||||||
|
"enum": [
|
||||||
|
"available",
|
||||||
|
"pending",
|
||||||
|
"sold"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xml": {
|
||||||
|
"name": "Pet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ApiResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"code": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"externalDocs": {
|
||||||
|
"description": "Find out more about Swagger",
|
||||||
|
"url": "http://swagger.io"
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,10 @@ const specUrl =
|
||||||
(userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml');
|
(userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml');
|
||||||
|
|
||||||
let store;
|
let store;
|
||||||
const options: RedocRawOptions = { nativeScrollbars: false };
|
const headers = {
|
||||||
|
'x-nutanix-client': 'ui',
|
||||||
|
};
|
||||||
|
const options: RedocRawOptions = { nativeScrollbars: false, enableConsole: true, providedByName: 'Intent ApiDocs by Nutanix', providedByUri: 'http://www.nutanix.com', additionalHeaders: headers };
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const spec = await loadAndBundleSpec(specUrl);
|
const spec = await loadAndBundleSpec(specUrl);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { renderToString } from 'react-dom/server';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { ServerStyleSheet } from 'styled-components';
|
|
||||||
// @ts-ignore
|
|
||||||
import { Redoc, createStore } from '../../';
|
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { renderToString } from 'react-dom/server';
|
||||||
|
import { ServerStyleSheet } from 'styled-components';
|
||||||
|
|
||||||
|
import { createStore, Redoc } from '../../';
|
||||||
|
|
||||||
const yaml = require('yaml-js');
|
const yaml = require('yaml-js');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
|
@ -19,7 +19,7 @@ const server = http.createServer(async (request, response) => {
|
||||||
fs.createReadStream('bundles/redoc.standalone.js', 'utf8').pipe(response);
|
fs.createReadStream('bundles/redoc.standalone.js', 'utf8').pipe(response);
|
||||||
} else if (request.url === '/') {
|
} else if (request.url === '/') {
|
||||||
const spec = yaml.load(readFileSync(resolve(__dirname, '../openapi.yaml')));
|
const spec = yaml.load(readFileSync(resolve(__dirname, '../openapi.yaml')));
|
||||||
let store = await createStore(spec, 'path/to/spec.yaml');
|
const store = await createStore(spec, 'path/to/spec.yaml');
|
||||||
|
|
||||||
const sheet = new ServerStyleSheet();
|
const sheet = new ServerStyleSheet();
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,26 @@ const babelHotLoader = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let proxy = {};
|
||||||
|
let https = false;
|
||||||
|
//we are using our own proxy here
|
||||||
|
if (process.env.PROXY && process.env.USERNAME && process.env.PASSWORD) {
|
||||||
|
proxy = {
|
||||||
|
"/api": {
|
||||||
|
auth: `${process.env.USERNAME}:${process.env.PASSWORD}`,
|
||||||
|
target: process.env.PROXY,
|
||||||
|
"secure": false,
|
||||||
|
changeOrigin: true,
|
||||||
|
ws: true,
|
||||||
|
xfwd: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
https = true;
|
||||||
|
console.log('Using proxy configuration provided with command line, https in use.\n');
|
||||||
|
} else {
|
||||||
|
console.log('Using proxy from PC/PE local server\n');
|
||||||
|
}
|
||||||
|
|
||||||
export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) => ({
|
export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) => ({
|
||||||
entry: [
|
entry: [
|
||||||
root('../src/polyfills.ts'),
|
root('../src/polyfills.ts'),
|
||||||
|
@ -79,8 +99,12 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
|
||||||
port: 9090,
|
port: 9090,
|
||||||
disableHostCheck: true,
|
disableHostCheck: true,
|
||||||
stats: 'minimal',
|
stats: 'minimal',
|
||||||
|
https,
|
||||||
|
proxy,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
devtool: 'source-map',
|
||||||
|
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.ts', '.tsx', '.js', '.json'],
|
extensions: ['.ts', '.tsx', '.js', '.json'],
|
||||||
alias:
|
alias:
|
||||||
|
|
85
package.json
85
package.json
|
@ -52,77 +52,79 @@
|
||||||
"docker:build": "docker build -f config/docker/Dockerfile -t redoc ."
|
"docker:build": "docker build -f config/docker/Dockerfile -t redoc ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.6.2",
|
"@babel/core": "7.5.5",
|
||||||
"@babel/plugin-syntax-decorators": "7.2.0",
|
"@babel/plugin-syntax-decorators": "7.2.0",
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||||
"@babel/plugin-syntax-jsx": "7.2.0",
|
"@babel/plugin-syntax-jsx": "7.2.0",
|
||||||
"@babel/plugin-syntax-typescript": "7.3.3",
|
"@babel/plugin-syntax-typescript": "7.3.3",
|
||||||
"@cypress/webpack-preprocessor": "4.1.0",
|
"@cypress/webpack-preprocessor": "4.1.0",
|
||||||
"@hot-loader/react-dom": "^16.9.0",
|
"@hot-loader/react-dom": "^16.8.6",
|
||||||
"@types/chai": "4.2.3",
|
"@types/chai": "4.1.7",
|
||||||
"@types/dompurify": "^0.0.33",
|
"@types/dompurify": "^0.0.33",
|
||||||
"@types/enzyme": "^3.10.3",
|
"@types/enzyme": "^3.10.3",
|
||||||
"@types/enzyme-to-json": "^1.5.3",
|
"@types/enzyme-to-json": "^1.5.3",
|
||||||
"@types/jest": "^24.0.18",
|
"@types/jest": "^24.0.15",
|
||||||
"@types/json-pointer": "^1.0.30",
|
"@types/json-pointer": "^1.0.30",
|
||||||
"@types/lodash": "^4.14.141",
|
"@types/lodash": "^4.14.136",
|
||||||
"@types/lunr": "^2.3.2",
|
"@types/lunr": "^2.3.2",
|
||||||
"@types/mark.js": "^8.11.4",
|
"@types/mark.js": "^8.11.4",
|
||||||
"@types/marked": "^0.6.5",
|
"@types/marked": "^0.6.5",
|
||||||
"@types/prismjs": "^1.16.0",
|
"@types/prismjs": "^1.16.0",
|
||||||
"@types/prop-types": "^15.7.3",
|
"@types/promise": "^7.1.30",
|
||||||
"@types/react": "^16.9.3",
|
"@types/prop-types": "^15.7.1",
|
||||||
"@types/react-dom": "^16.9.1",
|
"@types/qs": "^6.5.1",
|
||||||
|
"@types/react": "^16.8.23",
|
||||||
|
"@types/react-dom": "^16.8.5",
|
||||||
"@types/react-hot-loader": "^4.1.0",
|
"@types/react-hot-loader": "^4.1.0",
|
||||||
"@types/react-tabs": "^2.3.1",
|
"@types/react-tabs": "^2.3.1",
|
||||||
"@types/styled-components": "^4.1.19",
|
"@types/styled-components": "^4.1.18",
|
||||||
"@types/tapable": "1.0.4",
|
"@types/tapable": "1.0.4",
|
||||||
"@types/webpack": "^4.39.2",
|
"@types/webpack": "^4.32.1",
|
||||||
"@types/webpack-env": "^1.14.0",
|
"@types/webpack-env": "^1.14.0",
|
||||||
"@types/yargs": "^13.0.3",
|
"@types/yargs": "^13.0.0",
|
||||||
"babel-loader": "8.0.6",
|
"babel-loader": "8.0.6",
|
||||||
"babel-plugin-styled-components": "^1.10.6",
|
"babel-plugin-styled-components": "^1.10.6",
|
||||||
"beautify-benchmark": "^0.2.4",
|
"beautify-benchmark": "^0.2.4",
|
||||||
"bundlesize": "^0.18.0",
|
"bundlesize": "^0.18.0",
|
||||||
"conventional-changelog-cli": "^2.0.23",
|
"conventional-changelog-cli": "^2.0.23",
|
||||||
"copy-webpack-plugin": "^5.0.4",
|
"copy-webpack-plugin": "^5.0.4",
|
||||||
"core-js": "^3.2.1",
|
"core-js": "^3.1.4",
|
||||||
"coveralls": "^3.0.6",
|
"coveralls": "^3.0.5",
|
||||||
"css-loader": "^3.2.0",
|
"css-loader": "^3.1.0",
|
||||||
"cypress": "~3.4.1",
|
"cypress": "~3.4.0",
|
||||||
"deploy-to-gh-pages": "^1.3.7",
|
"deploy-to-gh-pages": "^1.3.7",
|
||||||
"enzyme": "^3.10.0",
|
"enzyme": "^3.10.0",
|
||||||
"enzyme-adapter-react-16": "^1.14.0",
|
"enzyme-adapter-react-16": "^1.14.0",
|
||||||
"enzyme-to-json": "^3.4.0",
|
"enzyme-to-json": "^3.3.5",
|
||||||
"fork-ts-checker-webpack-plugin": "1.5.0",
|
"fork-ts-checker-webpack-plugin": "1.4.3",
|
||||||
"html-webpack-plugin": "^3.1.0",
|
"html-webpack-plugin": "^3.1.0",
|
||||||
"jest": "^24.9.0",
|
"jest": "^24.8.0",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"mobx": "^4.3.1",
|
"mobx": "^4.3.1",
|
||||||
"prettier": "^1.18.2",
|
"prettier": "^1.18.2",
|
||||||
"prettier-eslint": "^9.0.0",
|
"prettier-eslint": "^9.0.0",
|
||||||
"raf": "^3.4.1",
|
"raf": "^3.4.1",
|
||||||
"react": "^16.10.1",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.10.1",
|
"react-dom": "^16.8.6",
|
||||||
"rimraf": "^3.0.0",
|
"rimraf": "^2.6.3",
|
||||||
"shelljs": "^0.8.3",
|
"shelljs": "^0.8.3",
|
||||||
"source-map-loader": "^0.2.4",
|
"source-map-loader": "^0.2.4",
|
||||||
"style-loader": "^1.0.0",
|
"style-loader": "^0.23.1",
|
||||||
"styled-components": "^4.4.0",
|
"styled-components": "^4.3.2",
|
||||||
"ts-jest": "24.1.0",
|
"ts-jest": "24.0.2",
|
||||||
"ts-loader": "6.2.0",
|
"ts-loader": "6.0.4",
|
||||||
"ts-node": "^8.4.1",
|
"ts-node": "^8.3.0",
|
||||||
"tslint": "^5.20.0",
|
"tslint": "^5.18.0",
|
||||||
"tslint-react": "^4.1.0",
|
"tslint-react": "^4.0.0",
|
||||||
"typescript": "^3.6.3",
|
"typescript": "^3.5.3",
|
||||||
"unfetch": "^4.1.0",
|
"unfetch": "^4.1.0",
|
||||||
"url-polyfill": "^1.1.7",
|
"url-polyfill": "^1.1.7",
|
||||||
"webpack": "^4.41.0",
|
"webpack": "^4.38.0",
|
||||||
"webpack-cli": "^3.3.9",
|
"webpack-cli": "^3.3.6",
|
||||||
"webpack-dev-server": "^3.8.1",
|
"webpack-dev-server": "^3.7.2",
|
||||||
"webpack-node-externals": "^1.6.0",
|
"webpack-node-externals": "^1.6.0",
|
||||||
"workerize-loader": "^1.1.0",
|
"workerize-loader": "^1.0.4",
|
||||||
"yaml-js": "^0.2.3"
|
"yaml-js": "^0.2.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
@ -133,29 +135,36 @@
|
||||||
"styled-components": "^4.1.1"
|
"styled-components": "^4.1.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ajv": "^6.4.0",
|
||||||
|
"ajv-errors": "^1.0.0",
|
||||||
|
"brace": "^0.11.1",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"decko": "^1.2.0",
|
"decko": "^1.2.0",
|
||||||
"dompurify": "^2.0.3",
|
"dompurify": "^1.0.11",
|
||||||
"eventemitter3": "^4.0.0",
|
"eventemitter3": "^4.0.0",
|
||||||
"json-pointer": "^0.6.0",
|
"json-pointer": "^0.6.0",
|
||||||
"json-schema-ref-parser": "^6.1.0",
|
"json-schema-ref-parser": "^6.1.0",
|
||||||
"lunr": "2.3.6",
|
"lunr": "2.3.6",
|
||||||
"mark.js": "^8.11.1",
|
"mark.js": "^8.11.1",
|
||||||
"marked": "^0.7.0",
|
"marked": "^0.7.0",
|
||||||
"memoize-one": "~5.0.5",
|
"memoize-one": "^5.0.5",
|
||||||
"mobx-react": "^6.1.3",
|
"mobx-react": "^6.1.1",
|
||||||
"openapi-sampler": "1.0.0-beta.15",
|
"openapi-sampler": "1.0.0-beta.15",
|
||||||
"perfect-scrollbar": "^1.4.0",
|
"perfect-scrollbar": "^1.4.0",
|
||||||
"polished": "^3.4.1",
|
"polished": "^3.4.1",
|
||||||
"prismjs": "^1.17.1",
|
"prismjs": "^1.17.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
|
"qs": "^6.5.2",
|
||||||
|
"react-ace": "^6.0.0",
|
||||||
"react-dropdown": "^1.6.4",
|
"react-dropdown": "^1.6.4",
|
||||||
"react-hot-loader": "^4.12.14",
|
"react-hot-loader": "^4.12.10",
|
||||||
|
"react-switch": "^5.0.1",
|
||||||
"react-tabs": "^3.0.0",
|
"react-tabs": "^3.0.0",
|
||||||
"slugify": "^1.3.5",
|
"slugify": "^1.3.4",
|
||||||
"stickyfill": "^1.1.1",
|
"stickyfill": "^1.1.1",
|
||||||
"swagger2openapi": "^5.3.1",
|
"swagger2openapi": "^5.3.1",
|
||||||
"tslib": "^1.10.0",
|
"tslib": "^1.10.0",
|
||||||
|
"uri-template-lite": "^19.4.0",
|
||||||
"url-template": "^2.0.8"
|
"url-template": "^2.0.8"
|
||||||
},
|
},
|
||||||
"bundlesize": [
|
"bundlesize": [
|
||||||
|
|
43
src/common-elements/SwitchBox.tsx
Normal file
43
src/common-elements/SwitchBox.tsx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import Switch from 'react-switch';
|
||||||
|
import {FlexLayout} from './index';
|
||||||
|
|
||||||
|
import styled from '../styled-components';
|
||||||
|
|
||||||
|
const CustomFlexLayout = styled(FlexLayout)`
|
||||||
|
align-items: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
interface LabelProps {
|
||||||
|
active: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Label = styled.label<LabelProps>`
|
||||||
|
color: ${props => props.active ? props.theme.colors.success.main : props.theme.colors.text.secondary}
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 120%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
interface TryItOutProps {
|
||||||
|
label: string;
|
||||||
|
checked: boolean;
|
||||||
|
onClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SwitchBox extends React.PureComponent<TryItOutProps> {
|
||||||
|
id = 'toggle-id-' + Date.now();
|
||||||
|
render() {
|
||||||
|
const { label, checked, onClick } = this.props;
|
||||||
|
return (
|
||||||
|
<CustomFlexLayout>
|
||||||
|
<Switch
|
||||||
|
id={this.id}
|
||||||
|
onChange={onClick}
|
||||||
|
checked={checked}
|
||||||
|
uncheckedIcon={false}
|
||||||
|
/>
|
||||||
|
<Label active={checked} htmlFor={this.id}>{label}</Label>
|
||||||
|
</CustomFlexLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
23
src/common-elements/buttons.ts
Normal file
23
src/common-elements/buttons.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import styled from '../styled-components';
|
||||||
|
|
||||||
|
export const Button = styled.button`
|
||||||
|
background: #248fb2;
|
||||||
|
border-radius: 0px;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.929em;
|
||||||
|
padding: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const SubmitButton = styled(Button)`
|
||||||
|
background: ${props => props.theme.colors.primary.main}
|
||||||
|
padding: 10px 30px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
outline: none;
|
||||||
|
margin: 1em 0;
|
||||||
|
min-width: 60px;
|
||||||
|
font-weight: bold;
|
||||||
|
order: 1;
|
||||||
|
`;
|
|
@ -9,3 +9,6 @@ export * from './mixins';
|
||||||
export * from './tabs';
|
export * from './tabs';
|
||||||
export * from './samples';
|
export * from './samples';
|
||||||
export * from './perfect-scrollbar';
|
export * from './perfect-scrollbar';
|
||||||
|
export * from './toggle';
|
||||||
|
export * from './input';
|
||||||
|
export * from './buttons';
|
||||||
|
|
8
src/common-elements/input.tsx
Normal file
8
src/common-elements/input.tsx
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import styled from '../styled-components';
|
||||||
|
|
||||||
|
export const TextField = styled.input`
|
||||||
|
padding: 0.5em;
|
||||||
|
margin: 0.5em;
|
||||||
|
border: 1px solid rgba(38,50,56,0.5);
|
||||||
|
border-radius: 3px;
|
||||||
|
`;
|
|
@ -75,3 +75,13 @@ export const Row = styled.div`
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const FlexLayout = styled.div`
|
||||||
|
align-items: flex-end;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const FlexLayoutReverse = styled(FlexLayout)`
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
`;
|
||||||
|
|
10
src/common-elements/toggle.tsx
Normal file
10
src/common-elements/toggle.tsx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import styled from '../styled-components';
|
||||||
|
|
||||||
|
export const Toggle = styled.input`
|
||||||
|
padding: 0.5em;
|
||||||
|
margin: 0.5em;
|
||||||
|
color: palevioletred;
|
||||||
|
background: papayawhip;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
`;
|
73
src/components/Console/ConsoleEditor.tsx
Normal file
73
src/components/Console/ConsoleEditor.tsx
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import AceEditor from 'react-ace';
|
||||||
|
|
||||||
|
import 'brace/mode/curly';
|
||||||
|
import 'brace/mode/json';
|
||||||
|
import 'brace/theme/github';
|
||||||
|
import 'brace/theme/monokai';
|
||||||
|
|
||||||
|
import {MediaTypeModel} from '../../services/models';
|
||||||
|
import {ConsoleEditorWrapper} from './ConsoleEditorWrapper';
|
||||||
|
|
||||||
|
export interface ConsoleEditorProps {
|
||||||
|
mediaTypes: MediaTypeModel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class ConsoleEditor extends React.Component<ConsoleEditorProps> {
|
||||||
|
|
||||||
|
editor: any;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { mediaTypes } = this.props;
|
||||||
|
|
||||||
|
if (!mediaTypes.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let sample = {};
|
||||||
|
for (const mediaType of mediaTypes) {
|
||||||
|
if (mediaType.name.indexOf('json') > -1) {
|
||||||
|
if (mediaType.examples) {
|
||||||
|
const example = getDefaultOrFirst(mediaType.examples);
|
||||||
|
sample = example && example.value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConsoleEditorWrapper>
|
||||||
|
<AceEditor
|
||||||
|
setOptions={{
|
||||||
|
enableBasicAutocompletion: true,
|
||||||
|
enableLiveAutocompletion: true,
|
||||||
|
enableSnippets: true,
|
||||||
|
showLineNumbers: true,
|
||||||
|
tabSize: 2,
|
||||||
|
}}
|
||||||
|
fontSize={15}
|
||||||
|
mode="json"
|
||||||
|
name="request-builder-editor"
|
||||||
|
editorProps={{ $blockScrolling: true }}
|
||||||
|
value={JSON.stringify(sample, null, 2)}
|
||||||
|
ref={(ace: AceEditor) => (this.editor = ace)}
|
||||||
|
/>
|
||||||
|
</ConsoleEditorWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultOrFirst(object) {
|
||||||
|
if (typeof object === 'object') {
|
||||||
|
if (typeof object.default === 'object') {
|
||||||
|
return object.default;
|
||||||
|
} else {
|
||||||
|
return object[Object.keys(object)[0]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
75
src/components/Console/ConsoleEditorWrapper.ts
Normal file
75
src/components/Console/ConsoleEditorWrapper.ts
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import {lighten} from 'polished';
|
||||||
|
import styled from '../../styled-components';
|
||||||
|
|
||||||
|
export const ConsoleEditorWrapper = styled.div`
|
||||||
|
font-family: ${props => props.theme.typography.code.fontFamily};
|
||||||
|
font-size: ${props => props.theme.typography.code.fontSize} !important;
|
||||||
|
direction: ltr;
|
||||||
|
white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')};
|
||||||
|
contain: content;
|
||||||
|
overflow-x: auto;
|
||||||
|
background: #11171a !important;
|
||||||
|
padding: 5px 0;
|
||||||
|
|
||||||
|
& .ace_editor {
|
||||||
|
background: #11171a !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_marker-layer .ace_selection {
|
||||||
|
background: ${lighten(0.05, '#11171a')} !important;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_marker-layer .ace_active-line {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_line, & .ace_editor .ace_cursor {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_marker-layer .ace_bracket {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_line .ace_fold {
|
||||||
|
background: none !important;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_line .ace_fold:hover {
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_string {
|
||||||
|
color: #71e4ff;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_variable {
|
||||||
|
color: #a0fbaa;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_indent-guide {
|
||||||
|
background: none;
|
||||||
|
color: rgba(255, 255, 255, 0.3)
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_indent-guide::after {
|
||||||
|
content: "|";
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_gutter {
|
||||||
|
background: ${lighten(0.01, '#11171a')} !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_gutter .ace_fold-widget {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_gutter .ace_fold-widget.ace_open::after {
|
||||||
|
content: "-";
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_gutter .ace_fold-widget.ace_closed::after {
|
||||||
|
content: "+";
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_gutter .ace_gutter-active-line {
|
||||||
|
background: rgba(0, 0, 0, 0.2) !important;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_gutter .ace_gutter-cell.ace_error {
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
& .ace_editor .ace_gutter .ace_gutter-cell.ace_error::before {
|
||||||
|
position: absolute;
|
||||||
|
color: red;
|
||||||
|
content: "X";
|
||||||
|
left: 0.5em;
|
||||||
|
}
|
||||||
|
`;
|
201
src/components/Console/ConsoleViewer.tsx
Normal file
201
src/components/Console/ConsoleViewer.tsx
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { SubmitButton } from '../../common-elements/buttons';
|
||||||
|
import { FlexLayoutReverse } from '../../common-elements/panels';
|
||||||
|
import { FieldModel, OperationModel } from '../../services/models';
|
||||||
|
import { OpenAPISchema } from '../../types';
|
||||||
|
import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
|
||||||
|
import { ConsoleEditor } from './ConsoleEditor';
|
||||||
|
|
||||||
|
const qs = require('qs');
|
||||||
|
|
||||||
|
export interface ConsoleViewerProps {
|
||||||
|
operation: OperationModel;
|
||||||
|
additionalHeaders?: object;
|
||||||
|
queryParamPrefix?: string;
|
||||||
|
queryParamSuffix?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConsoleViewerState {
|
||||||
|
result: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Schema {
|
||||||
|
_$ref?: any;
|
||||||
|
rawSchema?: OpenAPISchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class ConsoleViewer extends React.Component<ConsoleViewerProps, ConsoleViewerState> {
|
||||||
|
operation: OperationModel;
|
||||||
|
additionalHeaders: object;
|
||||||
|
visited = new Set();
|
||||||
|
private consoleEditor: any;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
result: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
onClickSend = async () => {
|
||||||
|
const ace = this.consoleEditor && this.consoleEditor.editor;
|
||||||
|
const { operation, additionalHeaders = {} } = this.props;
|
||||||
|
let value = ace && ace.editor.getValue();
|
||||||
|
|
||||||
|
const content = operation.requestBody && operation.requestBody.content;
|
||||||
|
const mediaType = content && content.mediaTypes[content.activeMimeIdx];
|
||||||
|
const endpoint = {
|
||||||
|
method: operation.httpVerb,
|
||||||
|
path: operation.servers[0].url + operation.path,
|
||||||
|
};
|
||||||
|
if (value) {
|
||||||
|
value = JSON.parse(value);
|
||||||
|
}
|
||||||
|
const contentType = mediaType && mediaType.name || 'application/json';
|
||||||
|
const contentTypeHeader = { 'Content-Type': contentType };
|
||||||
|
const headers = { ...additionalHeaders, ...contentTypeHeader };
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = await this.invoke(endpoint, value, headers);
|
||||||
|
this.setState({
|
||||||
|
result,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({
|
||||||
|
result: error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have a url like foo/bar/{uuid} uuid will be replaced with what user has typed in.
|
||||||
|
*/
|
||||||
|
addParamsToUrl(url: string, params: FieldModel[]) {
|
||||||
|
const queryParamPrefix = '{';
|
||||||
|
const queryParamSuffix = '}';
|
||||||
|
|
||||||
|
for (const fieldModel of params) {
|
||||||
|
console.log(fieldModel.name + ' ' + url);
|
||||||
|
console.log(fieldModel.$value);
|
||||||
|
if (url.indexOf(`${queryParamPrefix}${fieldModel.name}${queryParamSuffix}`) > -1 && fieldModel.$value.length > 0) {
|
||||||
|
url = url.replace(`${queryParamPrefix}${fieldModel.name}${queryParamSuffix}`, fieldModel.$value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.split(queryParamPrefix).length > 1) {
|
||||||
|
console.error('** we have missing query params ** ', url);
|
||||||
|
throw Error(`** we have missing query params ** ${url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async invoke(endpoint, body, headers = {}) {
|
||||||
|
try {
|
||||||
|
const { operation } = this.props;
|
||||||
|
let url = this.addParamsToUrl(endpoint.path, operation.parameters || []);
|
||||||
|
if (endpoint.method.toLocaleLowerCase() === 'get') {
|
||||||
|
url = url + '?' + qs.stringify(body || '');
|
||||||
|
}
|
||||||
|
const myHeaders = new Headers();
|
||||||
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
|
myHeaders.append(key, `${value}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const request = new Request(url, {
|
||||||
|
method: endpoint.method,
|
||||||
|
credentials: 'include',
|
||||||
|
redirect: 'manual',
|
||||||
|
headers: myHeaders,
|
||||||
|
body: (body) ? JSON.stringify(body) : undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await fetch(request);
|
||||||
|
|
||||||
|
const contentType = result.headers.get('content-type');
|
||||||
|
if (contentType && contentType.indexOf('application/json') !== -1) {
|
||||||
|
const resp = await result.json();
|
||||||
|
|
||||||
|
return { json: resp, statusCode: result.status, _fetchRes: result };
|
||||||
|
} else if (result.status === 200 && contentType && contentType.indexOf('text/plain') !== -1) {
|
||||||
|
const resp = await result.text();
|
||||||
|
return { resp, _fetchRes: result };
|
||||||
|
} else {
|
||||||
|
if (result && result.type && result.type === 'opaqueredirect') {
|
||||||
|
return {
|
||||||
|
json: {
|
||||||
|
endpoint,
|
||||||
|
error_code: 'RECEIVED_LOGIN_REDIRECT',
|
||||||
|
details: 'Your session expired. Please refresh the page.',
|
||||||
|
severity: 'error',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
json: {
|
||||||
|
endpoint,
|
||||||
|
error_code: 'INVALID_SERVER_RESPONSE',
|
||||||
|
details: 'Either server not authenticated or error on server',
|
||||||
|
severity: 'error',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { operation } = this.props;
|
||||||
|
const requestBodyContent = operation.requestBody && operation.requestBody.content && operation.requestBody.content;
|
||||||
|
const hasBodySample = requestBodyContent && requestBodyContent.hasSample;
|
||||||
|
const mediaTypes = (requestBodyContent && requestBodyContent.mediaTypes) ? requestBodyContent.mediaTypes : [];
|
||||||
|
const { result } = this.state;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3> Request </h3>
|
||||||
|
{hasBodySample && (
|
||||||
|
<ConsoleEditor
|
||||||
|
mediaTypes={mediaTypes}
|
||||||
|
ref={(editor: any) => (this.consoleEditor = editor)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<FlexLayoutReverse>
|
||||||
|
<SubmitButton onClick={this.onClickSend} >Send Request</SubmitButton>
|
||||||
|
</FlexLayoutReverse>
|
||||||
|
{result &&
|
||||||
|
<SourceCodeWithCopy lang="json" source={JSON.stringify(result, null, 2)} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSchema() {
|
||||||
|
const { operation } = this.props;
|
||||||
|
const requestBodyContent = operation.requestBody && operation.requestBody.content && operation.requestBody.content;
|
||||||
|
const mediaTypes = (requestBodyContent && requestBodyContent.mediaTypes) ? requestBodyContent.mediaTypes : [];
|
||||||
|
|
||||||
|
if (!mediaTypes.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const schema: Schema = {
|
||||||
|
};
|
||||||
|
for (const mediaType of mediaTypes) {
|
||||||
|
if (mediaType.name.indexOf('json') > -1) {
|
||||||
|
if (mediaType.schema) {
|
||||||
|
schema.rawSchema = mediaType.schema && mediaType.schema.rawSchema;
|
||||||
|
console.log('rawSchema : ' + JSON.stringify(schema));
|
||||||
|
console.log('schema : ' + JSON.stringify(mediaType.schema.schema));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return schema;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
2
src/components/Console/index.ts
Normal file
2
src/components/Console/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './ConsoleEditor';
|
||||||
|
export * from './ConsoleViewer';
|
|
@ -13,7 +13,7 @@ import {
|
||||||
WrappedShelfIcon,
|
WrappedShelfIcon,
|
||||||
} from '../../common-elements/fields-layout';
|
} from '../../common-elements/fields-layout';
|
||||||
|
|
||||||
import { ShelfIcon } from '../../common-elements/';
|
import { ShelfIcon, TextField } from '../../common-elements/';
|
||||||
|
|
||||||
import { FieldModel } from '../../services/models';
|
import { FieldModel } from '../../services/models';
|
||||||
import { Schema, SchemaOptions } from '../Schema/Schema';
|
import { Schema, SchemaOptions } from '../Schema/Schema';
|
||||||
|
@ -33,6 +33,12 @@ export class Field extends React.Component<FieldProps> {
|
||||||
toggle = () => {
|
toggle = () => {
|
||||||
this.props.field.toggle();
|
this.props.field.toggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onFieldChange = e => {
|
||||||
|
console.log('Textfield value is ' + e.target.placeholder + ' - ' + e.target.value);
|
||||||
|
this.props.field.setValue(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { className, field, isLast } = this.props;
|
const { className, field, isLast } = this.props;
|
||||||
const { name, expanded, deprecated, required, kind } = field;
|
const { name, expanded, deprecated, required, kind } = field;
|
||||||
|
@ -67,6 +73,9 @@ export class Field extends React.Component<FieldProps> {
|
||||||
<PropertyDetailsCell>
|
<PropertyDetailsCell>
|
||||||
<FieldDetails {...this.props} />
|
<FieldDetails {...this.props} />
|
||||||
</PropertyDetailsCell>
|
</PropertyDetailsCell>
|
||||||
|
{field && field.in === 'path' &&
|
||||||
|
<td><TextField placeholder={field.name} onChange={this.onFieldChange} /></td>
|
||||||
|
}
|
||||||
</tr>
|
</tr>
|
||||||
{field.expanded && withSubSchema && (
|
{field.expanded && withSubSchema && (
|
||||||
<tr key={field.name + 'inner'}>
|
<tr key={field.name + 'inner'}>
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
|
||||||
|
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
import { Badge, DarkRightPanel, H2, MiddlePanel, Row } from '../../common-elements';
|
import { Badge, DarkRightPanel, H2, MiddlePanel, Row } from '../../common-elements';
|
||||||
|
|
||||||
import { OptionsContext } from '../OptionsProvider';
|
|
||||||
|
|
||||||
import { ShareLink } from '../../common-elements/linkify';
|
import { ShareLink } from '../../common-elements/linkify';
|
||||||
import { Endpoint } from '../Endpoint/Endpoint';
|
|
||||||
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
|
|
||||||
import { Markdown } from '../Markdown/Markdown';
|
|
||||||
import { Parameters } from '../Parameters/Parameters';
|
|
||||||
import { RequestSamples } from '../RequestSamples/RequestSamples';
|
|
||||||
import { ResponsesList } from '../Responses/ResponsesList';
|
|
||||||
import { ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
|
||||||
|
|
||||||
import { OperationModel as OperationType } from '../../services/models';
|
import { OperationModel as OperationType } from '../../services/models';
|
||||||
import styled from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
|
import { ConsoleViewer } from '../Console/ConsoleViewer';
|
||||||
|
import { Endpoint } from '../Endpoint/Endpoint';
|
||||||
|
import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation';
|
||||||
import { Extensions } from '../Fields/Extensions';
|
import { Extensions } from '../Fields/Extensions';
|
||||||
|
import { Markdown } from '../Markdown/Markdown';
|
||||||
|
|
||||||
|
import {SwitchBox} from '../../common-elements/SwitchBox';
|
||||||
|
import {OptionsContext } from '../OptionsProvider';
|
||||||
|
import {Parameters } from '../Parameters/Parameters';
|
||||||
|
import {RequestSamples } from '../RequestSamples/RequestSamples';
|
||||||
|
import {ResponsesList } from '../Responses/ResponsesList';
|
||||||
|
import {ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
||||||
|
import {SecurityRequirements } from '../SecurityRequirement/SecurityRequirement';
|
||||||
|
|
||||||
const OperationRow = styled(Row)`
|
const OperationRow = styled(Row)`
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
|
@ -35,10 +36,29 @@ export interface OperationProps {
|
||||||
operation: OperationType;
|
operation: OperationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OperationState {
|
||||||
|
executeMode: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class Operation extends React.Component<OperationProps> {
|
export class Operation extends React.Component<OperationProps, OperationState> {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
executeMode: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onConsoleClick = () => {
|
||||||
|
this.setState({
|
||||||
|
executeMode: !this.state.executeMode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { operation } = this.props;
|
const { operation } = this.props;
|
||||||
|
const { executeMode } = this.state;
|
||||||
|
|
||||||
const { name: summary, description, deprecated, externalDocs } = operation;
|
const { name: summary, description, deprecated, externalDocs } = operation;
|
||||||
const hasDescription = !!(description || externalDocs);
|
const hasDescription = !!(description || externalDocs);
|
||||||
|
@ -52,6 +72,13 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
<ShareLink to={operation.id} />
|
<ShareLink to={operation.id} />
|
||||||
{summary} {deprecated && <Badge type="warning"> Deprecated </Badge>}
|
{summary} {deprecated && <Badge type="warning"> Deprecated </Badge>}
|
||||||
</H2>
|
</H2>
|
||||||
|
{options.enableConsole &&
|
||||||
|
<SwitchBox
|
||||||
|
onClick={this.onConsoleClick}
|
||||||
|
checked={this.state.executeMode}
|
||||||
|
label="Try it out!"
|
||||||
|
/>
|
||||||
|
}
|
||||||
{options.pathInMiddlePanel && <Endpoint operation={operation} inverted={true} />}
|
{options.pathInMiddlePanel && <Endpoint operation={operation} inverted={true} />}
|
||||||
{hasDescription && (
|
{hasDescription && (
|
||||||
<Description>
|
<Description>
|
||||||
|
@ -66,8 +93,17 @@ export class Operation extends React.Component<OperationProps> {
|
||||||
</MiddlePanel>
|
</MiddlePanel>
|
||||||
<DarkRightPanel>
|
<DarkRightPanel>
|
||||||
{!options.pathInMiddlePanel && <Endpoint operation={operation} />}
|
{!options.pathInMiddlePanel && <Endpoint operation={operation} />}
|
||||||
|
{executeMode &&
|
||||||
|
<div>
|
||||||
|
<ConsoleViewer operation={operation} additionalHeaders={options.additionalHeaders} queryParamPrefix={options.queryParamPrefix} queryParamSuffix={options.queryParamSuffix} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{!executeMode &&
|
||||||
<RequestSamples operation={operation} />
|
<RequestSamples operation={operation} />
|
||||||
|
}
|
||||||
|
{!executeMode &&
|
||||||
<ResponseSamples operation={operation} />
|
<ResponseSamples operation={operation} />
|
||||||
|
}
|
||||||
</DarkRightPanel>
|
</DarkRightPanel>
|
||||||
</OperationRow>
|
</OperationRow>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { TokenGroup } from '..';
|
||||||
|
|
||||||
|
import { DarkRightPanel, H2, MiddlePanel, Row, Section, ShareLink } from '../../common-elements';
|
||||||
|
|
||||||
import { SecuritySchemesModel } from '../../services/models';
|
import { SecuritySchemesModel } from '../../services/models';
|
||||||
|
|
||||||
import { H2, MiddlePanel, Row, Section, ShareLink } from '../../common-elements';
|
|
||||||
import { OpenAPISecurityScheme } from '../../types';
|
import { OpenAPISecurityScheme } from '../../types';
|
||||||
import { titleize } from '../../utils/helpers';
|
import { titleize } from '../../utils/helpers';
|
||||||
import { Markdown } from '../Markdown/Markdown';
|
import { Markdown } from '../Markdown/Markdown';
|
||||||
|
@ -18,11 +20,12 @@ const AUTH_TYPES = {
|
||||||
export interface OAuthFlowProps {
|
export interface OAuthFlowProps {
|
||||||
type: string;
|
type: string;
|
||||||
flow: OpenAPISecurityScheme['flows'][keyof OpenAPISecurityScheme['flows']];
|
flow: OpenAPISecurityScheme['flows'][keyof OpenAPISecurityScheme['flows']];
|
||||||
|
token?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OAuthFlow extends React.PureComponent<OAuthFlowProps> {
|
export class OAuthFlow extends React.PureComponent<OAuthFlowProps> {
|
||||||
render() {
|
render() {
|
||||||
const { type, flow } = this.props;
|
const { type, flow, token } = this.props;
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<th> {type} OAuth Flow </th>
|
<th> {type} OAuth Flow </th>
|
||||||
|
@ -56,6 +59,7 @@ export class OAuthFlow extends React.PureComponent<OAuthFlowProps> {
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
|
<td> {token} </td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +69,31 @@ export interface SecurityDefsProps {
|
||||||
securitySchemes: SecuritySchemesModel;
|
securitySchemes: SecuritySchemesModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SecurityDefs extends React.PureComponent<SecurityDefsProps> {
|
export interface SecurityDefsState {
|
||||||
|
tokens: Dict<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class SecurityDefs extends React.PureComponent<SecurityDefsProps, SecurityDefsState> {
|
||||||
|
|
||||||
|
state = {
|
||||||
|
tokens: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
mutateToken = (scheme, id) => {
|
||||||
|
return () => {
|
||||||
|
scheme.setToken(this.state.tokens[id]);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
setToken = id => {
|
||||||
|
return token => {
|
||||||
|
const tokens = this.state.tokens;
|
||||||
|
tokens[id] = token;
|
||||||
|
this.setState({tokens});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.props.securitySchemes.schemes.map(scheme => (
|
return this.props.securitySchemes.schemes.map(scheme => (
|
||||||
<Section id={scheme.sectionId} key={scheme.id}>
|
<Section id={scheme.sectionId} key={scheme.id}>
|
||||||
|
@ -82,22 +110,26 @@ export class SecurityDefs extends React.PureComponent<SecurityDefsProps> {
|
||||||
<tr>
|
<tr>
|
||||||
<th> Security scheme type: </th>
|
<th> Security scheme type: </th>
|
||||||
<td> {AUTH_TYPES[scheme.type] || scheme.type} </td>
|
<td> {AUTH_TYPES[scheme.type] || scheme.type} </td>
|
||||||
|
<td> Value </td>
|
||||||
</tr>
|
</tr>
|
||||||
{scheme.apiKey ? (
|
{scheme.apiKey ? (
|
||||||
<tr>
|
<tr>
|
||||||
<th> {titleize(scheme.apiKey.in || '')} parameter name:</th>
|
<th> {titleize(scheme.apiKey.in || '')} parameter name:</th>
|
||||||
<td> {scheme.apiKey.name} </td>
|
<td> {scheme.apiKey.name} </td>
|
||||||
|
<td> {scheme.token} </td>
|
||||||
</tr>
|
</tr>
|
||||||
) : scheme.http ? (
|
) : scheme.http ? (
|
||||||
[
|
[
|
||||||
<tr key="scheme">
|
<tr key="scheme">
|
||||||
<th> HTTP Authorization Scheme </th>
|
<th> HTTP Authorization Scheme </th>
|
||||||
<td> {scheme.http.scheme} </td>
|
<td> {scheme.http.scheme} </td>
|
||||||
|
<td> {scheme.token} </td>
|
||||||
</tr>,
|
</tr>,
|
||||||
scheme.http.scheme === 'bearer' && scheme.http.bearerFormat && (
|
scheme.http.scheme === 'bearer' && scheme.http.bearerFormat && (
|
||||||
<tr key="bearer">
|
<tr key="bearer">
|
||||||
<th> Bearer format </th>
|
<th> Bearer format </th>
|
||||||
<td> "{scheme.http.bearerFormat}" </td>
|
<td> "{scheme.http.bearerFormat}" </td>
|
||||||
|
<td> {scheme.token} </td>
|
||||||
</tr>
|
</tr>
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -109,16 +141,25 @@ export class SecurityDefs extends React.PureComponent<SecurityDefsProps> {
|
||||||
{scheme.openId.connectUrl}
|
{scheme.openId.connectUrl}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td> {scheme.token} </td>
|
||||||
</tr>
|
</tr>
|
||||||
) : scheme.flows ? (
|
) : scheme.flows ? (
|
||||||
Object.keys(scheme.flows).map(type => (
|
Object.keys(scheme.flows).map(type => (
|
||||||
<OAuthFlow key={type} type={type} flow={scheme.flows[type]} />
|
<OAuthFlow key={type} type={type} token={scheme.token} flow={scheme.flows[type]} />
|
||||||
))
|
))
|
||||||
) : null}
|
) : null}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</StyledMarkdownBlock>
|
</StyledMarkdownBlock>
|
||||||
</MiddlePanel>
|
</MiddlePanel>
|
||||||
|
<DarkRightPanel>
|
||||||
|
<TokenGroup
|
||||||
|
title={'Enter ' + scheme.id}
|
||||||
|
description={'You can add token here and store it to use in your request calls in this page.'}
|
||||||
|
onChange={this.setToken(scheme.sectionId)}
|
||||||
|
onSubmit={this.mutateToken(scheme, scheme.sectionId)}
|
||||||
|
/>
|
||||||
|
</DarkRightPanel>
|
||||||
</Row>
|
</Row>
|
||||||
</Section>
|
</Section>
|
||||||
));
|
));
|
||||||
|
|
84
src/components/TokenGroup/TokenGroup.tsx
Normal file
84
src/components/TokenGroup/TokenGroup.tsx
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import {Button, RightPanelHeader} from '../../common-elements';
|
||||||
|
import styled from '../../styled-components';
|
||||||
|
|
||||||
|
const SaveTokenButton = styled(Button)`
|
||||||
|
padding: 10px 30px;
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
outline: none;
|
||||||
|
margin: 0
|
||||||
|
min-width: 60px;
|
||||||
|
max-width: 100px;
|
||||||
|
font-weight: bold;
|
||||||
|
flex: 1 1;
|
||||||
|
order: 2;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TokenTextField = styled.input`
|
||||||
|
padding: 10px 30px 10px 20px;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
background-color: ${props => props.theme.codeSample.backgroundColor};
|
||||||
|
color: ${props => props.theme.codeSample.textColor}
|
||||||
|
white-space: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
border: none;
|
||||||
|
direction: ltr;
|
||||||
|
min-width: 300px;
|
||||||
|
flex: 4 1;
|
||||||
|
order: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TokenGroupContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
align-content: flex-start;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Description = styled.p`
|
||||||
|
color: white;
|
||||||
|
`;
|
||||||
|
|
||||||
|
interface TokenGroupProps {
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
onSubmit: () => void;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TokenGroup extends React.PureComponent<TokenGroupProps> {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.submit = this.submit.bind(this);
|
||||||
|
this.change = this.change.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
this.props.onSubmit();
|
||||||
|
}
|
||||||
|
|
||||||
|
change(e) {
|
||||||
|
this.props.onChange(e.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<RightPanelHeader>
|
||||||
|
{this.props.title}
|
||||||
|
</RightPanelHeader>
|
||||||
|
<TokenGroupContainer>
|
||||||
|
<TokenTextField onChange={this.change} />
|
||||||
|
<SaveTokenButton onClick={this.submit}>Save</SaveTokenButton>
|
||||||
|
</TokenGroupContainer>
|
||||||
|
<Description>
|
||||||
|
{this.props.description}
|
||||||
|
</Description>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
||||||
<Field
|
<Field
|
||||||
field={
|
field={
|
||||||
FieldModel {
|
FieldModel {
|
||||||
|
"$value": "",
|
||||||
"deprecated": false,
|
"deprecated": false,
|
||||||
"description": "",
|
"description": "",
|
||||||
"example": undefined,
|
"example": undefined,
|
||||||
|
@ -56,6 +57,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
||||||
<Field
|
<Field
|
||||||
field={
|
field={
|
||||||
FieldModel {
|
FieldModel {
|
||||||
|
"$value": "",
|
||||||
"deprecated": false,
|
"deprecated": false,
|
||||||
"description": "",
|
"description": "",
|
||||||
"example": undefined,
|
"example": undefined,
|
||||||
|
|
|
@ -30,3 +30,4 @@ export * from './StickySidebar/StickyResponsiveSidebar';
|
||||||
export * from './SearchBox/SearchBox';
|
export * from './SearchBox/SearchBox';
|
||||||
export * from './SchemaDefinition/SchemaDefinition';
|
export * from './SchemaDefinition/SchemaDefinition';
|
||||||
export * from './SourceCode/SourceCode';
|
export * from './SourceCode/SourceCode';
|
||||||
|
export * from './TokenGroup/TokenGroup';
|
||||||
|
|
|
@ -9,6 +9,8 @@ export interface RedocRawOptions {
|
||||||
theme?: ThemeInterface;
|
theme?: ThemeInterface;
|
||||||
scrollYOffset?: number | string | (() => number);
|
scrollYOffset?: number | string | (() => number);
|
||||||
hideHostname?: boolean | string;
|
hideHostname?: boolean | string;
|
||||||
|
enableConsole?: boolean;
|
||||||
|
additionalHeaders?: object;
|
||||||
expandResponses?: string | 'all';
|
expandResponses?: string | 'all';
|
||||||
requiredPropsFirst?: boolean | string;
|
requiredPropsFirst?: boolean | string;
|
||||||
sortPropsAlphabetically?: boolean | string;
|
sortPropsAlphabetically?: boolean | string;
|
||||||
|
@ -25,6 +27,11 @@ export interface RedocRawOptions {
|
||||||
menuToggle?: boolean | string;
|
menuToggle?: boolean | string;
|
||||||
jsonSampleExpandLevel?: number | string | 'all';
|
jsonSampleExpandLevel?: number | string | 'all';
|
||||||
|
|
||||||
|
providedByName?: string;
|
||||||
|
providedByUri?: string;
|
||||||
|
queryParamPrefix?: string;
|
||||||
|
queryParamSuffix?: string;
|
||||||
|
|
||||||
unstable_ignoreMimeParameters?: boolean;
|
unstable_ignoreMimeParameters?: boolean;
|
||||||
|
|
||||||
allowedMdComponents?: Dict<MDXComponentMeta>;
|
allowedMdComponents?: Dict<MDXComponentMeta>;
|
||||||
|
@ -144,6 +151,12 @@ export class RedocNormalizedOptions {
|
||||||
menuToggle: boolean;
|
menuToggle: boolean;
|
||||||
jsonSampleExpandLevel: number;
|
jsonSampleExpandLevel: number;
|
||||||
enumSkipQuotes: boolean;
|
enumSkipQuotes: boolean;
|
||||||
|
enableConsole: boolean;
|
||||||
|
additionalHeaders: object;
|
||||||
|
providedByName: string;
|
||||||
|
providedByUri: string;
|
||||||
|
queryParamPrefix: string;
|
||||||
|
queryParamSuffix: string;
|
||||||
|
|
||||||
/* tslint:disable-next-line */
|
/* tslint:disable-next-line */
|
||||||
unstable_ignoreMimeParameters: boolean;
|
unstable_ignoreMimeParameters: boolean;
|
||||||
|
@ -182,6 +195,12 @@ export class RedocNormalizedOptions {
|
||||||
raw.jsonSampleExpandLevel,
|
raw.jsonSampleExpandLevel,
|
||||||
);
|
);
|
||||||
this.enumSkipQuotes = argValueToBoolean(raw.enumSkipQuotes);
|
this.enumSkipQuotes = argValueToBoolean(raw.enumSkipQuotes);
|
||||||
|
this.enableConsole = argValueToBoolean(raw.enableConsole);
|
||||||
|
this.additionalHeaders = raw.additionalHeaders || {};
|
||||||
|
this.providedByName = raw.providedByName || 'Documentation Powered by ReDoc';
|
||||||
|
this.providedByUri = raw.providedByUri || 'https://github.com/Rebilly/ReDoc';
|
||||||
|
this.queryParamPrefix = raw.queryParamPrefix || '{';
|
||||||
|
this.queryParamSuffix = raw.queryParamSuffix || '}';
|
||||||
|
|
||||||
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
this.unstable_ignoreMimeParameters = argValueToBoolean(raw.unstable_ignoreMimeParameters);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ let worker: new () => Worker;
|
||||||
if (IS_BROWSER) {
|
if (IS_BROWSER) {
|
||||||
try {
|
try {
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
worker = require('workerize-loader?inline&fallback=false!./SearchWorker.worker');
|
worker = require('workerize-loader?fallback=false!./SearchWorker.worker');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
worker = require('./SearchWorker.worker').default;
|
worker = require('./SearchWorker.worker').default;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,8 @@ function getDefaultStyleValue(parameterLocation: OpenAPIParameterLocation): Open
|
||||||
* Field or Parameter model ready to be used by components
|
* Field or Parameter model ready to be used by components
|
||||||
*/
|
*/
|
||||||
export class FieldModel {
|
export class FieldModel {
|
||||||
@observable
|
@observable expanded: boolean = false;
|
||||||
expanded: boolean = false;
|
@observable $value: string = '';
|
||||||
|
|
||||||
schema: SchemaModel;
|
schema: SchemaModel;
|
||||||
name: string;
|
name: string;
|
||||||
required: boolean;
|
required: boolean;
|
||||||
|
@ -92,4 +91,9 @@ export class FieldModel {
|
||||||
toggle() {
|
toggle() {
|
||||||
this.expanded = !this.expanded;
|
this.expanded = !this.expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
setValue(value: string) {
|
||||||
|
this.$value = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import {observable} from 'mobx';
|
||||||
import { OpenAPISecurityScheme, Referenced } from '../../types';
|
import { OpenAPISecurityScheme, Referenced } from '../../types';
|
||||||
import { SECURITY_SCHEMES_SECTION_PREFIX } from '../../utils/openapi';
|
import { SECURITY_SCHEMES_SECTION_PREFIX } from '../../utils/openapi';
|
||||||
import { OpenAPIParser } from '../OpenAPIParser';
|
import { OpenAPIParser } from '../OpenAPIParser';
|
||||||
|
@ -22,6 +23,9 @@ export class SecuritySchemeModel {
|
||||||
connectUrl: string;
|
connectUrl: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@observable
|
||||||
|
token?: string = '';
|
||||||
|
|
||||||
constructor(parser: OpenAPIParser, id: string, scheme: Referenced<OpenAPISecurityScheme>) {
|
constructor(parser: OpenAPIParser, id: string, scheme: Referenced<OpenAPISecurityScheme>) {
|
||||||
const info = parser.deref(scheme);
|
const info = parser.deref(scheme);
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -52,9 +56,14 @@ export class SecuritySchemeModel {
|
||||||
this.flows = info.flows;
|
this.flows = info.flows;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setToken(token: string) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SecuritySchemesModel {
|
export class SecuritySchemesModel {
|
||||||
|
@observable
|
||||||
schemes: SecuritySchemeModel[];
|
schemes: SecuritySchemeModel[];
|
||||||
|
|
||||||
constructor(parser: OpenAPIParser) {
|
constructor(parser: OpenAPIParser) {
|
||||||
|
|
|
@ -149,6 +149,10 @@ const defaultTheme: ThemeInterface = {
|
||||||
},
|
},
|
||||||
codeSample: {
|
codeSample: {
|
||||||
backgroundColor: ({ rightPanel }) => darken(0.1, rightPanel.backgroundColor),
|
backgroundColor: ({ rightPanel }) => darken(0.1, rightPanel.backgroundColor),
|
||||||
|
textColor: ({ rightPanel }) => rightPanel.textColor,
|
||||||
|
},
|
||||||
|
styledPre: {
|
||||||
|
maxHeight: '500px',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -321,9 +325,13 @@ export interface ResolvedThemeInterface {
|
||||||
};
|
};
|
||||||
codeSample: {
|
codeSample: {
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
|
textColor: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
extensionsHook?: (name: string, props: any) => string;
|
extensionsHook?: (name: string, props: any) => string;
|
||||||
|
styledPre: {
|
||||||
|
maxHeight: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type primitive = string | number | boolean | undefined | null;
|
export type primitive = string | number | boolean | undefined | null;
|
||||||
|
|
1
src/utils/fetch.ts
Normal file
1
src/utils/fetch.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//parseparseFetchFetch
|
|
@ -9,11 +9,20 @@ export async function loadAndBundleSpec(specUrlOrObject: object | string): Promi
|
||||||
resolve: { http: { withCredentials: false } },
|
resolve: { http: { withCredentials: false } },
|
||||||
} as object)) as any;
|
} as object)) as any;
|
||||||
|
|
||||||
|
let v2Specs = spec;
|
||||||
if (spec.swagger !== undefined) {
|
if (spec.swagger !== undefined) {
|
||||||
return convertSwagger2OpenAPI(spec);
|
v2Specs = await convertSwagger2OpenAPI(spec);
|
||||||
} else {
|
|
||||||
return spec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we can derefrence the schema here for future use.
|
||||||
|
// import { cloneDeep } from 'lodash';
|
||||||
|
// const derefrencedSpec = await parser.dereference(cloneDeep(spec));
|
||||||
|
// const derefed = await parser.dereference(v2Specs, {
|
||||||
|
// resolve: { http: { withCredentials: false } },
|
||||||
|
// } as object);
|
||||||
|
|
||||||
|
return v2Specs;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function convertSwagger2OpenAPI(spec: any): Promise<OpenAPISpec> {
|
export function convertSwagger2OpenAPI(spec: any): Promise<OpenAPISpec> {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
"quotemark": [true, "single", "avoid-template", "jsx-double"],
|
"quotemark": [true, "single", "avoid-template", "jsx-double"],
|
||||||
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
|
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
|
||||||
"arrow-parens": [true, "ban-single-arg-parens"],
|
"arrow-parens": [true, "ban-single-arg-parens"],
|
||||||
"no-submodule-imports": [true, "prismjs", "perfect-scrollbar", "react-dom", "core-js"],
|
"no-submodule-imports": [true, "prismjs", "perfect-scrollbar", "react-dom", "core-js", "brace"],
|
||||||
"object-literal-key-quotes": [true, "as-needed"],
|
"object-literal-key-quotes": [true, "as-needed"],
|
||||||
"no-unused-expression": [true, "allow-tagged-template"],
|
"no-unused-expression": [true, "allow-tagged-template"],
|
||||||
"semicolon": [true, "always", "ignore-bound-class-methods"],
|
"semicolon": [true, "always", "ignore-bound-class-methods"],
|
||||||
|
|
Loading…
Reference in New Issue
Block a user