diff --git a/demo/openapi.yaml b/demo/openapi.yaml index b7c1833a..48a4d274 100644 --- a/demo/openapi.yaml +++ b/demo/openapi.yaml @@ -38,8 +38,6 @@ info: OAuth2 - an open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications. - - version: 1.0.0 title: Swagger Petstore termsOfService: 'http://swagger.io/terms/' diff --git a/demo/ssr/index.ts b/demo/ssr/index.ts index baac5331..142a58ef 100644 --- a/demo/ssr/index.ts +++ b/demo/ssr/index.ts @@ -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 { 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 http = require('http'); @@ -19,7 +19,7 @@ const server = http.createServer(async (request, response) => { fs.createReadStream('bundles/redoc.standalone.js', 'utf8').pipe(response); } else if (request.url === '/') { 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(); diff --git a/package.json b/package.json index fd15eb07..a0ec70b3 100644 --- a/package.json +++ b/package.json @@ -136,8 +136,6 @@ }, "dependencies": { "classnames": "^2.2.6", - "@types/chai": "4.1.3", - "@types/tapable": "1.0.2", "ajv": "^6.4.0", "ajv-errors": "^1.0.0", "brace": "^0.11.1", diff --git a/src/components/SecuritySchemes/SecuritySchemes.tsx b/src/components/SecuritySchemes/SecuritySchemes.tsx index fc5f3bc0..ebae4e44 100644 --- a/src/components/SecuritySchemes/SecuritySchemes.tsx +++ b/src/components/SecuritySchemes/SecuritySchemes.tsx @@ -1,8 +1,10 @@ +import { observer } from 'mobx-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 { H2, MiddlePanel, Row, Section, ShareLink } from '../../common-elements'; import { OpenAPISecurityScheme } from '../../types'; import { titleize } from '../../utils/helpers'; import { Markdown } from '../Markdown/Markdown'; @@ -18,11 +20,12 @@ const AUTH_TYPES = { export interface OAuthFlowProps { type: string; flow: OpenAPISecurityScheme['flows'][keyof OpenAPISecurityScheme['flows']]; + token?: string; } export class OAuthFlow extends React.PureComponent { render() { - const { type, flow } = this.props; + const { type, flow, token } = this.props; return ( {type} OAuth Flow @@ -56,6 +59,7 @@ export class OAuthFlow extends React.PureComponent { ))} + {token} ); } @@ -65,7 +69,31 @@ export interface SecurityDefsProps { securitySchemes: SecuritySchemesModel; } -export class SecurityDefs extends React.PureComponent { +export interface SecurityDefsState { + tokens: Dict; +} + +@observer +export class SecurityDefs extends React.PureComponent { + + 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() { return this.props.securitySchemes.schemes.map(scheme => (
@@ -82,22 +110,26 @@ export class SecurityDefs extends React.PureComponent { Security scheme type: {AUTH_TYPES[scheme.type] || scheme.type} + Value {scheme.apiKey ? ( {titleize(scheme.apiKey.in || '')} parameter name: {scheme.apiKey.name} + {scheme.token} ) : scheme.http ? ( [ HTTP Authorization Scheme {scheme.http.scheme} + {scheme.token} , scheme.http.scheme === 'bearer' && scheme.http.bearerFormat && ( Bearer format "{scheme.http.bearerFormat}" + {scheme.token} ), ] @@ -109,16 +141,25 @@ export class SecurityDefs extends React.PureComponent { {scheme.openId.connectUrl} + {scheme.token} ) : scheme.flows ? ( Object.keys(scheme.flows).map(type => ( - + )) ) : null} + + +
)); diff --git a/src/components/TokenGroup/TokenGroup.tsx b/src/components/TokenGroup/TokenGroup.tsx new file mode 100644 index 00000000..fd189e31 --- /dev/null +++ b/src/components/TokenGroup/TokenGroup.tsx @@ -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 { + 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 ( + <> + + {this.props.title} + + + + Save + + + {this.props.description} + + + ); + } +} diff --git a/src/components/index.ts b/src/components/index.ts index 0c7c19cb..3f88edd1 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -30,3 +30,4 @@ export * from './StickySidebar/StickyResponsiveSidebar'; export * from './SearchBox/SearchBox'; export * from './SchemaDefinition/SchemaDefinition'; export * from './SourceCode/SourceCode'; +export * from './TokenGroup/TokenGroup'; diff --git a/src/services/models/SecuritySchemes.ts b/src/services/models/SecuritySchemes.ts index fc5deda8..2fb62f92 100644 --- a/src/services/models/SecuritySchemes.ts +++ b/src/services/models/SecuritySchemes.ts @@ -1,3 +1,4 @@ +import {observable} from 'mobx'; import { OpenAPISecurityScheme, Referenced } from '../../types'; import { SECURITY_SCHEMES_SECTION_PREFIX } from '../../utils/openapi'; import { OpenAPIParser } from '../OpenAPIParser'; @@ -22,6 +23,9 @@ export class SecuritySchemeModel { connectUrl: string; }; + @observable + token?: string = ''; + constructor(parser: OpenAPIParser, id: string, scheme: Referenced) { const info = parser.deref(scheme); this.id = id; @@ -52,9 +56,14 @@ export class SecuritySchemeModel { this.flows = info.flows; } } + + setToken(token: string) { + this.token = token; + } } export class SecuritySchemesModel { + @observable schemes: SecuritySchemeModel[]; constructor(parser: OpenAPIParser) { diff --git a/src/theme.ts b/src/theme.ts index 6b20de7b..812be850 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -149,6 +149,7 @@ const defaultTheme: ThemeInterface = { }, codeSample: { backgroundColor: ({ rightPanel }) => darken(0.1, rightPanel.backgroundColor), + textColor: ({ rightPanel }) => rightPanel.textColor, }, styledPre: { maxHeight: '500px', @@ -324,6 +325,7 @@ export interface ResolvedThemeInterface { }; codeSample: { backgroundColor: string; + textColor: string; }; extensionsHook?: (name: string, props: any) => string; diff --git a/yarn.lock b/yarn.lock index ff531145..3c0db313 100644 --- a/yarn.lock +++ b/yarn.lock @@ -923,10 +923,10 @@ dependencies: "@babel/types" "^7.3.0" -"@types/chai@4.1.3": - version "4.1.3" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.3.tgz#b8a74352977a23b604c01aa784f5b793443fb7dc" - integrity sha512-f5dXGzOJycyzSMdaXVhiBhauL4dYydXwVpavfQ1mVCaGjR56a9QfklXObUxlIY9bGTmCPHEEZ04I16BZ/8w5ww== +"@types/chai@4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" + integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== "@types/cheerio@*": version "0.22.12" @@ -1132,16 +1132,11 @@ "@types/react-native" "*" csstype "^2.2.0" -"@types/tapable@*": +"@types/tapable@*", "@types/tapable@1.0.4": version "1.0.4" resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== -"@types/tapable@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd" - integrity sha512-42zEJkBpNfMEAvWR5WlwtTH22oDzcMjFsL9gDGExwF8X8WvAiw7Vwop7hPw03QT8TKfec83LwbHj6SvpqM4ELQ== - "@types/uglify-js@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082"