merge master

This commit is contained in:
Oprysk 2021-11-24 16:14:52 +02:00
commit 8364fade0c
43 changed files with 576 additions and 180 deletions

4
.husky/pre-commit Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run pre-commit

View File

@ -1,26 +1,28 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>%PAGE_TITLE%</title>
<link rel="icon" href="%PAGE_FAVICON%" />
<style>
body {
margin: 0;
padding: 0;
}
<head> redoc {
<meta charset="UTF-8" /> display: block;
<title>%PAGE_TITLE%</title> }
<link rel="icon" href="%PAGE_FAVICON%"> </style>
<style> <link
body { href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700"
margin: 0; rel="stylesheet"
padding: 0; />
} </head>
redoc {
display: block;
}
</style>
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
</head>
<body>
<redoc spec-url="%SPEC_URL%" %REDOC_OPTIONS%></redoc>
<script src="redoc.standalone.js"></script>
</body>
<body>
<redoc spec-url="%SPEC_URL%" %REDOC_OPTIONS%></redoc>
<script src="redoc.standalone.js"></script>
</body>
</html> </html>

View File

@ -29,14 +29,15 @@ The following options are supported:
### OpenAPI definition ### OpenAPI definition
You will need an OpenAPI definition. For testing purposes, you can use one of the following sample OpenAPI definitions: 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)
::: OpenAPI Specification info - 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)
:::info OpenAPI specification
For more information on the OpenAPI specification, refer to the [Learning OpenAPI 3](https://redoc.ly/docs/resources/learning-openapi/) For more information on the OpenAPI specification, refer to the [Learning OpenAPI 3](https://redoc.ly/docs/resources/learning-openapi/)
section in the documentation. section in the documentation.
::: :::
@ -57,9 +58,7 @@ project directory and run the following command:
openapi preview-docs openapi.yaml openapi preview-docs openapi.yaml
``` ```
::: openapi.yaml
Replace `openapi.yaml` in the example command with the file path to your OpenAPI definition. Replace `openapi.yaml` in the example command with the file path to your OpenAPI definition.
:::
By default, without providing a port, the preview starts on port 8080, and can be accessed at `http://localhost:8080`. 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`. To exit the preview, use `control+C`.
@ -70,9 +69,7 @@ You can alter the port if you are using 8080 already, for example:
openapi preview-docs -p 8888 openapi.yaml openapi preview-docs -p 8888 openapi.yaml
``` ```
::: openapi.yaml
Replace `openapi.yaml` in the example command with the file path to your OpenAPI definition. Replace `openapi.yaml` in the example command with the file path to your OpenAPI definition.
:::
For more information about the `preview-docs` command, refer to For more information about the `preview-docs` command, refer to
[OpenAPI CLI commands](https://redoc.ly/docs/cli/commands/preview-docs/#preview-docs) in the OpenAPI CLI documentation. [OpenAPI CLI commands](https://redoc.ly/docs/cli/commands/preview-docs/#preview-docs) in the OpenAPI CLI documentation.
@ -108,7 +105,7 @@ npm install -g http-server
Then, `cd` into your project directory and run the following command: Then, `cd` into your project directory and run the following command:
```node ```node
http-server http - server;
``` ```
The output after entering the command provides the local URL where the preview can be accessed. The output after entering the command provides the local URL where the preview can be accessed.

View File

@ -13,9 +13,12 @@ replace the `spec-url` attribute with the URL or local file address to your defi
<head> <head>
<title>Redoc</title> <title>Redoc</title>
<!-- needed for adaptive design --> <!-- needed for adaptive design -->
<meta charset="utf-8"/> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"> <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"> <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 Redoc doesn't change outer page styles
@ -28,24 +31,23 @@ replace the `spec-url` attribute with the URL or local file address to your defi
</style> </style>
</head> </head>
<body> <body>
<!-- <!--
Redoc element with link to your OpenAPI definition Redoc element with link to your OpenAPI definition
--> -->
<redoc spec-url='http://petstore.swagger.io/v2/swagger.json'></redoc> <redoc spec-url="http://petstore.swagger.io/v2/swagger.json"></redoc>
<!-- <!--
Link to Redoc JavaScript on CDN for rendering standalone element Link to Redoc JavaScript on CDN for rendering standalone element
--> -->
<script src="https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js"> </script> <script src="https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js"></script>
</body> </body>
</html> </html>
``` ```
:::attention Running Redoc locally requires an HTTP server :::attention Running Redoc locally requires an HTTP server
Loading local OpenAPI definitions is impossible without running a web server because of issues with 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 [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) and
other security reasons. Refer to [Running Redoc locally](https://redoc.ly/docs/deployment/intro/#running_redoc_locally) for other security reasons. Refer to [Running Redoc locally](./deployment/intro.md#running-redoc-locally) for
more information. more information.
::: :::
For a more detailed explanation with step-by-step instructions and additional options for using Redoc, refer to the [Redoc deployment guide](/deployment/intro). For a more detailed explanation with step-by-step instructions and additional options for using Redoc, refer to the [Redoc deployment guide](./deployment/intro.md).

View File

@ -1,15 +0,0 @@
redoc:
- label: Quickstart
- page: redoc/quickstart.md
- group: Deployment
expanded: false
page: redoc/deployment/intro.md
pages:
- label: HTML element
page: redoc/deployment/html.md
- label: React component
page: redoc/deployment/react.md
- label: Docker image
page: redoc/deployment/docker.md
- label: Command-line interface
page: redoc/deployment/cli.md

388
package-lock.json generated
View File

@ -5,6 +5,7 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "redoc",
"version": "2.0.0-rc.57", "version": "2.0.0-rc.57",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -89,12 +90,14 @@
"eslint-plugin-react": "^7.24.0", "eslint-plugin-react": "^7.24.0",
"fork-ts-checker-webpack-plugin": "^6.2.10", "fork-ts-checker-webpack-plugin": "^6.2.10",
"html-webpack-plugin": "^5.3.1", "html-webpack-plugin": "^5.3.1",
"husky": "^7.0.0",
"jest": "^27.0.3", "jest": "^27.0.3",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"license-checker": "^25.0.1", "license-checker": "^25.0.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mobx": "^6.3.2", "mobx": "^6.3.2",
"prettier": "^2.3.0", "prettier": "^2.3.2",
"pretty-quick": "^3.0.0",
"raf": "^3.4.1", "raf": "^3.4.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
@ -3888,6 +3891,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/array-differ": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/array-find-index": { "node_modules/array-find-index": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
@ -10204,6 +10216,21 @@
"node": ">=8.12.0" "node": ">=8.12.0"
} }
}, },
"node_modules/husky": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz",
"integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==",
"dev": true,
"bin": {
"husky": "lib/bin.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
}
},
"node_modules/iconv-lite": { "node_modules/iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -14466,6 +14493,15 @@
"integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==", "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==",
"dev": true "dev": true
}, },
"node_modules/mri": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -14490,6 +14526,31 @@
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
"dev": true "dev": true
}, },
"node_modules/multimatch": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
"integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
"dev": true,
"dependencies": {
"@types/minimatch": "^3.0.3",
"array-differ": "^3.0.0",
"array-union": "^2.1.0",
"arrify": "^2.0.1",
"minimatch": "^3.0.4"
},
"engines": {
"node": ">=8"
}
},
"node_modules/multimatch/node_modules/arrify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/nan": { "node_modules/nan": {
"version": "2.14.2", "version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
@ -15782,9 +15843,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "2.3.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz",
"integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==",
"dev": true, "dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
@ -15925,6 +15986,166 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/pretty-quick": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz",
"integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==",
"dev": true,
"dependencies": {
"chalk": "^3.0.0",
"execa": "^4.0.0",
"find-up": "^4.1.0",
"ignore": "^5.1.4",
"mri": "^1.1.5",
"multimatch": "^4.0.0"
},
"bin": {
"pretty-quick": "bin/pretty-quick.js"
},
"engines": {
"node": ">=10.13"
},
"peerDependencies": {
"prettier": ">=2.0.0"
}
},
"node_modules/pretty-quick/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/pretty-quick/node_modules/chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/pretty-quick/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/pretty-quick/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/pretty-quick/node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/pretty-quick/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/pretty-quick/node_modules/ignore": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/pretty-quick/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/pretty-quick/node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/pretty-quick/node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/pretty-quick/node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/pretty-quick/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/prettycli": { "node_modules/prettycli": {
"version": "1.4.3", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/prettycli/-/prettycli-1.4.3.tgz", "resolved": "https://registry.npmjs.org/prettycli/-/prettycli-1.4.3.tgz",
@ -23993,6 +24214,12 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true "dev": true
}, },
"array-differ": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
"dev": true
},
"array-find-index": { "array-find-index": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
@ -28930,6 +29157,12 @@
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
"dev": true "dev": true
}, },
"husky": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz",
"integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==",
"dev": true
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -32084,6 +32317,12 @@
"integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==", "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==",
"dev": true "dev": true
}, },
"mri": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
"dev": true
},
"ms": { "ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -32105,6 +32344,27 @@
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
"dev": true "dev": true
}, },
"multimatch": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
"integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
"dev": true,
"requires": {
"@types/minimatch": "^3.0.3",
"array-differ": "^3.0.0",
"array-union": "^2.1.0",
"arrify": "^2.0.1",
"minimatch": "^3.0.4"
},
"dependencies": {
"arrify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
"dev": true
}
}
},
"nan": { "nan": {
"version": "2.14.2", "version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
@ -33103,9 +33363,9 @@
"dev": true "dev": true
}, },
"prettier": { "prettier": {
"version": "2.3.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz",
"integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==",
"dev": true "dev": true
}, },
"pretty-bytes": { "pretty-bytes": {
@ -33209,6 +33469,120 @@
} }
} }
}, },
"pretty-quick": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz",
"integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==",
"dev": true,
"requires": {
"chalk": "^3.0.0",
"execa": "^4.0.0",
"find-up": "^4.1.0",
"ignore": "^5.1.4",
"mri": "^1.1.5",
"multimatch": "^4.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"ignore": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
"dev": true
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"prettycli": { "prettycli": {
"version": "1.4.3", "version": "1.4.3",
"resolved": "https://registry.npmjs.org/prettycli/-/prettycli-1.4.3.tgz", "resolved": "https://registry.npmjs.org/prettycli/-/prettycli-1.4.3.tgz",

View File

@ -54,7 +54,9 @@
"build:demo": "webpack --mode=production --config demo/webpack.config.ts", "build:demo": "webpack --mode=production --config demo/webpack.config.ts",
"deploy:demo": "aws s3 sync demo/dist s3://production-redoc-demo --acl=public-read", "deploy:demo": "aws s3 sync demo/dist s3://production-redoc-demo --acl=public-read",
"license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD;BSD-2-Clause;BSD-3-Clause' --summary", "license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD;BSD-2-Clause;BSD-3-Clause' --summary",
"docker:build": "docker build -f config/docker/Dockerfile -t redoc ." "docker:build": "docker build -f config/docker/Dockerfile -t redoc .",
"prepare": "husky install",
"pre-commit": "pretty-quick --staged && npm run lint"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.14.3", "@babel/core": "^7.14.3",
@ -112,12 +114,14 @@
"eslint-plugin-react": "^7.24.0", "eslint-plugin-react": "^7.24.0",
"fork-ts-checker-webpack-plugin": "^6.2.10", "fork-ts-checker-webpack-plugin": "^6.2.10",
"html-webpack-plugin": "^5.3.1", "html-webpack-plugin": "^5.3.1",
"husky": "^7.0.0",
"jest": "^27.0.3", "jest": "^27.0.3",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"license-checker": "^25.0.1", "license-checker": "^25.0.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mobx": "^6.3.2", "mobx": "^6.3.2",
"prettier": "^2.3.0", "prettier": "^2.3.2",
"pretty-quick": "^3.0.0",
"raf": "^3.4.1", "raf": "^3.4.1",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
@ -207,6 +211,6 @@
"singleQuote": true, "singleQuote": true,
"trailingComma": "all", "trailingComma": "all",
"printWidth": 100, "printWidth": 100,
"parser": "typescript" "arrowParens": "avoid"
} }
} }

View File

@ -66,7 +66,7 @@ export const PropertyNameCell = styled(PropertyCell)`
line-height: 20px; line-height: 20px;
white-space: nowrap; white-space: nowrap;
font-size: 13px; font-size: 13px;
font-family: ${(props) => props.theme.typography.code.fontFamily}; font-family: ${props => props.theme.typography.code.fontFamily};
&.deprecated { &.deprecated {
${deprecatedCss}; ${deprecatedCss};
@ -80,7 +80,7 @@ export const PropertyNameCell = styled(PropertyCell)`
export const PropertyDetailsCell = styled.td` export const PropertyDetailsCell = styled.td`
border-bottom: 1px solid #9fb4be; border-bottom: 1px solid #9fb4be;
padding: 10px 0; padding: 10px 0;
width: ${(props) => props.theme.schema.defaultDetailsWidth}; width: ${props => props.theme.schema.defaultDetailsWidth};
box-sizing: border-box; box-sizing: border-box;
tr.expanded & { tr.expanded & {
@ -90,7 +90,7 @@ export const PropertyDetailsCell = styled.td`
${media.lessThan('small')` ${media.lessThan('small')`
padding: 0 20px; padding: 0 20px;
border-bottom: none; border-bottom: none;
border-left: 1px solid ${(props) => props.theme.schema.linesColor}; border-left: 1px solid ${props => props.theme.schema.linesColor};
tr.last > & { tr.last > & {
border-left: none; border-left: none;

View File

@ -6,7 +6,7 @@ import styled, { css } from '../styled-components';
import { HistoryService } from '../services'; import { HistoryService } from '../services';
// tslint:disable-next-line // tslint:disable-next-line
export const linkifyMixin = (className) => css` export const linkifyMixin = className => css`
${className} { ${className} {
cursor: pointer; cursor: pointer;
margin-left: -20px; margin-left: -20px;
@ -33,13 +33,13 @@ export const linkifyMixin = (className) => css`
} }
`; `;
const isModifiedEvent = (event) => const isModifiedEvent = event =>
!!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
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: React.MouseEvent<HTMLAnchorElement>) => { (event: React.MouseEvent<HTMLAnchorElement>) => {
if (!store) return; if (!store) return;
navigate(store.menu.history, event, props.to); navigate(store.menu.history, event, props.to);
}, },

View File

@ -12,7 +12,7 @@ import styled, { createGlobalStyle } from '../styled-components';
* That's why the following ugly fix is required * That's why the following ugly fix is required
*/ */
const PerfectScrollbarConstructor = const PerfectScrollbarConstructor =
PerfectScrollbarNamespace.default || ((PerfectScrollbarNamespace as any) as PerfectScrollbarType); PerfectScrollbarNamespace.default || (PerfectScrollbarNamespace as any as PerfectScrollbarType);
const PSStyling = createGlobalStyle`${psStyles && psStyles.toString()}`; const PSStyling = createGlobalStyle`${psStyles && psStyles.toString()}`;

View File

@ -39,7 +39,12 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
const license = const license =
(info.license && ( (info.license && (
<InfoSpan> <InfoSpan>
License: {info.license.identifier ? info.license.identifier : (<a href={info.license.url}>{info.license.name}</a>)} License:{' '}
{info.license.identifier ? (
info.license.identifier
) : (
<a href={info.license.url}>{info.license.name}</a>
)}
</InfoSpan> </InfoSpan>
)) || )) ||
null; null;
@ -101,8 +106,8 @@ export class ApiInfo extends React.Component<ApiInfoProps> {
)) || )) ||
null} null}
</StyledMarkdownBlock> </StyledMarkdownBlock>
<Markdown source={store.spec.info.summary} data-role="redoc-summary"/> <Markdown source={store.spec.info.summary} data-role="redoc-summary" />
<Markdown source={store.spec.info.description} data-role="redoc-description"/> <Markdown source={store.spec.info.description} data-role="redoc-description" />
{externalDocs && <ExternalDocumentation externalDocs={externalDocs} />} {externalDocs && <ExternalDocumentation externalDocs={externalDocs} />}
</MiddlePanel> </MiddlePanel>
</Row> </Row>

View File

@ -35,7 +35,7 @@ export const EndpointInfo = styled.button<{ expanded?: boolean; inverted?: boole
(props.expanded && !props.inverted && `border-color: ${props.theme.colors.border.dark};`) || ''} (props.expanded && !props.inverted && `border-color: ${props.theme.colors.border.dark};`) || ''}
.${ServerRelativeURL} { .${ServerRelativeURL} {
color: ${props => (props.inverted ? props.theme.colors.text.primary : '#ffffff')} color: ${props => (props.inverted ? props.theme.colors.text.primary : '#ffffff')};
} }
&:focus { &:focus {
box-shadow: inset 0 2px 2px rgba(0, 0, 0, 0.45), 0 2px 0 rgba(128, 128, 128, 0.25); box-shadow: inset 0 2px 2px rgba(0, 0, 0, 0.45), 0 2px 0 rgba(128, 128, 128, 0.25);

View File

@ -59,7 +59,9 @@ 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} />
);
} }
} }
@ -78,14 +80,16 @@ export class FieldDetails extends React.PureComponent<FieldProps, { patternShown
)} )}
{schema.contentEncoding && ( {schema.contentEncoding && (
<TypeFormat> <TypeFormat>
{' '}&lt; {' '}
&lt;
{schema.contentEncoding} {schema.contentEncoding}
&gt;{' '} &gt;{' '}
</TypeFormat> </TypeFormat>
)} )}
{schema.contentMediaType && ( {schema.contentMediaType && (
<TypeFormat> <TypeFormat>
{' '}&lt; {' '}
&lt;
{schema.contentMediaType} {schema.contentMediaType}
&gt;{' '} &gt;{' '}
</TypeFormat> </TypeFormat>
@ -124,7 +128,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>
); );
} }
@ -142,7 +146,8 @@ function Examples({ field }: { field: FieldModel }) {
{Object.values(field.examples).map((example, idx) => { {Object.values(field.examples).map((example, idx) => {
return ( return (
<li key={idx}> <li key={idx}>
<ExampleValue>{getSerializedValue(field, example.value)}</ExampleValue> - {example.summary || example.description} <ExampleValue>{getSerializedValue(field, example.value)}</ExampleValue> -{' '}
{example.summary || example.description}
</li> </li>
); );
})} })}
@ -160,7 +165,6 @@ function getSerializedValue(field: FieldModel, example: any) {
} }
} }
const ExamplesList = styled.ul` const ExamplesList = styled.ul`
margin-top: 1em; margin-top: 1em;
padding-left: 0; padding-left: 0;

View File

@ -26,7 +26,6 @@ export const StyledMarkdownBlock = styled(
{ compact?: boolean; inline?: boolean } { compact?: boolean; inline?: boolean }
>, >,
)` )`
font-family: ${props => props.theme.typography.fontFamily}; font-family: ${props => props.theme.typography.fontFamily};
font-weight: ${props => props.theme.typography.fontWeightRegular}; font-weight: ${props => props.theme.typography.fontWeightRegular};
line-height: ${props => props.theme.typography.lineHeight}; line-height: ${props => props.theme.typography.lineHeight};
@ -81,7 +80,7 @@ export const StyledMarkdownBlock = styled(
pre { pre {
font-family: ${props => props.theme.typography.code.fontFamily}; font-family: ${props => props.theme.typography.code.fontFamily};
white-space:${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')}; white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')};
background-color: ${({ theme }) => theme.codeBlock.backgroundColor}; background-color: ${({ theme }) => theme.codeBlock.backgroundColor};
color: white; color: white;
padding: ${props => props.theme.spacing.unit * 4}px; padding: ${props => props.theme.spacing.unit * 4}px;
@ -121,7 +120,8 @@ export const StyledMarkdownBlock = styled(
margin: 0; margin: 0;
margin-bottom: 1em; margin-bottom: 1em;
ul, ol { ul,
ol {
margin-bottom: 0; margin-bottom: 0;
margin-top: 0; margin-top: 0;
} }

View File

@ -67,7 +67,10 @@ 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; const { isRequestType } = content;
return ( return (

View File

@ -1,6 +1,10 @@
import * as React from 'react'; import * as React from 'react';
import { argValueToBoolean, 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';
@ -32,4 +36,4 @@ export const RedocStandalone = function (props: RedocStandaloneProps) {
</StoreBuilder> </StoreBuilder>
</ErrorBoundary> </ErrorBoundary>
); );
} };

View File

@ -16,14 +16,17 @@ export class ArraySchema extends React.PureComponent<SchemaProps> {
const schema = this.props.schema; const schema = this.props.schema;
const itemsSchema = schema.items; const itemsSchema = schema.items;
const minMaxItems = schema.minItems === undefined && schema.maxItems === undefined ? const minMaxItems =
'' : schema.minItems === undefined && schema.maxItems === undefined
`(${humanizeConstraints(schema)})`; ? ''
: `(${humanizeConstraints(schema)})`;
if (schema.displayType && !itemsSchema && !minMaxItems.length) { if (schema.displayType && !itemsSchema && !minMaxItems.length) {
return (<div> return (
<TypeName>{schema.displayType}</TypeName> <div>
</div>); <TypeName>{schema.displayType}</TypeName>
</div>
);
} }
return ( return (

View File

@ -73,7 +73,7 @@ export class Schema extends React.Component<Partial<SchemaProps>> {
} }
// TODO: maybe adjust FieldDetails to accept schema // TODO: maybe adjust FieldDetails to accept schema
const field = ({ const field = {
schema, schema,
name: '', name: '',
required: false, required: false,
@ -82,7 +82,7 @@ export class Schema extends React.Component<Partial<SchemaProps>> {
deprecated: false, deprecated: false,
toggle: () => null, toggle: () => null,
expanded: false, expanded: false,
} as any) as FieldModel; // cast needed for hot-loader to not fail } as any as FieldModel; // cast needed for hot-loader to not fail
return ( return (
<div> <div>

View File

@ -100,7 +100,7 @@ export class SearchBox extends React.PureComponent<SearchBoxProps, SearchBoxStat
setResults(results: SearchResult[], term: string) { setResults(results: SearchResult[], term: string) {
this.setState({ this.setState({
results, results,
noResults: results.length === 0 noResults: results.length === 0,
}); });
this.props.marker.mark(term); this.props.marker.mark(term);
} }

View File

@ -30,7 +30,7 @@ const { Provider, Consumer } = StoreContext;
export { Provider as StoreProvider, Consumer as StoreConsumer, StoreContext }; export { Provider as StoreProvider, Consumer as StoreConsumer, StoreContext };
export function StoreBuilder(props: StoreBuilderProps) { export function StoreBuilder(props: StoreBuilderProps) {
const {spec, specUrl, options, onLoaded, children } = props; const { spec, specUrl, options, onLoaded, children } = props;
const [resolvedSpec, setResolvedSpec] = React.useState<any>(null); const [resolvedSpec, setResolvedSpec] = React.useState<any>(null);
@ -44,7 +44,7 @@ export function StoreBuilder(props: StoreBuilderProps) {
setResolvedSpec(resolved); setResolvedSpec(resolved);
} }
load(); load();
}, [spec, specUrl]) }, [spec, specUrl]);
const store = React.useMemo(() => { const store = React.useMemo(() => {
if (!resolvedSpec) return null; if (!resolvedSpec) return null;
@ -62,7 +62,7 @@ export function StoreBuilder(props: StoreBuilderProps) {
if (store && onLoaded) { if (store && onLoaded) {
onLoaded(); onLoaded();
} }
}, [store, onLoaded]) }, [store, onLoaded]);
return children({ return children({
loading: !store, loading: !store,

View File

@ -10,14 +10,15 @@ const options = new RedocNormalizedOptions({});
describe('Components', () => { describe('Components', () => {
describe('SecurityRequirement', () => { describe('SecurityRequirement', () => {
describe('SecurityRequirement', () => { describe('SecurityRequirement', () => {
it('should render \'None\' when empty object in security open api', () => { it("should render 'None' when empty object in security open api", () => {
const parser = new OpenAPIParser({ openapi: '3.0', info: { title: 'test', version: '0' }, paths: {} }, const parser = new OpenAPIParser(
{ openapi: '3.0', info: { title: 'test', version: '0' }, paths: {} },
undefined, undefined,
options, options,
); );
const securityRequirement = new SecurityRequirementModel({}, parser); const securityRequirement = new SecurityRequirementModel({}, parser);
const securityElement = shallow( const securityElement = shallow(
<SecurityRequirement key={1} security={securityRequirement} /> <SecurityRequirement key={1} security={securityRequirement} />,
).getElement(); ).getElement();
expect(securityElement.props.children.type.target).toEqual('span'); expect(securityElement.props.children.type.target).toEqual('span');
expect(securityElement.props.children.props.children).toEqual('None'); expect(securityElement.props.children.props.children).toEqual('None');

View File

@ -121,10 +121,7 @@ export class MarkdownRenderer {
prevRegexp = regexp; prevRegexp = regexp;
prevPos = currentPos; prevPos = currentPos;
} }
prevHeading.description = rawText prevHeading.description = rawText.substring(prevPos).replace(prevRegexp, '').trim();
.substring(prevPos)
.replace(prevRegexp, '')
.trim();
} }
headingRule = ( headingRule = (

View File

@ -226,7 +226,7 @@ export class MenuBuilder {
getTags(parser, webhooks, true); getTags(parser, webhooks, true);
} }
if (spec.paths){ if (spec.paths) {
getTags(parser, spec.paths); getTags(parser, spec.paths);
} }

View File

@ -193,7 +193,10 @@ export class OpenAPIParser {
if (keys.length === 0) { if (keys.length === 0) {
return resolved; return resolved;
} }
if (mergeAsAllOf && keys.some((k) => k !== 'description' && k !== 'title' && k !== 'externalDocs')) { if (
mergeAsAllOf &&
keys.some(k => k !== 'description' && k !== 'title' && k !== 'externalDocs')
) {
return { return {
allOf: [rest, resolved], allOf: [rest, resolved],
}; };
@ -244,7 +247,7 @@ export class OpenAPIParser {
} }
const allOfSchemas = schema.allOf const allOfSchemas = schema.allOf
.map((subSchema) => { .map(subSchema => {
if (subSchema && subSchema.$ref && used$Refs.has(subSchema.$ref)) { if (subSchema && subSchema.$ref && used$Refs.has(subSchema.$ref)) {
return undefined; return undefined;
} }
@ -258,7 +261,7 @@ export class OpenAPIParser {
schema: subMerged, schema: subMerged,
}; };
}) })
.filter((child) => child !== undefined) as Array<{ .filter(child => child !== undefined) as Array<{
$ref: string | undefined; $ref: string | undefined;
schema: MergedOpenAPISchema; schema: MergedOpenAPISchema;
}>; }>;
@ -337,7 +340,7 @@ export class OpenAPIParser {
const def = this.deref(schemas[defName]); const def = this.deref(schemas[defName]);
if ( if (
def.allOf !== undefined && def.allOf !== undefined &&
def.allOf.find((obj) => obj.$ref !== undefined && $refs.indexOf(obj.$ref) > -1) def.allOf.find(obj => obj.$ref !== undefined && $refs.indexOf(obj.$ref) > -1)
) { ) {
res['#/components/schemas/' + defName] = [def['x-discriminator-value'] || defName]; res['#/components/schemas/' + defName] = [def['x-discriminator-value'] || defName];
} }
@ -363,7 +366,7 @@ export class OpenAPIParser {
const beforeAllOf = allOf.slice(0, i); const beforeAllOf = allOf.slice(0, i);
const afterAllOf = allOf.slice(i + 1); const afterAllOf = allOf.slice(i + 1);
return { return {
oneOf: sub.oneOf.map((part) => { oneOf: sub.oneOf.map(part => {
const merged = this.mergeAllOf({ const merged = this.mergeAllOf({
allOf: [...beforeAllOf, part, ...afterAllOf], allOf: [...beforeAllOf, part, ...afterAllOf],
}); });

View File

@ -59,7 +59,7 @@ export class SearchStore<T> {
fromExternalJS(path?: string, exportName?: string) { fromExternalJS(path?: string, exportName?: string) {
if (path && exportName) { if (path && exportName) {
this.searchWorker.fromExternalJS(path, exportName) this.searchWorker.fromExternalJS(path, exportName);
} }
} }
} }

View File

@ -28,7 +28,10 @@ export class SpecStore {
this.externalDocs = this.parser.spec.externalDocs; this.externalDocs = this.parser.spec.externalDocs;
this.contentItems = MenuBuilder.buildStructure(this.parser, this.options); this.contentItems = MenuBuilder.buildStructure(this.parser, this.options);
this.securitySchemes = new SecuritySchemesModel(this.parser); this.securitySchemes = new SecuritySchemesModel(this.parser);
const webhookPath: Referenced<OpenAPIPath> = {...this.parser?.spec?.['x-webhooks'], ...this.parser?.spec.webhooks}; const webhookPath: Referenced<OpenAPIPath> = {
...this.parser?.spec?.['x-webhooks'],
...this.parser?.spec.webhooks,
};
this.webhooks = new WebhookModel(this.parser, options, webhookPath); this.webhooks = new WebhookModel(this.parser, options, webhookPath);
} }
} }

View File

@ -26,6 +26,5 @@ describe('Models', () => {
expect(parser.shallowDeref(schemaOrRef)).toMatchSnapshot(); expect(parser.shallowDeref(schemaOrRef)).toMatchSnapshot();
}); });
}); });
}); });

View File

@ -54,8 +54,8 @@ describe('Models', () => {
license: { license: {
name: 'MIT', name: 'MIT',
identifier: 'MIT', identifier: 'MIT',
url: 'https://opensource.org/licenses/MIT' url: 'https://opensource.org/licenses/MIT',
} },
}, },
} as any; } as any;

View File

@ -19,7 +19,6 @@ describe('Models', () => {
expect(contentItems[0].id).toEqual('tag/pet'); expect(contentItems[0].id).toEqual('tag/pet');
expect(contentItems[0].name).toEqual('pet'); expect(contentItems[0].name).toEqual('pet');
expect(contentItems[0].type).toEqual('tag'); expect(contentItems[0].type).toEqual('tag');
}); });
}); });
}); });

View File

@ -20,23 +20,23 @@ describe('Models', () => {
}); });
test('should calculate response type based on code', () => { test('should calculate response type based on code', () => {
let resp = new ResponseModel({...props, code: '200' }); let resp = new ResponseModel({ ...props, code: '200' });
expect(resp.type).toEqual('success'); expect(resp.type).toEqual('success');
resp = new ResponseModel({...props, code: '120' }); resp = new ResponseModel({ ...props, code: '120' });
expect(resp.type).toEqual('info'); expect(resp.type).toEqual('info');
resp = new ResponseModel({...props, code: '301' }); resp = new ResponseModel({ ...props, code: '301' });
expect(resp.type).toEqual('redirect'); expect(resp.type).toEqual('redirect');
resp = new ResponseModel({...props, code: '400' }); 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({...props, code: 'default' }); 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({...props, code: 'default', defaultAsError: true }); const resp = new ResponseModel({ ...props, code: 'default', defaultAsError: true });
expect(resp.type).toEqual('error'); expect(resp.type).toEqual('error');
}); });
}); });

View File

@ -108,7 +108,7 @@ export class OperationModel implements IMenuItem {
// NOTE: Callbacks by default should not inherit the specification's global `security` definition. // NOTE: Callbacks by default should not inherit the specification's global `security` definition.
// Can be defined individually per-callback in the specification. Defaults to none. // Can be defined individually per-callback in the specification. Defaults to none.
this.security = (operationSpec.security || []).map( this.security = (operationSpec.security || []).map(
(security) => new SecurityRequirementModel(security, parser), security => new SecurityRequirementModel(security, parser),
); );
// TODO: update getting pathInfo for overriding servers on path level // TODO: update getting pathInfo for overriding servers on path level
@ -122,7 +122,7 @@ export class OperationModel implements IMenuItem {
: this.pointer; : this.pointer;
this.security = (operationSpec.security || parser.spec.security || []).map( this.security = (operationSpec.security || parser.spec.security || []).map(
(security) => new SecurityRequirementModel(security, parser), security => new SecurityRequirementModel(security, parser),
); );
this.servers = normalizeServers( this.servers = normalizeServers(
@ -173,7 +173,8 @@ export class OperationModel implements IMenuItem {
@memoize @memoize
get requestBody() { get requestBody() {
return ( return (
this.operationSpec.requestBody && new RequestBodyModel({ this.operationSpec.requestBody &&
new RequestBodyModel({
parser: this.parser, parser: this.parser,
infoOrRef: this.operationSpec.requestBody, infoOrRef: this.operationSpec.requestBody,
options: this.options, options: this.options,
@ -218,7 +219,7 @@ export class OperationModel implements IMenuItem {
this.operationSpec.pathParameters, this.operationSpec.pathParameters,
this.operationSpec.parameters, this.operationSpec.parameters,
// TODO: fix pointer // TODO: fix pointer
).map((paramOrRef) => new FieldModel(this.parser, paramOrRef, this.pointer, this.options)); ).map(paramOrRef => new FieldModel(this.parser, paramOrRef, this.pointer, this.options));
if (this.options.sortPropsAlphabetically) { if (this.options.sortPropsAlphabetically) {
return sortByField(_parameters, 'name'); return sortByField(_parameters, 'name');
@ -234,7 +235,7 @@ export class OperationModel implements IMenuItem {
get responses() { get responses() {
let hasSuccessResponses = false; let hasSuccessResponses = false;
return Object.keys(this.operationSpec.responses || []) return Object.keys(this.operationSpec.responses || [])
.filter((code) => { .filter(code => {
if (code === 'default') { if (code === 'default') {
return true; return true;
} }
@ -245,7 +246,7 @@ 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({
parser: this.parser, parser: this.parser,
code, code,
@ -259,7 +260,7 @@ export class OperationModel implements IMenuItem {
@memoize @memoize
get callbacks() { get callbacks() {
return Object.keys(this.operationSpec.callbacks || []).map((callbackEventName) => { return Object.keys(this.operationSpec.callbacks || []).map(callbackEventName => {
return new CallbackModel( return new CallbackModel(
this.parser, this.parser,
callbackEventName, callbackEventName,

View File

@ -9,7 +9,7 @@ type RequestBodyProps = {
infoOrRef: Referenced<OpenAPIRequestBody>; infoOrRef: Referenced<OpenAPIRequestBody>;
options: RedocNormalizedOptions; options: RedocNormalizedOptions;
isEvent: boolean; isEvent: boolean;
} };
export class RequestBodyModel { export class RequestBodyModel {
description: string; description: string;

View File

@ -9,13 +9,13 @@ import { FieldModel } from './Field';
import { MediaContentModel } from './MediaContent'; import { MediaContentModel } from './MediaContent';
type ResponseProps = { type ResponseProps = {
parser: OpenAPIParser, parser: OpenAPIParser;
code: string, code: string;
defaultAsError: boolean, defaultAsError: boolean;
infoOrRef: Referenced<OpenAPIResponse>, infoOrRef: Referenced<OpenAPIResponse>;
options: RedocNormalizedOptions, options: RedocNormalizedOptions;
isEvent: boolean, isEvent: boolean;
} };
export class ResponseModel { export class ResponseModel {
@observable @observable

View File

@ -134,7 +134,10 @@ export class SchemaModel {
this.maxItems = schema.maxItems; this.maxItems = schema.maxItems;
if (!!schema.nullable || schema['x-nullable']) { if (!!schema.nullable || schema['x-nullable']) {
if (Array.isArray(this.type) && !this.type.some((value) => value === null || value === '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')) { } else if (!Array.isArray(this.type) && (this.type !== null || this.type !== 'null')) {
this.type = [this.type, 'null']; this.type = [this.type, 'null'];
@ -142,7 +145,7 @@ export class SchemaModel {
} }
this.displayType = Array.isArray(this.type) this.displayType = Array.isArray(this.type)
? this.type.map(item => item === null ? 'null' : item).join(' or ') ? this.type.map(item => (item === null ? 'null' : item)).join(' or ')
: this.type; : this.type;
if (this.isCircular) { if (this.isCircular) {
@ -155,7 +158,7 @@ export class SchemaModel {
} else if ( } else if (
isChild && isChild &&
Array.isArray(schema.oneOf) && Array.isArray(schema.oneOf) &&
schema.oneOf.find((s) => s.$ref === this.pointer) schema.oneOf.find(s => s.$ref === this.pointer)
) { ) {
// we hit allOf of the schema with the parent discriminator // we hit allOf of the schema with the parent discriminator
delete schema.oneOf; delete schema.oneOf;
@ -195,8 +198,7 @@ export class SchemaModel {
} }
if (Array.isArray(this.type)) { if (Array.isArray(this.type)) {
const filteredType = this.type.filter(item => item !== 'array'); const filteredType = this.type.filter(item => item !== 'array');
if (filteredType.length) if (filteredType.length) this.displayType += ` or ${filteredType.join(' or ')}`;
this.displayType += ` or ${filteredType.join(' or ')}`;
} }
} }
@ -215,7 +217,7 @@ export class SchemaModel {
const title = const title =
isNamedDefinition(variant.$ref) && !merged.title isNamedDefinition(variant.$ref) && !merged.title
? JsonPointer.baseName(variant.$ref) ? JsonPointer.baseName(variant.$ref)
: `${(merged.title || '')}${(merged.const && JSON.stringify(merged.const)) || ''}`; : `${merged.title || ''}${(merged.const && JSON.stringify(merged.const)) || ''}`;
const schema = new SchemaModel( const schema = new SchemaModel(
parser, parser,
@ -243,7 +245,7 @@ export class SchemaModel {
this.displayType = types.join(' or '); this.displayType = types.join(' or ');
} else { } else {
this.displayType = this.oneOf this.displayType = this.oneOf
.map((schema) => { .map(schema => {
let name = let name =
schema.typePrefix + schema.typePrefix +
(schema.title ? `${schema.title} (${schema.displayType})` : schema.displayType); (schema.title ? `${schema.title} (${schema.displayType})` : schema.displayType);
@ -364,7 +366,7 @@ function buildFields(
const props = schema.properties || {}; const props = schema.properties || {};
const additionalProps = schema.additionalProperties; const additionalProps = schema.additionalProperties;
const defaults = schema.default; const defaults = schema.default;
let fields = Object.keys(props || []).map((fieldName) => { let fields = Object.keys(props || []).map(fieldName => {
let field = props[fieldName]; let field = props[fieldName];
if (!field) { if (!field) {

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { hydrate as hydrateComponent, render } from 'react-dom'; import { hydrate as hydrateComponent, render } from 'react-dom';
import { configure } from "mobx" import { configure } from 'mobx';
import { Redoc, RedocStandalone } from './components/'; import { Redoc, RedocStandalone } from './components/';
import { AppStore, StoreState } from './services/AppStore'; import { AppStore, StoreState } from './services/AppStore';
@ -8,8 +8,8 @@ import { debugTime, debugTimeEnd } from './utils/debug';
import { querySelector } from './utils/dom'; import { querySelector } from './utils/dom';
configure({ configure({
useProxies: 'ifavailable' useProxies: 'ifavailable',
}) });
export { Redoc, AppStore } from '.'; export { Redoc, AppStore } from '.';

View File

@ -16,7 +16,7 @@ export const media = {
lessThan(breakpoint, print?: boolean, extra?: string) { lessThan(breakpoint, print?: boolean, extra?: string) {
return (...args) => css` return (...args) => css`
@media ${print ? 'print, ' : ''} screen and (max-width: ${props => @media ${print ? 'print, ' : ''} screen and (max-width: ${props =>
props.theme.breakpoints[breakpoint]})${extra || ''} { props.theme.breakpoints[breakpoint]}) ${extra || ''} {
${(css as any)(...args)}; ${(css as any)(...args)};
} }
`; `;

View File

@ -11,7 +11,9 @@ describe('#loadAndBundleSpec', () => {
}); });
it('should load And Bundle Spec demo/openapi-3-1.yaml', async () => { it('should load And Bundle Spec demo/openapi-3-1.yaml', async () => {
const spec = yaml.load(readFileSync(resolve(__dirname, '../../../demo/openapi-3-1.yaml'), 'utf-8')); const spec = yaml.load(
readFileSync(resolve(__dirname, '../../../demo/openapi-3-1.yaml'), 'utf-8'),
);
const bundledSpec = await loadAndBundleSpec(spec); const bundledSpec = await loadAndBundleSpec(spec);
expect(bundledSpec).toMatchSnapshot(); expect(bundledSpec).toMatchSnapshot();
}); });

View File

@ -12,7 +12,7 @@ function throttle(func, wait) {
context = args = null; context = args = null;
} }
}; };
return function() { return function () {
const now = new Date().getTime(); const now = new Date().getTime();
const remaining = wait - (now - previous); const remaining = wait - (now - previous);
context = this; context = this;

View File

@ -27,7 +27,7 @@ export function html2Str(html: string): string {
// scrollIntoViewIfNeeded polyfill // scrollIntoViewIfNeeded polyfill
if (typeof Element !== 'undefined' && !(Element as any).prototype.scrollIntoViewIfNeeded) { if (typeof Element !== 'undefined' && !(Element as any).prototype.scrollIntoViewIfNeeded) {
(Element as any).prototype.scrollIntoViewIfNeeded = function(centerIfNeeded) { (Element as any).prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded; centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded;
const parent = this.parentNode; const parent = this.parentNode;

View File

@ -50,7 +50,7 @@ export function flattenByProp<T extends object, P extends keyof T>(
for (const item of items) { for (const item of items) {
res.push(item); res.push(item);
if (item[prop]) { if (item[prop]) {
iterate((item[prop] as any) as T[]); iterate(item[prop] as any as T[]);
} }
} }
}; };

View File

@ -14,8 +14,8 @@ export async function loadAndBundleSpec(specUrlOrObject: object | string): Promi
const config = new Config({}); const config = new Config({});
const bundleOpts = { const bundleOpts = {
config, config,
base: IS_BROWSER ? window.location.href : process.cwd() base: IS_BROWSER ? window.location.href : process.cwd(),
} };
if (IS_BROWSER) { if (IS_BROWSER) {
config.resolve.http.customFetch = global.fetch; config.resolve.http.customFetch = global.fetch;
@ -24,13 +24,15 @@ export async function loadAndBundleSpec(specUrlOrObject: object | string): Promi
if (typeof specUrlOrObject === 'object' && specUrlOrObject !== null) { if (typeof specUrlOrObject === 'object' && specUrlOrObject !== null) {
bundleOpts['doc'] = { bundleOpts['doc'] = {
source: { absoluteRef: '' } as Source, source: { absoluteRef: '' } as Source,
parsed: specUrlOrObject parsed: specUrlOrObject,
} as Document } as Document;
} else { } else {
bundleOpts['ref'] = specUrlOrObject; bundleOpts['ref'] = specUrlOrObject;
} }
const { bundle: { parsed } } = await bundle(bundleOpts); const {
bundle: { parsed },
} = await bundle(bundleOpts);
return parsed.swagger !== undefined ? convertSwagger2OpenAPI(parsed) : parsed; return parsed.swagger !== undefined ? convertSwagger2OpenAPI(parsed) : parsed;
} }

View File

@ -3,7 +3,7 @@ const SENTINEL = {};
export function memoize<T>(target: any, name: string, descriptor: TypedPropertyDescriptor<T>) { export function memoize<T>(target: any, name: string, descriptor: TypedPropertyDescriptor<T>) {
if (typeof descriptor.value === 'function') { if (typeof descriptor.value === 'function') {
return (_memoizeMethod(target, name, descriptor) as any) as TypedPropertyDescriptor<T>; return _memoizeMethod(target, name, descriptor) as any as TypedPropertyDescriptor<T>;
} else if (typeof descriptor.get === 'function') { } else if (typeof descriptor.get === 'function') {
return _memoizeGetter(target, name, descriptor) as TypedPropertyDescriptor<T>; return _memoizeGetter(target, name, descriptor) as TypedPropertyDescriptor<T>;
} else { } else {

View File

@ -148,10 +148,10 @@ export function isFormUrlEncoded(contentType: string): boolean {
function delimitedEncodeField(fieldVal: any, fieldName: string, delimiter: string): string { function delimitedEncodeField(fieldVal: any, fieldName: string, delimiter: string): string {
if (Array.isArray(fieldVal)) { if (Array.isArray(fieldVal)) {
return fieldVal.map((v) => v.toString()).join(delimiter); return fieldVal.map(v => v.toString()).join(delimiter);
} else if (typeof fieldVal === 'object') { } else if (typeof fieldVal === 'object') {
return Object.keys(fieldVal) return Object.keys(fieldVal)
.map((k) => `${k}${delimiter}${fieldVal[k]}`) .map(k => `${k}${delimiter}${fieldVal[k]}`)
.join(delimiter); .join(delimiter);
} else { } else {
return fieldName + '=' + fieldVal.toString(); return fieldName + '=' + fieldVal.toString();
@ -164,7 +164,7 @@ function deepObjectEncodeField(fieldVal: any, fieldName: string): string {
return ''; return '';
} else if (typeof fieldVal === 'object') { } else if (typeof fieldVal === 'object') {
return Object.keys(fieldVal) return Object.keys(fieldVal)
.map((k) => `${fieldName}[${k}]=${fieldVal[k]}`) .map(k => `${fieldName}[${k}]=${fieldVal[k]}`)
.join('&'); .join('&');
} else { } else {
console.warn('deepObject style cannot be used with non-object value:' + fieldVal.toString()); console.warn('deepObject style cannot be used with non-object value:' + fieldVal.toString());
@ -196,7 +196,7 @@ export function urlFormEncodePayload(
throw new Error('Payload must have fields: ' + payload.toString()); throw new Error('Payload must have fields: ' + payload.toString());
} else { } else {
return Object.keys(payload) return Object.keys(payload)
.map((fieldName) => { .map(fieldName => {
const fieldVal = payload[fieldName]; const fieldVal = payload[fieldName];
const { style = 'form', explode = true } = encoding[fieldName] || {}; const { style = 'form', explode = true } = encoding[fieldName] || {};
switch (style) { switch (style) {
@ -477,7 +477,7 @@ export function sortByRequired(fields: FieldModel[], order: string[] = []) {
const orderedFields: FieldModel[] = []; const orderedFields: FieldModel[] = [];
const unorderedFields: FieldModel[] = []; const unorderedFields: FieldModel[] = [];
fields.forEach((field) => { fields.forEach(field => {
if (field.required) { if (field.required) {
order.includes(field.name) ? orderedFields.push(field) : unorderedFields.push(field); order.includes(field.name) ? orderedFields.push(field) : unorderedFields.push(field);
} else { } else {
@ -505,13 +505,13 @@ export function mergeParams(
operationParams: Array<Referenced<OpenAPIParameter>> = [], operationParams: Array<Referenced<OpenAPIParameter>> = [],
): Array<Referenced<OpenAPIParameter>> { ): Array<Referenced<OpenAPIParameter>> {
const operationParamNames = {}; const operationParamNames = {};
operationParams.forEach((param) => { operationParams.forEach(param => {
param = parser.shallowDeref(param); param = parser.shallowDeref(param);
operationParamNames[param.name + '_' + param.in] = true; operationParamNames[param.name + '_' + param.in] = true;
}); });
// filter out path params overridden by operation ones with the same name // filter out path params overridden by operation ones with the same name
pathParams = pathParams.filter((param) => { pathParams = pathParams.filter(param => {
param = parser.shallowDeref(param); param = parser.shallowDeref(param);
return !operationParamNames[param.name + '_' + param.in]; return !operationParamNames[param.name + '_' + param.in];
}); });
@ -523,7 +523,7 @@ export function mergeSimilarMediaTypes(
types: Record<string, OpenAPIMediaType>, types: Record<string, OpenAPIMediaType>,
): Record<string, OpenAPIMediaType> { ): Record<string, OpenAPIMediaType> {
const mergedTypes = {}; const mergedTypes = {};
Object.keys(types).forEach((name) => { Object.keys(types).forEach(name => {
const mime = types[name]; const mime = types[name];
// ignore content type parameters (e.g. charset) and merge // ignore content type parameters (e.g. charset) and merge
const normalizedMimeName = name.split(';')[0].trim(); const normalizedMimeName = name.split(';')[0].trim();
@ -571,7 +571,7 @@ export function normalizeServers(
return resolveUrl(baseUrl, url); return resolveUrl(baseUrl, url);
} }
return servers.map((server) => { return servers.map(server => {
return { return {
...server, ...server,
url: normalizeUrl(server.url), url: normalizeUrl(server.url),
@ -589,7 +589,7 @@ export function setSecuritySchemePrefix(prefix: string) {
SECURITY_SCHEMES_SECTION_PREFIX = prefix; SECURITY_SCHEMES_SECTION_PREFIX = prefix;
} }
export const shortenHTTPVerb = (verb) => export const shortenHTTPVerb = verb =>
({ ({
delete: 'del', delete: 'del',
options: 'opts', options: 'opts',
@ -620,7 +620,7 @@ export function extractExtensions(
showExtensions: string[] | true, showExtensions: string[] | true,
): Record<string, any> { ): Record<string, any> {
return Object.keys(obj) return Object.keys(obj)
.filter((key) => { .filter(key => {
if (showExtensions === true) { if (showExtensions === true) {
return key.startsWith('x-') && !isRedocExtension(key); return key.startsWith('x-') && !isRedocExtension(key);
} }
@ -635,6 +635,6 @@ export function extractExtensions(
export function pluralizeType(displayType: string): string { export function pluralizeType(displayType: string): string {
return displayType return displayType
.split(' or ') .split(' or ')
.map((type) => type.replace(/^(string|object|number|integer|array|boolean)s?( ?.*)/, '$1s$2')) .map(type => type.replace(/^(string|object|number|integer|array|boolean)s?( ?.*)/, '$1s$2'))
.join(' or '); .join(' or ');
} }