diff --git a/src/common-elements/shelfs.tsx b/src/common-elements/shelfs.tsx
index 8eb3d4a7..4e78b568 100644
--- a/src/common-elements/shelfs.tsx
+++ b/src/common-elements/shelfs.tsx
@@ -51,8 +51,10 @@ export const Badge = styled.span<{ type: string }>`
display: inline-block;
padding: 2px 8px;
margin: 0;
- background-color: ${props => props.theme.colors[props.type].main};
- color: ${props => props.theme.colors[props.type].contrastText};
+ background-color: ${props =>
+ props.type == 'm2m' ? 'none' : props.theme.colors[props.type].main};
+ border: ${props => (props.type == 'm2m' ? 'rgba(38, 50, 56, 0.5) 1px solid' : 'none')};
+ color: ${props => (props.type == 'm2m' ? 'black' : props.theme.colors[props.type].contrastText)};
font-size: ${props => props.theme.typography.code.fontSize};
vertical-align: middle;
line-height: 1.6;
diff --git a/src/components/Fields/FieldDetails.tsx b/src/components/Fields/FieldDetails.tsx
index de37063b..5b108cf7 100644
--- a/src/components/Fields/FieldDetails.tsx
+++ b/src/components/Fields/FieldDetails.tsx
@@ -35,6 +35,7 @@ export const FieldDetailsComponent = observer((props: FieldProps) => {
schema,
description,
deprecated,
+ m2m,
extensions,
in: _in,
const: _const,
@@ -107,6 +108,11 @@ export const FieldDetailsComponent = observer((props: FieldProps) => {
{l('deprecated')}
)}
+ {m2m && (
+
+ M2M
+
+ )}
{!renderDiscriminatorSwitch && (
diff --git a/src/components/Operation/Operation.tsx b/src/components/Operation/Operation.tsx
index b6904f62..cdcbc916 100644
--- a/src/components/Operation/Operation.tsx
+++ b/src/components/Operation/Operation.tsx
@@ -28,7 +28,15 @@ export interface OperationProps {
}
export const Operation = observer(({ operation }: OperationProps): JSX.Element => {
- const { name: summary, description, deprecated, externalDocs, isWebhook, httpVerb } = operation;
+ const {
+ name: summary,
+ description,
+ deprecated,
+ externalDocs,
+ isWebhook,
+ httpVerb,
+ m2m,
+ } = operation;
const hasDescription = !!(description || externalDocs);
const { showWebhookVerb } = React.useContext(OptionsContext);
return (
@@ -39,6 +47,7 @@ export const Operation = observer(({ operation }: OperationProps): JSX.Element =
{summary} {deprecated && Deprecated }
+ {m2m && M2M }
{isWebhook && (
{' '}
diff --git a/src/components/Schema/OneOfSchema.tsx b/src/components/Schema/OneOfSchema.tsx
index 311a3258..cdeb6457 100644
--- a/src/components/Schema/OneOfSchema.tsx
+++ b/src/components/Schema/OneOfSchema.tsx
@@ -60,6 +60,7 @@ export class OneOfSchema extends React.Component {
{oneOf[schema.activeOneOf].deprecated && Deprecated}
+ {oneOf[schema.activeOneOf].m2m && M2M}
diff --git a/src/services/AppStore.ts b/src/services/AppStore.ts
index 0c0dba35..eb7ff0b1 100644
--- a/src/services/AppStore.ts
+++ b/src/services/AppStore.ts
@@ -58,6 +58,8 @@ export class AppStore {
private scroll: ScrollService;
private disposer: Lambda | null = null;
+ private readonly listener: EventListenerOrEventListenerObject = this.updateOnEvent.bind(this);
+
constructor(
spec: OpenAPISpec,
specUrl?: string,
@@ -73,7 +75,7 @@ export class AppStore {
MenuStore.updateOnHistory(this.history.currentId, this.scroll);
// Listen for external event to update
- window.addEventListener('redocUpdatePosition', this.updateOnEvent);
+ window.addEventListener('redocUpdatePosition', this.listener);
// override the openApi standard to version 3.1.0
// TODO remove when fully supporting open API 3.1.0
@@ -101,7 +103,7 @@ export class AppStore {
dispose() {
this.scroll.dispose();
this.menu.dispose();
- window.removeEventListener('redocUpdatePosition', this.updateOnEvent);
+ window.removeEventListener('redocUpdatePosition', this.listener);
if (this.search) {
this.search.dispose();
}
@@ -129,10 +131,6 @@ export class AppStore {
};
}
- private updateOnEvent(): void {
- MenuStore.updateOnHistory(this.history.currentId, this.scroll);
- }
-
private updateMarkOnMenu(idx: number) {
const start = Math.max(0, idx);
const end = Math.min(this.menu.flatItems.length, start + 5);
@@ -157,6 +155,10 @@ export class AppStore {
this.marker.addOnly(elements);
this.marker.mark();
}
+
+ private updateOnEvent(): void {
+ MenuStore.updateOnHistory(this.history.currentId, this.scroll);
+ }
}
const DEFAULT_OPTIONS: RedocRawOptions = {
diff --git a/src/services/models/Field.ts b/src/services/models/Field.ts
index 59fcd73f..954c6677 100644
--- a/src/services/models/Field.ts
+++ b/src/services/models/Field.ts
@@ -51,6 +51,7 @@ export class FieldModel {
example?: string;
examples?: Record | any[];
deprecated: boolean;
+ m2m: boolean;
in?: OpenAPIParameterLocation;
kind: string;
extensions?: Record;
@@ -135,6 +136,7 @@ export class FieldModel {
}
this.deprecated = info.deprecated === undefined ? !!this.schema.deprecated : info.deprecated;
+ this.m2m = info.m2m === undefined ? !!this.schema.m2m : info.m2m;
if (options.showExtensions) {
this.extensions = extractExtensions(info, options.showExtensions);
diff --git a/src/services/models/Operation.ts b/src/services/models/Operation.ts
index e26b4a4c..04da3a64 100644
--- a/src/services/models/Operation.ts
+++ b/src/services/models/Operation.ts
@@ -25,6 +25,7 @@ import type { OpenAPIParser } from '../OpenAPIParser';
import type { RedocNormalizedOptions } from '../RedocNormalizedOptions';
import type { MediaContentModel } from './MediaContent';
import type { ContentItemModel, ExtendedOpenAPIOperation, IMenuItem } from '../types';
+import { MilesConstants } from '../../types';
export interface XPayloadSample {
lang: 'payload';
@@ -72,6 +73,7 @@ export class OperationModel implements IMenuItem {
operationHash?: string;
httpVerb: string;
deprecated: boolean;
+ m2m: boolean;
path: string;
servers: OpenAPIServer[];
security: SecurityRequirementModel[];
@@ -96,6 +98,9 @@ export class OperationModel implements IMenuItem {
this.externalDocs = operationSpec.externalDocs;
this.deprecated = !!operationSpec.deprecated;
+ this.m2m = !!extractExtensions(operationSpec, [MilesConstants.MILES_M2M])?.[
+ MilesConstants.MILES_M2M
+ ];
this.httpVerb = operationSpec.httpVerb;
this.deprecated = !!operationSpec.deprecated;
this.operationId = operationSpec.operationId;
diff --git a/src/services/models/Schema.ts b/src/services/models/Schema.ts
index e5d868b7..a31d69ba 100644
--- a/src/services/models/Schema.ts
+++ b/src/services/models/Schema.ts
@@ -44,6 +44,7 @@ export class SchemaModel {
displayFormat?: string;
nullable: boolean;
deprecated: boolean;
+ m2m: boolean;
pattern?: string;
example?: any;
examples?: any[];
@@ -126,6 +127,9 @@ export class SchemaModel {
this.example = schema.example;
this.examples = schema.examples;
this.deprecated = !!schema.deprecated;
+ this.m2m = !!extractExtensions(this.schema, [MilesConstants.MILES_M2M])?.[
+ MilesConstants.MILES_M2M
+ ];
this.pattern = schema.pattern;
this.externalDocs = schema.externalDocs;
diff --git a/src/theme.ts b/src/theme.ts
index b65546fa..36efed13 100644
--- a/src/theme.ts
+++ b/src/theme.ts
@@ -21,9 +21,15 @@ const defaultTheme: ThemeInterface = {
},
secondary: {
main: '#D47D17',
- light: ({ colors }) => lighten(colors.tonalOffset, colors.primary.main),
- dark: ({ colors }) => darken(colors.tonalOffset, colors.primary.main),
- contrastText: ({ colors }) => readableColor(colors.primary.main),
+ light: ({ colors }) => lighten(colors.tonalOffset, colors.secondary.main),
+ dark: ({ colors }) => darken(colors.tonalOffset, colors.secondary.main),
+ contrastText: ({ colors }) => readableColor(colors.secondary.main),
+ },
+ m2m: {
+ main: '#343A40',
+ light: ({ colors }) => lighten(colors.tonalOffset, colors.m2m.main),
+ dark: ({ colors }) => darken(colors.tonalOffset, colors.m2m.main),
+ contrastText: ({ colors }) => readableColor(colors.m2m.main),
},
success: {
main: '#1d8127',
@@ -271,6 +277,7 @@ export interface ResolvedThemeInterface {
tonalOffset: number;
primary: ColorSetting;
secondary: ColorSetting;
+ m2m: ColorSetting;
success: ColorSetting;
warning: ColorSetting;
error: ColorSetting;
diff --git a/src/types/miles.constants.ts b/src/types/miles.constants.ts
index 3bfba6c5..f2732e6a 100644
--- a/src/types/miles.constants.ts
+++ b/src/types/miles.constants.ts
@@ -1,5 +1,6 @@
export const MilesConstants = {
MILES_EXTRA_DESCRIPTION_PROPERTY_NAME: 'x-miles-extra-description',
MILES_VALIDATION_MODEL_PROPERTY_NAME: 'x-miles-validation-model',
+ MILES_M2M: 'x-miles-m2m',
HIDE_LOGO_QUERY_PARAM: 'hideLogo',
};
diff --git a/src/types/open-api.ts b/src/types/open-api.ts
index 62a1d584..2ef302f7 100644
--- a/src/types/open-api.ts
+++ b/src/types/open-api.ts
@@ -93,6 +93,7 @@ export interface OpenAPIParameter {
description?: string;
required?: boolean;
deprecated?: boolean;
+ m2m?: boolean;
allowEmptyValue?: boolean;
style?: OpenAPIParameterStyle;
explode?: boolean;