mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-09 14:44:51 +03:00
Merge branch 'master' of https://github.com/nutanix/ReDoc into add-validation
This commit is contained in:
commit
4f0bb8c57b
|
@ -1,6 +1,6 @@
|
||||||
*
|
*
|
||||||
!bundles/*
|
!bundles/*
|
||||||
!typings/*
|
!typings/**/*
|
||||||
!package.json
|
!package.json
|
||||||
!README.md
|
!README.md
|
||||||
!LICENSE
|
!LICENSE
|
|
@ -15,7 +15,7 @@ env:
|
||||||
addons:
|
addons:
|
||||||
chrome: stable
|
chrome: stable
|
||||||
before_script: npm run bundle
|
before_script: npm run bundle
|
||||||
script: npm test && npm run e2e-ci
|
script: npm test && [ "${TRAVIS_PULL_REQUEST}" = "false" ] && npm run e2e-ci || npm run e2e
|
||||||
after_script: cat ./coverage/lcov.info | coveralls
|
after_script: cat ./coverage/lcov.info | coveralls
|
||||||
before_deploy: npm run compile:cli && npm run declarations
|
before_deploy: npm run compile:cli && npm run declarations
|
||||||
deploy:
|
deploy:
|
||||||
|
|
23
CHANGELOG.md
23
CHANGELOG.md
|
@ -1,3 +1,26 @@
|
||||||
|
<a name="2.0.0-alpha.24"></a>
|
||||||
|
# [2.0.0-alpha.24](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.23...v2.0.0-alpha.24) (2018-06-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* temporary downgrade marked as it introduced breaking changes and a few bugs ([902f97a](https://github.com/Rebilly/ReDoc/commit/902f97a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="2.0.0-alpha.23"></a>
|
||||||
|
# [2.0.0-alpha.23](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.22...v2.0.0-alpha.23) (2018-05-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **cli:** make positional arguments required and handle errors in serve and bundle manually ([#518](https://github.com/Rebilly/ReDoc/issues/518)) ([370d08a](https://github.com/Rebilly/ReDoc/commit/370d08a))
|
||||||
|
* fix typings on npm ([d957ad7](https://github.com/Rebilly/ReDoc/commit/d957ad7))
|
||||||
|
* fix vertical line misaligned in firefox ([bde08f1](https://github.com/Rebilly/ReDoc/commit/bde08f1)), closes [#503](https://github.com/Rebilly/ReDoc/issues/503)
|
||||||
|
* mergeAllOf takes items into account ([#511](https://github.com/Rebilly/ReDoc/issues/511)) ([47b2177](https://github.com/Rebilly/ReDoc/commit/47b2177))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="2.0.0-alpha.22"></a>
|
<a name="2.0.0-alpha.22"></a>
|
||||||
# [2.0.0-alpha.22](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.21...v2.0.0-alpha.22) (2018-05-29)
|
# [2.0.0-alpha.22](https://github.com/Rebilly/ReDoc/compare/v2.0.0-alpha.21...v2.0.0-alpha.22) (2018-05-29)
|
||||||
|
|
||||||
|
|
|
@ -212,12 +212,13 @@ You can use all of the following options with standalone version on <redoc> tag
|
||||||
## Advanced usage of standalone version
|
## Advanced usage of standalone version
|
||||||
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:
|
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:
|
||||||
```js
|
```js
|
||||||
Redoc.init(specOrSpecUrl, options, element)
|
Redoc.init(specOrSpecUrl, options, element, callback?)
|
||||||
```
|
```
|
||||||
|
|
||||||
- `specOrSpecUrl` is either JSON object with specification or an URL to the spec in `JSON` or `YAML` format
|
- `specOrSpecUrl` is either JSON object with specification or an URL to the spec in `JSON` or `YAML` format
|
||||||
- `options` [options object](#redoc-options-object)
|
- `options` [options object](#redoc-options-object)
|
||||||
- `element` DOM element to put ReDoc into
|
- `element` DOM element to put ReDoc into
|
||||||
|
- `callback` (optional) - callback to be called after Redoc has been fully rendered
|
||||||
|
|
||||||
```js
|
```js
|
||||||
Redoc.init('http://petstore.swagger.io/v2/swagger.json', {
|
Redoc.init('http://petstore.swagger.io/v2/swagger.json', {
|
||||||
|
|
33
cli/index.ts
33
cli/index.ts
|
@ -32,7 +32,7 @@ const BUNDLES_DIR = dirname(require.resolve('redoc'));
|
||||||
|
|
||||||
/* tslint:disable-next-line */
|
/* tslint:disable-next-line */
|
||||||
YargsParser.command(
|
YargsParser.command(
|
||||||
'serve [spec]',
|
'serve <spec>',
|
||||||
'start the server',
|
'start the server',
|
||||||
yargs => {
|
yargs => {
|
||||||
yargs.positional('spec', {
|
yargs.positional('spec', {
|
||||||
|
@ -60,16 +60,22 @@ YargsParser.command(
|
||||||
return yargs;
|
return yargs;
|
||||||
},
|
},
|
||||||
async argv => {
|
async argv => {
|
||||||
await serve(argv.port, argv.spec, {
|
const config = {
|
||||||
ssr: argv.ssr,
|
ssr: argv.ssr,
|
||||||
watch: argv.watch,
|
watch: argv.watch,
|
||||||
templateFileName: argv.template,
|
templateFileName: argv.template,
|
||||||
redocOptions: argv.options || {},
|
redocOptions: argv.options || {},
|
||||||
});
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await serve(argv.port, argv.spec, config);
|
||||||
|
} catch (e) {
|
||||||
|
handleError(e);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.command(
|
.command(
|
||||||
'bundle [spec]',
|
'bundle <spec>',
|
||||||
'bundle spec into zero-dependency HTML-file',
|
'bundle spec into zero-dependency HTML-file',
|
||||||
yargs => {
|
yargs => {
|
||||||
yargs.positional('spec', {
|
yargs.positional('spec', {
|
||||||
|
@ -99,14 +105,20 @@ YargsParser.command(
|
||||||
return yargs;
|
return yargs;
|
||||||
},
|
},
|
||||||
async argv => {
|
async argv => {
|
||||||
await bundle(argv.spec, {
|
const config = {
|
||||||
ssr: true,
|
ssr: true,
|
||||||
output: argv.o,
|
output: argv.o,
|
||||||
cdn: argv.cdn,
|
cdn: argv.cdn,
|
||||||
title: argv.title,
|
title: argv.title,
|
||||||
templateFileName: argv.template,
|
templateFileName: argv.template,
|
||||||
redocOptions: argv.options || {},
|
redocOptions: argv.options || {},
|
||||||
});
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await bundle(argv.spec, config);
|
||||||
|
} catch (e) {
|
||||||
|
handleError(e);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.demandCommand()
|
.demandCommand()
|
||||||
|
@ -117,10 +129,6 @@ YargsParser.command(
|
||||||
})
|
})
|
||||||
.options('options', {
|
.options('options', {
|
||||||
describe: 'ReDoc options, use dot notation, e.g. options.nativeScrollbars',
|
describe: 'ReDoc options, use dot notation, e.g. options.nativeScrollbars',
|
||||||
})
|
|
||||||
.fail((message, error) => {
|
|
||||||
console.log(error.stack);
|
|
||||||
process.exit(1);
|
|
||||||
}).argv;
|
}).argv;
|
||||||
|
|
||||||
async function serve(port: number, pathToSpec: string, options: Options = {}) {
|
async function serve(port: number, pathToSpec: string, options: Options = {}) {
|
||||||
|
@ -296,3 +304,8 @@ function isURL(str: string): boolean {
|
||||||
function escapeUnicode(str) {
|
function escapeUnicode(str) {
|
||||||
return str.replace(/\u2028|\u2029/g, m => '\\u202' + (m === '\u2028' ? '8' : '9'));
|
return str.replace(/\u2028|\u2029/g, m => '\\u202' + (m === '\u2028' ? '8' : '9'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleError(error: Error) {
|
||||||
|
console.error(error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
4
custom.d.ts
vendored
4
custom.d.ts
vendored
|
@ -18,10 +18,6 @@ declare module '*.css' {
|
||||||
declare var __REDOC_VERSION__: string;
|
declare var __REDOC_VERSION__: string;
|
||||||
declare var __REDOC_REVISION__: string;
|
declare var __REDOC_REVISION__: string;
|
||||||
|
|
||||||
declare type Dict<T> = {
|
|
||||||
[key: string]: T;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface Element {
|
interface Element {
|
||||||
scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;
|
scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const demos = [
|
||||||
value: 'https://api.apis.guru/v2/specs/googleapis.com/calendar/v3/swagger.yaml',
|
value: 'https://api.apis.guru/v2/specs/googleapis.com/calendar/v3/swagger.yaml',
|
||||||
label: 'Google Calendar',
|
label: 'Google Calendar',
|
||||||
},
|
},
|
||||||
{ value: 'https://api.apis.guru/v2/specs/slack.com/1.0.3/swagger.yaml', label: 'Slack' },
|
{ value: 'https://api.apis.guru/v2/specs/slack.com/1.0.6/swagger.yaml', label: 'Slack' },
|
||||||
{ value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/swagger.yaml', label: 'Zoom.us' },
|
{ value: 'https://api.apis.guru/v2/specs/zoom.us/2.0.0/swagger.yaml', label: 'Zoom.us' },
|
||||||
{
|
{
|
||||||
value: 'https://api.apis.guru/v2/specs/graphhopper.com/1.0/swagger.yaml',
|
value: 'https://api.apis.guru/v2/specs/graphhopper.com/1.0/swagger.yaml',
|
||||||
|
|
|
@ -200,6 +200,16 @@ Extends OpenAPI [Parameter Object](http://swagger.io/specification/#parameterObj
|
||||||
###### Usage in ReDoc
|
###### Usage in ReDoc
|
||||||
`x-examples` are rendered in the JSON tab on the right panel of ReDoc.
|
`x-examples` are rendered in the JSON tab on the right panel of ReDoc.
|
||||||
|
|
||||||
|
### Response Object vendor extensions
|
||||||
|
Extneds OpeanAPI [Response Object](https://swagger.io/specification/#responseObject)
|
||||||
|
|
||||||
|
#### x-summary
|
||||||
|
| Field Name | Type | Description |
|
||||||
|
| :------------- | :------: | :---------- |
|
||||||
|
| x-summary | string | a short summary of the response |
|
||||||
|
|
||||||
|
###### Usage in ReDoc
|
||||||
|
If specified, `x-summary` is used as the response button text. Description is rendered under the button.
|
||||||
|
|
||||||
### Schema Object vendor extensions
|
### Schema Object vendor extensions
|
||||||
Extends OpenAPI [Schema Object](http://swagger.io/specification/#schemaObject)
|
Extends OpenAPI [Schema Object](http://swagger.io/specification/#schemaObject)
|
||||||
|
|
12
package.json
12
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "redoc",
|
"name": "redoc",
|
||||||
"version": "2.0.0-alpha.22",
|
"version": "2.0.0-alpha.24",
|
||||||
"description": "ReDoc",
|
"description": "ReDoc",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -51,10 +51,10 @@
|
||||||
"license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause' --summary"
|
"license-check": "license-checker --production --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause' --summary"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.0.0-beta.40",
|
"@babel/core": "7.0.0-beta.47",
|
||||||
"@babel/plugin-syntax-decorators": "^7.0.0-beta.42",
|
"@babel/plugin-syntax-decorators": "7.0.0-beta.47",
|
||||||
"@babel/plugin-syntax-jsx": "^7.0.0-beta.42",
|
"@babel/plugin-syntax-jsx": "7.0.0-beta.47",
|
||||||
"@babel/plugin-syntax-typescript": "^7.0.0-beta.42",
|
"@babel/plugin-syntax-typescript": "7.0.0-beta.47",
|
||||||
"@cypress/webpack-preprocessor": "2.0.1",
|
"@cypress/webpack-preprocessor": "2.0.1",
|
||||||
"@types/dompurify": "^0.0.31",
|
"@types/dompurify": "^0.0.31",
|
||||||
"@types/enzyme": "^3.1.8",
|
"@types/enzyme": "^3.1.8",
|
||||||
|
@ -138,7 +138,7 @@
|
||||||
"json-schema-ref-parser": "^5.0.0",
|
"json-schema-ref-parser": "^5.0.0",
|
||||||
"lunr": "^2.2.1",
|
"lunr": "^2.2.1",
|
||||||
"mark.js": "^8.11.1",
|
"mark.js": "^8.11.1",
|
||||||
"marked": "^0.4.0",
|
"marked": "0.3.18",
|
||||||
"mobx": "^4.3.0",
|
"mobx": "^4.3.0",
|
||||||
"mobx-react": "^5.0.0",
|
"mobx-react": "^5.0.0",
|
||||||
"openapi-sampler": "1.0.0-beta.12",
|
"openapi-sampler": "1.0.0-beta.12",
|
||||||
|
|
|
@ -117,7 +117,7 @@ export const InnerPropertiesWrap = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const PropertiesTable = styled.table`
|
export const PropertiesTable = styled.table`
|
||||||
border-collapse: collapse;
|
border-collapse: separate;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-size: ${props => props.theme.baseFont.size};
|
font-size: ${props => props.theme.baseFont.size};
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,7 @@ export class FieldDetails extends React.PureComponent<FieldProps> {
|
||||||
<div>
|
<div>
|
||||||
<TypePrefix>{schema.typePrefix}</TypePrefix>
|
<TypePrefix>{schema.typePrefix}</TypePrefix>
|
||||||
<TypeName>{schema.displayType}</TypeName>
|
<TypeName>{schema.displayType}</TypeName>
|
||||||
{schema.format && (
|
{schema.format && <TypeFormat> <{schema.format}> </TypeFormat>}
|
||||||
<TypeFormat>
|
|
||||||
{' <'}
|
|
||||||
{schema.format}>
|
|
||||||
</TypeFormat>
|
|
||||||
)}
|
|
||||||
{schema.title && <TypeTitle> ({schema.title}) </TypeTitle>}
|
{schema.title && <TypeTitle> ({schema.title}) </TypeTitle>}
|
||||||
<ConstraintsView constraints={schema.constraints} />
|
<ConstraintsView constraints={schema.constraints} />
|
||||||
{schema.nullable && <NullableLabel> Nullable </NullableLabel>}
|
{schema.nullable && <NullableLabel> Nullable </NullableLabel>}
|
||||||
|
|
|
@ -21,9 +21,10 @@ export class MediaTypeSamples extends React.Component<PayloadSamplesProps> {
|
||||||
const sampleView = isJsonLike(mimeType)
|
const sampleView = isJsonLike(mimeType)
|
||||||
? sample => <JsonViewer data={sample} />
|
? sample => <JsonViewer data={sample} />
|
||||||
: sample =>
|
: sample =>
|
||||||
(sample && <SourceCodeWithCopy lang={langFromMime(mimeType)} source={sample} />) || {
|
(sample !== undefined && (
|
||||||
noSample,
|
<SourceCodeWithCopy lang={langFromMime(mimeType)} source={sample} />
|
||||||
};
|
)) ||
|
||||||
|
noSample;
|
||||||
|
|
||||||
const examplesNames = Object.keys(examples);
|
const examplesNames = Object.keys(examples);
|
||||||
if (examplesNames.length === 0) {
|
if (examplesNames.length === 0) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { DropdownOrLabel } from '../DropdownOrLabel/DropdownOrLabel';
|
||||||
import { MediaTypesSwitch } from '../MediaTypeSwitch/MediaTypesSwitch';
|
import { MediaTypesSwitch } from '../MediaTypeSwitch/MediaTypesSwitch';
|
||||||
import { Schema } from '../Schema';
|
import { Schema } from '../Schema';
|
||||||
|
|
||||||
|
import { Markdown } from '../Markdown/Markdown';
|
||||||
import { ResponseHeaders } from './ResponseHeaders';
|
import { ResponseHeaders } from './ResponseHeaders';
|
||||||
import { ResponseDetailsWrap, StyledResponseTitle } from './styled.elements';
|
import { ResponseDetailsWrap, StyledResponseTitle } from './styled.elements';
|
||||||
|
|
||||||
|
@ -18,11 +19,11 @@ export class ResponseView extends React.Component<{ response: ResponseModel }> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { headers, type, description, code, expanded, content } = this.props.response;
|
const { headers, type, summary, description, code, expanded, content } = this.props.response;
|
||||||
const mimes =
|
const mimes =
|
||||||
content === undefined ? [] : content.mediaTypes.filter(mime => mime.schema !== undefined);
|
content === undefined ? [] : content.mediaTypes.filter(mime => mime.schema !== undefined);
|
||||||
|
|
||||||
const empty = headers.length === 0 && mimes.length === 0;
|
const empty = headers.length === 0 && mimes.length === 0 && !description;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -30,13 +31,14 @@ export class ResponseView extends React.Component<{ response: ResponseModel }> {
|
||||||
onClick={this.toggle}
|
onClick={this.toggle}
|
||||||
type={type}
|
type={type}
|
||||||
empty={empty}
|
empty={empty}
|
||||||
title={description || ''}
|
title={summary || ''}
|
||||||
code={code}
|
code={code}
|
||||||
opened={expanded}
|
opened={expanded}
|
||||||
/>
|
/>
|
||||||
{expanded &&
|
{expanded &&
|
||||||
!empty && (
|
!empty && (
|
||||||
<ResponseDetailsWrap>
|
<ResponseDetailsWrap>
|
||||||
|
{description && <Markdown source={description} />}
|
||||||
<ResponseHeaders headers={headers} />
|
<ResponseHeaders headers={headers} />
|
||||||
<MediaTypesSwitch content={content} renderDropdown={this.renderDropdown}>
|
<MediaTypesSwitch content={content} renderDropdown={this.renderDropdown}>
|
||||||
{({ schema }) => {
|
{({ schema }) => {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { IMenuItem, MenuStore } from '../../services/MenuStore';
|
||||||
import { MenuItems } from './MenuItems';
|
import { MenuItems } from './MenuItems';
|
||||||
|
|
||||||
import { PerfectScrollbar } from '../../common-elements/perfect-scrollbar';
|
import { PerfectScrollbar } from '../../common-elements/perfect-scrollbar';
|
||||||
|
import { RedocAttribution } from './styled.elements';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class SideMenu extends React.Component<{ menu: MenuStore }> {
|
export class SideMenu extends React.Component<{ menu: MenuStore }> {
|
||||||
|
@ -29,6 +30,11 @@ export class SideMenu extends React.Component<{ menu: MenuStore }> {
|
||||||
) : (
|
) : (
|
||||||
<PerfectScrollbar updateFn={this.saveScrollUpdate}>
|
<PerfectScrollbar updateFn={this.saveScrollUpdate}>
|
||||||
<MenuItems items={store.items} onActivate={this.activate} root={true} />
|
<MenuItems items={store.items} onActivate={this.activate} root={true} />
|
||||||
|
<RedocAttribution>
|
||||||
|
<a target="_blank" href="https://github.com/Rebilly/ReDoc">
|
||||||
|
Documentation Powered by ReDoc
|
||||||
|
</a>
|
||||||
|
</RedocAttribution>
|
||||||
</PerfectScrollbar>
|
</PerfectScrollbar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,3 +160,21 @@ export const MenuItemTitle = withProps<{ width?: string }>(styled.span)`
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const RedocAttribution = styled.div`
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin-top: ${({ theme }) => `${theme.spacingUnit / 2}px`};
|
||||||
|
padding: ${({ theme }) => `0 ${theme.spacingUnit}px`};
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
|
a,
|
||||||
|
a:visited,
|
||||||
|
a:hover {
|
||||||
|
color: ${({ theme }) => theme.colors.text} !important;
|
||||||
|
border-top: 1px solid #e1e1e1;
|
||||||
|
padding-top: 10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
|
@ -233,6 +233,15 @@ export class OpenAPIParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subSchema.items !== undefined) {
|
||||||
|
receiver.items = receiver.items || {};
|
||||||
|
// merge inner properties
|
||||||
|
receiver.items = this.mergeAllOf(
|
||||||
|
{ allOf: [receiver.items, subSchema.items] },
|
||||||
|
$ref + '/items',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (subSchema.required !== undefined) {
|
if (subSchema.required !== undefined) {
|
||||||
receiver.required = (receiver.required || []).concat(subSchema.required);
|
receiver.required = (receiver.required || []).concat(subSchema.required);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@ import { OpenAPIExternalDocumentation, OpenAPIServer } from '../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getOperationSummary,
|
getOperationSummary,
|
||||||
|
getStatusCodeType,
|
||||||
isAbsolutePath,
|
isAbsolutePath,
|
||||||
|
isStatusCode,
|
||||||
JsonPointer,
|
JsonPointer,
|
||||||
mergeParams,
|
mergeParams,
|
||||||
sortByRequired,
|
sortByRequired,
|
||||||
|
@ -99,10 +101,15 @@ export class OperationModel implements IMenuItem {
|
||||||
let hasSuccessResponses = false;
|
let hasSuccessResponses = false;
|
||||||
this.responses = Object.keys(operationSpec.responses || [])
|
this.responses = Object.keys(operationSpec.responses || [])
|
||||||
.filter(code => {
|
.filter(code => {
|
||||||
if (parseInt(code, 10) >= 100 && parseInt(code, 10) <= 399) {
|
if (code === 'default') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getStatusCodeType(code) === 'success') {
|
||||||
hasSuccessResponses = true;
|
hasSuccessResponses = true;
|
||||||
}
|
}
|
||||||
return isNumeric(code) || code === 'default';
|
|
||||||
|
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(
|
||||||
|
|
|
@ -13,6 +13,7 @@ export class ResponseModel {
|
||||||
|
|
||||||
content?: MediaContentModel;
|
content?: MediaContentModel;
|
||||||
code: string;
|
code: string;
|
||||||
|
summary: string;
|
||||||
description: string;
|
description: string;
|
||||||
type: string;
|
type: string;
|
||||||
headers: FieldModel[] = [];
|
headers: FieldModel[] = [];
|
||||||
|
@ -32,7 +33,15 @@ export class ResponseModel {
|
||||||
if (info.content !== undefined) {
|
if (info.content !== undefined) {
|
||||||
this.content = new MediaContentModel(parser, info.content, false, options);
|
this.content = new MediaContentModel(parser, info.content, false, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info['x-summary'] !== undefined) {
|
||||||
|
this.summary = info['x-summary'];
|
||||||
this.description = info.description || '';
|
this.description = info.description || '';
|
||||||
|
} else {
|
||||||
|
this.summary = info.description || '';
|
||||||
|
this.description = '';
|
||||||
|
}
|
||||||
|
|
||||||
this.type = getStatusCodeType(code, defaultAsError);
|
this.type = getStatusCodeType(code, defaultAsError);
|
||||||
|
|
||||||
const headers = info.headers;
|
const headers = info.headers;
|
||||||
|
|
5
src/types/index.d.ts
vendored
5
src/types/index.d.ts
vendored
|
@ -1,3 +1,8 @@
|
||||||
export * from './open-api';
|
export * from './open-api';
|
||||||
|
|
||||||
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
||||||
|
declare global {
|
||||||
|
type Dict<T> = {
|
||||||
|
[key: string]: T;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -6,21 +6,35 @@ import {
|
||||||
OpenAPISchema,
|
OpenAPISchema,
|
||||||
Referenced,
|
Referenced,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
import { isNumeric } from './helpers';
|
||||||
|
|
||||||
export function getStatusCodeType(statusCode: string | number, defaultAsError = false): string {
|
function isWildcardStatusCode(statusCode: string | number): statusCode is string {
|
||||||
|
return typeof statusCode === 'string' && /\dxx/i.test(statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isStatusCode(statusCode: string) {
|
||||||
|
return statusCode === 'default' || isNumeric(statusCode) || isWildcardStatusCode(statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStatusCodeType(statusCode: string, defaultAsError = false): string {
|
||||||
if (statusCode === 'default') {
|
if (statusCode === 'default') {
|
||||||
return defaultAsError ? 'error' : 'success';
|
return defaultAsError ? 'error' : 'success';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statusCode < 100 || statusCode > 599) {
|
let code = parseInt(statusCode, 10);
|
||||||
|
if (isWildcardStatusCode(statusCode)) {
|
||||||
|
code *= 100; // parseInt('2xx') parses to 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code < 100 || code > 599) {
|
||||||
throw new Error('invalid HTTP code');
|
throw new Error('invalid HTTP code');
|
||||||
}
|
}
|
||||||
let res = 'success';
|
let res = 'success';
|
||||||
if (statusCode >= 300 && statusCode < 400) {
|
if (code >= 300 && code < 400) {
|
||||||
res = 'redirect';
|
res = 'redirect';
|
||||||
} else if (statusCode >= 400) {
|
} else if (code >= 400) {
|
||||||
res = 'error';
|
res = 'error';
|
||||||
} else if (statusCode < 200) {
|
} else if (code < 200) {
|
||||||
res = 'info';
|
res = 'info';
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -14,7 +14,7 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/highlight" "7.0.0-beta.46"
|
"@babel/highlight" "7.0.0-beta.46"
|
||||||
|
|
||||||
"@babel/core@^7.0.0-beta.40":
|
"@babel/core@7.0.0-beta.47":
|
||||||
version "7.0.0-beta.47"
|
version "7.0.0-beta.47"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.47.tgz#b9c164fb9a1e1083f067c236a9da1d7a7d759271"
|
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.47.tgz#b9c164fb9a1e1083f067c236a9da1d7a7d759271"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -98,19 +98,19 @@
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
js-tokens "^3.0.0"
|
js-tokens "^3.0.0"
|
||||||
|
|
||||||
"@babel/plugin-syntax-decorators@^7.0.0-beta.42":
|
"@babel/plugin-syntax-decorators@7.0.0-beta.47":
|
||||||
version "7.0.0-beta.47"
|
version "7.0.0-beta.47"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.0.0-beta.47.tgz#a42f10fcd651940bc475d93b3ac23432b4a8a293"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.0.0-beta.47.tgz#a42f10fcd651940bc475d93b3ac23432b4a8a293"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-plugin-utils" "7.0.0-beta.47"
|
"@babel/helper-plugin-utils" "7.0.0-beta.47"
|
||||||
|
|
||||||
"@babel/plugin-syntax-jsx@^7.0.0-beta.42":
|
"@babel/plugin-syntax-jsx@7.0.0-beta.47":
|
||||||
version "7.0.0-beta.47"
|
version "7.0.0-beta.47"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.47.tgz#f3849d94288695d724bd205b4f6c3c99e4ec24a4"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.47.tgz#f3849d94288695d724bd205b4f6c3c99e4ec24a4"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-plugin-utils" "7.0.0-beta.47"
|
"@babel/helper-plugin-utils" "7.0.0-beta.47"
|
||||||
|
|
||||||
"@babel/plugin-syntax-typescript@^7.0.0-beta.42":
|
"@babel/plugin-syntax-typescript@7.0.0-beta.47":
|
||||||
version "7.0.0-beta.47"
|
version "7.0.0-beta.47"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0-beta.47.tgz#108d4c83ff48ddcb8f0532252a9892e805ddc64c"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0-beta.47.tgz#108d4c83ff48ddcb8f0532252a9892e805ddc64c"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6542,9 +6542,9 @@ mark.js@^8.11.1:
|
||||||
version "8.11.1"
|
version "8.11.1"
|
||||||
resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5"
|
resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5"
|
||||||
|
|
||||||
marked@^0.4.0:
|
marked@0.3.18:
|
||||||
version "0.4.0"
|
version "0.3.18"
|
||||||
resolved "https://registry.yarnpkg.com/marked/-/marked-0.4.0.tgz#9ad2c2a7a1791f10a852e0112f77b571dce10c66"
|
resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.18.tgz#3ef058cd926101849b92a7a7c15db18c7fc76b2f"
|
||||||
|
|
||||||
math-expression-evaluator@^1.2.14:
|
math-expression-evaluator@^1.2.14:
|
||||||
version "1.2.17"
|
version "1.2.17"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user