Skip to content

Commit

Permalink
feat: add basic support openApi 3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexVarchuk committed May 19, 2021
1 parent e03c4e8 commit 1c67023
Show file tree
Hide file tree
Showing 14 changed files with 43 additions and 39 deletions.
2 changes: 1 addition & 1 deletion e2e/integration/menu.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('Menu', () => {
it('should have valid items count', () => {
cy.get('.menu-content')
.find('li')
.should('have.length', 34);
.should('have.length', 33);
});

it('should sync active menu items while scroll', () => {
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
"styled-components": "^4.1.1 || ^5.1.1"
},
"dependencies": {
"@redocly/openapi-core": "^1.0.0-beta.44",
"@redocly/openapi-core": "^1.0.0-beta.45",
"@redocly/react-dropdown-aria": "^2.0.11",
"@types/node": "^13.11.1",
"classnames": "^2.2.6",
Expand Down
5 changes: 0 additions & 5 deletions src/common-elements/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@ export const RecursiveLabel = styled(FieldLabel)`
font-size: 13px;
`;

export const NullableLabel = styled(FieldLabel)`
color: #0e7c86;
font-size: 13px;
`;

export const PatternLabel = styled(FieldLabel)`
color: #0e7c86;
&::before,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Fields/EnumValues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { RedocRawOptions } from '../../services/RedocNormalizedOptions';

export interface EnumValuesProps {
values: string[];
type: string;
type: string | string[];
}

export interface EnumValuesState {
Expand Down
2 changes: 0 additions & 2 deletions src/components/Fields/FieldDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';

import {
NullableLabel,
PatternLabel,
RecursiveLabel,
TypeFormat,
Expand Down Expand Up @@ -79,7 +78,6 @@ export class FieldDetails extends React.PureComponent<FieldProps, { patternShown
)}
{schema.title && !hideSchemaTitles && <TypeTitle> ({schema.title}) </TypeTitle>}
<ConstraintsView constraints={schema.constraints} />
{schema.nullable && <NullableLabel> {l('nullable')} </NullableLabel>}
{schema.pattern && !hideSchemaPattern && (
<>
<PatternLabel>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Redoc/Redoc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class Redoc extends React.Component<RedocProps> {
const store = this.props.store;
return (
<ThemeProvider theme={options.theme}>
<StoreProvider value={this.props.store}>
<StoreProvider value={store}>
<OptionsProvider value={options}>
<RedocWrap className="redoc-wrap">
<StickyResponsiveSidebar menu={menu} className="menu-content">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat
"format": undefined,
"isCircular": undefined,
"isPrimitive": true,
"nullable": false,
"options": "<<<filtered>>>",
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/packSize",
Expand Down Expand Up @@ -79,7 +78,6 @@ exports[`Components SchemaView discriminator should correctly render discriminat
"format": undefined,
"isCircular": undefined,
"isPrimitive": true,
"nullable": false,
"options": "<<<filtered>>>",
"pattern": undefined,
"pointer": "#/components/schemas/Dog/properties/type",
Expand Down
2 changes: 0 additions & 2 deletions src/services/Labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export interface LabelsConfig {
deprecated: string;
example: string;
examples: string;
nullable: string;
recursive: string;
arrayOf: string;
webhook: string;
Expand All @@ -22,7 +21,6 @@ const labels: LabelsConfig = {
deprecated: 'Deprecated',
example: 'Example',
examples: 'Examples',
nullable: 'Nullable',
recursive: 'Recursive',
arrayOf: 'Array of ',
webhook: 'Event',
Expand Down
4 changes: 2 additions & 2 deletions src/services/MenuBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ export class MenuBuilder {
}

getTags(spec.paths);
if (spec['x-webhooks']) {
getTags(spec['x-webhooks'], true);
if (spec.webhooks) {
getTags(spec.webhooks, true);
}

function getTags(paths: OpenAPIPaths, isWebhook?: boolean) {
Expand Down
24 changes: 11 additions & 13 deletions src/services/models/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { l } from '../Labels';
export class SchemaModel {
pointer: string;

type: string;
type: string | string[];
displayType: string;
typePrefix: string = '';
title: string;
Expand Down Expand Up @@ -77,11 +77,6 @@ export class SchemaModel {
this.pointer = schemaOrRef.$ref || pointer || '';
this.rawSchema = parser.deref(schemaOrRef);

if (Array.isArray(this.rawSchema.type)) {
this.rawSchema.oneOf = this.rawSchema.type.map( type => ({type}));
delete this.rawSchema.type;
}

this.schema = parser.mergeAllOf(this.rawSchema, this.pointer, isChild);

this.init(parser, isChild);
Expand Down Expand Up @@ -110,23 +105,28 @@ export class SchemaModel {
this.title =
schema.title || (isNamedDefinition(this.pointer) && JsonPointer.baseName(this.pointer)) || '';
this.description = schema.description || '';
this.type = schema.type || detectType(schema);
this.type = (Array.isArray(schema.type) && schema.type) || (schema.type || detectType(schema));
this.format = schema.format;
this.nullable = !!schema.nullable;
this.enum = schema.enum || [];
this.example = schema.example;
this.deprecated = !!schema.deprecated;
this.pattern = schema.pattern;
this.externalDocs = schema.externalDocs;

this.constraints = humanizeConstraints(schema);
this.displayType = Array.isArray(this.type) ? this.type.join(' or ') : this.type;
this.displayFormat = this.format;
this.isPrimitive = isPrimitiveType(schema, this.type);
this.default = schema.default;
this.readOnly = !!schema.readOnly;
this.writeOnly = !!schema.writeOnly;

if (!!schema.nullable) {
if (Array.isArray(this.type)) this.type.push('null');
else this.type = [this.type, 'null'];
}

this.displayType = Array.isArray(this.type) ? this.type.join(' or ') : this.type;

if (this.isCircular) {
return;
}
Expand All @@ -144,8 +144,7 @@ export class SchemaModel {
}

if (schema.oneOf !== undefined) {
this.nullable = this.nullable || schema.oneOf.some(s => s.type === 'null');
this.initOneOf(schema.oneOf.filter(s => s.type !== 'null'), parser);
this.initOneOf(schema.oneOf, parser);
this.oneOfType = 'One of';
if (schema.anyOf !== undefined) {
console.warn(
Expand All @@ -156,8 +155,7 @@ export class SchemaModel {
}

if (schema.anyOf !== undefined) {
this.nullable = this.nullable || schema.anyOf.some(s => s.type === 'null');
this.initOneOf(schema.anyOf.filter(s => s.type !== 'null'), parser);
this.initOneOf(schema.anyOf, parser);
this.oneOfType = 'Any of';
return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/types/open-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface OpenAPISpec {
tags?: OpenAPITag[];
externalDocs?: OpenAPIExternalDocumentation;
'x-webhooks'?: OpenAPIPaths;
webhooks?: OpenAPIPaths;
}

export interface OpenAPIInfo {
Expand Down Expand Up @@ -107,7 +108,7 @@ export interface OpenAPIExample {

export interface OpenAPISchema {
$ref?: string;
type?: string;
type?: string | string[];
properties?: { [name: string]: OpenAPISchema };
additionalProperties?: boolean | OpenAPISchema;
description?: string;
Expand Down
14 changes: 14 additions & 0 deletions src/utils/__tests__/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,20 @@ describe('Utils', () => {
expect(isPrimitiveType(schema)).toEqual(false);
});

it('Should return false for array of strings', () => {
const schema = {
type: ['object', 'string'],
};
expect(isPrimitiveType(schema)).toEqual(false);
});

it('Should return false for array of string which include the null value', () => {
const schema = {
type: ['object', 'string', 'null'],
};
expect(isPrimitiveType(schema)).toEqual(false);
});

it('Should return false for array with non-empty objects', () => {
const schema = {
type: 'array',
Expand Down
6 changes: 4 additions & 2 deletions src/utils/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const schemaKeywordTypes = {
};

export function detectType(schema: OpenAPISchema): string {
if (schema.type !== undefined) {
if (schema.type !== undefined && !Array.isArray(schema.type)) {
return schema.type;
}
const keywords = Object.keys(schemaKeywordTypes);
Expand All @@ -110,7 +110,7 @@ export function detectType(schema: OpenAPISchema): string {
return 'any';
}

export function isPrimitiveType(schema: OpenAPISchema, type: string | undefined = schema.type) {
export function isPrimitiveType(schema: OpenAPISchema, type: string | string[] | undefined = schema.type) {
if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
return false;
}
Expand All @@ -128,6 +128,8 @@ export function isPrimitiveType(schema: OpenAPISchema, type: string | undefined
return false;
}

if (Array.isArray(type)) return false

return true;
}

Expand Down

0 comments on commit 1c67023

Please sign in to comment.