mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-08 06:04:56 +03:00
Support for required additionalProperties
This commit is contained in:
parent
dc5430e53d
commit
ceaa2ead53
|
@ -398,10 +398,16 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
format: int32
|
||||
allOf:
|
||||
- type: object
|
||||
additionalProperties:
|
||||
x-additionalPropertiesName: status
|
||||
type: integer
|
||||
format: int32
|
||||
- required:
|
||||
- inStock
|
||||
- soldOut
|
||||
|
||||
security:
|
||||
- api_key: []
|
||||
/store/order:
|
||||
|
|
|
@ -45,6 +45,16 @@ export const RequiredLabel = styled(FieldLabel.withComponent('div'))`
|
|||
line-height: 1;
|
||||
`;
|
||||
|
||||
export const RequiredImplicitFieldName = styled(FieldLabel.withComponent('div'))`
|
||||
line-height: 20px;
|
||||
white-space: nowrap;
|
||||
font-size: 1em;
|
||||
font-family: ${props => props.theme.typography.code.fontFamily};
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
margin-left: 20px;
|
||||
`;
|
||||
|
||||
export const RecursiveLabel = styled(FieldLabel)`
|
||||
color: ${({ theme }) => theme.colors.warning.main};
|
||||
font-size: 13px;
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ClickablePropertyNameCell, RequiredLabel } from '../../common-elements/fields';
|
||||
import {
|
||||
ClickablePropertyNameCell,
|
||||
RequiredImplicitFieldName,
|
||||
RequiredLabel,
|
||||
} from '../../common-elements/fields';
|
||||
import { FieldDetails } from './FieldDetails';
|
||||
|
||||
import {
|
||||
|
@ -34,7 +38,7 @@ export class Field extends React.Component<FieldProps> {
|
|||
};
|
||||
render() {
|
||||
const { className, field, isLast } = this.props;
|
||||
const { name, expanded, deprecated, required, kind } = field;
|
||||
const { name, expanded, deprecated, required, requiredNames, kind } = field;
|
||||
const withSubSchema = !field.schema.isPrimitive && !field.schema.isCircular;
|
||||
|
||||
const paramName = withSubSchema ? (
|
||||
|
@ -53,6 +57,13 @@ export class Field extends React.Component<FieldProps> {
|
|||
<PropertyNameCell className={deprecated ? 'deprecated' : undefined} kind={kind} title={name}>
|
||||
<PropertyBullet />
|
||||
{name}
|
||||
{requiredNames && (
|
||||
requiredNames.map((value, idx) => {
|
||||
return (
|
||||
<RequiredImplicitFieldName key={idx}> {value} </RequiredImplicitFieldName>
|
||||
);
|
||||
})
|
||||
)}
|
||||
{required && <RequiredLabel> required </RequiredLabel>}
|
||||
</PropertyNameCell>
|
||||
);
|
||||
|
|
|
@ -15,6 +15,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
|||
"kind": "field",
|
||||
"name": "packSize",
|
||||
"required": false,
|
||||
"requiredNames": undefined,
|
||||
"schema": SchemaModel {
|
||||
"activeOneOf": 0,
|
||||
"constraints": Array [],
|
||||
|
@ -65,6 +66,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat
|
|||
"kind": "field",
|
||||
"name": "type",
|
||||
"required": true,
|
||||
"requiredNames": undefined,
|
||||
"schema": SchemaModel {
|
||||
"activeOneOf": 0,
|
||||
"constraints": Array [],
|
||||
|
|
|
@ -35,6 +35,7 @@ export class FieldModel {
|
|||
schema: SchemaModel;
|
||||
name: string;
|
||||
required: boolean;
|
||||
requiredNames?: string[];
|
||||
description: string;
|
||||
example?: string;
|
||||
deprecated: boolean;
|
||||
|
@ -57,6 +58,7 @@ export class FieldModel {
|
|||
this.name = infoOrRef.name || info.name;
|
||||
this.in = info.in;
|
||||
this.required = !!info.required;
|
||||
this.requiredNames = info.requiredNames;
|
||||
|
||||
let fieldSchema = info.schema;
|
||||
let serializationMime = '';
|
||||
|
|
|
@ -287,16 +287,22 @@ function buildFields(
|
|||
sortByRequired(fields, !options.sortPropsAlphabetically ? schema.required : undefined);
|
||||
}
|
||||
|
||||
const explicitFieldNames = fields.map(field => field.name);
|
||||
const implicitRequiredNames = schema.required === undefined ? [] :
|
||||
schema.required.filter(fieldName => !explicitFieldNames.includes(fieldName));
|
||||
|
||||
if (typeof additionalProps === 'object' || additionalProps === true) {
|
||||
const additionalPropertiesName = typeof additionalProps === 'object'
|
||||
? additionalProps['x-additionalPropertiesName'] || 'property name'
|
||||
: 'property name';
|
||||
|
||||
fields.push(
|
||||
new FieldModel(
|
||||
parser,
|
||||
{
|
||||
name: (typeof additionalProps === 'object'
|
||||
? additionalProps['x-additionalPropertiesName'] || 'property name'
|
||||
: 'property name'
|
||||
).concat('*'),
|
||||
required: false,
|
||||
name: additionalPropertiesName.concat('*'),
|
||||
requiredNames: implicitRequiredNames,
|
||||
required: implicitRequiredNames.length > 0,
|
||||
schema: additionalProps === true ? {} : additionalProps,
|
||||
kind: 'additionalProperties',
|
||||
},
|
||||
|
@ -304,6 +310,23 @@ function buildFields(
|
|||
options,
|
||||
),
|
||||
);
|
||||
} else if (implicitRequiredNames.length > 0) {
|
||||
const firstImplicitName = additionalProps === false ? '(incorrectly required)' :
|
||||
(implicitRequiredNames.shift() || '');
|
||||
fields.push(
|
||||
new FieldModel(
|
||||
parser,
|
||||
{
|
||||
name: firstImplicitName,
|
||||
requiredNames: implicitRequiredNames,
|
||||
required: true,
|
||||
schema: {},
|
||||
kind: 'field',
|
||||
},
|
||||
$ref + '/properties/' + firstImplicitName,
|
||||
options,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return fields;
|
||||
|
|
1
src/types/open-api.d.ts
vendored
1
src/types/open-api.d.ts
vendored
|
@ -84,6 +84,7 @@ export interface OpenAPIParameter {
|
|||
in?: OpenAPIParameterLocation;
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
requiredNames?: string[];
|
||||
deprecated?: boolean;
|
||||
allowEmptyValue?: boolean;
|
||||
style?: OpenAPIParameterStyle;
|
||||
|
|
|
@ -114,6 +114,9 @@ export function isPrimitiveType(schema: OpenAPISchema, type: string | undefined
|
|||
}
|
||||
|
||||
if (type === 'object') {
|
||||
if (schema.required !== undefined && schema.required.length !== 0) {
|
||||
return false;
|
||||
}
|
||||
return schema.properties !== undefined
|
||||
? Object.keys(schema.properties).length === 0
|
||||
: schema.additionalProperties === undefined;
|
||||
|
|
Loading…
Reference in New Issue
Block a user