From 2a927eb27ce66ae920953657a5e739fba64b7c98 Mon Sep 17 00:00:00 2001 From: Arian Rahimi Date: Sun, 9 Feb 2020 18:04:30 +0330 Subject: [PATCH] feat: ConsoleViewer can send the proper request customized by user now --- demo/openapi.yaml | 20 +++---- demo/playground/hmr-playground.tsx | 4 +- src/components/Console/ConsoleViewer.tsx | 55 ++++++++----------- src/components/ContentItems/ContentItems.tsx | 32 +++++------ src/components/Operation/Operation.tsx | 13 ++++- src/components/Redoc/Redoc.tsx | 2 +- .../SecurityRequirement.tsx | 22 ++++---- 7 files changed, 68 insertions(+), 80 deletions(-) diff --git a/demo/openapi.yaml b/demo/openapi.yaml index 48a4d274..574fb379 100644 --- a/demo/openapi.yaml +++ b/demo/openapi.yaml @@ -1,8 +1,8 @@ openapi: 3.0.0 servers: - - url: //petstore.swagger.io/v2 + - url: https://petstore.swagger.io/v2 description: Default server - - url: //petstore.swagger.io/sandbox + - url: https://petstore.swagger.io/sandbox description: Sandbox server info: description: | @@ -101,7 +101,7 @@ paths: '405': description: Invalid input security: - - petstore_auth: + - authorization: - 'write:pets' - 'read:pets' x-code-samples: @@ -149,7 +149,7 @@ paths: '405': description: Validation exception security: - - petstore_auth: + - authorization: - 'write:pets' - 'read:pets' x-code-samples: @@ -217,7 +217,7 @@ paths: '405': description: Invalid input security: - - petstore_auth: + - authorization: - 'write:pets' - 'read:pets' requestBody: @@ -256,7 +256,7 @@ paths: '400': description: Invalid pet value security: - - petstore_auth: + - authorization: - 'write:pets' - 'read:pets' '/pet/{petId}/uploadImage': @@ -282,7 +282,7 @@ paths: schema: $ref: '#/components/schemas/ApiResponse' security: - - petstore_auth: + - authorization: - 'write:pets' - 'read:pets' requestBody: @@ -332,7 +332,7 @@ paths: '400': description: Invalid status value security: - - petstore_auth: + - authorization: - 'write:pets' - 'read:pets' /pet/findByTags: @@ -372,7 +372,7 @@ paths: '400': description: Invalid tag value security: - - petstore_auth: + - authorization: - 'write:pets' - 'read:pets' /store/inventory: @@ -923,7 +923,7 @@ components: description: List of user object required: true securitySchemes: - petstore_auth: + authorization: description: | Get access to data while protecting your account credentials. OAuth2 is also a safer and more secure way to give you access. diff --git a/demo/playground/hmr-playground.tsx b/demo/playground/hmr-playground.tsx index 4f06b045..4f98b0c4 100644 --- a/demo/playground/hmr-playground.tsx +++ b/demo/playground/hmr-playground.tsx @@ -25,9 +25,7 @@ const specUrl = (userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml'); let store; -const headers = { - 'x-nutanix-client': 'ui', -}; +const headers = {}; const options: RedocRawOptions = { nativeScrollbars: false, enableConsole: true, providedByName: 'Intent ApiDocs by Nutanix', providedByUri: 'http://www.nutanix.com', additionalHeaders: headers }; async function init() { diff --git a/src/components/Console/ConsoleViewer.tsx b/src/components/Console/ConsoleViewer.tsx index 0fa4822c..f21cb5c6 100644 --- a/src/components/Console/ConsoleViewer.tsx +++ b/src/components/Console/ConsoleViewer.tsx @@ -1,9 +1,9 @@ import { observer } from 'mobx-react'; import * as React from 'react'; +import { SecuritySchemeModel } from '../../../typings/services/models'; import { SubmitButton } from '../../common-elements/buttons'; import { FlexLayoutReverse } from '../../common-elements/panels'; -import { FieldModel, OperationModel } from '../../services/models'; -import { OpenAPISchema } from '../../types'; +import { FieldModel, OperationModel, SecuritySchemesModel } from '../../services/models'; import { SourceCodeWithCopy } from '../SourceCode/SourceCode'; import { ConsoleEditor } from './ConsoleEditor'; @@ -14,6 +14,7 @@ export interface ConsoleViewerProps { additionalHeaders?: object; queryParamPrefix?: string; queryParamSuffix?: string; + securitySchemes: SecuritySchemesModel; } export interface ConsoleViewerState { @@ -22,7 +23,6 @@ export interface ConsoleViewerState { export interface Schema { _$ref?: any; - rawSchema?: OpenAPISchema; } @observer @@ -40,7 +40,8 @@ export class ConsoleViewer extends React.Component { const ace = this.consoleEditor && this.consoleEditor.editor; - const { operation, additionalHeaders = {} } = this.props; + const { operation, securitySchemes: {schemes}, additionalHeaders = {} } = this.props; + let value = ace && ace.editor.getValue(); const content = operation.requestBody && operation.requestBody.content; @@ -54,7 +55,23 @@ export class ConsoleViewer extends React.Component = new Map(); + schemes.forEach(scheme => { + schemeMapper.set(scheme.id, scheme); + }); + + const securityHeaders: Dict = {}; + + operation.security.forEach(({schemes: [{ id }]}) => { + if (schemeMapper.has(id)) { + // this part of code needs a ts-ignore because typescript couldn't detect that schemeMapper.get(id) - + // has been checked to avoid token of undefined. + // @ts-ignore + securityHeaders[id] = schemeMapper.get(id).token; + } + }); + const headers = { ...additionalHeaders, ...contentTypeHeader, ...securityHeaders }; let result; try { result = await this.invoke(endpoint, value, headers); @@ -76,8 +93,6 @@ export class ConsoleViewer extends React.Component -1 && fieldModel.$value.length > 0) { url = url.replace(`${queryParamPrefix}${fieldModel.name}${queryParamSuffix}`, fieldModel.$value); } @@ -106,7 +121,6 @@ export class ConsoleViewer extends React.Component ); } - - 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; - - } } diff --git a/src/components/ContentItems/ContentItems.tsx b/src/components/ContentItems/ContentItems.tsx index 01f76eb5..5120d4c8 100644 --- a/src/components/ContentItems/ContentItems.tsx +++ b/src/components/ContentItems/ContentItems.tsx @@ -1,35 +1,40 @@ import { observer } from 'mobx-react'; import * as React from 'react'; +import { AppStore } from '../../services'; import { ExternalDocumentation } from '../ExternalDocumentation/ExternalDocumentation'; import { AdvancedMarkdown } from '../Markdown/AdvancedMarkdown'; import { H1, H2, MiddlePanel, Row, Section, ShareLink } from '../../common-elements'; import { ContentItemModel } from '../../services/MenuBuilder'; -import { GroupModel, OperationModel } from '../../services/models'; +import { GroupModel } from '../../services/models'; import { Operation } from '../Operation/Operation'; -@observer -export class ContentItems extends React.Component<{ +export interface ContentItemsProps { items: ContentItemModel[]; -}> { + store: AppStore; +} + +@observer +export class ContentItems extends React.Component { render() { - const items = this.props.items; + const { items, store } = this.props; if (items.length === 0) { return null; } - return items.map(item => ); + return items.map(item => ); } } export interface ContentItemProps { item: ContentItemModel; + store: AppStore; } @observer export class ContentItem extends React.Component { render() { - const item = this.props.item; + const { item, store } = this.props; let content; const { type } = item; switch (type) { @@ -41,7 +46,7 @@ export class ContentItem extends React.Component { content = ; break; case 'operation': - content = ; + content = ; break; default: content = ; @@ -54,7 +59,7 @@ export class ContentItem extends React.Component { {content} )} - {item.items && } + {item.items && } ); } @@ -90,12 +95,3 @@ export class SectionItem extends React.Component { ); } } - -@observer -export class OperationItem extends React.Component<{ - item: OperationModel; -}> { - render() { - return ; - } -} diff --git a/src/components/Operation/Operation.tsx b/src/components/Operation/Operation.tsx index d31b5e15..d9883c92 100644 --- a/src/components/Operation/Operation.tsx +++ b/src/components/Operation/Operation.tsx @@ -5,7 +5,7 @@ import { Badge, DarkRightPanel, H2, MiddlePanel, Row } from '../../common-elemen import { ShareLink } from '../../common-elements/linkify'; -import { OperationModel as OperationType } from '../../services/models'; +import { OperationModel as OperationType, SecuritySchemesModel } from '../../services/models'; import styled from '../../styled-components'; import { ConsoleViewer } from '../Console/ConsoleViewer'; import { Endpoint } from '../Endpoint/Endpoint'; @@ -34,6 +34,7 @@ const Description = styled.div` export interface OperationProps { operation: OperationType; + securitySchemes: SecuritySchemesModel; } export interface OperationState { @@ -57,7 +58,7 @@ export class Operation extends React.Component { } render() { - const { operation } = this.props; + const { operation, securitySchemes } = this.props; const { executeMode } = this.state; const { name: summary, description, deprecated, externalDocs } = operation; @@ -95,7 +96,13 @@ export class Operation extends React.Component { {!options.pathInMiddlePanel && } {executeMode &&
- +
} {!executeMode && diff --git a/src/components/Redoc/Redoc.tsx b/src/components/Redoc/Redoc.tsx index 2b43e77d..de665930 100644 --- a/src/components/Redoc/Redoc.tsx +++ b/src/components/Redoc/Redoc.tsx @@ -57,7 +57,7 @@ export class Redoc extends React.Component { - + diff --git a/src/components/SecurityRequirement/SecurityRequirement.tsx b/src/components/SecurityRequirement/SecurityRequirement.tsx index e6aafb30..dafb5299 100644 --- a/src/components/SecurityRequirement/SecurityRequirement.tsx +++ b/src/components/SecurityRequirement/SecurityRequirement.tsx @@ -67,18 +67,16 @@ export class SecurityRequirement extends React.PureComponent - {security.schemes.map(scheme => { - return ( - - {scheme.id} - {scheme.scopes.length > 0 && ' ('} - {scheme.scopes.map(scope => ( - {scope} - ))} - {scheme.scopes.length > 0 && ') '} - - ); - })} + {security.schemes.map(scheme => ( + + {scheme.id} + {scheme.scopes.length > 0 && ' ('} + {scheme.scopes.map(scope => ( + {scope} + ))} + {scheme.scopes.length > 0 && ') '} + + ))} ); }