mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-08 06:04:56 +03:00
Merge commit 'cfb6f0fde0d5b3bc57f8eb6c7cb90e6f39017116'
# Conflicts: # src/common-elements/panels.ts # src/components/ApiLogo/ApiLogo.tsx
This commit is contained in:
commit
ce84bafad5
12
.dockerignore
Normal file
12
.dockerignore
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
*
|
||||||
|
!src/
|
||||||
|
!config
|
||||||
|
!demo/favicon.png
|
||||||
|
|
||||||
|
!custom.d.ts
|
||||||
|
!typings/styled-patch.d.ts
|
||||||
|
!tsconfig.json
|
||||||
|
!webpack.config.ts
|
||||||
|
|
||||||
|
!package.json
|
||||||
|
!yarn.lock
|
4
.github/CONTRIBUTING.md
vendored
4
.github/CONTRIBUTING.md
vendored
|
@ -27,7 +27,7 @@ You will need [Node.js](http://nodejs.org) at `v8.0.0+` and [Yarn](https://yarnp
|
||||||
After cloning the repo, run:
|
After cloning the repo, run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ yarn install # or yarn
|
$ yarn install # or npm
|
||||||
```
|
```
|
||||||
|
|
||||||
### Commonly used NPM scripts
|
### Commonly used NPM scripts
|
||||||
|
@ -91,4 +91,4 @@ There are some other scripts available in the `scripts` section of the `package.
|
||||||
- **`src/types`**: contains extra typescript typings including OpenAPI doc typings
|
- **`src/types`**: contains extra typescript typings including OpenAPI doc typings
|
||||||
- **`src/utils`**: utility functions
|
- **`src/utils`**: utility functions
|
||||||
- **`src/styled-components.ts`**: - reexprots styled-components with proper typescript annotations using theme
|
- **`src/styled-components.ts`**: - reexprots styled-components with proper typescript annotations using theme
|
||||||
- **`src/theme.ts`**: - default theme (colors, fonts, etc) used by all the components
|
- **`src/theme.ts`**: - default theme (colors, fonts, etc) used by all the components
|
||||||
|
|
39
CHANGELOG.md
39
CHANGELOG.md
|
@ -1,3 +1,42 @@
|
||||||
|
# [2.0.0-rc.0](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.41...v2.0.0-rc.0) (2018-11-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* false-positive recursive detection with oneOf ([59eaa8d](https://github.com/Rebilly/ReDoc/commit/59eaa8d)), closes [#723](https://github.com/Rebilly/ReDoc/issues/723) [#585](https://github.com/Rebilly/ReDoc/issues/585)
|
||||||
|
* fix hideHostname also hiding basePath ([b5f3224](https://github.com/Rebilly/ReDoc/commit/b5f3224)), closes [#677](https://github.com/Rebilly/ReDoc/issues/677)
|
||||||
|
* fix spacing with nested markdown lists ([f2f6909](https://github.com/Rebilly/ReDoc/commit/f2f6909)), closes [#718](https://github.com/Rebilly/ReDoc/issues/718)
|
||||||
|
* improve scrolling performance in Chrome with non-wrapped json examples ([a69c402](https://github.com/Rebilly/ReDoc/commit/a69c402))
|
||||||
|
* nested oneOf button spacing ([3673720](https://github.com/Rebilly/ReDoc/commit/3673720)), closes [#719](https://github.com/Rebilly/ReDoc/issues/719)
|
||||||
|
* onLoaded callback not run on spec error ([e77df0c](https://github.com/Rebilly/ReDoc/commit/e77df0c)), closes [#690](https://github.com/Rebilly/ReDoc/issues/690)
|
||||||
|
* theme improvments by [@stasiukanya](https://github.com/stasiukanya) ([e2d0cd5](https://github.com/Rebilly/ReDoc/commit/e2d0cd5))
|
||||||
|
* **cli:** old peer dependency issue with styled-components ([#699](https://github.com/Rebilly/ReDoc/issues/699)) ([9e2853c](https://github.com/Rebilly/ReDoc/commit/9e2853c))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add feature to specify href for logo explicitly ([#645](https://github.com/Rebilly/ReDoc/issues/645)) ([87fd7d7](https://github.com/Rebilly/ReDoc/commit/87fd7d7))
|
||||||
|
* add support for markdown in Server Object ([155d214](https://github.com/Rebilly/ReDoc/commit/155d214))
|
||||||
|
* Add support for minLength and maxLength constraint humanization ([#700](https://github.com/Rebilly/ReDoc/issues/700)) ([f40568b](https://github.com/Rebilly/ReDoc/commit/f40568b)), closes [#42](https://github.com/Rebilly/ReDoc/issues/42) [/github.com/Rebilly/ReDoc/issues/42#issuecomment-371883853](https://github.com//github.com/Rebilly/ReDoc/issues/42/issues/issuecomment-371883853)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="2.0.0-alpha.41"></a>
|
||||||
|
# [2.0.0-alpha.41](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.40...v2.0.0-alpha.41) (2018-10-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add null check in dispose method ([#675](https://github.com/Rebilly/ReDoc/issues/675)) ([6b7c5b7](https://github.com/Rebilly/ReDoc/commit/6b7c5b7))
|
||||||
|
* extensionHook not being used ([a4a4013](https://github.com/Rebilly/ReDoc/commit/a4a4013)), closes [#665](https://github.com/Rebilly/ReDoc/issues/665)
|
||||||
|
* fix issue with broken markdown caused by marked bug ([70cf293](https://github.com/Rebilly/ReDoc/commit/70cf293))
|
||||||
|
|
||||||
|
### Peer dependencies updates
|
||||||
|
|
||||||
|
* ReDoc now requires `styled-components@^4.0.1` to be installed if used as React component
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="2.0.0-alpha.40"></a>
|
<a name="2.0.0-alpha.40"></a>
|
||||||
# [2.0.0-alpha.40](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.39...v2.0.0-alpha.40) (2018-10-05)
|
# [2.0.0-alpha.40](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.39...v2.0.0-alpha.40) (2018-10-05)
|
||||||
|
|
||||||
|
|
15
README.md
15
README.md
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
[](https://travis-ci.org/Rebilly/ReDoc) [](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [](https://david-dm.org/Rebilly/ReDoc) [](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [](https://www.npmjs.com/package/redoc) [](https://github.com/Rebilly/ReDoc/blob/master/LICENSE)
|
[](https://travis-ci.org/Rebilly/ReDoc) [](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [](https://david-dm.org/Rebilly/ReDoc) [](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [](https://www.npmjs.com/package/redoc) [](https://github.com/Rebilly/ReDoc/blob/master/LICENSE)
|
||||||
|
|
||||||
[](https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js) [](https://www.npmjs.com/package/redoc) [](https://www.jsdelivr.com/package/npm/redoc)
|
[](https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js) [](https://www.npmjs.com/package/redoc) [](https://www.jsdelivr.com/package/npm/redoc) [](https://hub.docker.com/r/redocly/redoc/)
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -184,6 +184,17 @@ You can also specify `onLoaded` callback which will be called each time Redoc ha
|
||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## The Docker way
|
||||||
|
|
||||||
|
ReDoc is available as pre-built Docker image in official [Docker Hub repository](https://hub.docker.com/r/redocly/redoc/). You may simply pull & run it:
|
||||||
|
|
||||||
|
docker pull redocly/redoc
|
||||||
|
docker run -p 8080:80 redocly/redoc
|
||||||
|
|
||||||
|
Also you may rewrite some predefined environment variables defined in [Dockerfile](./config/docker/Dockerfile). By default ReDoc starts with demo Petstore spec located at `http://petstore.swagger.io/v2/swagger.json`, but you may change this URL using environment variable `SPEC_URL`:
|
||||||
|
|
||||||
|
docker run -p 8080:80 -e SPEC_URL=https://api.example.com/openapi.json redocly/redoc
|
||||||
|
|
||||||
## ReDoc CLI
|
## ReDoc CLI
|
||||||
|
|
||||||
[See here](https://github.com/Rebilly/ReDoc/blob/master/cli/README.md)
|
[See here](https://github.com/Rebilly/ReDoc/blob/master/cli/README.md)
|
||||||
|
@ -194,7 +205,7 @@ You can also specify `onLoaded` callback which will be called each time Redoc ha
|
||||||
You can inject Security Definitions widget into any place of your specification `description`. Check out details [here](docs/security-definitions-injection.md).
|
You can inject Security Definitions widget into any place of your specification `description`. Check out details [here](docs/security-definitions-injection.md).
|
||||||
|
|
||||||
### Swagger vendor extensions
|
### Swagger vendor extensions
|
||||||
ReDoc makes use of the following [vendor extensions](http://swagger.io/specification/#vendorExtensions):
|
ReDoc makes use of the following [vendor extensions](https://swagger.io/specification/#specificationExtensions):
|
||||||
* [`x-logo`](docs/redoc-vendor-extensions.md#x-logo) - is used to specify API logo
|
* [`x-logo`](docs/redoc-vendor-extensions.md#x-logo) - is used to specify API logo
|
||||||
* [`x-traitTag`](docs/redoc-vendor-extensions.md#x-traitTag) - useful for handling out common things like Pagination, Rate-Limits, etc
|
* [`x-traitTag`](docs/redoc-vendor-extensions.md#x-traitTag) - useful for handling out common things like Pagination, Rate-Limits, etc
|
||||||
* [`x-code-samples`](docs/redoc-vendor-extensions.md#x-code-samples) - specify operation code samples
|
* [`x-code-samples`](docs/redoc-vendor-extensions.md#x-code-samples) - specify operation code samples
|
||||||
|
|
23
cli/Dockerfile
Normal file
23
cli/Dockerfile
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Package the 'redoc-cli' as a docker image.
|
||||||
|
#
|
||||||
|
# To build:
|
||||||
|
# $ cd <Redoc project directory>
|
||||||
|
# $ docker build -t redoc-cli -f cli/Dockerfile .
|
||||||
|
#
|
||||||
|
# To run:
|
||||||
|
# To display the command line options:
|
||||||
|
# $ docker run --rm -it redoc-cli --help
|
||||||
|
# .. will display the comand line help
|
||||||
|
#
|
||||||
|
# To turn `swagger.yml` file in the current directory, to html documentation 'redoc-static.html'
|
||||||
|
# $ docker run --rm -it -v $PWD:/data redoc-cli bundle swagger.yml
|
||||||
|
|
||||||
|
FROM node:alpine
|
||||||
|
|
||||||
|
RUN npm install -g redoc-cli
|
||||||
|
|
||||||
|
WORKDIR /data
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
ENTRYPOINT ["redoc-cli"]
|
||||||
|
CMD []
|
55
cli/index.ts
55
cli/index.ts
|
@ -5,15 +5,16 @@ import { renderToString } from 'react-dom/server';
|
||||||
import { ServerStyleSheet } from 'styled-components';
|
import { ServerStyleSheet } from 'styled-components';
|
||||||
|
|
||||||
import { compile } from 'handlebars';
|
import { compile } from 'handlebars';
|
||||||
import { createServer, ServerRequest, ServerResponse } from 'http';
|
import { createServer, IncomingMessage, ServerResponse } from 'http';
|
||||||
import { dirname, join } from 'path';
|
import { dirname, join, resolve } from 'path';
|
||||||
|
|
||||||
import * as zlib from 'zlib';
|
import * as zlib from 'zlib';
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { createStore, loadAndBundleSpec, Redoc } from 'redoc';
|
import { createStore, loadAndBundleSpec, Redoc } from 'redoc';
|
||||||
|
|
||||||
import { createReadStream, existsSync, readFileSync, ReadStream, watch, writeFileSync } from 'fs';
|
import {watch} from 'chokidar';
|
||||||
|
import { createReadStream, existsSync, readFileSync, ReadStream, writeFileSync } from 'fs';
|
||||||
import * as mkdirp from 'mkdirp';
|
import * as mkdirp from 'mkdirp';
|
||||||
|
|
||||||
import * as YargsParser from 'yargs';
|
import * as YargsParser from 'yargs';
|
||||||
|
@ -167,28 +168,25 @@ async function serve(port: number, pathToSpec: string, options: Options = {}) {
|
||||||
server.listen(port, () => console.log(`Server started: http://127.0.0.1:${port}`));
|
server.listen(port, () => console.log(`Server started: http://127.0.0.1:${port}`));
|
||||||
|
|
||||||
if (options.watch && existsSync(pathToSpec)) {
|
if (options.watch && existsSync(pathToSpec)) {
|
||||||
const pathToSpecDirectory = dirname(pathToSpec);
|
const pathToSpecDirectory = resolve(dirname(pathToSpec));
|
||||||
const watchOptions = {
|
const watchOptions = {
|
||||||
recursive: true,
|
ignored: /(^|[\/\\])\../,
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
const watcher = watch(pathToSpecDirectory, watchOptions);
|
||||||
pathToSpecDirectory,
|
const log = console.log.bind(console);
|
||||||
watchOptions,
|
watcher
|
||||||
debounce(async (event, filename) => {
|
.on('change', async path => {
|
||||||
if (event === 'change' || event === 'rename') {
|
log(`${path} changed, updating docs`);
|
||||||
console.log(`${join(pathToSpecDirectory, filename)} changed, updating docs`);
|
try {
|
||||||
try {
|
spec = await loadAndBundleSpec(pathToSpec);
|
||||||
spec = await loadAndBundleSpec(pathToSpec);
|
pageHTML = await getPageHTML(spec, pathToSpec, options);
|
||||||
pageHTML = await getPageHTML(spec, pathToSpec, options);
|
log('Updated successfully');
|
||||||
console.log('Updated successfully');
|
} catch (e) {
|
||||||
} catch (e) {
|
console.error('Error while updating: ', e.message);
|
||||||
console.error('Error while updating: ', e.message);
|
}})
|
||||||
}
|
.on('error', error => console.error(`Watcher error: ${error}`))
|
||||||
}
|
.on('ready', () => log(`👀 Watching ${pathToSpecDirectory} for changes...`));
|
||||||
}, 2200),
|
|
||||||
);
|
|
||||||
console.log(`👀 Watching ${pathToSpecDirectory} for changes...`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +256,7 @@ async function getPageHTML(
|
||||||
// credits: https://stackoverflow.com/a/9238214/1749888
|
// credits: https://stackoverflow.com/a/9238214/1749888
|
||||||
function respondWithGzip(
|
function respondWithGzip(
|
||||||
contents: string | ReadStream,
|
contents: string | ReadStream,
|
||||||
request: ServerRequest,
|
request: IncomingMessage,
|
||||||
response: ServerResponse,
|
response: ServerResponse,
|
||||||
headers = {},
|
headers = {},
|
||||||
) {
|
) {
|
||||||
|
@ -291,17 +289,6 @@ function respondWithGzip(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function debounce(callback: (...args) => void, time: number) {
|
|
||||||
let interval;
|
|
||||||
return (...args) => {
|
|
||||||
clearTimeout(interval);
|
|
||||||
interval = setTimeout(() => {
|
|
||||||
interval = null;
|
|
||||||
callback(...args);
|
|
||||||
}, time);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function isURL(str: string): boolean {
|
function isURL(str: string): boolean {
|
||||||
return /^(https?:)\/\//m.test(str);
|
return /^(https?:)\/\//m.test(str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "redoc-cli",
|
"name": "redoc-cli",
|
||||||
"version": "0.6.4",
|
"version": "0.7.0",
|
||||||
"description": "ReDoc's Command Line Interface",
|
"description": "ReDoc's Command Line Interface",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": "index.js",
|
"bin": "index.js",
|
||||||
|
@ -8,16 +8,17 @@
|
||||||
"author": "Roman Hotsiy <gotsijroman@gmail.com>",
|
"author": "Roman Hotsiy <gotsijroman@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"chokidar": "^2.0.4",
|
||||||
"handlebars": "^4.0.11",
|
"handlebars": "^4.0.11",
|
||||||
"isarray": "^2.0.4",
|
"isarray": "^2.0.4",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"mobx": "^4.2.0",
|
"mobx": "^4.2.0",
|
||||||
"react": "^16.4.2",
|
"react": "^16.6.3",
|
||||||
"react-dom": "^16.4.2",
|
"react-dom": "^16.6.3",
|
||||||
"redoc": "^2.0.0-alpha.37",
|
"redoc": "^2.0.0-alpha.41",
|
||||||
"styled-components": "^3.4.0",
|
"styled-components": "^4.1.1",
|
||||||
"tslib": "^1.9.3",
|
"tslib": "^1.9.3",
|
||||||
"yargs": "^12.0.1"
|
"yargs": "^12.0.5"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ci-publish": "ci-publish"
|
"ci-publish": "ci-publish"
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/chokidar": "^1.7.5",
|
||||||
"@types/handlebars": "^4.0.39",
|
"@types/handlebars": "^4.0.39",
|
||||||
"@types/mkdirp": "^0.5.2",
|
"@types/mkdirp": "^0.5.2",
|
||||||
"ci-publish": "^1.3.1"
|
"ci-publish": "^1.3.1"
|
||||||
|
|
1725
cli/yarn.lock
1725
cli/yarn.lock
File diff suppressed because it is too large
Load Diff
|
@ -9,10 +9,16 @@ FROM node:alpine
|
||||||
|
|
||||||
RUN apk update && apk add --no-cache git
|
RUN apk update && apk add --no-cache git
|
||||||
|
|
||||||
# generate bundle
|
# Install dependencies
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
COPY . /build
|
COPY package.json yarn.lock /build/
|
||||||
RUN yarn install --frozen-lockfile --ignore-optional --ignore-scripts
|
RUN yarn install --frozen-lockfile --ignore-optional --ignore-scripts
|
||||||
|
|
||||||
|
# copy only required for the build files
|
||||||
|
COPY src /build/src
|
||||||
|
COPY webpack.config.ts tsconfig.json custom.d.ts /build/
|
||||||
|
COPY typings/styled-patch.d.ts /build/typings/styled-patch.d.ts
|
||||||
|
|
||||||
RUN npm run bundle:standalone
|
RUN npm run bundle:standalone
|
||||||
|
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
|
@ -1,8 +1,4 @@
|
||||||
# Redoc docker image
|
# Official ReDoc Docker Image
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
docker build -t redoc .
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -23,4 +19,8 @@ Serve local file:
|
||||||
- `PAGE_FAVICON` (default `"favicon.png"`) - URL to page favicon
|
- `PAGE_FAVICON` (default `"favicon.png"`) - URL to page favicon
|
||||||
- `SPEC_URL` (default `"http://petstore.swagger.io/v2/swagger.json"`) - URL to spec
|
- `SPEC_URL` (default `"http://petstore.swagger.io/v2/swagger.json"`) - URL to spec
|
||||||
- `PORT` (default `80`) - nginx port
|
- `PORT` (default `80`) - nginx port
|
||||||
- `REDOC_OPTIONS` - [`<redoc>` tag attributes](https://github.com/Rebilly/ReDoc#redoc-tag-attributes)
|
- `REDOC_OPTIONS` - [`<redoc>` tag attributes](https://github.com/Rebilly/ReDoc#redoc-tag-attributes)
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
docker build -t redoc .
|
||||||
|
|
6
config/docker/hooks/build
Executable file
6
config/docker/hooks/build
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# DockerHub cd into Dockerfile location before buil
|
||||||
|
# So we have to undo this.
|
||||||
|
cd ../..
|
||||||
|
docker build -f config/docker/Dockerfile -t $IMAGE_NAME .
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<redoc spec-url="%SPEC_URL%" %REDOC_OPTIONS%></redoc>
|
<redoc spec-url="%SPEC_URL%" %REDOC_OPTIONS%></redoc>
|
||||||
<script src="/redoc.standalone.js"></script>
|
<script src="redoc.standalone.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
|
@ -4,16 +4,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styled, { StyledFunction } from 'styled-components';
|
import styled from '../src/styled-components';
|
||||||
|
|
||||||
function withProps<T, U extends HTMLElement = HTMLElement>(
|
const DropDownItem = styled.li<{ active?: boolean }>`
|
||||||
styledFunction: StyledFunction<React.HTMLProps<U>>,
|
${(props: any) => (props.active ? 'background-color: #eee' : '')};
|
||||||
): StyledFunction<T & React.HTMLProps<U>> {
|
|
||||||
return styledFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DropDownItem = withProps<{ active: boolean }>(styled.li)`
|
|
||||||
${props => ((props as any).active ? 'background-color: #eee' : '')};
|
|
||||||
padding: 13px 16px;
|
padding: 13px 16px;
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
|
|
|
@ -296,6 +296,8 @@ paths:
|
||||||
style: form
|
style: form
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: array
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 3
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
|
@ -784,6 +786,7 @@ components:
|
||||||
photoUrls:
|
photoUrls:
|
||||||
description: The list of URL to a cute photos featuring pet
|
description: The list of URL to a cute photos featuring pet
|
||||||
type: array
|
type: array
|
||||||
|
maxItems: 20
|
||||||
xml:
|
xml:
|
||||||
name: photoUrl
|
name: photoUrl
|
||||||
wrapped: true
|
wrapped: true
|
||||||
|
@ -796,6 +799,7 @@ components:
|
||||||
tags:
|
tags:
|
||||||
description: Tags attached to the pet
|
description: Tags attached to the pet
|
||||||
type: array
|
type: array
|
||||||
|
minItems: 1
|
||||||
xml:
|
xml:
|
||||||
name: tag
|
name: tag
|
||||||
wrapped: true
|
wrapped: true
|
||||||
|
|
|
@ -36,6 +36,7 @@ const babelLoader = mode => ({
|
||||||
plugins: compact([
|
plugins: compact([
|
||||||
['@babel/plugin-syntax-typescript', { isTSX: true }],
|
['@babel/plugin-syntax-typescript', { isTSX: true }],
|
||||||
['@babel/plugin-syntax-decorators', { legacy: true }],
|
['@babel/plugin-syntax-decorators', { legacy: true }],
|
||||||
|
'@babel/plugin-syntax-dynamic-import',
|
||||||
'@babel/plugin-syntax-jsx',
|
'@babel/plugin-syntax-jsx',
|
||||||
mode !== 'production' ? 'react-hot-loader/babel' : undefined,
|
mode !== 'production' ? 'react-hot-loader/babel' : undefined,
|
||||||
[
|
[
|
||||||
|
@ -96,7 +97,7 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
|
||||||
{
|
{
|
||||||
test: /\.tsx?$/,
|
test: /\.tsx?$/,
|
||||||
use: [tsLoader(env), babelLoader(mode)],
|
use: [tsLoader(env), babelLoader(mode)],
|
||||||
exclude: ['node_modules'],
|
exclude: [/node_modules/],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
|
@ -132,7 +133,11 @@ export default (env: { playground?: boolean; bench?: boolean } = {}, { mode }) =
|
||||||
new webpack.NamedModulesPlugin(),
|
new webpack.NamedModulesPlugin(),
|
||||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: env.playground ? 'demo/playground/index.html' : 'demo/index.html',
|
template: env.playground
|
||||||
|
? 'demo/playground/index.html'
|
||||||
|
: env.bench
|
||||||
|
? 'benchmark/index.html'
|
||||||
|
: 'demo/index.html',
|
||||||
}),
|
}),
|
||||||
new ForkTsCheckerWebpackPlugin(),
|
new ForkTsCheckerWebpackPlugin(),
|
||||||
ignore(/js-yaml\/dumper\.js$/),
|
ignore(/js-yaml\/dumper\.js$/),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# ReDoc vendor extensions
|
# ReDoc vendor extensions
|
||||||
ReDoc makes use of the following [vendor extensions](http://swagger.io/specification/#vendorExtensions)
|
ReDoc makes use of the following [vendor extensions](https://swagger.io/specification/#specificationExtensions)
|
||||||
|
|
||||||
### Swagger Object vendor extensions
|
### Swagger Object vendor extensions
|
||||||
Extend OpenAPI root [Swagger Object](http://swagger.io/specification/#swaggerObject)
|
Extend OpenAPI root [Swagger Object](https://swagger.io/specification/#oasObject)
|
||||||
#### x-servers
|
#### x-servers
|
||||||
Backported from OpenAPI 3.0 [`servers`](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#server-object). Currently doesn't support templates.
|
Backported from OpenAPI 3.0 [`servers`](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#server-object). Currently doesn't support templates.
|
||||||
|
|
||||||
#### x-tagGroups
|
#### x-tagGroups
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ The information about API logo
|
||||||
| url | string | The URL pointing to the spec logo. MUST be in the format of a URL. It SHOULD be an absolute URL so your API definition is usable from any location
|
| url | string | The URL pointing to the spec logo. MUST be in the format of a URL. It SHOULD be an absolute URL so your API definition is usable from any location
|
||||||
| backgroundColor | string | background color to be used. MUST be RGB color in [hexadecimal format] (https://en.wikipedia.org/wiki/Web_colors#Hex_triplet)
|
| backgroundColor | string | background color to be used. MUST be RGB color in [hexadecimal format] (https://en.wikipedia.org/wiki/Web_colors#Hex_triplet)
|
||||||
| altText | string | Text to use for alt tag on the logo. Defaults to 'logo' if nothing is provided.
|
| altText | string | Text to use for alt tag on the logo. Defaults to 'logo' if nothing is provided.
|
||||||
|
| href | string | The URL pointing to the contact page. Default to 'info.contact.url' field of the OAS.
|
||||||
|
|
||||||
|
|
||||||
###### x-logo example
|
###### x-logo example
|
||||||
|
@ -205,7 +206,7 @@ Extends OpenAPI [Parameter Object](http://swagger.io/specification/#parameterObj
|
||||||
`x-examples` are rendered in the JSON tab on the right panel of ReDoc.
|
`x-examples` are rendered in the JSON tab on the right panel of ReDoc.
|
||||||
|
|
||||||
### Response Object vendor extensions
|
### Response Object vendor extensions
|
||||||
Extends OpenAPI [Response Object](https://swagger.io/specification/#responseObject)
|
Extends OpenAPI [Response Object](https://swagger.io/specification/#requestBodyObject)
|
||||||
|
|
||||||
#### x-summary
|
#### x-summary
|
||||||
| Field Name | Type | Description |
|
| Field Name | Type | Description |
|
||||||
|
|
143
package.json
143
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "redoc",
|
"name": "redoc",
|
||||||
"version": "2.0.0-alpha.40",
|
"version": "2.0.0-rc.0",
|
||||||
"description": "ReDoc",
|
"description": "ReDoc",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -48,84 +48,87 @@
|
||||||
"compile:cli": "tsc custom.d.ts cli/index.ts --target es6 --module commonjs --types yargs",
|
"compile:cli": "tsc custom.d.ts cli/index.ts --target es6 --module commonjs --types yargs",
|
||||||
"build:demo": "webpack --mode=production --config demo/webpack.config.ts",
|
"build:demo": "webpack --mode=production --config demo/webpack.config.ts",
|
||||||
"deploy:demo": "npm run build:demo && deploy-to-gh-pages --update demo/dist",
|
"deploy:demo": "npm run build:demo && deploy-to-gh-pages --update demo/dist",
|
||||||
"license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD;BSD-2-Clause;BSD-3-Clause' --summary"
|
"license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD;BSD-2-Clause;BSD-3-Clause' --summary",
|
||||||
|
"docker:build": "docker build -f config/docker/Dockerfile -t redoc ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.0.0-rc.2",
|
"@babel/core": "7.1.6",
|
||||||
"@babel/plugin-syntax-decorators": "7.0.0-rc.2",
|
"@babel/plugin-syntax-decorators": "7.1.0",
|
||||||
"@babel/plugin-syntax-jsx": "7.0.0-rc.2",
|
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||||
"@babel/plugin-syntax-typescript": "7.0.0-rc.2",
|
"@babel/plugin-syntax-jsx": "7.0.0",
|
||||||
"@cypress/webpack-preprocessor": "2.0.1",
|
"@babel/plugin-syntax-typescript": "7.1.5",
|
||||||
"@types/chai": "4.1.4",
|
"@cypress/webpack-preprocessor": "4.0.2",
|
||||||
"@types/dompurify": "^0.0.31",
|
"@types/chai": "4.1.7",
|
||||||
"@types/enzyme": "^3.1.13",
|
"@types/dompurify": "^0.0.32",
|
||||||
|
"@types/enzyme": "^3.1.15",
|
||||||
"@types/enzyme-to-json": "^1.5.2",
|
"@types/enzyme-to-json": "^1.5.2",
|
||||||
"@types/jest": "^23.3.1",
|
"@types/jest": "^23.3.9",
|
||||||
"@types/json-pointer": "^1.0.30",
|
"@types/json-pointer": "^1.0.30",
|
||||||
"@types/lodash": "^4.14.116",
|
"@types/lodash": "^4.14.118",
|
||||||
"@types/lunr": "^2.1.6",
|
"@types/lunr": "^2.1.6",
|
||||||
"@types/mark.js": "^8.11.1",
|
"@types/mark.js": "^8.11.1",
|
||||||
"@types/marked": "^0.4.1",
|
"@types/marked": "^0.4.2",
|
||||||
"@types/prismjs": "^1.6.4",
|
"@types/prismjs": "^1.6.4",
|
||||||
"@types/prop-types": "^15.5.5",
|
"@types/prop-types": "^15.5.6",
|
||||||
"@types/react": "^16.4.11",
|
"@types/react": "^16.7.7",
|
||||||
"@types/react-dom": "^16.0.7",
|
"@types/react-dom": "^16.0.10",
|
||||||
"@types/react-hot-loader": "^4.1.0",
|
"@types/react-hot-loader": "^4.1.0",
|
||||||
"@types/react-tabs": "^1.0.5",
|
"@types/react-tabs": "^2.3.0",
|
||||||
|
"@types/styled-components": "^4.1.1",
|
||||||
"@types/tapable": "1.0.4",
|
"@types/tapable": "1.0.4",
|
||||||
"@types/webpack": "^4.4.11",
|
"@types/webpack": "^4.4.19",
|
||||||
"@types/webpack-env": "^1.13.0",
|
"@types/webpack-env": "^1.13.0",
|
||||||
"@types/yargs": "^11.1.1",
|
"@types/yargs": "^12.0.1",
|
||||||
"babel-loader": "8.0.0-beta.2",
|
"babel-loader": "8.0.4",
|
||||||
"babel-plugin-styled-components": "^1.5.1",
|
"babel-plugin-styled-components": "^1.9.0",
|
||||||
"beautify-benchmark": "^0.2.4",
|
"beautify-benchmark": "^0.2.4",
|
||||||
"bundlesize": "^0.17.0",
|
"bundlesize": "^0.17.0",
|
||||||
"conventional-changelog-cli": "^2.0.5",
|
"conventional-changelog-cli": "^2.0.11",
|
||||||
"copy-webpack-plugin": "^4.5.2",
|
"copy-webpack-plugin": "^4.6.0",
|
||||||
"core-js": "^2.5.7",
|
"core-js": "^2.5.7",
|
||||||
"coveralls": "^3.0.2",
|
"coveralls": "^3.0.2",
|
||||||
"css-loader": "^1.0.0",
|
"css-loader": "^1.0.1",
|
||||||
"cypress": "~3.1.0",
|
"cypress": "~3.1.2",
|
||||||
"deploy-to-gh-pages": "^1.3.6",
|
"deploy-to-gh-pages": "^1.3.6",
|
||||||
"enzyme": "^3.4.4",
|
"enzyme": "^3.7.0",
|
||||||
"enzyme-adapter-react-16": "^1.2.0",
|
"enzyme-adapter-react-16": "^1.7.0",
|
||||||
"enzyme-to-json": "^3.3.4",
|
"enzyme-to-json": "^3.3.4",
|
||||||
"fork-ts-checker-webpack-plugin": "0.4.3",
|
"fork-ts-checker-webpack-plugin": "0.5.0",
|
||||||
"html-webpack-plugin": "^3.1.0",
|
"html-webpack-plugin": "^3.1.0",
|
||||||
"jest": "^23.5.0",
|
"jest": "^23.6.0",
|
||||||
"license-checker": "^20.2.0",
|
"license-checker": "^24.0.1",
|
||||||
"lodash": "^4.17.10",
|
"lodash": "^4.17.11",
|
||||||
"mobx": "^4.3.1",
|
"mobx": "^4.3.1",
|
||||||
"prettier": "^1.14.2",
|
"prettier": "^1.15.2",
|
||||||
"prettier-eslint": "^8.8.2",
|
"prettier-eslint": "^8.8.2",
|
||||||
"puppeteer": "^1.7.0",
|
"puppeteer": "^1.10.0",
|
||||||
"raf": "^3.4.0",
|
"raf": "^3.4.1",
|
||||||
"react": "^16.4.2",
|
"react": "^16.6.3",
|
||||||
"react-dom": "^16.4.2",
|
"react-dom": "^16.6.3",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
"shelljs": "^0.8.1",
|
"shelljs": "^0.8.3",
|
||||||
"source-map-loader": "^0.2.4",
|
"source-map-loader": "^0.2.4",
|
||||||
"style-loader": "^0.22.1",
|
"style-loader": "^0.23.1",
|
||||||
"styled-components": "^3.4.5",
|
"styled-components": "^4.1.1",
|
||||||
"swagger2openapi": "^3.2.8",
|
"swagger2openapi": "^3.2.14",
|
||||||
"ts-jest": "23.0.1",
|
"ts-jest": "23.10.5",
|
||||||
"ts-loader": "4.5.0",
|
"ts-loader": "5.3.1",
|
||||||
"ts-node": "^7.0.1",
|
"ts-node": "^7.0.1",
|
||||||
"tslint": "^5.11.0",
|
"tslint": "^5.11.0",
|
||||||
"tslint-react": "^3.4.0",
|
"tslint-react": "^3.4.0",
|
||||||
"typescript": "^3.0.1",
|
"typescript": "^3.1.6",
|
||||||
"webpack": "^4.17.1",
|
"webpack": "^4.26.1",
|
||||||
"webpack-cli": "^3.1.0",
|
"webpack-cli": "^3.1.2",
|
||||||
"webpack-dev-server": "^3.1.5",
|
"webpack-dev-server": "^3.1.10",
|
||||||
"webpack-node-externals": "^1.6.0",
|
"webpack-node-externals": "^1.6.0",
|
||||||
"workerize-loader": "^1.0.3",
|
"workerize-loader": "^1.0.4",
|
||||||
"yaml-js": "^0.2.3"
|
"yaml-js": "^0.2.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"mobx": "^4.2.0",
|
"mobx": "^4.2.0",
|
||||||
"react": "^16.2.0",
|
"react": "^16.2.0",
|
||||||
"react-dom": "^16.2.0",
|
"react-dom": "^16.2.0",
|
||||||
"styled-components": "^3.4.0"
|
"styled-components": "^4.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
|
@ -133,10 +136,10 @@
|
||||||
"dompurify": "^1.0.7",
|
"dompurify": "^1.0.7",
|
||||||
"eventemitter3": "^3.0.0",
|
"eventemitter3": "^3.0.0",
|
||||||
"json-pointer": "^0.6.0",
|
"json-pointer": "^0.6.0",
|
||||||
"json-schema-ref-parser": "^5.1.2",
|
"json-schema-ref-parser": "^6.0.1",
|
||||||
"lunr": "^2.3.2",
|
"lunr": "^2.3.2",
|
||||||
"mark.js": "^8.11.1",
|
"mark.js": "^8.11.1",
|
||||||
"marked": "^0.5.1",
|
"marked": "^0.5.2",
|
||||||
"memoize-one": "^4.0.0",
|
"memoize-one": "^4.0.0",
|
||||||
"mobx-react": "^5.2.5",
|
"mobx-react": "^5.2.5",
|
||||||
"openapi-sampler": "1.0.0-beta.14",
|
"openapi-sampler": "1.0.0-beta.14",
|
||||||
|
@ -151,10 +154,6 @@
|
||||||
"stickyfill": "^1.1.1",
|
"stickyfill": "^1.1.1",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
|
||||||
"@types/chai": "4.0.8",
|
|
||||||
"@types/tapable": "1.0.0"
|
|
||||||
},
|
|
||||||
"bundlesize": [
|
"bundlesize": [
|
||||||
{
|
{
|
||||||
"path": "./bundles/redoc.standalone.js",
|
"path": "./bundles/redoc.standalone.js",
|
||||||
|
@ -162,30 +161,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"jest": {
|
"jest": {
|
||||||
"transform": {
|
|
||||||
"^.+\\.tsx?$": "ts-jest"
|
|
||||||
},
|
|
||||||
"setupTestFrameworkScriptFile": "<rootDir>/src/setupTests.ts",
|
"setupTestFrameworkScriptFile": "<rootDir>/src/setupTests.ts",
|
||||||
"testPathIgnorePatterns": [
|
"preset": "ts-jest",
|
||||||
"/node_modules/",
|
|
||||||
"/benchmark/"
|
|
||||||
],
|
|
||||||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
|
|
||||||
"moduleFileExtensions": [
|
|
||||||
"ts",
|
|
||||||
"tsx",
|
|
||||||
"js",
|
|
||||||
"jsx",
|
|
||||||
"json"
|
|
||||||
],
|
|
||||||
"moduleNameMapper": {
|
|
||||||
"\\.(css|less)$": "<rootDir>/src/empty.js"
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"ts-jest": {
|
|
||||||
"skipBabel": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"collectCoverageFrom": [
|
"collectCoverageFrom": [
|
||||||
"src/**/*.{ts,tsx}"
|
"src/**/*.{ts,tsx}"
|
||||||
],
|
],
|
||||||
|
@ -195,8 +172,16 @@
|
||||||
"text-summary"
|
"text-summary"
|
||||||
],
|
],
|
||||||
"coveragePathIgnorePatterns": [
|
"coveragePathIgnorePatterns": [
|
||||||
"\\.d\\.ts$"
|
"\\.d\\.ts$",
|
||||||
]
|
"/benchmark/",
|
||||||
|
"/node_modules/"
|
||||||
|
],
|
||||||
|
"modulePathIgnorePatterns": [
|
||||||
|
"/benchmark/"
|
||||||
|
],
|
||||||
|
"moduleNameMapper": {
|
||||||
|
"\\.(css|less)$": "<rootDir>/src/empty.js"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
|
|
|
@ -19,6 +19,7 @@ const Tip = styled.div`
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 0.3em 0.6em;
|
padding: 0.3em 0.6em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
box-shadow: 0px 0px 5px 0px rgba(204, 204, 204, 1);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Content = styled.div`
|
const Content = styled.div`
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import Dropdown from 'react-dropdown';
|
import Dropdown from 'react-dropdown';
|
||||||
|
|
||||||
import { StyledComponentClass } from 'styled-components';
|
import styled from '../styled-components';
|
||||||
import styled, { withProps } from '../styled-components';
|
|
||||||
|
|
||||||
export interface DropdownOption {
|
export interface DropdownOption {
|
||||||
label: string;
|
label: string;
|
||||||
|
@ -14,17 +13,17 @@ export interface DropdownProps {
|
||||||
onChange: (val: DropdownOption) => void;
|
onChange: (val: DropdownOption) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StyledDropdown = withProps<DropdownProps>(styled(Dropdown))`
|
export const StyledDropdown = styled(Dropdown)`
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: auto;
|
width: auto;
|
||||||
font-family: ${props => props.theme.typography.headings.fontFamily};
|
font-family: ${props => props.theme.typography.headings.fontFamily};
|
||||||
|
|
||||||
.Dropdown-control {
|
.Dropdown-control {
|
||||||
font-family: ${props => props.theme.typography.headings.fontFamily};
|
font-family: ${props => props.theme.typography.headings.fontFamily};
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: .929em;
|
font-size: 0.929em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
@ -39,6 +38,8 @@ export const StyledDropdown = withProps<DropdownProps>(styled(Dropdown))`
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
background: white;
|
background: white;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: ${props => props.theme.colors.primary.main};
|
border-color: ${props => props.theme.colors.primary.main};
|
||||||
color: ${props => props.theme.colors.primary.main};
|
color: ${props => props.theme.colors.primary.main};
|
||||||
|
@ -84,14 +85,14 @@ export const StyledDropdown = withProps<DropdownProps>(styled(Dropdown))`
|
||||||
padding: 0.4em;
|
padding: 0.4em;
|
||||||
|
|
||||||
&.is-selected {
|
&.is-selected {
|
||||||
background-color: rgba(0, 0, 0, 0.05)
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(38, 50, 56, 0.12)
|
background-color: rgba(38, 50, 56, 0.12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
` as StyledComponentClass<any, DropdownProps>;
|
`;
|
||||||
|
|
||||||
export const SimpleDropdown = styled(StyledDropdown)`
|
export const SimpleDropdown = styled(StyledDropdown)`
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
@ -105,7 +106,7 @@ export const SimpleDropdown = styled(StyledDropdown)`
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: ${props => props.theme.colors.main};
|
color: ${props => props.theme.colors.primary.main};
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// import { transparentize } from 'polished';
|
// import { transparentize } from 'polished';
|
||||||
|
|
||||||
import styled, { extensionsHook, withProps } from '../styled-components';
|
import styled, { extensionsHook } from '../styled-components';
|
||||||
import { deprecatedCss } from './mixins';
|
import { deprecatedCss } from './mixins';
|
||||||
|
|
||||||
export const PropertiesTableCaption = styled.caption`
|
export const PropertiesTableCaption = styled.caption`
|
||||||
|
@ -10,7 +10,7 @@ export const PropertiesTableCaption = styled.caption`
|
||||||
color: ${props => props.theme.colors.text.secondary};
|
color: ${props => props.theme.colors.text.secondary};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const PropertyCell = styled.td`
|
export const PropertyCell = styled.td<{ kind?: string }>`
|
||||||
border-left: 1px solid ${props => props.theme.schema.linesColor};
|
border-left: 1px solid ${props => props.theme.schema.linesColor};
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -58,7 +58,7 @@ export const PropertyCellWithInner = styled(PropertyCell)`
|
||||||
padding: 0;
|
padding: 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const PropertyNameCell = withProps<{ kind?: string }>(styled(PropertyCell))`
|
export const PropertyNameCell = styled(PropertyCell)`
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
|
@ -8,7 +8,7 @@ const headerFontSize = {
|
||||||
|
|
||||||
export const headerCommonMixin = level => css`
|
export const headerCommonMixin = level => css`
|
||||||
font-family: ${props => props.theme.typography.headings.fontFamily};
|
font-family: ${props => props.theme.typography.headings.fontFamily};
|
||||||
font-weight: 400;
|
font-weight: ${({ theme }) => theme.typography.headings.fontWeight};
|
||||||
font-size: ${headerFontSize[level]};
|
font-size: ${headerFontSize[level]};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SECTION_ATTR } from '../services/MenuStore';
|
import { SECTION_ATTR } from '../services/MenuStore';
|
||||||
import styled, { media, withProps } from '../styled-components';
|
import styled, { media } from '../styled-components';
|
||||||
|
|
||||||
export const MiddlePanel = styled.div`
|
export const MiddlePanel = styled.div`
|
||||||
width: calc(100% - ${props => props.theme.rightPanel.width});
|
width: calc(100% - ${props => props.theme.rightPanel.width});
|
||||||
|
@ -12,18 +12,16 @@ export const MiddlePanel = styled.div`
|
||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Section = withProps<{ underlined?: boolean }>(
|
export const Section = styled.div.attrs(props => ({
|
||||||
styled.div.attrs({
|
[SECTION_ATTR]: props.id,
|
||||||
[SECTION_ATTR]: props => props.id,
|
className: props.className ? `section ${props.className}` : 'section',
|
||||||
className: 'section',
|
})) <{ underlined?: boolean }>`
|
||||||
} as any),
|
|
||||||
)`
|
|
||||||
padding: ${props => props.theme.spacing.sectionVertical}px 0;
|
padding: ${props => props.theme.spacing.sectionVertical}px 0;
|
||||||
|
|
||||||
${media.lessThan('medium', true)`
|
${media.lessThan('medium', true)`
|
||||||
padding: 0;
|
padding: 0;
|
||||||
`}
|
`}
|
||||||
${props =>
|
${(props: any) =>
|
||||||
(props.underlined &&
|
(props.underlined &&
|
||||||
`
|
`
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -42,7 +40,7 @@ export const Section = withProps<{ underlined?: boolean }>(
|
||||||
|
|
||||||
export const RightPanel = styled.div`
|
export const RightPanel = styled.div`
|
||||||
width: ${props => props.theme.rightPanel.width};
|
width: ${props => props.theme.rightPanel.width};
|
||||||
color: #fafbfc;
|
color: ${({ theme }) => theme.rightPanel.textColor};
|
||||||
background-color: ${props => props.theme.rightPanel.backgroundColor};
|
background-color: ${props => props.theme.rightPanel.backgroundColor};
|
||||||
padding: 0 ${props => props.theme.spacing.sectionHorizontal}px;
|
padding: 0 ${props => props.theme.spacing.sectionHorizontal}px;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import PerfectScrollbarType, * as PerfectScrollbarNamespace from 'perfect-scroll
|
||||||
import psStyles from 'perfect-scrollbar/css/perfect-scrollbar.css';
|
import psStyles from 'perfect-scrollbar/css/perfect-scrollbar.css';
|
||||||
|
|
||||||
import { OptionsContext } from '../components/OptionsProvider';
|
import { OptionsContext } from '../components/OptionsProvider';
|
||||||
import styled, { injectGlobal } from '../styled-components';
|
import styled, { createGlobalStyle } from '../styled-components';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* perfect scrollbar umd bundle uses exports assignment while module uses default export
|
* perfect scrollbar umd bundle uses exports assignment while module uses default export
|
||||||
|
@ -14,7 +14,7 @@ import styled, { injectGlobal } from '../styled-components';
|
||||||
const PerfectScrollbarConstructor =
|
const PerfectScrollbarConstructor =
|
||||||
PerfectScrollbarNamespace.default || ((PerfectScrollbarNamespace as any) as PerfectScrollbarType);
|
PerfectScrollbarNamespace.default || ((PerfectScrollbarNamespace as any) as PerfectScrollbarType);
|
||||||
|
|
||||||
injectGlobal`${psStyles && psStyles.toString()}`;
|
const PSStyling = createGlobalStyle`${psStyles && psStyles.toString()}`;
|
||||||
|
|
||||||
const StyledScrollWrapper = styled.div`
|
const StyledScrollWrapper = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -58,9 +58,12 @@ export class PerfectScrollbar extends React.Component<PerfectScrollbarProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledScrollWrapper className={`scrollbar-container ${className}`} innerRef={this.handleRef}>
|
<>
|
||||||
{children}
|
<PSStyling />
|
||||||
</StyledScrollWrapper>
|
<StyledScrollWrapper className={`scrollbar-container ${className}`} ref={this.handleRef}>
|
||||||
|
{children}
|
||||||
|
</StyledScrollWrapper>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import styled, { withProps } from '../styled-components';
|
import styled from '../styled-components';
|
||||||
|
|
||||||
export const OneOfList = styled.ul`
|
export const OneOfList = styled.ul`
|
||||||
margin: 0;
|
margin: 0 0 3px 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -15,7 +15,7 @@ export const OneOfLabel = styled.span`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const OneOfButton = withProps<{ active: boolean }>(styled.li)`
|
export const OneOfButton = styled.li<{ active: boolean }>`
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as classnames from 'classnames';
|
import * as classnames from 'classnames';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styled, { withProps } from '../styled-components';
|
import styled from '../styled-components';
|
||||||
|
|
||||||
const directionMap = {
|
const directionMap = {
|
||||||
left: '90deg',
|
left: '90deg',
|
||||||
|
@ -49,7 +49,7 @@ export const ShelfIcon = styled(IntShelfIcon)`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Badge = withProps<{ type: string }>(styled.span)`
|
export const Badge = styled.span<{ type: string }>`
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import { darken } from 'polished';
|
||||||
import { Tabs as ReactTabs } from 'react-tabs';
|
import { Tabs as ReactTabs } from 'react-tabs';
|
||||||
|
|
||||||
import styled from '../styled-components';
|
import styled from '../styled-components';
|
||||||
|
|
||||||
export { Tab, TabList, TabPanel } from 'react-tabs';
|
export { Tab, TabList, TabPanel } from 'react-tabs';
|
||||||
|
@ -14,14 +16,14 @@ export const Tabs = styled(ReactTabs)`
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
background-color: ${({ theme }) => darken(0.05, theme.rightPanel.backgroundColor)};
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
outline: none;
|
outline: none;
|
||||||
color: #ccc;
|
color: ${({ theme }) => darken(theme.colors.tonalOffset, theme.rightPanel.textColor)};
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
border: 1px solid #181f22;
|
border: 1px solid ${({ theme }) => darken(0.1, theme.rightPanel.backgroundColor)};
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
|
@ -29,7 +31,7 @@ export const Tabs = styled(ReactTabs)`
|
||||||
|
|
||||||
&.react-tabs__tab--selected {
|
&.react-tabs__tab--selected {
|
||||||
color: ${props => props.theme.colors.text.primary};
|
color: ${props => props.theme.colors.text.primary};
|
||||||
background: #e2e2e2;
|
background: ${({ theme }) => theme.rightPanel.textColor};
|
||||||
}
|
}
|
||||||
|
|
||||||
&:only-child {
|
&:only-child {
|
||||||
|
@ -55,7 +57,7 @@ export const Tabs = styled(ReactTabs)`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
> .react-tabs__tab-panel {
|
> .react-tabs__tab-panel {
|
||||||
background: #171e21;
|
background: ${({ theme }) => theme.codeSample.backgroundColor};
|
||||||
& > div,
|
& > div,
|
||||||
& > pre {
|
& > pre {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
@ -74,7 +76,7 @@ export const SmallTabs = styled(Tabs)`
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
border-bottom: 1px dashed;
|
border-bottom: 1px dashed;
|
||||||
color: #787b7d;
|
color: ${({ theme }) => darken(theme.colors.tonalOffset, theme.rightPanel.textColor)};
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background: none;
|
background: none;
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ export const SmallTabs = styled(Tabs)`
|
||||||
}
|
}
|
||||||
|
|
||||||
&.react-tabs__tab--selected {
|
&.react-tabs__tab--selected {
|
||||||
color: #babcbf;
|
color: ${({ theme }) => theme.rightPanel.textColor};
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ export class ApiLogo extends React.Component<{ info: OpenAPIInfo }> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logoHref = logoInfo.href || (info.contact && info.contact.url);
|
||||||
|
|
||||||
// Use the english word logo if no alt text is provided
|
// Use the english word logo if no alt text is provided
|
||||||
const altText = logoInfo.altText ? logoInfo.altText : 'logo';
|
const altText = logoInfo.altText ? logoInfo.altText : 'logo';
|
||||||
|
|
||||||
|
@ -25,7 +27,7 @@ export class ApiLogo extends React.Component<{ info: OpenAPIInfo }> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LogoWrap className="api-logo">
|
<LogoWrap className="api-logo">
|
||||||
{info.contact && info.contact.url ? LinkWrap(info.contact.url)(logo) : logo}{' '}
|
{logoHref ? LinkWrap(logoHref)(logo) : logo}
|
||||||
</LogoWrap>
|
</LogoWrap>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { ShelfIcon } from '../../common-elements';
|
import { ShelfIcon } from '../../common-elements';
|
||||||
import { OperationModel } from '../../services';
|
import { OperationModel } from '../../services';
|
||||||
|
import { Markdown } from '../Markdown/Markdown';
|
||||||
import { OptionsContext } from '../OptionsProvider';
|
import { OptionsContext } from '../OptionsProvider';
|
||||||
import { SelectOnClick } from '../SelectOnClick/SelectOnClick';
|
import { SelectOnClick } from '../SelectOnClick/SelectOnClick';
|
||||||
|
|
||||||
|
import { getBasePath } from '../../utils';
|
||||||
import {
|
import {
|
||||||
EndpointInfo,
|
EndpointInfo,
|
||||||
HttpVerb,
|
HttpVerb,
|
||||||
|
@ -60,10 +62,14 @@ export class Endpoint extends React.Component<EndpointProps, EndpointState> {
|
||||||
<ServersOverlay expanded={expanded}>
|
<ServersOverlay expanded={expanded}>
|
||||||
{operation.servers.map(server => (
|
{operation.servers.map(server => (
|
||||||
<ServerItem key={server.url}>
|
<ServerItem key={server.url}>
|
||||||
<div>{server.description}</div>
|
<Markdown source={server.description || ''} compact={true} />
|
||||||
<SelectOnClick>
|
<SelectOnClick>
|
||||||
<ServerUrl>
|
<ServerUrl>
|
||||||
{!(hideHostname || options.hideHostname) && <span>{server.url}</span>}
|
<span>
|
||||||
|
{hideHostname || options.hideHostname
|
||||||
|
? getBasePath(server.url)
|
||||||
|
: server.url}
|
||||||
|
</span>
|
||||||
{operation.path}
|
{operation.path}
|
||||||
</ServerUrl>
|
</ServerUrl>
|
||||||
</SelectOnClick>
|
</SelectOnClick>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import styled, { withProps } from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
|
|
||||||
export const OperationEndpointWrap = styled.div`
|
export const OperationEndpointWrap = styled.div`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -14,10 +14,11 @@ export const ServerRelativeURL = styled.span`
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const EndpointInfo = withProps<{ expanded?: boolean; inverted?: boolean }>(styled.div)`
|
export const EndpointInfo = styled.div<{ expanded?: boolean; inverted?: boolean }>`
|
||||||
padding: 10px 30px 10px ${props => (props.inverted ? '10px' : '20px')};
|
padding: 10px 30px 10px ${props => (props.inverted ? '10px' : '20px')};
|
||||||
border-radius: ${props => (props.inverted ? '0' : '4px 4px 0 0')};
|
border-radius: ${props => (props.inverted ? '0' : '4px 4px 0 0')};
|
||||||
background-color: ${props => (props.inverted ? 'transparent' : '#222d32')};
|
background-color: ${props =>
|
||||||
|
props.inverted ? 'transparent' : props.theme.codeSample.backgroundColor};
|
||||||
display: flex;
|
display: flex;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -33,12 +34,12 @@ export const EndpointInfo = withProps<{ expanded?: boolean; inverted?: boolean }
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const HttpVerb = withProps<{ type: string }>(styled.span).attrs({
|
export const HttpVerb = styled.span.attrs((props: { type: string }) => ({
|
||||||
className: props => `http-verb ${props.type}`,
|
className: `http-verb ${props.type}`,
|
||||||
})`
|
}))<{ type: string }>`
|
||||||
font-size: 0.929em;
|
font-size: 0.929em;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
background-color: ${props => props.theme.colors.http[props.type] || '#999999'};
|
background-color: ${(props: any) => props.theme.colors.http[props.type] || '#999999'};
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
@ -46,7 +47,7 @@ export const HttpVerb = withProps<{ type: string }>(styled.span).attrs({
|
||||||
margin: 0;
|
margin: 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ServersOverlay = withProps<{ expanded: boolean }>(styled.div)`
|
export const ServersOverlay = styled.div<{ expanded: boolean }>`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styled, { withProps } from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
import { OpenAPIExternalDocumentation } from '../../types';
|
import { OpenAPIExternalDocumentation } from '../../types';
|
||||||
import { linksCss } from '../Markdown/styled.elements';
|
import { linksCss } from '../Markdown/styled.elements';
|
||||||
|
|
||||||
const LinkWrap = withProps<{ compact?: boolean }>(styled.div)`
|
const LinkWrap = styled.div<{ compact?: boolean }>`
|
||||||
${linksCss};
|
${linksCss};
|
||||||
${({ compact }) => (!compact ? 'margin: 1em 0' : '')}
|
${({ compact }) => (!compact ? 'margin: 1em 0' : '')}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Json extends React.PureComponent<JsonProps> {
|
||||||
<PrismDiv
|
<PrismDiv
|
||||||
className={this.props.className}
|
className={this.props.className}
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
innerRef={node => (this.node = node!)}
|
ref={node => (this.node = node!)}
|
||||||
dangerouslySetInnerHTML={{ __html: jsonToHTML(this.props.data) }}
|
dangerouslySetInnerHTML={{ __html: jsonToHTML(this.props.data) }}
|
||||||
/>
|
/>
|
||||||
</JsonViewerWrap>
|
</JsonViewerWrap>
|
||||||
|
|
|
@ -9,6 +9,7 @@ export const jsonStyles = css`
|
||||||
font-size: ${props => props.theme.typography.code.fontSize};
|
font-size: ${props => props.theme.typography.code.fontSize};
|
||||||
|
|
||||||
white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')};
|
white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')};
|
||||||
|
contain: content;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
.callback-function {
|
.callback-function {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styled, { withProps } from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
|
|
||||||
import { Spinner } from './Spinner.svg';
|
import { Spinner } from './Spinner.svg';
|
||||||
|
|
||||||
const LoadingMessage = withProps<{ color: string }>(styled.div)`
|
const LoadingMessage = styled.div<{ color: string }>`
|
||||||
font-family: helvetica, sans;
|
font-family: helvetica, sans;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { headerCommonMixin, linkifyMixin } from '../../common-elements';
|
import { headerCommonMixin, linkifyMixin } from '../../common-elements';
|
||||||
import { PrismDiv } from '../../common-elements/PrismDiv';
|
import { PrismDiv } from '../../common-elements/PrismDiv';
|
||||||
import styled, { css, extensionsHook, withProps } from '../../styled-components';
|
import styled, { css, extensionsHook, ResolvedThemeInterface } from '../../styled-components';
|
||||||
|
|
||||||
|
import { StyledComponent } from 'styled-components';
|
||||||
|
|
||||||
export const linksCss = css`
|
export const linksCss = css`
|
||||||
a {
|
a {
|
||||||
|
@ -17,9 +19,11 @@ export const linksCss = css`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const StyledMarkdownBlock = withProps<{ compact?: boolean; inline?: boolean }>(
|
export const StyledMarkdownBlock = styled(PrismDiv as StyledComponent<
|
||||||
styled(PrismDiv),
|
'div',
|
||||||
)`
|
ResolvedThemeInterface,
|
||||||
|
{ compact?: boolean; inline?: boolean }
|
||||||
|
>)`
|
||||||
|
|
||||||
font-family: ${props => props.theme.typography.fontFamily};
|
font-family: ${props => props.theme.typography.fontFamily};
|
||||||
font-weight: ${props => props.theme.typography.fontWeightRegular};
|
font-weight: ${props => props.theme.typography.fontWeightRegular};
|
||||||
|
@ -68,6 +72,7 @@ export const StyledMarkdownBlock = withProps<{ compact?: boolean; inline?: boole
|
||||||
border: 1px solid rgba(38, 50, 56, 0.1);
|
border: 1px solid rgba(38, 50, 56, 0.1);
|
||||||
padding: 0.1em 0.25em 0.2em;
|
padding: 0.1em 0.25em 0.2em;
|
||||||
font-size: ${props => props.theme.typography.code.fontSize};
|
font-size: ${props => props.theme.typography.code.fontSize};
|
||||||
|
font-weight: ${({ theme }) => theme.typography.code.fontWeight};
|
||||||
|
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
@ -113,9 +118,11 @@ export const StyledMarkdownBlock = withProps<{ compact?: boolean; inline?: boole
|
||||||
padding-left: 2em;
|
padding-left: 2em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
// > li {
|
|
||||||
// margin: 0.5em 0;
|
ul, ol {
|
||||||
// }
|
margin-bottom: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
|
@ -135,7 +142,7 @@ export const StyledMarkdownBlock = withProps<{ compact?: boolean; inline?: boole
|
||||||
border-top: 1px solid #ccc;
|
border-top: 1px solid #ccc;
|
||||||
|
|
||||||
&:nth-child(2n) {
|
&:nth-child(2n) {
|
||||||
background-color: #f8f8f8;
|
background-color: ${({ theme }) => theme.schema.nestedBackground};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ export class MediaTypeSamples extends React.Component<PayloadSamplesProps> {
|
||||||
}
|
}
|
||||||
if (examplesNames.length > 1) {
|
if (examplesNames.length > 1) {
|
||||||
return (
|
return (
|
||||||
<SmallTabs>
|
<SmallTabs defaultIndex={0}>
|
||||||
<TabList>
|
<TabList>
|
||||||
{examplesNames.map(name => (
|
{examplesNames.map(name => (
|
||||||
<Tab key={name}> {examples[name].summary || name} </Tab>
|
<Tab key={name}> {examples[name].summary || name} </Tab>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// @ts-ignore
|
||||||
|
import Dropdown from 'react-dropdown';
|
||||||
import styled from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
|
|
||||||
import { StyledDropdown } from '../../common-elements';
|
import { StyledDropdown } from '../../common-elements';
|
||||||
|
@ -13,7 +15,7 @@ export const InvertedSimpleDropdown = styled(StyledDropdown)`
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
font-size: 0.929em;
|
font-size: 0.929em;
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.9);
|
border-bottom: 1px solid ${({ theme }) => theme.rightPanel.textColor};
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
|
@ -23,11 +25,11 @@ export const InvertedSimpleDropdown = styled(StyledDropdown)`
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0 1.2em 0 0;
|
padding: 0 1.2em 0 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: ${({ theme }) => theme.rightPanel.textColor};
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
||||||
.Dropdown-arrow {
|
.Dropdown-arrow {
|
||||||
border-top-color: rgba(255, 255, 255, 0.9);
|
border-top-color: ${({ theme }) => theme.rightPanel.textColor};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.Dropdown-menu {
|
.Dropdown-menu {
|
||||||
|
|
|
@ -43,7 +43,14 @@ export const BackgroundStub = styled.div`
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: calc((100% - ${({ theme }) => theme.menu.width}) * 0.4);
|
width: ${({ theme }) => {
|
||||||
|
if (theme.rightPanel.width.endsWith('%')) {
|
||||||
|
const percents = parseInt(theme.rightPanel.width, 10);
|
||||||
|
return `calc((100% - ${theme.menu.width}) * ${percents / 100})`;
|
||||||
|
} else {
|
||||||
|
return theme.rightPanel.width;
|
||||||
|
}
|
||||||
|
}};
|
||||||
${media.lessThan('medium', true)`
|
${media.lessThan('medium', true)`
|
||||||
display: none;
|
display: none;
|
||||||
`};
|
`};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { darken } from 'polished';
|
||||||
import styled from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
import { MenuItemLabel } from '../SideMenu/styled.elements';
|
import { MenuItemLabel } from '../SideMenu/styled.elements';
|
||||||
|
|
||||||
|
@ -7,19 +8,20 @@ export const SearchWrap = styled.div`
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SearchInput = styled.input.attrs({
|
export const SearchInput = styled.input.attrs(() => ({
|
||||||
className: 'search-input',
|
className: 'search-input',
|
||||||
})`
|
}))`
|
||||||
width: calc(100% - ${props => props.theme.spacing.unit * 8}px);
|
width: calc(100% - ${props => props.theme.spacing.unit * 8}px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0 ${props => props.theme.spacing.unit * 4}px;
|
margin: 0 ${props => props.theme.spacing.unit * 4}px;
|
||||||
padding: 5px ${props => props.theme.spacing.unit * 2}px 5px
|
padding: 5px ${props => props.theme.spacing.unit * 2}px 5px
|
||||||
${props => props.theme.spacing.unit * 4}px;
|
${props => props.theme.spacing.unit * 4}px;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-bottom: 1px solid #e1e1e1;
|
border-bottom: 1px solid ${({ theme }) => darken(0.1, theme.menu.backgroundColor)};
|
||||||
|
font-family: ${({ theme }) => theme.typography.fontFamily};
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: ${props => props.theme.colors.text};
|
color: ${props => props.theme.menu.textColor};
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
outline: none;
|
outline: none;
|
||||||
`;
|
`;
|
||||||
|
@ -44,7 +46,7 @@ export const SearchIcon = styled((props: { className?: string }) => (
|
||||||
width: 0.9em;
|
width: 0.9em;
|
||||||
|
|
||||||
path {
|
path {
|
||||||
fill: ${props => props.theme.colors.text};
|
fill: ${props => props.theme.menu.textColor};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ export class MenuItem extends React.Component<MenuItemProps> {
|
||||||
<MenuItemLi
|
<MenuItemLi
|
||||||
onClick={this.activate}
|
onClick={this.activate}
|
||||||
depth={item.depth}
|
depth={item.depth}
|
||||||
innerRef={this.saveRef}
|
ref={this.saveRef}
|
||||||
data-item-id={item.id}
|
data-item-id={item.id}
|
||||||
>
|
>
|
||||||
{item.type === 'operation' ? (
|
{item.type === 'operation' ? (
|
||||||
|
@ -80,20 +80,14 @@ export class MenuItem extends React.Component<MenuItemProps> {
|
||||||
|
|
||||||
export interface OperationMenuItemContentProps {
|
export interface OperationMenuItemContentProps {
|
||||||
item: OperationModel;
|
item: OperationModel;
|
||||||
className?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class OperationMenuItemContent extends React.Component<OperationMenuItemContentProps> {
|
class OperationMenuItemContent extends React.Component<OperationMenuItemContentProps> {
|
||||||
render() {
|
render() {
|
||||||
const { item, className } = this.props;
|
const { item } = this.props;
|
||||||
return (
|
return (
|
||||||
<MenuItemLabel
|
<MenuItemLabel depth={item.depth} active={item.active} deprecated={item.deprecated}>
|
||||||
className={className}
|
|
||||||
depth={item.depth}
|
|
||||||
active={item.active}
|
|
||||||
deprecated={item.deprecated}
|
|
||||||
>
|
|
||||||
<OperationBadge type={item.httpVerb}>{shortenHTTPVerb(item.httpVerb)}</OperationBadge>
|
<OperationBadge type={item.httpVerb}>{shortenHTTPVerb(item.httpVerb)}</OperationBadge>
|
||||||
<MenuItemTitle width="calc(100% - 38px)">
|
<MenuItemTitle width="calc(100% - 38px)">
|
||||||
{item.name}
|
{item.name}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import * as classnames from 'classnames';
|
import * as classnames from 'classnames';
|
||||||
|
import { darken } from 'polished';
|
||||||
|
|
||||||
import { deprecatedCss, ShelfIcon } from '../../common-elements';
|
import { deprecatedCss, ShelfIcon } from '../../common-elements';
|
||||||
import styled, { css, withProps } from '../../styled-components';
|
import styled, { css } from '../../styled-components';
|
||||||
|
|
||||||
export const OperationBadge = withProps<{ type: string }>(styled.span).attrs({
|
export const OperationBadge = styled.span.attrs((props: { type: string }) => ({
|
||||||
className: props => `operation-type ${props.type}`,
|
className: `operation-type ${props.type}`,
|
||||||
})`
|
}))<{ type: string }>`
|
||||||
width: 32px;
|
width: 32px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: ${props => props.theme.typography.code.fontSize};
|
height: ${props => props.theme.typography.code.fontSize};
|
||||||
|
@ -57,21 +58,21 @@ export const OperationBadge = withProps<{ type: string }>(styled.span).attrs({
|
||||||
}
|
}
|
||||||
|
|
||||||
&.head {
|
&.head {
|
||||||
background-color: ${props => props.theme.colors.http.head};
|
background-color: ${props => props.theme.colors.http.head};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function menuItemActiveBg(depth): string {
|
function menuItemActiveBg(depth, { theme }): string {
|
||||||
if (depth > 1) {
|
if (depth > 1) {
|
||||||
return '#e1e1e1';
|
return darken(0.1, theme.menu.backgroundColor);
|
||||||
} else if (depth === 1) {
|
} else if (depth === 1) {
|
||||||
return '#f0f0f0';
|
return darken(0.05, theme.menu.backgroundColor);
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MenuItemUl = withProps<{ expanded: boolean }>(styled.ul)`
|
export const MenuItemUl = styled.ul<{ expanded: boolean }>`
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ export const MenuItemUl = withProps<{ expanded: boolean }>(styled.ul)`
|
||||||
${props => (props.expanded ? '' : 'display: none;')};
|
${props => (props.expanded ? '' : 'display: none;')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const MenuItemLi = withProps<{ depth: number }>(styled.li)`
|
export const MenuItemLi = styled.li<{ depth: number }>`
|
||||||
list-style: none inside none;
|
list-style: none inside none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -97,7 +98,7 @@ export const menuItemDepth = {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
color: ${props => props.theme.colors.text.primary};
|
color: ${props => props.theme.menu.textColor};
|
||||||
`,
|
`,
|
||||||
1: css`
|
1: css`
|
||||||
font-size: 0.929em;
|
font-size: 0.929em;
|
||||||
|
@ -107,27 +108,25 @@ export const menuItemDepth = {
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
2: css`
|
2: css`
|
||||||
color: ${props => props.theme.colors.text.primary};
|
color: ${props => props.theme.menu.textColor};
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MenuItemLabel = withProps<{
|
export interface MenuItemLabelType {
|
||||||
depth: number;
|
depth: number;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
deprecated?: boolean;
|
deprecated?: boolean;
|
||||||
type?: string;
|
type?: string;
|
||||||
}>(
|
}
|
||||||
styled.label.attrs({
|
|
||||||
role: 'menuitem',
|
export const MenuItemLabel = styled.label.attrs((props: MenuItemLabelType) => ({
|
||||||
className: props =>
|
role: 'menuitem',
|
||||||
classnames('-depth' + props.depth, {
|
className: classnames('-depth' + props.depth, {
|
||||||
active: props.active,
|
active: props.active,
|
||||||
}),
|
|
||||||
}),
|
}),
|
||||||
)`
|
}))<MenuItemLabelType>`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: ${props =>
|
color: ${props => (props.active ? props.theme.colors.primary.main : props.theme.menu.textColor)};
|
||||||
props.active ? props.theme.colors.primary.main : props.theme.colors.text.primary};
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 12.5px ${props => props.theme.spacing.unit * 4}px;
|
padding: 12.5px ${props => props.theme.spacing.unit * 4}px;
|
||||||
${({ depth, type, theme }) =>
|
${({ depth, type, theme }) =>
|
||||||
|
@ -136,12 +135,12 @@ export const MenuItemLabel = withProps<{
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-family: ${props => props.theme.typography.headings.fontFamily};
|
font-family: ${props => props.theme.typography.headings.fontFamily};
|
||||||
${props => menuItemDepth[props.depth]};
|
${props => menuItemDepth[props.depth]};
|
||||||
background-color: ${props => (props.active ? menuItemActiveBg(props.depth) : '')};
|
background-color: ${props => (props.active ? menuItemActiveBg(props.depth, props) : '')};
|
||||||
|
|
||||||
${props => (props.deprecated && deprecatedCss) || ''};
|
${props => (props.deprecated && deprecatedCss) || ''};
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: ${props => menuItemActiveBg(props.depth)};
|
background-color: ${props => menuItemActiveBg(props.depth, props)};
|
||||||
}
|
}
|
||||||
|
|
||||||
${ShelfIcon} {
|
${ShelfIcon} {
|
||||||
|
@ -153,7 +152,7 @@ export const MenuItemLabel = withProps<{
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const MenuItemTitle = withProps<{ width?: string }>(styled.span)`
|
export const MenuItemTitle = styled.span<{ width?: string }>`
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
width: ${props => (props.width ? props.width : 'auto')};
|
width: ${props => (props.width ? props.width : 'auto')};
|
||||||
|
@ -173,8 +172,8 @@ export const RedocAttribution = styled.div`
|
||||||
a,
|
a,
|
||||||
a:visited,
|
a:visited,
|
||||||
a:hover {
|
a:hover {
|
||||||
color: ${theme.colors.text.primary} !important;
|
color: ${theme.menu.textColor} !important;
|
||||||
border-top: 1px solid #e1e1e1;
|
border-top: 1px solid ${darken(0.1, theme.menu.backgroundColor)};
|
||||||
padding: ${theme.spacing.unit}px 0;
|
padding: ${theme.spacing.unit}px 0;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as React from 'react';
|
||||||
|
|
||||||
import { MenuStore } from '../../services/MenuStore';
|
import { MenuStore } from '../../services/MenuStore';
|
||||||
import { RedocNormalizedOptions, RedocRawOptions } from '../../services/RedocNormalizedOptions';
|
import { RedocNormalizedOptions, RedocRawOptions } from '../../services/RedocNormalizedOptions';
|
||||||
import styled, { media, withProps } from '../../styled-components';
|
import styled, { media } from '../../styled-components';
|
||||||
import { IS_BROWSER } from '../../utils/index';
|
import { IS_BROWSER } from '../../utils/index';
|
||||||
import { OptionsContext } from '../OptionsProvider';
|
import { OptionsContext } from '../OptionsProvider';
|
||||||
import { AnimatedChevronButton } from './ChevronSvg';
|
import { AnimatedChevronButton } from './ChevronSvg';
|
||||||
|
@ -21,7 +21,7 @@ export interface StickySidebarProps {
|
||||||
|
|
||||||
const stickyfill = Stickyfill && Stickyfill();
|
const stickyfill = Stickyfill && Stickyfill();
|
||||||
|
|
||||||
const StyledStickySidebar = withProps<{ open?: boolean }>(styled.div)`
|
const StyledStickySidebar = styled.div<{ open?: boolean }>`
|
||||||
width: ${props => props.theme.menu.width};
|
width: ${props => props.theme.menu.width};
|
||||||
background-color: ${props => props.theme.menu.backgroundColor};
|
background-color: ${props => props.theme.menu.backgroundColor};
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -122,7 +122,7 @@ export class StickyResponsiveSidebar extends React.Component<StickySidebarProps>
|
||||||
className={this.props.className}
|
className={this.props.className}
|
||||||
style={style(options)}
|
style={style(options)}
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
innerRef={el => {
|
ref={el => {
|
||||||
this.stickyElement = el as any;
|
this.stickyElement = el as any;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -52,7 +52,14 @@ export class StoreBuilder extends Component<StoreBuilderProps, StoreBuilderState
|
||||||
if (!spec) {
|
if (!spec) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return new AppStore(spec, specUrl, options);
|
try {
|
||||||
|
return new AppStore(spec, specUrl, options);
|
||||||
|
} catch (e) {
|
||||||
|
if (this.props.onLoaded) {
|
||||||
|
this.props.onLoaded(e);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -4,7 +4,9 @@ import defaultTheme from '../theme';
|
||||||
|
|
||||||
export default class TestThemeProvider extends React.Component {
|
export default class TestThemeProvider extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return <ThemeProvider theme={defaultTheme}>{this.props.children}</ThemeProvider>;
|
return (
|
||||||
|
<ThemeProvider theme={defaultTheme}>{React.Children.only(this.props.children)}</ThemeProvider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { observe } from 'mobx';
|
import { Lambda, observe } from 'mobx';
|
||||||
|
|
||||||
import { OpenAPISpec } from '../types';
|
import { OpenAPISpec } from '../types';
|
||||||
import { loadAndBundleSpec } from '../utils/loadAndBundleSpec';
|
import { loadAndBundleSpec } from '../utils/loadAndBundleSpec';
|
||||||
|
@ -58,7 +58,7 @@ export class AppStore {
|
||||||
marker = new MarkerService();
|
marker = new MarkerService();
|
||||||
|
|
||||||
private scroll: ScrollService;
|
private scroll: ScrollService;
|
||||||
private disposer;
|
private disposer: Lambda | null = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
spec: OpenAPISpec,
|
spec: OpenAPISpec,
|
||||||
|
@ -96,7 +96,9 @@ export class AppStore {
|
||||||
dispose() {
|
dispose() {
|
||||||
this.scroll.dispose();
|
this.scroll.dispose();
|
||||||
this.menu.dispose();
|
this.menu.dispose();
|
||||||
this.disposer();
|
if (this.disposer != null) {
|
||||||
|
this.disposer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -291,6 +291,12 @@ export class OpenAPIParser {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exitParents(shema: MergedOpenAPISchema) {
|
||||||
|
for (const parent$ref of shema.parentRefs || []) {
|
||||||
|
this.exitRef({ $ref: parent$ref });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private hoistOneOfs(schema: OpenAPISchema) {
|
private hoistOneOfs(schema: OpenAPISchema) {
|
||||||
if (schema.allOf === undefined) {
|
if (schema.allOf === undefined) {
|
||||||
return schema;
|
return schema;
|
||||||
|
@ -304,9 +310,14 @@ export class OpenAPIParser {
|
||||||
const afterAllOf = allOf.slice(i + 1);
|
const afterAllOf = allOf.slice(i + 1);
|
||||||
return {
|
return {
|
||||||
oneOf: sub.oneOf.map(part => {
|
oneOf: sub.oneOf.map(part => {
|
||||||
return this.mergeAllOf({
|
const merged = this.mergeAllOf({
|
||||||
allOf: [...beforeAllOf, part, ...afterAllOf],
|
allOf: [...beforeAllOf, part, ...afterAllOf],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// each oneOf should be independent so exiting all the parent refs
|
||||||
|
// otherwise it will cause false-positive recursive detection
|
||||||
|
this.exitParents(merged);
|
||||||
|
return merged;
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,14 +126,13 @@ export class RedocNormalizedOptions {
|
||||||
allowedMdComponents: Dict<MDXComponentMeta>;
|
allowedMdComponents: Dict<MDXComponentMeta>;
|
||||||
|
|
||||||
constructor(raw: RedocRawOptions, defaults: RedocRawOptions = {}) {
|
constructor(raw: RedocRawOptions, defaults: RedocRawOptions = {}) {
|
||||||
let hook;
|
|
||||||
raw = { ...defaults, ...raw };
|
raw = { ...defaults, ...raw };
|
||||||
if (raw.theme && raw.theme.extensionsHook) {
|
const hook = raw.theme && raw.theme.extensionsHook;
|
||||||
hook = raw.theme.extensionsHook;
|
this.theme = resolveTheme(
|
||||||
raw.theme.extensionsHook = undefined;
|
mergeObjects({} as any, defaultTheme, { ...raw.theme, extensionsHook: undefined }),
|
||||||
}
|
);
|
||||||
this.theme = resolveTheme(mergeObjects({} as any, defaultTheme, raw.theme || {}));
|
|
||||||
this.theme.extensionsHook = hook;
|
this.theme.extensionsHook = hook as any;
|
||||||
|
|
||||||
this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset);
|
this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset);
|
||||||
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
|
this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname);
|
||||||
|
|
|
@ -21,15 +21,15 @@ describe('Models', () => {
|
||||||
parser = new OpenAPIParser(spec, undefined, opts);
|
parser = new OpenAPIParser(spec, undefined, opts);
|
||||||
const schema = new SchemaModel(parser, spec.components.schemas.Test, '', opts);
|
const schema = new SchemaModel(parser, spec.components.schemas.Test, '', opts);
|
||||||
expect(schema.fields).toHaveLength(3);
|
expect(schema.fields).toHaveLength(3);
|
||||||
const oneOfField = schema.fields[0];
|
const oneOfField = schema.fields![0];
|
||||||
expect(oneOfField.schema.displayType).toBe('Foo (object) or Bar (object)');
|
expect(oneOfField.schema.displayType).toBe('Foo (object) or Bar (object)');
|
||||||
expect(oneOfField.schema.oneOf[0].title).toBe('Foo');
|
expect(oneOfField.schema.oneOf![0].title).toBe('Foo');
|
||||||
expect(oneOfField.schema.oneOf[1].title).toBe('Bar');
|
expect(oneOfField.schema.oneOf![1].title).toBe('Bar');
|
||||||
|
|
||||||
const anyOfField = schema.fields[1];
|
const anyOfField = schema.fields![1];
|
||||||
expect(anyOfField.schema.displayType).toBe('Foo (object) or Bar (object)');
|
expect(anyOfField.schema.displayType).toBe('Foo (object) or Bar (object)');
|
||||||
expect(anyOfField.schema.oneOf[0].title).toBe('Foo');
|
expect(anyOfField.schema.oneOf![0].title).toBe('Foo');
|
||||||
expect(anyOfField.schema.oneOf[1].title).toBe('Bar');
|
expect(anyOfField.schema.oneOf![1].title).toBe('Bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('oneOf/allOf schema complex displayType', () => {
|
test('oneOf/allOf schema complex displayType', () => {
|
||||||
|
|
|
@ -11,6 +11,9 @@ export class ApiInfoModel implements OpenAPIInfo {
|
||||||
contact?: OpenAPIContact;
|
contact?: OpenAPIContact;
|
||||||
license?: OpenAPILicense;
|
license?: OpenAPILicense;
|
||||||
|
|
||||||
|
downloadLink?: string;
|
||||||
|
downloadFileName?: string;
|
||||||
|
|
||||||
constructor(private parser: OpenAPIParser) {
|
constructor(private parser: OpenAPIParser) {
|
||||||
Object.assign(this, parser.spec.info);
|
Object.assign(this, parser.spec.info);
|
||||||
this.description = parser.spec.info.description || '';
|
this.description = parser.spec.info.description || '';
|
||||||
|
@ -18,9 +21,12 @@ export class ApiInfoModel implements OpenAPIInfo {
|
||||||
if (firstHeadingLinePos > -1) {
|
if (firstHeadingLinePos > -1) {
|
||||||
this.description = this.description.substring(0, firstHeadingLinePos);
|
this.description = this.description.substring(0, firstHeadingLinePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.downloadLink = this.getDownloadLink();
|
||||||
|
this.downloadFileName = this.getDownloadFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
get downloadLink(): string | undefined {
|
private getDownloadLink(): string | undefined {
|
||||||
if (this.parser.specUrl) {
|
if (this.parser.specUrl) {
|
||||||
return this.parser.specUrl;
|
return this.parser.specUrl;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +39,7 @@ export class ApiInfoModel implements OpenAPIInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get downloadFileName(): string | undefined {
|
private getDownloadFileName(): string | undefined {
|
||||||
if (!this.parser.specUrl) {
|
if (!this.parser.specUrl) {
|
||||||
return 'swagger.json';
|
return 'swagger.json';
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,11 +75,7 @@ export class SchemaModel {
|
||||||
this.init(parser, isChild);
|
this.init(parser, isChild);
|
||||||
|
|
||||||
parser.exitRef(schemaOrRef);
|
parser.exitRef(schemaOrRef);
|
||||||
|
parser.exitParents(this.schema);
|
||||||
for (const parent$ref of this.schema.parentRefs || []) {
|
|
||||||
// exit all the refs visited during allOf traverse
|
|
||||||
parser.exitRef({ $ref: parent$ref });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.showExtensions) {
|
if (options.showExtensions) {
|
||||||
this.extensions = extractExtensions(this.schema, options.showExtensions);
|
this.extensions = extractExtensions(this.schema, options.showExtensions);
|
||||||
|
@ -164,20 +160,28 @@ export class SchemaModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private initOneOf(oneOf: OpenAPISchema[], parser: OpenAPIParser) {
|
private initOneOf(oneOf: OpenAPISchema[], parser: OpenAPIParser) {
|
||||||
this.oneOf = oneOf!.map(
|
this.oneOf = oneOf!.map((variant, idx) => {
|
||||||
(variant, idx) =>
|
const merged = parser.mergeAllOf(variant, this.pointer + '/oneOf/' + idx);
|
||||||
new SchemaModel(
|
|
||||||
parser,
|
const schema = new SchemaModel(
|
||||||
// merge base schema into each of oneOf's subschemas
|
parser,
|
||||||
{
|
// merge base schema into each of oneOf's subschemas
|
||||||
// variant may already have allOf so merge it to not get overwritten
|
{
|
||||||
...parser.mergeAllOf(variant, this.pointer + '/oneOf/' + idx),
|
// variant may already have allOf so merge it to not get overwritten
|
||||||
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
|
...merged,
|
||||||
} as OpenAPISchema,
|
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
|
||||||
this.pointer + '/oneOf/' + idx,
|
} as OpenAPISchema,
|
||||||
this.options,
|
this.pointer + '/oneOf/' + idx,
|
||||||
),
|
this.options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// each oneOf should be independent so exiting all the parent refs
|
||||||
|
// otherwise it will cause false-positive recursive detection
|
||||||
|
parser.exitParents(merged);
|
||||||
|
|
||||||
|
return schema;
|
||||||
|
});
|
||||||
|
|
||||||
this.displayType = this.oneOf
|
this.displayType = this.oneOf
|
||||||
.map(schema => {
|
.map(schema => {
|
||||||
let name =
|
let name =
|
||||||
|
|
|
@ -1,24 +1,13 @@
|
||||||
import * as React from 'react';
|
|
||||||
import * as styledComponents from 'styled-components';
|
import * as styledComponents from 'styled-components';
|
||||||
|
|
||||||
import { ResolvedThemeInterface } from './theme';
|
import { ResolvedThemeInterface } from './theme';
|
||||||
|
|
||||||
export { ResolvedThemeInterface };
|
export { ResolvedThemeInterface };
|
||||||
|
|
||||||
export type InterpolationFunction<P> = styledComponents.InterpolationFunction<P>;
|
|
||||||
|
|
||||||
export type StyledFunction<T> = styledComponents.ThemedStyledFunction<T, ResolvedThemeInterface>;
|
|
||||||
|
|
||||||
function withProps<T, U extends HTMLElement = HTMLElement>(
|
|
||||||
styledFunction: StyledFunction<React.HTMLProps<U>>,
|
|
||||||
): StyledFunction<T & React.HTMLProps<U>> {
|
|
||||||
return styledFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
default: styled,
|
default: styled,
|
||||||
css,
|
css,
|
||||||
injectGlobal,
|
createGlobalStyle,
|
||||||
keyframes,
|
keyframes,
|
||||||
ThemeProvider,
|
ThemeProvider,
|
||||||
} = (styledComponents as any) as styledComponents.ThemedStyledComponentsModule<
|
} = (styledComponents as any) as styledComponents.ThemedStyledComponentsModule<
|
||||||
|
@ -54,7 +43,7 @@ export const media = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export { css, injectGlobal, keyframes, ThemeProvider, withProps };
|
export { css, createGlobalStyle, keyframes, ThemeProvider };
|
||||||
export default styled;
|
export default styled;
|
||||||
|
|
||||||
export function extensionsHook(styledName: string) {
|
export function extensionsHook(styledName: string) {
|
||||||
|
|
20
src/theme.ts
20
src/theme.ts
|
@ -95,7 +95,7 @@ const defaultTheme: ThemeInterface = {
|
||||||
},
|
},
|
||||||
typography: {
|
typography: {
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
lineHeight: '1.5',
|
lineHeight: '1.5em',
|
||||||
fontWeightRegular: '400',
|
fontWeightRegular: '400',
|
||||||
fontWeightBold: '600',
|
fontWeightBold: '600',
|
||||||
fontWeightLight: '300',
|
fontWeightLight: '300',
|
||||||
|
@ -104,6 +104,7 @@ const defaultTheme: ThemeInterface = {
|
||||||
optimizeSpeed: true,
|
optimizeSpeed: true,
|
||||||
headings: {
|
headings: {
|
||||||
fontFamily: 'Montserrat, sans-serif',
|
fontFamily: 'Montserrat, sans-serif',
|
||||||
|
fontWeight: '400',
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
fontSize: '13px',
|
fontSize: '13px',
|
||||||
|
@ -111,18 +112,19 @@ const defaultTheme: ThemeInterface = {
|
||||||
lineHeight: ({ typography }) => typography.lineHeight,
|
lineHeight: ({ typography }) => typography.lineHeight,
|
||||||
fontWeight: ({ typography }) => typography.fontWeightRegular,
|
fontWeight: ({ typography }) => typography.fontWeightRegular,
|
||||||
color: '#e53935',
|
color: '#e53935',
|
||||||
backgroundColor: 'rgba(38, 50, 56, 0.04)',
|
backgroundColor: 'rgba(38, 50, 56, 0.05)',
|
||||||
wrap: false,
|
wrap: false,
|
||||||
},
|
},
|
||||||
links: {
|
links: {
|
||||||
color: ({ colors }) => colors.primary.main,
|
color: ({ colors }) => colors.primary.main,
|
||||||
visited: ({ colors }) => colors.primary.main,
|
visited: ({ typography }) => typography.links.color,
|
||||||
hover: ({ colors }) => lighten(0.2, colors.primary.main),
|
hover: ({ typography }) => lighten(0.2, typography.links.color),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
menu: {
|
menu: {
|
||||||
width: '260px',
|
width: '260px',
|
||||||
backgroundColor: '#fafafa',
|
backgroundColor: '#fafafa',
|
||||||
|
textColor: '#333333',
|
||||||
groupItems: {
|
groupItems: {
|
||||||
textTransform: 'uppercase',
|
textTransform: 'uppercase',
|
||||||
},
|
},
|
||||||
|
@ -131,7 +133,7 @@ const defaultTheme: ThemeInterface = {
|
||||||
},
|
},
|
||||||
arrow: {
|
arrow: {
|
||||||
size: '1.5em',
|
size: '1.5em',
|
||||||
color: theme => theme.colors.text.primary,
|
color: theme => theme.menu.textColor,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
logo: {
|
logo: {
|
||||||
|
@ -143,6 +145,9 @@ const defaultTheme: ThemeInterface = {
|
||||||
width: '40%',
|
width: '40%',
|
||||||
textColor: '#ffffff',
|
textColor: '#ffffff',
|
||||||
},
|
},
|
||||||
|
codeSample: {
|
||||||
|
backgroundColor: ({ rightPanel }) => darken(0.1, rightPanel.backgroundColor),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defaultTheme;
|
export default defaultTheme;
|
||||||
|
@ -275,6 +280,7 @@ export interface ResolvedThemeInterface {
|
||||||
};
|
};
|
||||||
headings: {
|
headings: {
|
||||||
fontFamily: string;
|
fontFamily: string;
|
||||||
|
fontWeight: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
links: {
|
links: {
|
||||||
|
@ -286,6 +292,7 @@ export interface ResolvedThemeInterface {
|
||||||
menu: {
|
menu: {
|
||||||
width: string;
|
width: string;
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
|
textColor: string;
|
||||||
groupItems: {
|
groupItems: {
|
||||||
textTransform: string;
|
textTransform: string;
|
||||||
};
|
};
|
||||||
|
@ -306,6 +313,9 @@ export interface ResolvedThemeInterface {
|
||||||
textColor: string;
|
textColor: string;
|
||||||
width: string;
|
width: string;
|
||||||
};
|
};
|
||||||
|
codeSample: {
|
||||||
|
backgroundColor: string;
|
||||||
|
};
|
||||||
|
|
||||||
extensionsHook?: (name: string, props: any) => string;
|
extensionsHook?: (name: string, props: any) => string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
detectType,
|
detectType,
|
||||||
getOperationSummary,
|
getOperationSummary,
|
||||||
getStatusCodeType,
|
getStatusCodeType,
|
||||||
|
humanizeConstraints,
|
||||||
isOperationName,
|
isOperationName,
|
||||||
isPrimitiveType,
|
isPrimitiveType,
|
||||||
mergeParams,
|
mergeParams,
|
||||||
|
@ -321,4 +322,35 @@ describe('Utils', () => {
|
||||||
expect(servers[2].url).toEqual('http://127.0.0.3');
|
expect(servers[2].url).toEqual('http://127.0.0.3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('openapi humanizeConstraints', () => {
|
||||||
|
const itemConstraintSchema = (
|
||||||
|
min: number | undefined = undefined,
|
||||||
|
max: number | undefined = undefined,
|
||||||
|
) => ({ type: 'array', minItems: min, maxItems: max });
|
||||||
|
|
||||||
|
it('should not have a humanized constraint without schema constraints', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema())).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when minItems is set', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(2))).toContain('>= 2 items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when maxItems is set', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(undefined, 8))).toContain('<= 8 items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when minItems and maxItems are both set', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(2, 8))).toContain('[ 2 .. 8 ] items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when minItems and maxItems are the same', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(7, 7))).toContain('7 items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humazined constraint when justMinItems is set, and it is equal to 1', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(1))).toContain('non-empty');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -161,3 +161,7 @@ export function resolveUrl(url: string, to: string) {
|
||||||
}
|
}
|
||||||
return stripTrailingSlash(res);
|
return stripTrailingSlash(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getBasePath(serverUrl: string): string {
|
||||||
|
return new URL(serverUrl).pathname;
|
||||||
|
}
|
||||||
|
|
|
@ -141,29 +141,44 @@ export function isNamedDefinition(pointer?: string): boolean {
|
||||||
return /^#\/components\/schemas\/[^\/]+$/.test(pointer || '');
|
return /^#\/components\/schemas\/[^\/]+$/.test(pointer || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function humanizeRangeConstraint(
|
||||||
|
description: string,
|
||||||
|
min: number | undefined,
|
||||||
|
max: number | undefined,
|
||||||
|
): string | undefined {
|
||||||
|
let stringRange;
|
||||||
|
if (min !== undefined && max !== undefined) {
|
||||||
|
if (min === max) {
|
||||||
|
stringRange = `${min} ${description}`;
|
||||||
|
} else {
|
||||||
|
stringRange = `[ ${min} .. ${max} ] ${description}`;
|
||||||
|
}
|
||||||
|
} else if (max !== undefined) {
|
||||||
|
stringRange = `<= ${max} ${description}`;
|
||||||
|
} else if (min !== undefined) {
|
||||||
|
if (min === 1) {
|
||||||
|
stringRange = 'non-empty';
|
||||||
|
} else {
|
||||||
|
stringRange = `>= ${min} ${description}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringRange;
|
||||||
|
}
|
||||||
|
|
||||||
export function humanizeConstraints(schema: OpenAPISchema): string[] {
|
export function humanizeConstraints(schema: OpenAPISchema): string[] {
|
||||||
const res: string[] = [];
|
const res: string[] = [];
|
||||||
|
|
||||||
let stringRange;
|
const stringRange = humanizeRangeConstraint('characters', schema.minLength, schema.maxLength);
|
||||||
if (schema.minLength !== undefined && schema.maxLength !== undefined) {
|
|
||||||
if (schema.minLength === schema.maxLength) {
|
|
||||||
stringRange = `${schema.minLength} characters`;
|
|
||||||
} else {
|
|
||||||
stringRange = `[ ${schema.minLength} .. ${schema.maxLength} ] characters`;
|
|
||||||
}
|
|
||||||
} else if (schema.maxLength !== undefined) {
|
|
||||||
stringRange = `<= ${schema.maxLength} characters`;
|
|
||||||
} else if (schema.minLength !== undefined) {
|
|
||||||
if (schema.minLength === 1) {
|
|
||||||
stringRange = 'non-empty';
|
|
||||||
} else {
|
|
||||||
stringRange = `>= ${schema.minLength} characters`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stringRange !== undefined) {
|
if (stringRange !== undefined) {
|
||||||
res.push(stringRange);
|
res.push(stringRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const arrayRange = humanizeRangeConstraint('items', schema.minItems, schema.maxItems);
|
||||||
|
if (arrayRange !== undefined) {
|
||||||
|
res.push(arrayRange);
|
||||||
|
}
|
||||||
|
|
||||||
let numberRange;
|
let numberRange;
|
||||||
if (schema.minimum !== undefined && schema.maximum !== undefined) {
|
if (schema.minimum !== undefined && schema.maximum !== undefined) {
|
||||||
numberRange = schema.exclusiveMinimum ? '( ' : '[ ';
|
numberRange = schema.exclusiveMinimum ? '( ' : '[ ';
|
||||||
|
|
42
typings/styled-patch.d.ts
vendored
42
typings/styled-patch.d.ts
vendored
|
@ -1,43 +1,21 @@
|
||||||
import * as styledComponents from 'styled-components';
|
import * as styledComponents from 'styled-components';
|
||||||
|
|
||||||
// Styled components typings for using babel-plugin BEFORE typescript
|
// FIXME
|
||||||
declare module 'styled-components' {
|
declare module 'styled-components' {
|
||||||
interface ThemedStyledFunction<P, T, O = P> {
|
export interface ThemedStyledFunction<
|
||||||
// adding "| string[]" for transpileTemplateLiterals and similar below
|
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
|
||||||
(
|
T extends object,
|
||||||
strings: TemplateStringsArray | string[],
|
O extends object = {},
|
||||||
...interpolations: Interpolation<ThemedStyledProps<P, T>>[]
|
A extends keyof any = never
|
||||||
): StyledComponentClass<P, T, O>;
|
> extends ThemedStyledFunctionBase<C, T, O, A> {
|
||||||
|
withConfig(config: any): any;
|
||||||
new <U>(
|
// tslint:enable:unified-signatures
|
||||||
strings: TemplateStringsArray | string[],
|
|
||||||
...interpolations: Interpolation<ThemedStyledProps<P & U, T>>[]
|
|
||||||
): StyledComponentClass<P & U, T, O & U>;
|
|
||||||
|
|
||||||
// adding "withConfig" for transpileTemplateLiterals
|
|
||||||
withConfig(config: any): ThemedStyledFunction<P, T, O>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ThemedCssFunction<T> {
|
|
||||||
// adding "| string[]" for transpileTemplateLiterals and similar below
|
|
||||||
(
|
|
||||||
strings: TemplateStringsArray | string[],
|
|
||||||
...interpolations: SimpleInterpolation[]
|
|
||||||
): InterpolationValue[];
|
|
||||||
<P>(
|
|
||||||
strings: TemplateStringsArray | string[],
|
|
||||||
...interpolations: Interpolation<ThemedStyledProps<P, T>>[]
|
|
||||||
): FlattenInterpolation<ThemedStyledProps<P, T>>[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ThemedStyledComponentsModule<T> {
|
interface ThemedStyledComponentsModule<T> {
|
||||||
keyframes(
|
keyframes(
|
||||||
strings: TemplateStringsArray | string[],
|
strings: TemplateStringsArray | string[],
|
||||||
...interpolations: SimpleInterpolation[]
|
...interpolations: SimpleInterpolation[]
|
||||||
): string;
|
): Keyframes;
|
||||||
injectGlobal(
|
|
||||||
strings: TemplateStringsArray | string[],
|
|
||||||
...interpolations: SimpleInterpolation[]
|
|
||||||
): void;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,18 @@ const nodeExternals = require('webpack-node-externals')({
|
||||||
});
|
});
|
||||||
|
|
||||||
const VERSION = JSON.stringify(require('./package.json').version);
|
const VERSION = JSON.stringify(require('./package.json').version);
|
||||||
const REVISION = JSON.stringify(
|
let REVISION;
|
||||||
require('child_process')
|
|
||||||
.execSync('git rev-parse --short HEAD')
|
try {
|
||||||
.toString()
|
REVISION = JSON.stringify(
|
||||||
.trim(),
|
require('child_process')
|
||||||
);
|
.execSync('git rev-parse --short HEAD')
|
||||||
|
.toString()
|
||||||
|
.trim(),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Skipping REDOC_REVISION');
|
||||||
|
}
|
||||||
|
|
||||||
const BANNER = `ReDoc - OpenAPI/Swagger-generated API Reference Documentation
|
const BANNER = `ReDoc - OpenAPI/Swagger-generated API Reference Documentation
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
|
@ -106,7 +112,7 @@ export default (env: { standalone?: boolean } = {}, { mode }) => ({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
exclude: ['node_modules'],
|
exclude: [/node_modules/],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /node_modules\/(swagger2openapi|reftools|oas-resolver|oas-kit-common|oas-schema-walker)\/.*\.js$/,
|
test: /node_modules\/(swagger2openapi|reftools|oas-resolver|oas-kit-common|oas-schema-walker)\/.*\.js$/,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user