mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-06 05:10:20 +03:00
Merge branch 'master' into max-sample-depth-option
This commit is contained in:
commit
974352fe5f
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: 'type: bug'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Minimal reproducible OpenAPI snippet(if possible)**
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the problem to be solved**
|
||||||
|
A clear and concise description of what problem to be solved
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
13
.github/pull_request_template.md
vendored
Normal file
13
.github/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
## What/Why/How?
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
## Screenshots (optional)
|
||||||
|
|
||||||
|
## Check yourself
|
||||||
|
|
||||||
|
- [ ] Code is linted
|
||||||
|
- [ ] Tested
|
||||||
|
- [ ] All new/updated code is covered with tests
|
6
.github/sync.yml
vendored
Normal file
6
.github/sync.yml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
group:
|
||||||
|
- files:
|
||||||
|
- source: docs/
|
||||||
|
dest: docs/redoc
|
||||||
|
repos: |
|
||||||
|
Redocly/docs
|
45
.github/workflows/main.yml
vendored
Normal file
45
.github/workflows/main.yml
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
name: Publish Docker image
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
jobs:
|
||||||
|
push_to_registry:
|
||||||
|
name: Push Docker image to GitHub Packages
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Check out the repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Prepare
|
||||||
|
id: prep
|
||||||
|
run: |
|
||||||
|
DOCKER_IMAGE=ghcr.io/redocly/redoc/cli
|
||||||
|
VERSION=edge
|
||||||
|
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||||
|
VERSION=${GITHUB_REF#refs/tags/}
|
||||||
|
elif [[ $GITHUB_REF == refs/heads/* ]]; then
|
||||||
|
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
|
||||||
|
elif [[ $GITHUB_REF == refs/pull/* ]]; then
|
||||||
|
VERSION=pr-${{ github.event.number }}
|
||||||
|
fi
|
||||||
|
TAGS="${DOCKER_IMAGE}:${VERSION}"
|
||||||
|
if [ "${{ github.event_name }}" = "push" ]; then
|
||||||
|
TAGS="$TAGS,${DOCKER_IMAGE}:sha-${GITHUB_SHA::8}"
|
||||||
|
fi
|
||||||
|
echo ::set-output name=version::${VERSION}
|
||||||
|
echo ::set-output name=tags::${TAGS}
|
||||||
|
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
- name: Push to GitHub Packages
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./cli
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.prep.outputs.tags }}
|
18
.github/workflows/sync.yml
vendored
Normal file
18
.github/workflows/sync.yml
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
name: Sync Files
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@master
|
||||||
|
- name: Run GitHub File Sync
|
||||||
|
uses: Redocly/repo-file-sync-action@master
|
||||||
|
with:
|
||||||
|
GH_PAT: ${{ secrets.GH_PAT }}
|
||||||
|
COMMIT_PREFIX: "sync:"
|
||||||
|
SKIP_PR: true
|
36
CHANGELOG.md
36
CHANGELOG.md
|
@ -1,3 +1,39 @@
|
||||||
|
# [2.0.0-rc.56](https://github.com/Redocly/redoc/compare/v2.0.0-rc.53...v2.0.0-rc.56) (2021-08-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* handle empty object in security array ([#1678](https://github.com/Redocly/redoc/issues/1678)) ([9e1ea70](https://github.com/Redocly/redoc/commit/9e1ea703e56a71567b13d0d22e2d69945a22de4d))
|
||||||
|
* hideLoading options in redoc standalone ([#1709](https://github.com/Redocly/redoc/issues/1709)) ([6a52a16](https://github.com/Redocly/redoc/commit/6a52a16d5b75a2955da7217c4a264f0fa8e98c89))
|
||||||
|
* improve openapi 3.1 ([#1700](https://github.com/Redocly/redoc/issues/1700)) ([cd2d6f7](https://github.com/Redocly/redoc/commit/cd2d6f76e87c8385786a9c8e51c0d11c79d9707c))
|
||||||
|
- show contentEncoding on fields
|
||||||
|
- crash with OpenAPI 3.1 type as array of strings in requestBody
|
||||||
|
- nullable label not shown
|
||||||
|
* nullable object's fields were missing ([#1721](https://github.com/Redocly/redoc/issues/1721)) ([ddf297b](https://github.com/Redocly/redoc/commit/ddf297b11269ef515bd62771912a5609721d5e39))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add github action to build docker images and push to ghcr.io on release ([#1614](https://github.com/Redocly/redoc/issues/1614)) ([919a5f0](https://github.com/Redocly/redoc/commit/919a5f02fb94ca869011d5eaf63ee71b61b60150))
|
||||||
|
* add yaml highlight ([#1684](https://github.com/Redocly/redoc/issues/1684)) ([d724440](https://github.com/Redocly/redoc/commit/d72444008533623c87f238fe8758b1dd518b89eb))
|
||||||
|
* added localization for some labels ([#1675](https://github.com/Redocly/redoc/issues/1675)) ([ec50858](https://github.com/Redocly/redoc/commit/ec50858ec47af08c5fe553266fe3c209fba97eae))
|
||||||
|
|
||||||
|
|
||||||
|
# [2.0.0-rc.55](https://github.com/Redocly/redoc/compare/v2.0.0-rc.54...v2.0.0-rc.55) (2021-07-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* broken linkify ([3df72fb](https://github.com/Redocly/redoc/commit/3df72fb99ff24fb9a551565b7568d96f8614ed6f)), closes [#1655](https://github.com/Redocly/redoc/issues/1655)
|
||||||
|
* fix accidentally removed onLoaded ([b41a8b4](https://github.com/Redocly/redoc/commit/b41a8b4ac714084dc25de7914fa1f99386e907e2)), closes [#1656](https://github.com/Redocly/redoc/issues/1656)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* added git folder sync config ([a69f0fb](https://github.com/Redocly/redoc/commit/a69f0fb00986a04c812ab273711e8f3501b98139))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.0.0-rc.54](https://github.com/Redocly/redoc/compare/v2.0.0-rc.53...v2.0.0-rc.54) (2021-06-09)
|
# [2.0.0-rc.54](https://github.com/Redocly/redoc/compare/v2.0.0-rc.53...v2.0.0-rc.54) (2021-06-09)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ Additionally, all the 1.x releases are hosted on our GitHub Pages-based CDN **(d
|
||||||
- [Commbox](https://www.commbox.io/api/)
|
- [Commbox](https://www.commbox.io/api/)
|
||||||
- [APIs.guru](https://apis.guru/api-doc/)
|
- [APIs.guru](https://apis.guru/api-doc/)
|
||||||
- [FastAPI](https://github.com/tiangolo/fastapi)
|
- [FastAPI](https://github.com/tiangolo/fastapi)
|
||||||
|
- [BoxKnight](https://www.docs.boxknight.com/)
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
|
|
|
@ -3,20 +3,29 @@
|
||||||
**[ReDoc](https://github.com/Redocly/redoc)'s Command Line Interface**
|
**[ReDoc](https://github.com/Redocly/redoc)'s Command Line Interface**
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
You can use redoc cli by installing `redoc-cli` globally or using [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b).
|
|
||||||
|
You can use `redoc-cli` by installing [the package](https://www.npmjs.com/package/redoc-cli) globally,
|
||||||
|
or using [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Two following commands are available:
|
The two following commands are available:
|
||||||
|
|
||||||
- `redoc-cli serve [spec]` - starts the server with `spec` rendered with ReDoc. Supports SSR mode (`--ssr`) and can watch the spec (`--watch`)
|
- `redoc-cli serve [spec]` - starts the server with `spec` rendered with ReDoc.
|
||||||
- `redoc-cli bundle [spec]` - bundles spec and ReDoc into **zero-dependency** HTML file.
|
Supports a server-side rendering mode (`--ssr`),
|
||||||
|
and can watch the spec (`--watch`) to automatically reload the page whenever it changes.
|
||||||
|
- `redoc-cli bundle [spec]` - bundles `spec` and ReDoc into a **zero-dependency** HTML file.
|
||||||
|
|
||||||
Some examples:
|
Some examples:
|
||||||
|
|
||||||
- Bundle with main color changed to `orange`: <br> `$ redoc-cli bundle [spec] --options.theme.colors.primary.main=orange`
|
- Bundle with the main color changed to `orange`:<br/>
|
||||||
- Serve with `nativeScrollbars` option set to true: <br> `$ redoc-cli serve [spec] --options.nativeScrollbars`
|
`$ redoc-cli bundle [spec] --options.theme.colors.primary.main=orange`
|
||||||
- Bundle using custom template (check [default template](https://github.com/Redocly/redoc/blob/master/cli/template.hbs) for reference): <br> `$ redoc-cli bundle [spec] -t custom.hbs`
|
- Serve with the `nativeScrollbars` option set to true:<br/>
|
||||||
- Bundle using custom template and add custom `templateOptions`: <br> `$ redoc-cli bundle [spec] -t custom.hbs --templateOptions.metaDescription "Page meta description"`
|
`$ redoc-cli serve [spec] --options.nativeScrollbars`
|
||||||
|
- Bundle using a custom [Handlebars](https://handlebarsjs.com/) template
|
||||||
|
(check the [default template](https://github.com/Redocly/redoc/blob/master/cli/template.hbs) for an example):<br/>
|
||||||
|
`$ redoc-cli bundle [spec] -t custom.hbs`
|
||||||
|
- Bundle using a custom template and add custom `templateOptions`:<br/>
|
||||||
|
`$ redoc-cli bundle [spec] -t custom.hbs --templateOptions.metaDescription "Page meta description"`
|
||||||
|
|
||||||
For more details run `redoc-cli --help`.
|
For more details, run `redoc-cli --help`.
|
||||||
|
|
116
cli/npm-shrinkwrap.json
generated
116
cli/npm-shrinkwrap.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "redoc-cli",
|
"name": "redoc-cli",
|
||||||
"version": "0.12.1",
|
"version": "0.12.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "redoc-cli",
|
"name": "redoc-cli",
|
||||||
"version": "0.12.1",
|
"version": "0.12.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^3.5.1",
|
"chokidar": "^3.5.1",
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
"node-libs-browser": "^2.2.1",
|
"node-libs-browser": "^2.2.1",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"redoc": "2.0.0-rc.54",
|
"redoc": "2.0.0-rc.56",
|
||||||
"styled-components": "^5.3.0",
|
"styled-components": "^5.3.0",
|
||||||
"yargs": "^17.0.1"
|
"yargs": "^17.0.1"
|
||||||
},
|
},
|
||||||
|
@ -605,17 +605,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||||
},
|
},
|
||||||
"node_modules/clipboard": {
|
|
||||||
"version": "2.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz",
|
|
||||||
"integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"good-listener": "^1.2.2",
|
|
||||||
"select": "^1.1.2",
|
|
||||||
"tiny-emitter": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cliui": {
|
"node_modules/cliui": {
|
||||||
"version": "7.0.4",
|
"version": "7.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||||
|
@ -782,12 +771,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz",
|
||||||
"integrity": "sha1-/UPHNelnuAEzBohKVvvmZZlraBc="
|
"integrity": "sha1-/UPHNelnuAEzBohKVvvmZZlraBc="
|
||||||
},
|
},
|
||||||
"node_modules/delegate": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/des.js": {
|
"node_modules/des.js": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
|
||||||
|
@ -976,15 +959,6 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/good-listener": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
|
||||||
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"delegate": "^3.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/handlebars": {
|
"node_modules/handlebars": {
|
||||||
"version": "4.7.7",
|
"version": "4.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
|
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
|
||||||
|
@ -1602,12 +1576,9 @@
|
||||||
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
|
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
|
||||||
},
|
},
|
||||||
"node_modules/prismjs": {
|
"node_modules/prismjs": {
|
||||||
"version": "1.23.0",
|
"version": "1.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz",
|
||||||
"integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==",
|
"integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow=="
|
||||||
"optionalDependencies": {
|
|
||||||
"clipboard": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/process": {
|
"node_modules/process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
|
@ -1780,9 +1751,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/redoc": {
|
"node_modules/redoc": {
|
||||||
"version": "2.0.0-rc.54",
|
"version": "2.0.0-rc.56",
|
||||||
"resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-rc.54.tgz",
|
"resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-rc.56.tgz",
|
||||||
"integrity": "sha512-xwukaWdoktkDAoQuhajekdC54+/lSLwIUqJCNSTVEjeYEuZPq2tFUj9H5SBt8/YSq5UF/zOmDQrXPWMgildQpQ==",
|
"integrity": "sha512-ir2TtQ2d/1FqZWIoLmUZ3qvAAnO6jg8dt0SV75TanmfCXpEABcElXWH3mtUf6qKlvgDVt40diDCVuSvyPPxkAw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.14.0",
|
"@babel/runtime": "^7.14.0",
|
||||||
"@redocly/openapi-core": "^1.0.0-beta.50",
|
"@redocly/openapi-core": "^1.0.0-beta.50",
|
||||||
|
@ -1802,7 +1773,7 @@
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"perfect-scrollbar": "^1.5.1",
|
"perfect-scrollbar": "^1.5.1",
|
||||||
"polished": "^4.1.3",
|
"polished": "^4.1.3",
|
||||||
"prismjs": "^1.23.0",
|
"prismjs": "^1.24.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react-tabs": "^3.2.2",
|
"react-tabs": "^3.2.2",
|
||||||
"slugify": "~1.4.7",
|
"slugify": "~1.4.7",
|
||||||
|
@ -1890,12 +1861,6 @@
|
||||||
"object-assign": "^4.1.1"
|
"object-assign": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/select": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
|
||||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/setimmediate": {
|
"node_modules/setimmediate": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||||
|
@ -2122,12 +2087,6 @@
|
||||||
"node": ">=0.6.0"
|
"node": ">=0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tiny-emitter": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/to-arraybuffer": {
|
"node_modules/to-arraybuffer": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
|
||||||
|
@ -2853,17 +2812,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||||
},
|
},
|
||||||
"clipboard": {
|
|
||||||
"version": "2.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz",
|
|
||||||
"integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==",
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"good-listener": "^1.2.2",
|
|
||||||
"select": "^1.1.2",
|
|
||||||
"tiny-emitter": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cliui": {
|
"cliui": {
|
||||||
"version": "7.0.4",
|
"version": "7.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||||
|
@ -3010,12 +2958,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz",
|
||||||
"integrity": "sha1-/UPHNelnuAEzBohKVvvmZZlraBc="
|
"integrity": "sha1-/UPHNelnuAEzBohKVvvmZZlraBc="
|
||||||
},
|
},
|
||||||
"delegate": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"des.js": {
|
"des.js": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
|
||||||
|
@ -3169,15 +3111,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
|
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
|
||||||
},
|
},
|
||||||
"good-listener": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
|
||||||
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"delegate": "^3.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"handlebars": {
|
"handlebars": {
|
||||||
"version": "4.7.7",
|
"version": "4.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
|
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
|
||||||
|
@ -3648,12 +3581,9 @@
|
||||||
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
|
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
|
||||||
},
|
},
|
||||||
"prismjs": {
|
"prismjs": {
|
||||||
"version": "1.23.0",
|
"version": "1.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz",
|
||||||
"integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==",
|
"integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow=="
|
||||||
"requires": {
|
|
||||||
"clipboard": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"process": {
|
"process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
|
@ -3811,9 +3741,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redoc": {
|
"redoc": {
|
||||||
"version": "2.0.0-rc.54",
|
"version": "2.0.0-rc.56",
|
||||||
"resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-rc.54.tgz",
|
"resolved": "https://registry.npmjs.org/redoc/-/redoc-2.0.0-rc.56.tgz",
|
||||||
"integrity": "sha512-xwukaWdoktkDAoQuhajekdC54+/lSLwIUqJCNSTVEjeYEuZPq2tFUj9H5SBt8/YSq5UF/zOmDQrXPWMgildQpQ==",
|
"integrity": "sha512-ir2TtQ2d/1FqZWIoLmUZ3qvAAnO6jg8dt0SV75TanmfCXpEABcElXWH3mtUf6qKlvgDVt40diDCVuSvyPPxkAw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.14.0",
|
"@babel/runtime": "^7.14.0",
|
||||||
"@redocly/openapi-core": "^1.0.0-beta.50",
|
"@redocly/openapi-core": "^1.0.0-beta.50",
|
||||||
|
@ -3833,7 +3763,7 @@
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"perfect-scrollbar": "^1.5.1",
|
"perfect-scrollbar": "^1.5.1",
|
||||||
"polished": "^4.1.3",
|
"polished": "^4.1.3",
|
||||||
"prismjs": "^1.23.0",
|
"prismjs": "^1.24.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react-tabs": "^3.2.2",
|
"react-tabs": "^3.2.2",
|
||||||
"slugify": "~1.4.7",
|
"slugify": "~1.4.7",
|
||||||
|
@ -3892,12 +3822,6 @@
|
||||||
"object-assign": "^4.1.1"
|
"object-assign": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"select": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
|
||||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"setimmediate": {
|
"setimmediate": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||||
|
@ -4083,12 +4007,6 @@
|
||||||
"setimmediate": "^1.0.4"
|
"setimmediate": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tiny-emitter": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"to-arraybuffer": {
|
"to-arraybuffer": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "redoc-cli",
|
"name": "redoc-cli",
|
||||||
"version": "0.12.1",
|
"version": "0.12.3",
|
||||||
"description": "ReDoc's Command Line Interface",
|
"description": "ReDoc's Command Line Interface",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": "index.js",
|
"bin": "index.js",
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
"node-libs-browser": "^2.2.1",
|
"node-libs-browser": "^2.2.1",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"redoc": "2.0.0-rc.54",
|
"redoc": "2.0.0-rc.56",
|
||||||
"styled-components": "^5.3.0",
|
"styled-components": "^5.3.0",
|
||||||
"yargs": "^17.0.1"
|
"yargs": "^17.0.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,7 +16,8 @@ RUN npm ci --no-optional --ignore-scripts
|
||||||
|
|
||||||
# copy only required for the build files
|
# copy only required for the build files
|
||||||
COPY src /build/src
|
COPY src /build/src
|
||||||
COPY webpack.config.ts tsconfig.json custom.d.ts /build/
|
COPY webpack.config.ts tsconfig.json custom.d.ts /build/
|
||||||
|
COPY config/webpack-utils.ts /build/config/
|
||||||
COPY typings/styled-patch.d.ts /build/typings/styled-patch.d.ts
|
COPY typings/styled-patch.d.ts /build/typings/styled-patch.d.ts
|
||||||
|
|
||||||
RUN npm run bundle:standalone
|
RUN npm run bundle:standalone
|
||||||
|
|
|
@ -15,7 +15,7 @@ const demos = [
|
||||||
value: 'https://api.apis.guru/v2/specs/googleapis.com/calendar/v3/openapi.yaml',
|
value: 'https://api.apis.guru/v2/specs/googleapis.com/calendar/v3/openapi.yaml',
|
||||||
label: 'Google Calendar',
|
label: 'Google Calendar',
|
||||||
},
|
},
|
||||||
{ value: 'https://api.apis.guru/v2/specs/slack.com/1.5.0/openapi.yaml', label: 'Slack' },
|
{ value: 'https://api.apis.guru/v2/specs/slack.com/1.7.0/openapi.yaml', label: 'Slack' },
|
||||||
{ value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/openapi.yaml', label: 'Zoom.us' },
|
{ value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/openapi.yaml', label: 'Zoom.us' },
|
||||||
{ value: 'https://docs.graphhopper.com/openapi.json', label: 'GraphHopper' },
|
{ value: 'https://docs.graphhopper.com/openapi.json', label: 'GraphHopper' },
|
||||||
];
|
];
|
||||||
|
@ -77,7 +77,7 @@ class DemoApp extends React.Component<
|
||||||
let proxiedUrl = specUrl;
|
let proxiedUrl = specUrl;
|
||||||
if (specUrl !== DEFAULT_SPEC) {
|
if (specUrl !== DEFAULT_SPEC) {
|
||||||
proxiedUrl = cors
|
proxiedUrl = cors
|
||||||
? '\\\\cors.apis.guru/' + urlResolve(window.location.href, specUrl)
|
? '\\\\cors.redoc.ly/' + urlResolve(window.location.href, specUrl)
|
||||||
: specUrl;
|
: specUrl;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1166,6 +1166,11 @@ components:
|
||||||
description: User status
|
description: User status
|
||||||
type: integer
|
type: integer
|
||||||
format: int32
|
format: int32
|
||||||
|
image:
|
||||||
|
description: User image
|
||||||
|
type: string
|
||||||
|
contentEncoding: base64
|
||||||
|
contentMediaType: image/png
|
||||||
xml:
|
xml:
|
||||||
name: User
|
name: User
|
||||||
requestBodies:
|
requestBodies:
|
||||||
|
|
|
@ -1193,7 +1193,7 @@ x-webhooks:
|
||||||
summary: New pet
|
summary: New pet
|
||||||
description: Information about a new pet in the systems
|
description: Information about a new pet in the systems
|
||||||
operationId: newPet
|
operationId: newPet
|
||||||
tags:
|
tags:
|
||||||
- pet
|
- pet
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
|
@ -1202,4 +1202,4 @@ x-webhooks:
|
||||||
$ref: "#/components/schemas/Pet"
|
$ref: "#/components/schemas/Pet"
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Return a 200 status to indicate that the data was received successfully
|
description: Return a 200 status to indicate that the data was received successfully
|
||||||
|
|
112
docs/quickstart/cli.md
Normal file
112
docs/quickstart/cli.md
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
---
|
||||||
|
title: Using the Redoc CLI
|
||||||
|
---
|
||||||
|
|
||||||
|
# Using the Redoc CLI
|
||||||
|
|
||||||
|
With Redoc's command-line interface you can bundle your OpenAPI definition and API documentation
|
||||||
|
(made with Redoc) into a zero-dependency HTML file and locally render your
|
||||||
|
OpenAPI definition with Redoc.
|
||||||
|
|
||||||
|
## Step 1 - Install Redoc CLI
|
||||||
|
|
||||||
|
You can install the `redoc-cli` package globally using one of the following package managers:
|
||||||
|
|
||||||
|
- [npm](https://docs.npmjs.com/about-npm)
|
||||||
|
- [yarn](https://classic.yarnpkg.com/en/docs/getting-started)
|
||||||
|
|
||||||
|
Or you can install `redoc-cli` using [npx](https://www.freecodecamp.org/news/npm-vs-npx-whats-the-difference/).
|
||||||
|
|
||||||
|
### Install Redoc CLI with yarn
|
||||||
|
|
||||||
|
To install the `redoc-cli` package globally with yarn:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn global add redoc-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install Redoc with npm
|
||||||
|
|
||||||
|
To install the `redoc-cli` package globally with npm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i -g redoc-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install with `npx`
|
||||||
|
|
||||||
|
To install the `redoc-cli` package locally with `npx`, navigate to your project
|
||||||
|
directory in your terminal, then use the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx redoc-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2 - Use the CLI
|
||||||
|
|
||||||
|
### Redoc CLI commands
|
||||||
|
|
||||||
|
The CLI includes the following commands:
|
||||||
|
|
||||||
|
- **`redoc-cli serve [spec]`:** Starts a local server with Redoc. You must include the required parameter, spec, which is
|
||||||
|
a reference to an OpenAPI definition. Options include:
|
||||||
|
- `--ssr`: Implements a server-side rendering model.
|
||||||
|
- `--watch`: Automatically reloads the server while you edit your OpenAPI definition.
|
||||||
|
- `--options`: Customizes your output using [Redoc options](https://redoc.ly/docs/api-reference-docs/configuration/).
|
||||||
|
To add nested options, use dot notation.
|
||||||
|
- **`redoc-cli bundle [spec]`:** Bundles `spec` and Redoc into a zero-dependency HTML file. Options include:
|
||||||
|
- `-t` or `--template`: Uses custom [Handlebars](https://handlebarsjs.com/) templates to render your OpenAPI definition.
|
||||||
|
- `--templateOptions`: Adds template options you want to pass to your
|
||||||
|
custom Handlebars template. To add options, use dot notation.
|
||||||
|
- **`--help`:** Prints help text for the Redoc CLI commands and options.
|
||||||
|
- **`--version`:** Prints the version of the `redoc-cli` package you have installed.
|
||||||
|
|
||||||
|
### Redoc CLI examples
|
||||||
|
|
||||||
|
#### Bundle
|
||||||
|
|
||||||
|
Bundle with the main color changed to `orange`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
redoc-cli bundle openapi.yaml --options.theme.colors.primary.main=orange
|
||||||
|
```
|
||||||
|
|
||||||
|
Bundle using a custom Handlebars template and add custom `templateOptions`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
redoc-cli bundle http://petstore.swagger.io/v2/swagger.json -t custom.hbs --templateOptions.metaDescription "Page meta description"
|
||||||
|
```
|
||||||
|
|
||||||
|
Sample Handlebars template:
|
||||||
|
|
||||||
|
```handlebars
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf8" />
|
||||||
|
<title>{{title}}</title>
|
||||||
|
<!-- needed for adaptive design -->
|
||||||
|
<meta description="{{{templateOptions.metaDescription}}}">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{{{redocHead}}}
|
||||||
|
{{#unless disableGoogleFont}}<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">{{/unless}}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{{redocHTML}}}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Serve
|
||||||
|
|
||||||
|
Serve with the `nativeScrollbars` option set to `true`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
redoc-cli serve openapi/dist.yaml --options.nativeScrollbars
|
||||||
|
```
|
39
docs/quickstart/docker.md
Normal file
39
docs/quickstart/docker.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
title: Using the Redoc Docker image
|
||||||
|
---
|
||||||
|
|
||||||
|
# Using the Redoc Docker image
|
||||||
|
|
||||||
|
Redoc is available as a pre-built Docker image in [Docker Hub](https://hub.docker.com/r/redocly/redoc/).
|
||||||
|
|
||||||
|
If you have [Docker](https://docs.docker.com/get-docker/) installed, pull the image with the following command:
|
||||||
|
|
||||||
|
```docker
|
||||||
|
docker pull redocly/redoc
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run the image with the following command:
|
||||||
|
|
||||||
|
```docker
|
||||||
|
docker run -p 8080:80 redocly/redoc
|
||||||
|
```
|
||||||
|
|
||||||
|
The preview starts on port 8080, based on the port used in the command,
|
||||||
|
and can be accessed at `http://localhost:8080`.
|
||||||
|
To exit the preview, use `control+C`.
|
||||||
|
|
||||||
|
By default Redoc starts with a demo Swagger Petstore OpenAPI definition located at
|
||||||
|
http://petstore.swagger.io/v2/swagger.json. You can update this URL using
|
||||||
|
the environment variable `SPEC_URL`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -p 8080:80 -e SPEC_URL=https://api.example.com/openapi.json redocly/redoc
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using a Dockerfile
|
||||||
|
|
||||||
|
You can also create a Dockerfile with some predefined environment variables. Check out
|
||||||
|
a sample [Dockerfile](https://github.com/Redocly/redoc/blob/master/config/docker/Dockerfile)
|
||||||
|
in our code repo.
|
214
docs/quickstart/html.md
Normal file
214
docs/quickstart/html.md
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
---
|
||||||
|
title: Using the Redoc HTML element
|
||||||
|
---
|
||||||
|
|
||||||
|
# Using the Redoc HTML element
|
||||||
|
|
||||||
|
## TL;DR final code example
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Redoc</title>
|
||||||
|
<!-- needed for adaptive design -->
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Redoc doesn't change outer page styles
|
||||||
|
-->
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<redoc spec-url='http://petstore.swagger.io/v2/swagger.json'></redoc>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js"> </script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
:::attention Running Redoc locally requires an HTTP server
|
||||||
|
Loading local OpenAPI definitions is impossible without running a web server because of issues with
|
||||||
|
[same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) and
|
||||||
|
other security reasons.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Running Redoc locally
|
||||||
|
|
||||||
|
If you want to view your Redoc output locally, you can simulate an HTTP server.
|
||||||
|
|
||||||
|
#### Using Redocly OpenAPI CLI
|
||||||
|
|
||||||
|
Redocly OpenAPI CLI is an open source command-line tool that includes a command
|
||||||
|
for simulating an HTTP server to provide a preview of your OpenAPI definition locally.
|
||||||
|
|
||||||
|
If you have [OpenAPI CLI](https://redoc.ly/docs/cli/#installation-and-usage) installed, `cd` into your
|
||||||
|
project directory and run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openapi preview-docs openapi.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, without providing a port, the preview starts on port 8080, and can be accessed at `http://localhost:8080`.
|
||||||
|
To exit the preview, use `control+C`.
|
||||||
|
|
||||||
|
#### Using Python
|
||||||
|
|
||||||
|
If you have [Python 3](https://www.python.org/downloads/) installed, `cd` into your
|
||||||
|
project directory and run the following command:
|
||||||
|
|
||||||
|
```python
|
||||||
|
python3 -m http.server
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have [Python 2](https://www.python.org/downloads/) installed, `cd` into your
|
||||||
|
project directory and run the following command:
|
||||||
|
|
||||||
|
```python
|
||||||
|
python -m SimpleHTTPServer 8000
|
||||||
|
```
|
||||||
|
|
||||||
|
The output after entering the command provides the local URL where the preview can be accessed.
|
||||||
|
To exit the preview, use `control-C`.
|
||||||
|
|
||||||
|
#### Using Node.js
|
||||||
|
|
||||||
|
If you have [Node.js](https://nodejs.org/en/download/) installed, install `http-server`
|
||||||
|
using the following npm command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g http-server
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, `cd` into your project directory and run the following command:
|
||||||
|
|
||||||
|
```node
|
||||||
|
http-server
|
||||||
|
```
|
||||||
|
|
||||||
|
The output after entering the command provides the local URL where the preview can be accessed.
|
||||||
|
To exit the preview, use `control-C`.
|
||||||
|
|
||||||
|
## Step 1 - Install Redoc
|
||||||
|
|
||||||
|
You can install Redoc using one of the following package managers:
|
||||||
|
|
||||||
|
- [npm](https://docs.npmjs.com/about-npm)
|
||||||
|
- [yarn](https://classic.yarnpkg.com/en/docs/getting-started)
|
||||||
|
|
||||||
|
:::attention Initialize your package manager
|
||||||
|
If you do not have a `package.json` file in your project directory,
|
||||||
|
you need to add one by initializing npm or yarn in your project. Use the command `npm init` for npm,
|
||||||
|
or `yarn init` for yarn. These initialization commands will lead you through the process
|
||||||
|
of creating a `package.json` file in your project.
|
||||||
|
|
||||||
|
For more information, see
|
||||||
|
[Creating a package.json file](https://docs.npmjs.com/creating-a-package-json-file)
|
||||||
|
in the npm documentation or [Yarn init](https://classic.yarnpkg.com/en/docs/cli/init/)
|
||||||
|
in the yarn documentation.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Install Redoc with yarn
|
||||||
|
|
||||||
|
After navigating to your project directory in your terminal, use the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn add redoc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install Redoc with npm
|
||||||
|
|
||||||
|
After navigating to your project directory in your terminal, use the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i redoc
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2 - Reference the Redoc script
|
||||||
|
|
||||||
|
You can reference the Redoc script using either a link to the files hosted on a CDN
|
||||||
|
or the files located in your `node modules` folder.
|
||||||
|
|
||||||
|
### CDN link
|
||||||
|
|
||||||
|
To reference the Redoc script with a CDN link:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js"> </script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node modules link
|
||||||
|
|
||||||
|
To reference the Redoc script with a node modules link:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script src="node_modules/redoc/bundles/redoc.standalone.js"> </script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 3 - Add the <redoc> element
|
||||||
|
|
||||||
|
You can add the <redoc> element to your HTML page and reference your OpenAPI
|
||||||
|
definition using the `spec-url` attribute, or you can initialize Redoc using
|
||||||
|
a globally exposed Redoc object.
|
||||||
|
|
||||||
|
### Using the `spec-url` attribute
|
||||||
|
|
||||||
|
To add the <redoc> element with the `spec-url` attribute:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<redoc spec-url="url/to/your/spec"></redoc>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
```html
|
||||||
|
<redoc spec-url="http://petstore.swagger.io/v2/swagger.json"></redoc>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use a local file (JSON or YAML) in your project, for instance:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<redoc spec-url="dist.json"></redoc>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using a Redoc object
|
||||||
|
|
||||||
|
To add the <redoc> element with a globally exposed Redoc object:
|
||||||
|
|
||||||
|
```js
|
||||||
|
Redoc.init(specOrSpecUrl, options, element, callback)
|
||||||
|
```
|
||||||
|
- `specOrSpecUrl`: Either a JSON object with the OpenAPI definition or a URL to the
|
||||||
|
definition in JSON or YAML format.
|
||||||
|
- `options`: See [options object](https://redoc.ly/docs/api-reference-docs/configuration/) reference.
|
||||||
|
- `element`: DOM element Redoc will be inserted into.
|
||||||
|
- `callback`(optional): Callback to be called after Redoc has been fully rendered.
|
||||||
|
It is also called on errors with `error` as the first argument.
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
Redoc.init('http://petstore.swagger.io/v2/swagger.json', {
|
||||||
|
scrollYOffset: 50
|
||||||
|
}, document.getElementById('redoc-container'))
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use a local file (JSON or YAML) in your project, for instance:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
Redoc.init('dist.yaml', {
|
||||||
|
scrollYOffset: 50
|
||||||
|
}, document.getElementById('redoc-container'))
|
||||||
|
</script>
|
||||||
|
```
|
44
docs/quickstart/intro.md
Normal file
44
docs/quickstart/intro.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
title: Redoc quickstart guide
|
||||||
|
---
|
||||||
|
|
||||||
|
# Redoc quickstart guide
|
||||||
|
|
||||||
|
This guide includes step-by-step instructions for how to get started using
|
||||||
|
Redoc to render your OpenAPI definition.
|
||||||
|
|
||||||
|
Redoc offers multiple options for rendering your OpenAPI definition.
|
||||||
|
You should select the option that best fits your needs.
|
||||||
|
|
||||||
|
The following options are supported:
|
||||||
|
|
||||||
|
- **[Live demo](https://redocly.github.io/redoc/):**
|
||||||
|
The live demo offers a fast way to see how your OpenAPI will render with Redoc.
|
||||||
|
- **[HTML element](./html.md):**
|
||||||
|
Using the HTML element works well for typical website deployments.
|
||||||
|
- **[React component](./react.md):**
|
||||||
|
Using the React component is an option for users with a React-based application.
|
||||||
|
- **[Docker image](./docker.md):**
|
||||||
|
Using the Docker image works in a container-based deployment.
|
||||||
|
- **[CLI](./cli.md):**
|
||||||
|
Using the CLI is an option for users who prefer to use a command-line interface.
|
||||||
|
|
||||||
|
## Before you start
|
||||||
|
|
||||||
|
You will need an OpenAPI definition. For testing purposes, you can use one of the following sample OpenAPI definitions:
|
||||||
|
- OpenAPI 3.0
|
||||||
|
- [Rebilly Users OpenAPI Definition](https://raw.githubusercontent.com/Rebilly/api-definitions/main/openapi/users.yaml)
|
||||||
|
- [Swagger Petstore Sample OpenAPI Definition](https://petstore3.swagger.io/api/v3/openapi.json)
|
||||||
|
- OpenAPI 2.0
|
||||||
|
- [Thingful OpenAPI Definition](https://raw.githubusercontent.com/thingful/openapi-spec/master/spec/swagger.yaml)
|
||||||
|
- [Fitbit Plus OpenAPI Definition](https://raw.githubusercontent.com/TwineHealth/TwineDeveloperDocs/master/spec/swagger.yaml)
|
||||||
|
|
||||||
|
For more information on the OpenAPI specification, refer to the [Learning OpenAPI 3](https://redoc.ly/docs/resources/learning-openapi/)
|
||||||
|
section in the documentation.
|
||||||
|
|
||||||
|
## Live demo online
|
||||||
|
|
||||||
|
If you want to see how ReDoc will render your OpenAPI definition, you can try it out online at https://redocly.github.io/redoc/.
|
||||||
|
|
||||||
|
A version of the Swagger Petstore API is displayed by default. To test it with your own OpenAPI definition, enter the URL for your
|
||||||
|
definition and select the **TRY IT** button.
|
78
docs/quickstart/react.md
Normal file
78
docs/quickstart/react.md
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
---
|
||||||
|
title: Using the Redoc React component
|
||||||
|
---
|
||||||
|
|
||||||
|
# Using the Redoc React component
|
||||||
|
|
||||||
|
## Before you start
|
||||||
|
|
||||||
|
Install the following dependencies required by Redoc if you do not already have them installed:
|
||||||
|
|
||||||
|
- `react`
|
||||||
|
- `react-dom`
|
||||||
|
- `mobx`
|
||||||
|
- `styled-components`
|
||||||
|
- `core-js`
|
||||||
|
|
||||||
|
If you have npm installed, you can install these dependencies using the following command:
|
||||||
|
|
||||||
|
```js
|
||||||
|
npm i react react-dom mobx styled-components core-js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 1 - Import the `RedocStandalone` component
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { RedocStandalone } from 'redoc';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2 - Use the component
|
||||||
|
|
||||||
|
You can either link to your OpenAPI definition with a URL, using the following format:
|
||||||
|
|
||||||
|
```react
|
||||||
|
<RedocStandalone specUrl="url/to/your/spec"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
Or you can pass your OpenAPI definition as an object, using the following format:
|
||||||
|
|
||||||
|
```js
|
||||||
|
<RedocStandalone spec={/* spec as an object */}/>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Optional - Pass options
|
||||||
|
|
||||||
|
Options can be passed into the RedocStandalone component to alter how it renders.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```js
|
||||||
|
<RedocStandalone
|
||||||
|
specUrl="http://petstore.swagger.io/v2/swagger.json"
|
||||||
|
options={{
|
||||||
|
nativeScrollbars: true,
|
||||||
|
theme: { colors: { primary: { main: '#dd5522' } } },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information on configuration options, refer to the
|
||||||
|
[Configuration options for Reference docs](https://redoc.ly/docs/api-reference-docs/configuration/)
|
||||||
|
section of the documentation. Options available for Redoc are noted,
|
||||||
|
"Supported in Redoc CE".
|
||||||
|
|
||||||
|
## Optional - Specify `onLoaded` callback
|
||||||
|
|
||||||
|
You can also specify the `onLoaded` callback, which is called each time Redoc
|
||||||
|
is fully rendered or when an error occurs (with an error as the first argument).
|
||||||
|
|
||||||
|
```js
|
||||||
|
<RedocStandalone
|
||||||
|
specUrl="http://petstore.swagger.io/v2/swagger.json"
|
||||||
|
onLoaded={error => {
|
||||||
|
if (!error) {
|
||||||
|
console.log('Yay!');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
```
|
13
docs/sidebars.yaml
Normal file
13
docs/sidebars.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
redoc:
|
||||||
|
- group: Quickstart
|
||||||
|
expanded: false
|
||||||
|
page: redoc/quickstart/intro.md
|
||||||
|
pages:
|
||||||
|
- label: HTML element
|
||||||
|
page: redoc/quickstart/html.md
|
||||||
|
- label: React component
|
||||||
|
page: redoc/quickstart/react.md
|
||||||
|
- label: Docker image
|
||||||
|
page: redoc/quickstart/docker.md
|
||||||
|
- label: Command-line interface
|
||||||
|
page: redoc/quickstart/cli.md
|
100
package-lock.json
generated
100
package-lock.json
generated
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "redoc",
|
"name": "redoc",
|
||||||
"version": "2.0.0-rc.54",
|
"version": "2.0.0-rc.56",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "2.0.0-rc.54",
|
"version": "2.0.0-rc.56",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.14.0",
|
"@babel/runtime": "^7.14.0",
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"perfect-scrollbar": "^1.5.1",
|
"perfect-scrollbar": "^1.5.1",
|
||||||
"polished": "^4.1.3",
|
"polished": "^4.1.3",
|
||||||
"prismjs": "^1.23.0",
|
"prismjs": "^1.24.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react-tabs": "^3.2.2",
|
"react-tabs": "^3.2.2",
|
||||||
"slugify": "~1.4.7",
|
"slugify": "~1.4.7",
|
||||||
|
@ -5186,17 +5186,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/clipboard": {
|
|
||||||
"version": "2.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz",
|
|
||||||
"integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"good-listener": "^1.2.2",
|
|
||||||
"select": "^1.1.2",
|
|
||||||
"tiny-emitter": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cliui": {
|
"node_modules/cliui": {
|
||||||
"version": "7.0.4",
|
"version": "7.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||||
|
@ -6686,12 +6675,6 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/delegate": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/delegates": {
|
"node_modules/delegates": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
|
@ -9589,15 +9572,6 @@
|
||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/good-listener": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
|
||||||
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"delegate": "^3.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/graceful-fs": {
|
"node_modules/graceful-fs": {
|
||||||
"version": "4.2.6",
|
"version": "4.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||||
|
@ -15988,12 +15962,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prismjs": {
|
"node_modules/prismjs": {
|
||||||
"version": "1.23.0",
|
"version": "1.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz",
|
||||||
"integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==",
|
"integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow=="
|
||||||
"optionalDependencies": {
|
|
||||||
"clipboard": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/process": {
|
"node_modules/process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
|
@ -17029,12 +17000,6 @@
|
||||||
"url": "https://opencollective.com/webpack"
|
"url": "https://opencollective.com/webpack"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/select": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
|
||||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/select-hose": {
|
"node_modules/select-hose": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||||
|
@ -18755,12 +18720,6 @@
|
||||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/tiny-emitter": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/tmp": {
|
"node_modules/tmp": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||||
|
@ -25034,17 +24993,6 @@
|
||||||
"string-width": "^4.2.0"
|
"string-width": "^4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"clipboard": {
|
|
||||||
"version": "2.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz",
|
|
||||||
"integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==",
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"good-listener": "^1.2.2",
|
|
||||||
"select": "^1.1.2",
|
|
||||||
"tiny-emitter": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cliui": {
|
"cliui": {
|
||||||
"version": "7.0.4",
|
"version": "7.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||||
|
@ -26202,12 +26150,6 @@
|
||||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"delegate": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"delegates": {
|
"delegates": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
|
@ -28470,15 +28412,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"good-listener": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
|
||||||
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"delegate": "^3.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"graceful-fs": {
|
"graceful-fs": {
|
||||||
"version": "4.2.6",
|
"version": "4.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||||
|
@ -33297,12 +33230,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prismjs": {
|
"prismjs": {
|
||||||
"version": "1.23.0",
|
"version": "1.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz",
|
||||||
"integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==",
|
"integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow=="
|
||||||
"requires": {
|
|
||||||
"clipboard": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"process": {
|
"process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
|
@ -34124,12 +34054,6 @@
|
||||||
"ajv-keywords": "^3.5.2"
|
"ajv-keywords": "^3.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"select": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
|
||||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"select-hose": {
|
"select-hose": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||||
|
@ -35533,12 +35457,6 @@
|
||||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"tiny-emitter": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"tmp": {
|
"tmp": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "redoc",
|
"name": "redoc",
|
||||||
"version": "2.0.0-rc.54",
|
"version": "2.0.0-rc.56",
|
||||||
"description": "ReDoc",
|
"description": "ReDoc",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"perfect-scrollbar": "^1.5.1",
|
"perfect-scrollbar": "^1.5.1",
|
||||||
"polished": "^4.1.3",
|
"polished": "^4.1.3",
|
||||||
"prismjs": "^1.23.0",
|
"prismjs": "^1.24.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react-tabs": "^3.2.2",
|
"react-tabs": "^3.2.2",
|
||||||
"slugify": "~1.4.7",
|
"slugify": "~1.4.7",
|
||||||
|
|
|
@ -39,9 +39,9 @@ const isModifiedEvent = (event) =>
|
||||||
export function Link(props: { to: string; className?: string; children?: any }) {
|
export function Link(props: { to: string; className?: string; children?: any }) {
|
||||||
const store = React.useContext(StoreContext);
|
const store = React.useContext(StoreContext);
|
||||||
const clickHandler = React.useCallback(
|
const clickHandler = React.useCallback(
|
||||||
(event) => {
|
(event: React.MouseEvent<HTMLAnchorElement>) => {
|
||||||
if (!store) return;
|
if (!store) return;
|
||||||
navigate(store.menu.history, event);
|
navigate(store.menu.history, event, props.to);
|
||||||
},
|
},
|
||||||
[store],
|
[store],
|
||||||
);
|
);
|
||||||
|
@ -60,14 +60,14 @@ export function Link(props: { to: string; className?: string; children?: any })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigate(history: HistoryService, event) {
|
function navigate(history: HistoryService, event: React.MouseEvent<HTMLAnchorElement>, to: string) {
|
||||||
if (
|
if (
|
||||||
!event.defaultPrevented && // onClick prevented default
|
!event.defaultPrevented && // onClick prevented default
|
||||||
event.button === 0 && // ignore everything but left clicks
|
event.button === 0 && // ignore everything but left clicks
|
||||||
!isModifiedEvent(event) // ignore clicks with modifier keys
|
!isModifiedEvent(event) // ignore clicks with modifier keys
|
||||||
) {
|
) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
history.replace(this.props.to);
|
history.replace(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
InfoSpanBox,
|
InfoSpanBox,
|
||||||
InfoSpanBoxWrap,
|
InfoSpanBoxWrap,
|
||||||
} from './styled.elements';
|
} from './styled.elements';
|
||||||
|
import { l } from '../../services/Labels';
|
||||||
|
|
||||||
export interface ApiInfoProps {
|
export interface ApiInfoProps {
|
||||||
store: AppStore;
|
store: AppStore;
|
||||||
|
@ -79,14 +80,14 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
|
||||||
</ApiHeader>
|
</ApiHeader>
|
||||||
{!hideDownloadButton && (
|
{!hideDownloadButton && (
|
||||||
<p>
|
<p>
|
||||||
Download OpenAPI specification:
|
{l('downloadSpecification')}:
|
||||||
<DownloadButton
|
<DownloadButton
|
||||||
download={downloadFilename || true}
|
download={downloadFilename || true}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={downloadLink}
|
href={downloadLink}
|
||||||
onClick={this.handleDownloadClick}
|
onClick={this.handleDownloadClick}
|
||||||
>
|
>
|
||||||
Download
|
{l('download')}
|
||||||
</DownloadButton>
|
</DownloadButton>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -59,7 +59,7 @@ export class FieldDetails extends React.PureComponent<FieldProps, { patternShown
|
||||||
} else {
|
} else {
|
||||||
const label = l('example') + ':';
|
const label = l('example') + ':';
|
||||||
const raw = !!field.in;
|
const raw = !!field.in;
|
||||||
renderedExamples = <FieldDetail label={label} value={getSerializedValue(field, field.example)} raw={raw} />;
|
renderedExamples = <FieldDetail label={label} value={getSerializedValue(field, field.example)} raw={raw} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,20 @@ export class FieldDetails extends React.PureComponent<FieldProps, { patternShown
|
||||||
>{' '}
|
>{' '}
|
||||||
</TypeFormat>
|
</TypeFormat>
|
||||||
)}
|
)}
|
||||||
|
{schema.contentEncoding && (
|
||||||
|
<TypeFormat>
|
||||||
|
{' '}<
|
||||||
|
{schema.contentEncoding}
|
||||||
|
>{' '}
|
||||||
|
</TypeFormat>
|
||||||
|
)}
|
||||||
|
{schema.contentMediaType && (
|
||||||
|
<TypeFormat>
|
||||||
|
{' '}<
|
||||||
|
{schema.contentMediaType}
|
||||||
|
>{' '}
|
||||||
|
</TypeFormat>
|
||||||
|
)}
|
||||||
{schema.title && !hideSchemaTitles && <TypeTitle> ({schema.title}) </TypeTitle>}
|
{schema.title && !hideSchemaTitles && <TypeTitle> ({schema.title}) </TypeTitle>}
|
||||||
<ConstraintsView constraints={schema.constraints} />
|
<ConstraintsView constraints={schema.constraints} />
|
||||||
{schema.pattern && !hideSchemaPattern && (
|
{schema.pattern && !hideSchemaPattern && (
|
||||||
|
@ -110,7 +124,7 @@ export class FieldDetails extends React.PureComponent<FieldProps, { patternShown
|
||||||
<ExternalDocumentation externalDocs={schema.externalDocs} compact={true} />
|
<ExternalDocumentation externalDocs={schema.externalDocs} compact={true} />
|
||||||
)}
|
)}
|
||||||
{(renderDiscriminatorSwitch && renderDiscriminatorSwitch(this.props)) || null}
|
{(renderDiscriminatorSwitch && renderDiscriminatorSwitch(this.props)) || null}
|
||||||
{field.const && (<FieldDetail label={l('const') + ':'} value={field.const}/>) || null}
|
{field.const && (<FieldDetail label={l('const') + ':'} value={field.const} />) || null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,13 +69,14 @@ function DropdownWithinHeader(props) {
|
||||||
|
|
||||||
export function BodyContent(props: { content: MediaContentModel; description?: string }): JSX.Element {
|
export function BodyContent(props: { content: MediaContentModel; description?: string }): JSX.Element {
|
||||||
const { content, description } = props;
|
const { content, description } = props;
|
||||||
|
const { isRequestType } = content;
|
||||||
return (
|
return (
|
||||||
<MediaTypesSwitch content={content} renderDropdown={DropdownWithinHeader}>
|
<MediaTypesSwitch content={content} renderDropdown={DropdownWithinHeader}>
|
||||||
{({ schema }) => {
|
{({ schema }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{description !== undefined && <Markdown source={description} />}
|
{description !== undefined && <Markdown source={description} />}
|
||||||
<Schema skipReadOnly={true} key="schema" schema={schema} />
|
<Schema skipReadOnly={isRequestType} key="schema" schema={schema} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { RedocNormalizedOptions, RedocRawOptions } from '../services/RedocNormalizedOptions';
|
import { argValueToBoolean, RedocNormalizedOptions, RedocRawOptions } from '../services/RedocNormalizedOptions';
|
||||||
import { ErrorBoundary } from './ErrorBoundary';
|
import { ErrorBoundary } from './ErrorBoundary';
|
||||||
import { Loading } from './Loading/Loading';
|
import { Loading } from './Loading/Loading';
|
||||||
import { Redoc } from './Redoc/Redoc';
|
import { Redoc } from './Redoc/Redoc';
|
||||||
|
@ -15,7 +15,7 @@ export interface RedocStandaloneProps {
|
||||||
|
|
||||||
export const RedocStandalone = function (props: RedocStandaloneProps) {
|
export const RedocStandalone = function (props: RedocStandaloneProps) {
|
||||||
const { spec, specUrl, options = {}, onLoaded } = props;
|
const { spec, specUrl, options = {}, onLoaded } = props;
|
||||||
const hideLoading = options.hideLoading !== undefined;
|
const hideLoading = argValueToBoolean(options.hideLoading, false);
|
||||||
|
|
||||||
const normalizedOpts = new RedocNormalizedOptions(options);
|
const normalizedOpts = new RedocNormalizedOptions(options);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
|
||||||
|
|
||||||
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
|
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
|
||||||
import { OptionsContext } from '../OptionsProvider';
|
import { OptionsContext } from '../OptionsProvider';
|
||||||
|
import { l } from '../../services/Labels';
|
||||||
|
|
||||||
export interface RequestSamplesProps {
|
export interface RequestSamplesProps {
|
||||||
operation: OperationModel;
|
operation: OperationModel;
|
||||||
|
@ -26,7 +27,7 @@ export class RequestSamples extends React.Component<RequestSamplesProps> {
|
||||||
return (
|
return (
|
||||||
(hasSamples && (
|
(hasSamples && (
|
||||||
<div>
|
<div>
|
||||||
<RightPanelHeader> Request samples </RightPanelHeader>
|
<RightPanelHeader> {l('requestSamples')} </RightPanelHeader>
|
||||||
|
|
||||||
<Tabs defaultIndex={0}>
|
<Tabs defaultIndex={0}>
|
||||||
<TabList hidden={hideTabList}>
|
<TabList hidden={hideTabList}>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { OperationModel } from '../../services/models';
|
||||||
|
|
||||||
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
|
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
|
||||||
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
|
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
|
||||||
|
import { l } from '../../services/Labels';
|
||||||
|
|
||||||
export interface ResponseSamplesProps {
|
export interface ResponseSamplesProps {
|
||||||
operation: OperationModel;
|
operation: OperationModel;
|
||||||
|
@ -23,7 +24,7 @@ export class ResponseSamples extends React.Component<ResponseSamplesProps> {
|
||||||
return (
|
return (
|
||||||
(responses.length > 0 && (
|
(responses.length > 0 && (
|
||||||
<div>
|
<div>
|
||||||
<RightPanelHeader> Response samples </RightPanelHeader>
|
<RightPanelHeader> {l('responseSamples')} </RightPanelHeader>
|
||||||
|
|
||||||
<Tabs defaultIndex={0}>
|
<Tabs defaultIndex={0}>
|
||||||
<TabList>
|
<TabList>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { l } from '../../services/Labels';
|
||||||
import { ResponseModel } from '../../services/models';
|
import { ResponseModel } from '../../services/models';
|
||||||
import styled from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
import { ResponseView } from './Response';
|
import { ResponseView } from './Response';
|
||||||
|
@ -26,7 +27,7 @@ export class ResponsesList extends React.PureComponent<ResponseListProps> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ResponsesHeader>{isCallback ? 'Callback responses' : 'Responses'}</ResponsesHeader>
|
<ResponsesHeader>{isCallback ? l('callbackResponses') : l('responses')}</ResponsesHeader>
|
||||||
{responses.map(response => {
|
{responses.map(response => {
|
||||||
return <ResponseView key={response.code} response={response} />;
|
return <ResponseView key={response.code} response={response} />;
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -4,7 +4,8 @@ import { Schema, SchemaProps } from './Schema';
|
||||||
|
|
||||||
import { ArrayClosingLabel, ArrayOpenningLabel } from '../../common-elements';
|
import { ArrayClosingLabel, ArrayOpenningLabel } from '../../common-elements';
|
||||||
import styled from '../../styled-components';
|
import styled from '../../styled-components';
|
||||||
import {humanizeConstraints} from "../../utils";
|
import { humanizeConstraints } from '../../utils';
|
||||||
|
import { TypeName } from '../../common-elements/fields';
|
||||||
|
|
||||||
const PaddedSchema = styled.div`
|
const PaddedSchema = styled.div`
|
||||||
padding-left: ${({ theme }) => theme.spacing.unit * 2}px;
|
padding-left: ${({ theme }) => theme.spacing.unit * 2}px;
|
||||||
|
@ -13,12 +14,20 @@ const PaddedSchema = styled.div`
|
||||||
export class ArraySchema extends React.PureComponent<SchemaProps> {
|
export class ArraySchema extends React.PureComponent<SchemaProps> {
|
||||||
render() {
|
render() {
|
||||||
const itemsSchema = this.props.schema.items!;
|
const itemsSchema = this.props.schema.items!;
|
||||||
|
const schema = this.props.schema;
|
||||||
|
|
||||||
const itemConstraintSchema = (
|
const itemConstraintSchema = (
|
||||||
min: number | undefined = undefined,
|
min: number | undefined = undefined,
|
||||||
max: number | undefined = undefined,
|
max: number | undefined = undefined,
|
||||||
) => ({ type: 'array', minItems: min, maxItems: max });
|
) => ({ type: 'array', minItems: min, maxItems: max });
|
||||||
|
|
||||||
const minMaxItems = humanizeConstraints(itemConstraintSchema(itemsSchema.schema.minItems, itemsSchema.schema.maxItems));
|
const minMaxItems = humanizeConstraints(itemConstraintSchema(itemsSchema?.schema?.minItems, itemsSchema?.schema?.maxItems));
|
||||||
|
|
||||||
|
if (schema.displayType && !itemsSchema && !minMaxItems.length) {
|
||||||
|
return (<div>
|
||||||
|
<TypeName>{schema.displayType}</TypeName>
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -63,20 +63,15 @@ export class Schema extends React.Component<Partial<SchemaProps>> {
|
||||||
return <OneOfSchema schema={schema} {...this.props} />;
|
return <OneOfSchema schema={schema} {...this.props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type && Array.isArray(type)) {
|
const types = Array.isArray(type) ? type : [type];
|
||||||
|
if (types.includes('object')) {
|
||||||
|
if (schema.fields?.length) {
|
||||||
|
return <ObjectSchema {...(this.props as any)} />;
|
||||||
|
}
|
||||||
|
} else if (types.includes('array')) {
|
||||||
return <ArraySchema {...(this.props as any)} />;
|
return <ArraySchema {...(this.props as any)} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 'object':
|
|
||||||
if (schema.fields?.length) {
|
|
||||||
return <ObjectSchema {...(this.props as any)} />;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'array':
|
|
||||||
return <ArraySchema {...(this.props as any)} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: maybe adjust FieldDetails to accept schema
|
// TODO: maybe adjust FieldDetails to accept schema
|
||||||
const field = ({
|
const field = ({
|
||||||
schema,
|
schema,
|
||||||
|
|
|
@ -8,8 +8,8 @@ import { SecurityRequirementModel } from '../../services/models/SecurityRequirem
|
||||||
import { linksCss } from '../Markdown/styled.elements';
|
import { linksCss } from '../Markdown/styled.elements';
|
||||||
|
|
||||||
const ScopeName = styled.code`
|
const ScopeName = styled.code`
|
||||||
font-size: ${props => props.theme.typography.code.fontSize};
|
font-size: ${(props) => props.theme.typography.code.fontSize};
|
||||||
font-family: ${props => props.theme.typography.code.fontFamily};
|
font-family: ${(props) => props.theme.typography.code.fontFamily};
|
||||||
border: 1px solid ${({ theme }) => theme.colors.border.dark};
|
border: 1px solid ${({ theme }) => theme.colors.border.dark};
|
||||||
margin: 0 3px;
|
margin: 0 3px;
|
||||||
padding: 0.2em;
|
padding: 0.2em;
|
||||||
|
@ -67,18 +67,22 @@ export class SecurityRequirement extends React.PureComponent<SecurityRequirement
|
||||||
const security = this.props.security;
|
const security = this.props.security;
|
||||||
return (
|
return (
|
||||||
<SecurityRequirementOrWrap>
|
<SecurityRequirementOrWrap>
|
||||||
{security.schemes.map(scheme => {
|
{security.schemes.length ? (
|
||||||
return (
|
security.schemes.map((scheme) => {
|
||||||
<SecurityRequirementAndWrap key={scheme.id}>
|
return (
|
||||||
<Link to={scheme.sectionId}>{scheme.id}</Link>
|
<SecurityRequirementAndWrap key={scheme.id}>
|
||||||
{scheme.scopes.length > 0 && ' ('}
|
<Link to={scheme.sectionId}>{scheme.id}</Link>
|
||||||
{scheme.scopes.map(scope => (
|
{scheme.scopes.length > 0 && ' ('}
|
||||||
<ScopeName key={scope}>{scope}</ScopeName>
|
{scheme.scopes.map((scope) => (
|
||||||
))}
|
<ScopeName key={scope}>{scope}</ScopeName>
|
||||||
{scheme.scopes.length > 0 && ') '}
|
))}
|
||||||
</SecurityRequirementAndWrap>
|
{scheme.scopes.length > 0 && ') '}
|
||||||
);
|
</SecurityRequirementAndWrap>
|
||||||
})}
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<SecurityRequirementAndWrap>None</SecurityRequirementAndWrap>
|
||||||
|
)}
|
||||||
</SecurityRequirementOrWrap>
|
</SecurityRequirementOrWrap>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +93,7 @@ const AuthHeaderColumn = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const SecuritiesColumn = styled.div`
|
const SecuritiesColumn = styled.div`
|
||||||
width: ${props => props.theme.schema.defaultDetailsWidth};
|
width: ${(props) => props.theme.schema.defaultDetailsWidth};
|
||||||
${media.lessThan('small')`
|
${media.lessThan('small')`
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
`}
|
`}
|
||||||
|
|
|
@ -58,6 +58,12 @@ export function StoreBuilder(props: StoreBuilderProps) {
|
||||||
}
|
}
|
||||||
}, [resolvedSpec, specUrl, options]);
|
}, [resolvedSpec, specUrl, options]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (store && onLoaded) {
|
||||||
|
onLoaded();
|
||||||
|
}
|
||||||
|
}, [store, onLoaded])
|
||||||
|
|
||||||
return children({
|
return children({
|
||||||
loading: !store,
|
loading: !store,
|
||||||
store,
|
store,
|
||||||
|
|
27
src/components/__tests__/SecurityRequirement.test.tsx
Normal file
27
src/components/__tests__/SecurityRequirement.test.tsx
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
|
import { OpenAPIParser } from '../../services';
|
||||||
|
import { SecurityRequirementModel } from '../../services/models/SecurityRequirement';
|
||||||
|
import { SecurityRequirement } from '../SecurityRequirement/SecurityRequirement';
|
||||||
|
import { RedocNormalizedOptions } from '../../services/RedocNormalizedOptions';
|
||||||
|
|
||||||
|
const options = new RedocNormalizedOptions({});
|
||||||
|
describe('Components', () => {
|
||||||
|
describe('SecurityRequirement', () => {
|
||||||
|
describe('SecurityRequirement', () => {
|
||||||
|
it('should render \'None\' when empty object in security open api', () => {
|
||||||
|
const parser = new OpenAPIParser({ openapi: '3.0', info: { title: 'test', version: '0' }, paths: {} },
|
||||||
|
undefined,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
const securityRequirement = new SecurityRequirementModel({}, parser);
|
||||||
|
const securityElement = shallow(
|
||||||
|
<SecurityRequirement key={1} security={securityRequirement} />
|
||||||
|
).getElement();
|
||||||
|
expect(securityElement.props.children.type.target).toEqual('span');
|
||||||
|
expect(securityElement.props.children.props.children).toEqual('None');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -20,6 +20,8 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
||||||
"activeOneOf": 0,
|
"activeOneOf": 0,
|
||||||
"const": "",
|
"const": "",
|
||||||
"constraints": Array [],
|
"constraints": Array [],
|
||||||
|
"contentEncoding": undefined,
|
||||||
|
"contentMediaType": undefined,
|
||||||
"default": undefined,
|
"default": undefined,
|
||||||
"deprecated": false,
|
"deprecated": false,
|
||||||
"description": "",
|
"description": "",
|
||||||
|
@ -71,6 +73,8 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
||||||
"activeOneOf": 0,
|
"activeOneOf": 0,
|
||||||
"const": "",
|
"const": "",
|
||||||
"constraints": Array [],
|
"constraints": Array [],
|
||||||
|
"contentEncoding": undefined,
|
||||||
|
"contentMediaType": undefined,
|
||||||
"default": undefined,
|
"default": undefined,
|
||||||
"deprecated": false,
|
"deprecated": false,
|
||||||
"description": "",
|
"description": "",
|
||||||
|
|
|
@ -10,6 +10,12 @@ export interface LabelsConfig {
|
||||||
arrayOf: string;
|
arrayOf: string;
|
||||||
webhook: string;
|
webhook: string;
|
||||||
const: string;
|
const: string;
|
||||||
|
download: string;
|
||||||
|
downloadSpecification: string;
|
||||||
|
responses: string;
|
||||||
|
callbackResponses: string;
|
||||||
|
requestSamples: string;
|
||||||
|
responseSamples: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LabelsConfigRaw = Partial<LabelsConfig>;
|
export type LabelsConfigRaw = Partial<LabelsConfig>;
|
||||||
|
@ -26,6 +32,12 @@ const labels: LabelsConfig = {
|
||||||
arrayOf: 'Array of ',
|
arrayOf: 'Array of ',
|
||||||
webhook: 'Event',
|
webhook: 'Event',
|
||||||
const: 'Value',
|
const: 'Value',
|
||||||
|
download: 'Download',
|
||||||
|
downloadSpecification: 'Download OpenAPI specification',
|
||||||
|
responses: 'Responses',
|
||||||
|
callbackResponses: 'Callback responses',
|
||||||
|
requestSamples: 'Request samples',
|
||||||
|
responseSamples: 'Response samples',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function setRedocLabels(_labels?: LabelsConfigRaw) {
|
export function setRedocLabels(_labels?: LabelsConfigRaw) {
|
||||||
|
|
|
@ -45,12 +45,12 @@ export interface RedocRawOptions {
|
||||||
generatedPayloadSamplesMaxDepth?: number;
|
generatedPayloadSamplesMaxDepth?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function argValueToBoolean(val?: string | boolean, defaultValue?: boolean): boolean {
|
export function argValueToBoolean(val?: string | boolean, defaultValue?: boolean): boolean {
|
||||||
if (val === undefined) {
|
if (val === undefined) {
|
||||||
return defaultValue || false;
|
return defaultValue || false;
|
||||||
}
|
}
|
||||||
if (typeof val === 'string') {
|
if (typeof val === 'string') {
|
||||||
return val === 'false' ? false : true;
|
return val !== 'false';
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
27
src/services/__tests__/models/RequestBody.test.ts
Normal file
27
src/services/__tests__/models/RequestBody.test.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { RequestBodyModel } from '../../models/RequestBody';
|
||||||
|
import { OpenAPIParser } from '../../OpenAPIParser';
|
||||||
|
import { RedocNormalizedOptions } from '../../RedocNormalizedOptions';
|
||||||
|
|
||||||
|
const opts = new RedocNormalizedOptions({});
|
||||||
|
describe('Models', () => {
|
||||||
|
describe('RequestBodyModel', () => {
|
||||||
|
let parser, props;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
parser = new OpenAPIParser({ openapi: '3.0.0' } as any, undefined, opts);
|
||||||
|
props = {
|
||||||
|
parser,
|
||||||
|
infoOrRef: {},
|
||||||
|
options: opts,
|
||||||
|
isEvent: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should work with default props', () => {
|
||||||
|
const consoleError = jest.spyOn(global.console, 'error');
|
||||||
|
const req = new RequestBodyModel(props);
|
||||||
|
expect(consoleError).not.toHaveBeenCalled();
|
||||||
|
expect(req).toEqual({ description: '', required: false });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -5,30 +5,38 @@ import { RedocNormalizedOptions } from '../../RedocNormalizedOptions';
|
||||||
const opts = new RedocNormalizedOptions({});
|
const opts = new RedocNormalizedOptions({});
|
||||||
describe('Models', () => {
|
describe('Models', () => {
|
||||||
describe('ResponseModel', () => {
|
describe('ResponseModel', () => {
|
||||||
let parser;
|
let parser, props;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
parser = new OpenAPIParser({ openapi: '3.0.0' } as any, undefined, opts);
|
parser = new OpenAPIParser({ openapi: '3.0.0' } as any, undefined, opts);
|
||||||
|
props = {
|
||||||
|
parser,
|
||||||
|
defaultAsError: false,
|
||||||
|
infoOrRef: {},
|
||||||
|
options: opts,
|
||||||
|
isEvent: false,
|
||||||
|
code: 'default',
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should calculate response type based on code', () => {
|
test('should calculate response type based on code', () => {
|
||||||
let resp = new ResponseModel(parser, '200', false, {}, opts);
|
let resp = new ResponseModel({...props, code: '200' });
|
||||||
expect(resp.type).toEqual('success');
|
expect(resp.type).toEqual('success');
|
||||||
resp = new ResponseModel(parser, '120', false, {}, opts);
|
resp = new ResponseModel({...props, code: '120' });
|
||||||
expect(resp.type).toEqual('info');
|
expect(resp.type).toEqual('info');
|
||||||
resp = new ResponseModel(parser, '301', false, {}, opts);
|
resp = new ResponseModel({...props, code: '301' });
|
||||||
expect(resp.type).toEqual('redirect');
|
expect(resp.type).toEqual('redirect');
|
||||||
resp = new ResponseModel(parser, '400', false, {}, opts);
|
resp = new ResponseModel({...props, code: '400' });
|
||||||
expect(resp.type).toEqual('error');
|
expect(resp.type).toEqual('error');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('default should be successful by default', () => {
|
test('default should be successful by default', () => {
|
||||||
const resp = new ResponseModel(parser, 'default', false, {}, opts);
|
const resp = new ResponseModel({...props, code: 'default' });
|
||||||
expect(resp.type).toEqual('success');
|
expect(resp.type).toEqual('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('default should be error if defaultAsError is true', () => {
|
test('default should be error if defaultAsError is true', () => {
|
||||||
const resp = new ResponseModel(parser, 'default', true, {}, opts);
|
const resp = new ResponseModel({...props, code: 'default', defaultAsError: true });
|
||||||
expect(resp.type).toEqual('error');
|
expect(resp.type).toEqual('error');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -53,8 +53,8 @@ export class MediaTypeModel {
|
||||||
generateExample(parser: OpenAPIParser, info: OpenAPIMediaType) {
|
generateExample(parser: OpenAPIParser, info: OpenAPIMediaType) {
|
||||||
const samplerOptions = {
|
const samplerOptions = {
|
||||||
skipReadOnly: this.isRequestType,
|
skipReadOnly: this.isRequestType,
|
||||||
skipNonRequired: this.isRequestType && this.onlyRequiredInSamples,
|
|
||||||
skipWriteOnly: !this.isRequestType,
|
skipWriteOnly: !this.isRequestType,
|
||||||
|
skipNonRequired: this.isRequestType && this.onlyRequiredInSamples,
|
||||||
maxSampleDepth: this.generatedPayloadSamplesMaxDepth,
|
maxSampleDepth: this.generatedPayloadSamplesMaxDepth,
|
||||||
};
|
};
|
||||||
if (this.schema && this.schema.oneOf) {
|
if (this.schema && this.schema.oneOf) {
|
||||||
|
|
|
@ -76,6 +76,7 @@ export class OperationModel implements IMenuItem {
|
||||||
extensions: Record<string, any>;
|
extensions: Record<string, any>;
|
||||||
isCallback: boolean;
|
isCallback: boolean;
|
||||||
isWebhook: boolean;
|
isWebhook: boolean;
|
||||||
|
isEvent: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private parser: OpenAPIParser,
|
private parser: OpenAPIParser,
|
||||||
|
@ -98,7 +99,8 @@ export class OperationModel implements IMenuItem {
|
||||||
this.operationId = operationSpec.operationId;
|
this.operationId = operationSpec.operationId;
|
||||||
this.path = operationSpec.pathName;
|
this.path = operationSpec.pathName;
|
||||||
this.isCallback = isCallback;
|
this.isCallback = isCallback;
|
||||||
this.isWebhook = !!operationSpec.isWebhook;
|
this.isWebhook = operationSpec.isWebhook;
|
||||||
|
this.isEvent = this.isCallback || this.isWebhook;
|
||||||
|
|
||||||
this.name = getOperationSummary(operationSpec);
|
this.name = getOperationSummary(operationSpec);
|
||||||
|
|
||||||
|
@ -171,8 +173,12 @@ export class OperationModel implements IMenuItem {
|
||||||
@memoize
|
@memoize
|
||||||
get requestBody() {
|
get requestBody() {
|
||||||
return (
|
return (
|
||||||
this.operationSpec.requestBody &&
|
this.operationSpec.requestBody && new RequestBodyModel({
|
||||||
new RequestBodyModel(this.parser, this.operationSpec.requestBody, this.options)
|
parser: this.parser,
|
||||||
|
infoOrRef: this.operationSpec.requestBody,
|
||||||
|
options: this.options,
|
||||||
|
isEvent: this.isEvent,
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,13 +246,14 @@ export class OperationModel implements IMenuItem {
|
||||||
return isStatusCode(code);
|
return isStatusCode(code);
|
||||||
}) // filter out other props (e.g. x-props)
|
}) // filter out other props (e.g. x-props)
|
||||||
.map((code) => {
|
.map((code) => {
|
||||||
return new ResponseModel(
|
return new ResponseModel({
|
||||||
this.parser,
|
parser: this.parser,
|
||||||
code,
|
code,
|
||||||
hasSuccessResponses,
|
defaultAsError: hasSuccessResponses,
|
||||||
this.operationSpec.responses[code],
|
infoOrRef: this.operationSpec.responses[code],
|
||||||
this.options,
|
options: this.options,
|
||||||
);
|
isEvent: this.isEvent,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,22 +4,27 @@ import { OpenAPIParser } from '../OpenAPIParser';
|
||||||
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
|
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
|
||||||
import { MediaContentModel } from './MediaContent';
|
import { MediaContentModel } from './MediaContent';
|
||||||
|
|
||||||
|
type RequestBodyProps = {
|
||||||
|
parser: OpenAPIParser;
|
||||||
|
infoOrRef: Referenced<OpenAPIRequestBody>;
|
||||||
|
options: RedocNormalizedOptions;
|
||||||
|
isEvent: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class RequestBodyModel {
|
export class RequestBodyModel {
|
||||||
description: string;
|
description: string;
|
||||||
required: boolean;
|
required: boolean;
|
||||||
content?: MediaContentModel;
|
content?: MediaContentModel;
|
||||||
|
|
||||||
constructor(
|
constructor(props: RequestBodyProps) {
|
||||||
parser: OpenAPIParser,
|
const { parser, infoOrRef, options, isEvent } = props;
|
||||||
infoOrRef: Referenced<OpenAPIRequestBody>,
|
const isRequest = isEvent ? false : true;
|
||||||
options: RedocNormalizedOptions,
|
|
||||||
) {
|
|
||||||
const info = parser.deref(infoOrRef);
|
const info = parser.deref(infoOrRef);
|
||||||
this.description = info.description || '';
|
this.description = info.description || '';
|
||||||
this.required = !!info.required;
|
this.required = !!info.required;
|
||||||
parser.exitRef(infoOrRef);
|
parser.exitRef(infoOrRef);
|
||||||
if (info.content !== undefined) {
|
if (info.content !== undefined) {
|
||||||
this.content = new MediaContentModel(parser, info.content, true, options);
|
this.content = new MediaContentModel(parser, info.content, isRequest, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,15 @@ import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
|
||||||
import { FieldModel } from './Field';
|
import { FieldModel } from './Field';
|
||||||
import { MediaContentModel } from './MediaContent';
|
import { MediaContentModel } from './MediaContent';
|
||||||
|
|
||||||
|
type ResponseProps = {
|
||||||
|
parser: OpenAPIParser,
|
||||||
|
code: string,
|
||||||
|
defaultAsError: boolean,
|
||||||
|
infoOrRef: Referenced<OpenAPIResponse>,
|
||||||
|
options: RedocNormalizedOptions,
|
||||||
|
isEvent: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
export class ResponseModel {
|
export class ResponseModel {
|
||||||
@observable
|
@observable
|
||||||
expanded: boolean = false;
|
expanded: boolean = false;
|
||||||
|
@ -19,13 +28,9 @@ export class ResponseModel {
|
||||||
type: string;
|
type: string;
|
||||||
headers: FieldModel[] = [];
|
headers: FieldModel[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(props: ResponseProps) {
|
||||||
parser: OpenAPIParser,
|
const { parser, code, defaultAsError, infoOrRef, options, isEvent } = props;
|
||||||
code: string,
|
const isRequest = isEvent ? true : false;
|
||||||
defaultAsError: boolean,
|
|
||||||
infoOrRef: Referenced<OpenAPIResponse>,
|
|
||||||
options: RedocNormalizedOptions,
|
|
||||||
) {
|
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
|
|
||||||
this.expanded = options.expandResponses === 'all' || options.expandResponses[code];
|
this.expanded = options.expandResponses === 'all' || options.expandResponses[code];
|
||||||
|
@ -34,7 +39,7 @@ export class ResponseModel {
|
||||||
parser.exitRef(infoOrRef);
|
parser.exitRef(infoOrRef);
|
||||||
this.code = code;
|
this.code = code;
|
||||||
if (info.content !== undefined) {
|
if (info.content !== undefined) {
|
||||||
this.content = new MediaContentModel(parser, info.content, false, options);
|
this.content = new MediaContentModel(parser, info.content, isRequest, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info['x-summary'] !== undefined) {
|
if (info['x-summary'] !== undefined) {
|
||||||
|
|
|
@ -61,6 +61,8 @@ export class SchemaModel {
|
||||||
schema: MergedOpenAPISchema;
|
schema: MergedOpenAPISchema;
|
||||||
extensions?: Record<string, any>;
|
extensions?: Record<string, any>;
|
||||||
const: any;
|
const: any;
|
||||||
|
contentEncoding?: string;
|
||||||
|
contentMediaType?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param isChild if schema discriminator Child
|
* @param isChild if schema discriminator Child
|
||||||
|
@ -98,6 +100,10 @@ export class SchemaModel {
|
||||||
this.activeOneOf = idx;
|
this.activeOneOf = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasType(type: string) {
|
||||||
|
return this.type === type || (Array.isArray(this.type) && this.type.includes(type));
|
||||||
|
}
|
||||||
|
|
||||||
init(parser: OpenAPIParser, isChild: boolean) {
|
init(parser: OpenAPIParser, isChild: boolean) {
|
||||||
const schema = this.schema;
|
const schema = this.schema;
|
||||||
this.isCircular = schema['x-circular-ref'];
|
this.isCircular = schema['x-circular-ref'];
|
||||||
|
@ -120,10 +126,14 @@ export class SchemaModel {
|
||||||
this.readOnly = !!schema.readOnly;
|
this.readOnly = !!schema.readOnly;
|
||||||
this.writeOnly = !!schema.writeOnly;
|
this.writeOnly = !!schema.writeOnly;
|
||||||
this.const = schema.const || '';
|
this.const = schema.const || '';
|
||||||
|
this.contentEncoding = schema.contentEncoding;
|
||||||
|
this.contentMediaType = schema.contentMediaType;
|
||||||
|
|
||||||
if (!!schema.nullable) {
|
if (!!schema.nullable || schema['x-nullable']) {
|
||||||
if (Array.isArray(this.type) && !this.type.includes('null')) {
|
if (Array.isArray(this.type) && !this.type.some((value) => value === null || value === 'null')) {
|
||||||
this.type = [...this.type, 'null'];
|
this.type = [...this.type, 'null'];
|
||||||
|
} else if (!Array.isArray(this.type) && (this.type !== null || this.type !== 'null')) {
|
||||||
|
this.type = [this.type, 'null'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,9 +174,9 @@ export class SchemaModel {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.type === 'object') {
|
if (this.hasType('object')) {
|
||||||
this.fields = buildFields(parser, schema, this.pointer, this.options);
|
this.fields = buildFields(parser, schema, this.pointer, this.options);
|
||||||
} else if ((this.type === 'array' || Array.isArray(this.type)) && schema.items) {
|
} else if (this.hasType('array') && schema.items) {
|
||||||
this.items = new SchemaModel(parser, schema.items, this.pointer + '/items', this.options);
|
this.items = new SchemaModel(parser, schema.items, this.pointer + '/items', this.options);
|
||||||
this.displayType = pluralizeType(this.items.displayType);
|
this.displayType = pluralizeType(this.items.displayType);
|
||||||
this.displayFormat = this.items.format;
|
this.displayFormat = this.items.format;
|
||||||
|
|
|
@ -147,6 +147,8 @@ export interface OpenAPISchema {
|
||||||
enum?: any[];
|
enum?: any[];
|
||||||
example?: any;
|
example?: any;
|
||||||
const?: string;
|
const?: string;
|
||||||
|
contentEncoding?: string;
|
||||||
|
contentMediaType?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenAPIDiscriminator {
|
export interface OpenAPIDiscriminator {
|
||||||
|
|
|
@ -2187,6 +2187,12 @@ Object {
|
||||||
"id": Object {
|
"id": Object {
|
||||||
"$ref": "#/components/schemas/Id",
|
"$ref": "#/components/schemas/Id",
|
||||||
},
|
},
|
||||||
|
"image": Object {
|
||||||
|
"contentEncoding": "base64",
|
||||||
|
"contentMediaType": "image/png",
|
||||||
|
"description": "User image",
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
"lastName": Object {
|
"lastName": Object {
|
||||||
"description": "User last name",
|
"description": "User last name",
|
||||||
"example": "Smith",
|
"example": "Smith",
|
||||||
|
|
|
@ -19,6 +19,7 @@ import 'prismjs/components/prism-ruby.js';
|
||||||
import 'prismjs/components/prism-scala.js';
|
import 'prismjs/components/prism-scala.js';
|
||||||
import 'prismjs/components/prism-sql.js';
|
import 'prismjs/components/prism-sql.js';
|
||||||
import 'prismjs/components/prism-swift.js';
|
import 'prismjs/components/prism-swift.js';
|
||||||
|
import 'prismjs/components/prism-yaml.js';
|
||||||
|
|
||||||
const DEFAULT_LANG = 'clike';
|
const DEFAULT_LANG = 'clike';
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,8 @@ const schemaKeywordTypes = {
|
||||||
maxLength: 'string',
|
maxLength: 'string',
|
||||||
minLength: 'string',
|
minLength: 'string',
|
||||||
pattern: 'string',
|
pattern: 'string',
|
||||||
|
contentEncoding: 'string',
|
||||||
|
contentMediaType: 'string',
|
||||||
|
|
||||||
items: 'array',
|
items: 'array',
|
||||||
maxItems: 'array',
|
maxItems: 'array',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user