chore: merge master into

This commit is contained in:
Andriy Zaleskyy 2021-10-11 15:58:47 +03:00
commit 032caeb952
22 changed files with 488 additions and 120 deletions

View File

@ -1,42 +0,0 @@
name: Redoc demo CI/CD
on:
push:
tags:
- v[0-9]*.[0-9]*.[0-9]*
jobs:
build-and-unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: npm ci
- run: npm run bundle
- run: npm test
deploy:
needs: build-and-unit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: cache node modules
uses: actions/cache@v1
with:
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Install dependencies
run: npm ci
- name: Build package
run: npm run build:demo
- name: Deploy to S3 bucket
run: npm run deploy:demo
- name: Invalidate
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CF_DEMO_DISTRIBUTION_ID }} --paths "/*"

12
.github/workflows/e2e-tests.yml vendored Normal file
View File

@ -0,0 +1,12 @@
name: Tests e2e
on: [push]
jobs:
build-and-e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: npm ci
- run: npm run bundle
- run: npm run e2e

115
.github/workflows/publish-cli.yml vendored Normal file
View File

@ -0,0 +1,115 @@
name: Publish cli
on:
push:
tags:
- v[0-9]*.[0-9]*.[0-9]*
jobs:
bundle:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- name: Cache node modules
uses: actions/cache@v2
with:
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- run: npm ci
- run: npm run bundle
- name: Store bundle artifact
uses: actions/upload-artifact@v2
with:
name: bundles-cli
path: bundles
retention-days: 1
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: npm ci
- run: npm test
e2e-tests:
needs: [bundle]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: npm ci
- name: Download bundled artifact
uses: actions/download-artifact@v2
with:
name: bundles
path: bundles-cli
- run: npm run e2e
bundle-cli:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- name: Cache node modules
uses: actions/cache@v2
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- name: Install dependencies
run: npm ci
- name: Bundle
run: npm run compile:cli
- name: Store bundle artifact
uses: actions/upload-artifact@v2
with:
name: cli
path: cli
retention-days: 1
check-version-cli:
name: Check Version
runs-on: ubuntu-latest
needs: [bundle-cli, unit-tests, e2e-tests]
outputs:
changed: ${{ steps.check.outputs.changed }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
- name: Check if version has been updated
id: check
uses: EndBug/version-check@v2.0.1
with:
file-name: ./cli/package.json
file-url: https://unpkg.com/redoc-cli/package.json
static-checking: localIsNew
publish-cli:
needs: [ check-version-cli ]
if: needs.check-version-cli.outputs.changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v1
with:
node-version: "14.x"
- uses: actions/checkout@v2
- name: Download cli bundled artifact
uses: actions/download-artifact@v2
with:
name: cli
path: cli
- name: Cache node modules
uses: actions/cache@v2
with:
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- name: Publish to NPM
run: cd cli/ && npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

100
.github/workflows/publish.yml vendored Normal file
View File

@ -0,0 +1,100 @@
name: Publish
on:
push:
tags:
- v[0-9]*.[0-9]*.[0-9]*
jobs:
bundle:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- name: Cache node modules
uses: actions/cache@v2
with:
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- run: npm ci
- run: npm run bundle
- name: Store bundle artifact
uses: actions/upload-artifact@v2
with:
name: bundles
path: bundles
retention-days: 1
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: npm ci
- run: npm test
e2e-tests:
needs: [bundle]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: npm ci
- name: Download bundled artifact
uses: actions/download-artifact@v2
with:
name: bundles
path: bundles
- run: npm run e2e
deploy-demo:
needs: [bundle, unit-tests, e2e-tests]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Install dependencies
run: npm ci
- name: Download bundled artifacts
uses: actions/download-artifact@v2
with:
name: bundles
path: bundles
- name: Build package
run: npm run build:demo
- name: Deploy to S3 bucket
run: npm run deploy:demo
- name: Invalidate
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CF_DEMO_DISTRIBUTION_ID }} --paths "/*"
publish:
needs: [bundle, unit-tests, e2e-tests]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v1
with:
node-version: "14.x"
- uses: actions/checkout@v2
- name: Download bundled artifacts
uses: actions/download-artifact@v2
with:
name: bundles
path: bundles
- name: Cache node modules
uses: actions/cache@v2
with:
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ hashFiles('package-lock.json') }}
npm-
- name: Before deploy
run: npm run declarations
- name: Publish to NPM
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: After script
run: cat ./coverage/lcov.info | coveralls

View File

@ -1,32 +0,0 @@
language: node_js
node_js:
- '12'
cache:
directories:
- "~/.cache"
env:
global:
- GH_REF: github.com/Redocly/redoc.git
- GIT_AUTHOR_EMAIL: redoc-bot@users.noreply.github.com
- GIT_AUTHOR_NAME: RedocBot
- secure: apiavCfCQngL9Een1m7MIXMf3bqO3rY4YY59TMBl/yFKi80CEsHPHhgVUkl6hC+aM5PeBt/vgjh37rHMX31j/pcSZ4Z8SO/4Bwr36iHfhSxSEuAQog8P07qWqH7wYYWGIVmF682stgl0fYF+GN92sx/6edFVzsWVECf2G7imtICKSTbhKGm3Dhn2JwGnhD7eyfgZ33omgiaswumdu0xABoXDfqSZR+16fC4Ap5rhv3fXO9ndvRNy1STn376nT+my6e86UrQL4aS/S+HNHgIe1BUs+5cOp6Jgw6t0ie7phY0EAiECsRxy9K4e3Dctv9m6+Wma4+vy65MS0zGyrqey6oyV4l827sCOjrD1qcqc9bX6FlMSouVoNfE4ZjINNAbgigTaiLSoDSPcf5I5smkkM2ezzFOMSZwZxNdaNL2LKb97vc8m/ZUkv0sKZyT7oqVL7aJweEivsSHj5l2KR8Z7XrVB1y2eI6GvyTSa/d+CL4dSRzjh8+IRN047YBrdTKD5IkdT0upfoBu14WPUfFmLKxX+iMCslXRWb6kwojhrWNYmZvL65KRAzJ6+eIPDG/W5QUOpYyYT77bLlBQjVo6NmVvl9v3HMECq9CHH0ivKFBGPiKMOx7cJkTax3FuyznOW2WCXB9kTb5Zk9toaiNlSp9L6ll/h2Eyxa6n6sWUgmmM=
- secure: vVRg9BKGBwF2MbXQnEccFL+XW0/7RaBmge9k7jbGYScBwkP3XjnQ/Xaj0cvTz2CM2EqXsbpwfvr4Jo+enW/E3MGy5RiEzv5hUe/jIFRR0gfAFbZxSTvg5xiFhTDffqQk0fncO4jXu+wPO5lZ2CMRWzyXz3i1MZhjMcAgoDr1+TRss/EGXLNHxr2RM88tpUW0fV2prIRoyGqhCgnYZtrm7hmr41Ej+itg1MqZLml/Rjkt3KsNgI+z0O5Qn3QSAO8GtPZqeftQxAjevOmxZGcssxY8EJvqbjAujr4y51WncXpEmCRPSY2J9R5+fkgZurqwnJapbQpjwKYemok3ps7EHg2gWkAlmPdQO4LKpbffGkM/o5b+8+HdIuQZugsSWQD9hUSftTAFLcfA1isi7V2lHE1m8bX/vk9zIyDdcPSwIaFe9y+w3PexwFmTjPLq+nia/UY2kARFZMEIFAJby6gkA70DcAJ50QOM86InJu5DSzGbIssgTGAXCn0TPPyGveaurVLw8x61j3yh8LDF46gUHey3rqv6WjpCM9h/vg7X/gq5ve/5Q2KHscUKfs/sA53Mt7qPeqRZY1QCaaRjzqJO/ZraHqWWeKmPKaWhPGR0kYEnkvB+K9GZ+HNSWCltjCO4SJ1xeEl7CRqQxAwdiMATF5SKqyiC+bn5oc35mFgbRF8=
- secure: ela1tn4wkJQZ8O4iv+4pIZi5cebxeCStVF1tEUe6qa6WWgJYVXmS2tEv3QQ36NUBFrP58Y6yl10XguPnvj/2BCqcZI4FUBHh3BfiBoUtXxDCVKI5LtlniNiOFGUwfzEeYka8T51zFlcUXSCCaxHkRZbmBsIzeJ39UwTi5fy0qwLv9GgL0czhwm8I8sZ8gyWdGmqpXNFEsb9JP4ZA3mw2qpWkGpGAqQPD9XSCkU3LmX1/ltwsBMAgGYKLLo7vU8d5KV2c8L1Gnxfl6BvfmqUD/dsas/1rnk08rU2nez5ekuQa2tJRkDLOv8bqvrGRLjHSUa3yPuisC6SsDGSU7/3DcozZyYsz7WQ6WI8tYabyjqqeJTF1N8a5T3IbZaZNV1J4JHOO9Cb/y7gIg4edANg6tbe7MzZpdEPRBnw6OkdTdirpNsWQ/jnfpY1hn6mraQZz/q8yaz3W21NjbBJhVnvfh5gWLKQ3YAAziCBhmmrThFhUu0czz+G920MuFo477TBcxvlrE7CaNJ0Q6yYkDehEPOv3jvEs1QVHPwuRrlaLTbBhrlTICKZ58gdX30O8N4i0Xgp/v6qrC03bplnMQc8E/uC61wcVLJixnlZVp8FODpUvPjsxVFkpuNSOIAaiqcERmoiPXx05Epzmr78hjU5rYCx/1MmVoeB4gs9YO+4guD4=
addons:
chrome: stable
apt:
packages:
- libgconf-2-4
before_script: npm run bundle
script: npm test && ([ "${TRAVIS_PULL_REQUEST}" = "false" ] && npm run e2e-ci || npm
run e2e)
after_script: cat ./coverage/lcov.info | coveralls
before_deploy: npm run compile:cli && npm run declarations
deploy:
- provider: npm
skip_cleanup: true
email: gotsijroman@gmail.com
tag: next
api_key: "$NPM_TOKEN"
on:
tags: true

142
README.md
View File

@ -1,7 +1,7 @@
<div align="center">
<img alt="ReDoc logo" src="https://raw.githubusercontent.com/Redocly/redoc/master/docs/images/redoc-logo.png" width="400px" />
<img alt="Redoc logo" src="https://raw.githubusercontent.com/Redocly/redoc/master//docs/images/redoc.png" width="400px" />
**OpenAPI/Swagger-generated API Reference Documentation**
# Generate interactive API documentation from OpenAPI definitions
[![Build Status](https://travis-ci.com/Redocly/redoc.svg?branch=master)](https://travis-ci.com/Redocly/redoc) [![Coverage Status](https://coveralls.io/repos/Redocly/redoc/badge.svg?branch=master&service=github)](https://coveralls.io/github/Redocly/redoc?branch=master) [![dependencies Status](https://david-dm.org/Redocly/redoc/status.svg)](https://david-dm.org/Redocly/redoc) [![devDependencies Status](https://david-dm.org/Redocly/redoc/dev-status.svg)](https://david-dm.org/Redocly/redoc#info=devDependencies) [![npm](http://img.shields.io/npm/v/redoc.svg)](https://www.npmjs.com/package/redoc) [![License](https://img.shields.io/npm/l/redoc.svg)](https://github.com/Redocly/redoc/blob/master/LICENSE)
@ -11,30 +11,93 @@
**This is the README for the `2.x` version of Redoc (React-based).**
**The README for the `1.x` version is on the [v1.x](https://github.com/Redocly/redoc/tree/v1.x) branch**
![ReDoc demo](https://raw.githubusercontent.com/Redocly/redoc/master/demo/redoc-demo.png)
## About Redoc
## [Live demo](http://redocly.github.io/redoc/)
Redoc is an open-source tool for generating documentation from OpenAPI (fka Swagger) definitions.
[<img alt="Deploy to Github" src="http://i.imgur.com/YZmaqk3.png" height="60px">](https://github.com/Rebilly/generator-openapi-repo#generator-openapi-repo--) [<img alt="ReDoc as a service" src="http://i.imgur.com/edqdCv6.png" height="60px">](https://redoc.ly) [<img alt="Customization services" src="http://i.imgur.com/c4sUF7M.png" height="60px">](https://redoc.ly/#services)
By default Redoc offers a three-panel, responsive layout:
- The left panel contains a search bar and navigation menu.
- The central panel contains the documentation.
- The right panel contains request and response examples.
![Redoc demo](https://raw.githubusercontent.com/Redocly/redoc/master/demo/redoc-demo.png)
## Live demo
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 **TRY IT**.
## Redoc vs. Reference vs. Portals
Redoc is Redocly's community-edition product. Looking for something more?
Checkout the following feature comparison of Redocly's premium products versus Redoc:
| Features | Redoc | Reference | Portals |
|------------------------------|:---------:|:---------:|:-----------:|
| **Specs** | | | |
| Swagger 2.0 | √ | √ | √ |
| OpenAPI 3.0 | √ | √ | √ |
| OpenAPI 3.1 | √ (basic) | √ | √ |
| | | | |
| **Theming** | | | |
| Fonts/colors | √ | √ | √ |
| Extra theme options | | √ | √ |
| | | | |
| **Performance** | | | |
| Pagination | | √ | √ |
| Search (enhanced) | | √ | √ |
| Search (server-side) | | | √ |
| | | | |
| **Multiple APIs** | | | |
| Multiple versions | | √ | √ |
| Multiple APIs | | | √ |
| API catalog | | | √ |
| | | | |
| **Additional features** | | | |
| Try-it console | | √ | √ |
| Automated code samples | | √ | √ |
| Deep links | | √ | √ |
| More SEO control | | | √ |
| Contextual docs | | | √ |
| Landing pages | | | √ |
| React hooks for more control | | | √ |
| Personalization | | | √ |
| Analytics integrations | | | √ |
| Feedback | | | Coming Soon |
Refer to the Redocly's documentation for more information on these products:
- [Portals](https://redoc.ly/docs/developer-portal/introduction/)
- [Reference](https://redoc.ly/docs/api-reference-docs/getting-started/)
- [Redoc](https://redoc.ly/docs/redoc/quickstart/intro/)
## Features
- Responsive three-panel design with menu/scrolling synchronization
- [Multiple deployment options](https://redoc.ly/docs/redoc/quickstart/intro/)
- [Server-side rendering (SSR) ready](https://redoc.ly/docs/redoc/quickstart/cli/#redoc-cli-commands)
- Ability to integrate your API introduction into the side menu
- [Simple integration with `create-react-app`](https://redoc.ly/docs/redoc/quickstart/react/)
[See an example](https://github.com/APIs-guru/create-react-app-redoc)
[Example repo](https://github.com/APIs-guru/create-react-app-redoc)
- [Command-line interface to bundle your docs into a **zero-dependency** HTML file](https://redoc.ly/docs/redoc/quickstart/cli/)
- Responsive three-panel design with menu/scrolling synchronization
- Deep linking support
- Ability to integrate your API introduction into the side menu
- High-level grouping in side-menu with [`x-tagGroups`](https://redoc.ly/docs/api-reference-docs/specification-extensions/x-tag-groups/) specification extension
- Neat **interactive** documentation for nested objects <br>
![](docs/images/nested-demo.gif)
## Customization options
[<img alt="Customization services" src="http://i.imgur.com/c4sUF7M.png" height="60px">](https://redoc.ly/#services)
- High-level grouping in side-menu with the [`x-tagGroups`](https://redoc.ly/docs/api-reference-docs/specification-extensions/x-tag-groups/) specification extension
- Branding/customizations using the [`theme` option](https://redoc.ly/docs/api-reference-docs/configuration/theming/)
## Support
- OpenAPI v3.0 support
- Basic OpenAPI v3.1 support
- Broad OpenAPI v2.0 feature support (yes, it supports even `discriminator`) <br>
![](docs/images/discriminator-demo.gif)
- Neat **interactive** documentation for nested objects <br>
![](docs/images/nested-demo.gif)
- Code samples support (via vendor extension) <br>
![](docs/images/code-samples-demo.gif)
@ -44,12 +107,12 @@
- `next` release: https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js
Additionally, all the 1.x releases are hosted on our GitHub Pages-based CDN **(deprecated)**:
- particular release, e.g. `v1.2.0`: https://rebilly.github.io/ReDoc/releases/v1.2.0/redoc.min.js
- particular release, for example `v1.2.0`: https://rebilly.github.io/ReDoc/releases/v1.2.0/redoc.min.js
- `v1.x.x` release: https://rebilly.github.io/ReDoc/releases/v1.x.x/redoc.min.js
- `latest` release: https://rebilly.github.io/ReDoc/releases/latest/redoc.min.js - it will point to latest 1.x.x release since 2.x releases are not hosted on this CDN but on unpkg.
## Version Guidance
| ReDoc Release | OpenAPI Specification |
| Redoc Release | OpenAPI Specification |
|:--------------|:----------------------|
| 2.0.0-alpha.54| 3.1, 3.0.x, 2.0 |
| 2.0.0-alpha.x | 3.0, 2.0 |
@ -66,16 +129,59 @@ Additionally, all the 1.x releases are hosted on our GitHub Pages-based CDN **(d
- [APIs.guru](https://apis.guru/api-doc/)
- [BoxKnight](https://www.docs.boxknight.com/)
## Lint OpenAPI definitions
Redocly's OpenAPI CLI is an open source command-line tool that you can use to lint
your OpenAPI definition. Linting helps you to catch errors and inconsistencies in your
OpenAPI definition before publishing.
Refer to [Lint configuration](https://redoc.ly/docs/cli/guides/lint/) in the OpenAPI documentation for more information.
## Deployment
### TL;DR final code example
To render your OpenAPI definition using Redoc, use the following HTML code sample and
replace the `spec-url` attribute with the url or local file address to your definition.
```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>
```
For step-by-step instructions for how to get started using Redoc
to render your OpenAPI definition, refer to the
[Redoc quickstart guide](https://redoc.ly/docs/redoc/quickstart/intro/).
[**Redoc quickstart guide**](https://redoc.ly/docs/redoc/quickstart/intro/).
[**IE11 Support Notes**](docs/usage-with-ie11.md)
See [**IE11 Support Notes**](docs/usage-with-ie11.md) for information on
IE support for Redoc.
## ReDoc CLI
## Redoc CLI
For more information on Redoc's commmand-line interface, refer to
[Using the Redoc CLI](https://redoc.ly/docs/redoc/quickstart/cli/).
[**Using the Redoc CLI**](https://redoc.ly/docs/redoc/quickstart/cli/).
## Configuration

View File

@ -533,6 +533,20 @@ paths:
subscriptionId:
type: string
example: AAA-123-BBB-456
'200':
description: Successful operation
content:
application/json:
schema:
type: array
maxItems: 999
minItems: 0
items:
type: array
maxItems: 777
minItems: 111
items:
type: number
callbacks:
orderInProgress:
'{$request.body#/callbackUrl}?event={$request.body#/eventName}':

View File

@ -377,7 +377,9 @@ paths:
application/xml:
schema:
type: array
maxItems: 999
items:
maxItems: 111
$ref: '#/components/schemas/Pet'
'400':
description: Invalid tag value

BIN
docs/images/redoc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -13,15 +13,12 @@ const PaddedSchema = styled.div`
export class ArraySchema extends React.PureComponent<SchemaProps> {
render() {
const itemsSchema = this.props.schema.items!;
const schema = this.props.schema;
const itemsSchema = schema.items;
const itemConstraintSchema = (
min: number | undefined = undefined,
max: number | undefined = undefined,
) => ({ type: 'array', minItems: min, maxItems: max });
const minMaxItems = humanizeConstraints(itemConstraintSchema(itemsSchema?.schema?.minItems, itemsSchema?.schema?.maxItems));
const minMaxItems = schema.minItems === undefined && schema.maxItems === undefined ?
'' :
`(${humanizeConstraints(schema)})`;
if (schema.displayType && !itemsSchema && !minMaxItems.length) {
return (<div>
@ -31,7 +28,7 @@ export class ArraySchema extends React.PureComponent<SchemaProps> {
return (
<div>
<ArrayOpenningLabel> Array ({minMaxItems})</ArrayOpenningLabel>
<ArrayOpenningLabel> Array {minMaxItems}</ArrayOpenningLabel>
<PaddedSchema>
<Schema {...this.props} schema={itemsSchema} />
</PaddedSchema>

View File

@ -33,6 +33,8 @@ exports[`Components SchemaView discriminator should correctly render discriminat
"format": undefined,
"isCircular": undefined,
"isPrimitive": true,
"maxItems": undefined,
"minItems": undefined,
"options": "<<<filtered>>>",
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/packSize",
@ -86,6 +88,8 @@ exports[`Components SchemaView discriminator should correctly render discriminat
"format": undefined,
"isCircular": undefined,
"isPrimitive": true,
"maxItems": undefined,
"minItems": undefined,
"options": "<<<filtered>>>",
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/type",

View File

@ -174,6 +174,18 @@ export class OpenAPIParser {
return obj;
}
shallowDeref<T extends unknown>(obj: OpenAPIRef | T): T {
if (this.isRef(obj)) {
const schemaName = getDefinitionName(obj.$ref);
if (schemaName && this.options.ignoreNamedSchemas.has(schemaName)) {
return { type: 'object', title: schemaName } as T;
}
const resolved = this.byRef<T>(obj.$ref);
return this.allowMergeRefs ? this.mergeRefs(obj, resolved, false) : (resolved as T);
}
return obj;
}
mergeRefs(ref, resolved, mergeAsAllOf: boolean) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { $ref, ...rest } = ref;
@ -183,7 +195,7 @@ export class OpenAPIParser {
}
if (mergeAsAllOf && keys.some((k) => k !== 'description' && k !== 'title' && k !== 'externalDocs')) {
return {
allOf: [resolved, rest],
allOf: [rest, resolved],
};
} else {
// small optimization
@ -194,13 +206,6 @@ export class OpenAPIParser {
}
}
shalowDeref<T extends object>(obj: OpenAPIRef | T): T {
if (this.isRef(obj)) {
return this.byRef<T>(obj.$ref)!;
}
return obj;
}
/**
* Merge allOf constraints.
* @param schema schema with allOF

View File

@ -1,5 +1,6 @@
import { OpenAPIParser } from '../OpenAPIParser';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
import { OpenAPIParameter, Referenced } from '../../types';
const opts = new RedocNormalizedOptions({});
@ -13,5 +14,18 @@ describe('Models', () => {
parser = new OpenAPIParser(spec, undefined, opts);
expect(parser.mergeAllOf(spec.components.schemas.test)).toMatchSnapshot();
});
test('should override description from $ref of the referenced component, when sibling description exists ', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const spec = require('./fixtures/siblingRefDescription.json');
parser = new OpenAPIParser(spec, undefined, opts);
const schemaOrRef: Referenced<OpenAPIParameter> = {
$ref: '#/components/schemas/Test',
description: 'Overriden description',
};
expect(parser.shallowDeref(schemaOrRef)).toMatchSnapshot();
});
});
});

View File

@ -86,3 +86,10 @@ Object {
],
}
`;
exports[`Models Schema should override description from $ref of the referenced component, when sibling description exists 1`] = `
Object {
"description": "Overriden description",
"type": "object",
}
`;

View File

@ -0,0 +1,39 @@
{
"openapi": "3.1.0",
"info": {
"title": "AA",
"version": "1.0"
},
"paths": {
"/test": {
"get": {
"operationId": "test",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"testAttr": {
"description": "Overriden description",
"$ref": "#/components/schemas/Test"
}
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Test": {
"type": "object",
"description": "Refed description"
}
}
}
}

View File

@ -40,7 +40,7 @@ export class MediaTypeModel {
this.examples = {
default: new ExampleModel(
parser,
{ value: parser.shalowDeref(info.example) },
{ value: parser.shallowDeref(info.example) },
name,
info.encoding,
),

View File

@ -63,6 +63,8 @@ export class SchemaModel {
const: any;
contentEncoding?: string;
contentMediaType?: string;
minItems?: number;
maxItems?: number;
/**
* @param isChild if schema discriminator Child
@ -128,6 +130,8 @@ export class SchemaModel {
this.const = schema.const || '';
this.contentEncoding = schema.contentEncoding;
this.contentMediaType = schema.contentMediaType;
this.minItems = schema.minItems;
this.maxItems = schema.maxItems;
if (!!schema.nullable || schema['x-nullable']) {
if (Array.isArray(this.type) && !this.type.some((value) => value === null || value === 'null')) {
@ -359,7 +363,7 @@ function buildFields(
): FieldModel[] {
const props = schema.properties || {};
const additionalProps = schema.additionalProperties;
const defaults = schema.default || {};
const defaults = schema.default;
let fields = Object.keys(props || []).map((fieldName) => {
let field = props[fieldName];
@ -380,7 +384,7 @@ function buildFields(
required,
schema: {
...field,
default: field.default === undefined ? defaults[fieldName] : field.default,
default: field.default === undefined && defaults ? defaults[fieldName] : field.default,
},
},
$ref + '/properties/' + fieldName,

View File

@ -729,7 +729,9 @@ try {
"schema": Object {
"items": Object {
"$ref": "#/components/schemas/Pet",
"maxItems": 111,
},
"maxItems": 999,
"type": "array",
},
},
@ -3245,6 +3247,26 @@ culpa qui officia deserunt mollit anim id est laborum.
},
},
"responses": Object {
"200": Object {
"content": Object {
"application/json": Object {
"schema": Object {
"items": Object {
"items": Object {
"type": "number",
},
"maxItems": 777,
"minItems": 111,
"type": "array",
},
"maxItems": 999,
"minItems": 0,
"type": "array",
},
},
},
"description": "Successful operation",
},
"201": Object {
"content": Object {
"application/json": Object {

View File

@ -412,10 +412,10 @@ describe('Utils', () => {
describe('openapi humanizeConstraints', () => {
const itemConstraintSchema = (
min: number | undefined = undefined,
max: number | undefined = undefined,
multipleOf: number | undefined = undefined,
uniqueItems?: boolean,
min?: number,
max?: number,
multipleOf?: number,
uniqueItems?: boolean
) => ({ type: 'array', minItems: min, maxItems: max, multipleOf, uniqueItems });
it('should not have a humanized constraint without schema constraints', () => {

View File

@ -15,6 +15,7 @@ import 'prismjs/components/prism-objectivec.js';
import 'prismjs/components/prism-perl.js';
import 'prismjs/components/prism-php.js';
import 'prismjs/components/prism-python.js';
import 'prismjs/components/prism-q.js';
import 'prismjs/components/prism-ruby.js';
import 'prismjs/components/prism-scala.js';
import 'prismjs/components/prism-sql.js';

View File

@ -505,13 +505,13 @@ export function mergeParams(
): Array<Referenced<OpenAPIParameter>> {
const operationParamNames = {};
operationParams.forEach(param => {
param = parser.shalowDeref(param);
param = parser.shallowDeref(param);
operationParamNames[param.name + '_' + param.in] = true;
});
// filter out path params overridden by operation ones with the same name
pathParams = pathParams.filter(param => {
param = parser.shalowDeref(param);
param = parser.shallowDeref(param);
return !operationParamNames[param.name + '_' + param.in];
});