Skip to content

Commit 44541a0

Browse files
committed
Use x-enumDescriptions in UI
1 parent 8b0388c commit 44541a0

File tree

7 files changed

+125
-17
lines changed

7 files changed

+125
-17
lines changed

demo/examples/petstore.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ paths:
351351
- available
352352
- pending
353353
- sold
354+
x-enumDescriptions:
355+
available: When the pet is available
356+
pending: When the pet is being sold
357+
sold: When the pet has been sold
354358
default: available
355359
responses:
356360
"200":
@@ -1114,6 +1118,15 @@ components:
11141118
- available
11151119
- pending
11161120
- sold
1121+
x-enumDescriptions:
1122+
available: When the pet is available
1123+
pending: When the pet is being sold
1124+
sold: |
1125+
When the pet has been sold.
1126+
1127+
These descriptions can contain line
1128+
1129+
breaks and also [links](https://docusaurus.io/)
11171130
petType:
11181131
description: Type of a pet
11191132
type: string

packages/docusaurus-plugin-openapi-docs/src/markdown/createParamsDetails.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,17 @@ export function createParamsDetails({ parameters, type }: Props) {
4343
create("div", {
4444
children: [
4545
create("ul", {
46-
children: params.map((param) =>
47-
create("ParamsItem", {
46+
children: params.map((param) => {
47+
return create("ParamsItem", {
4848
className: "paramsItem",
49-
param: param,
50-
})
51-
),
49+
param: {
50+
...param,
51+
enumDescriptions: Object.entries(
52+
param?.schema?.items?.["x-enumDescriptions"] ?? {}
53+
),
54+
},
55+
});
56+
}),
5257
}),
5358
],
5459
}),

packages/docusaurus-plugin-openapi-docs/src/openapi/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ export interface ParameterObject {
197197
param?: Object;
198198
// ignoring stylings: matrix, label, form, simple, spaceDelimited,
199199
// pipeDelimited and deepObject
200+
"x-enumDescriptions": Record<string, string>;
200201
}
201202

202203
export interface ParameterObjectWithRef {
@@ -353,6 +354,7 @@ export type SchemaObject = Omit<
353354
example?: any;
354355
deprecated?: boolean;
355356
"x-tags"?: string[];
357+
"x-enumDescriptions"?: Record<string, string>;
356358
};
357359

358360
export type SchemaObjectWithRef = Omit<

packages/docusaurus-plugin-openapi-docs/src/openapi/utils/services/OpenAPIParser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ export class OpenAPIParser {
270270
const {
271271
type,
272272
enum: enumProperty,
273+
"x-enumDescription": enumDescription,
273274
properties,
274275
items,
275276
required,

packages/docusaurus-theme-openapi-docs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"react-modal": "^3.15.1",
5858
"react-redux": "^7.2.0",
5959
"rehype-raw": "^6.1.1",
60+
"remark-gfm": "3.0.1",
6061
"sass": "^1.58.1",
6162
"sass-loader": "^13.3.2",
6263
"webpack": "^5.61.0",

packages/docusaurus-theme-openapi-docs/src/theme/ParamsItem/index.tsx

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import TabItem from "@theme/TabItem";
1414
import clsx from "clsx";
1515
import ReactMarkdown from "react-markdown";
1616
import rehypeRaw from "rehype-raw";
17+
import remarkGfm from "remark-gfm";
1718

1819
import { createDescription } from "../../markdown/createDescription";
1920
import { getQualifierMessage, getSchemaName } from "../../markdown/schema";
@@ -39,12 +40,38 @@ export interface Props {
3940
required: boolean;
4041
deprecated: boolean;
4142
schema: any;
43+
enumDescriptions?: [string, string][];
4244
};
4345
}
4446

45-
function ParamsItem({
46-
param: { description, example, examples, name, required, schema, deprecated },
47-
}: Props) {
47+
const getEnumDescriptionMarkdown = (enumDescriptions?: [string, string][]) => {
48+
if (enumDescriptions?.length) {
49+
return `| Enum | Description |
50+
| ---- | ----- |
51+
${enumDescriptions
52+
.map((desc) => {
53+
return `| ${desc[0]} | ${desc[1]} | `.replaceAll("\n", "<br/>");
54+
})
55+
.join("\n")}
56+
`;
57+
}
58+
59+
return "";
60+
};
61+
62+
function ParamsItem({ param, ...rest }: Props) {
63+
const {
64+
description,
65+
example,
66+
examples,
67+
name,
68+
required,
69+
deprecated,
70+
enumDescriptions,
71+
} = param;
72+
73+
let schema = param.schema;
74+
4875
if (!schema || !schema?.type) {
4976
schema = { type: "any" };
5077
}
@@ -91,6 +118,19 @@ function ParamsItem({
91118
</div>
92119
));
93120

121+
const renderEnumDescriptions = guard(
122+
getEnumDescriptionMarkdown(enumDescriptions),
123+
(value) => {
124+
return (
125+
<ReactMarkdown
126+
rehypePlugins={[rehypeRaw]}
127+
remarkPlugins={[remarkGfm]}
128+
children={value}
129+
/>
130+
);
131+
}
132+
);
133+
94134
const renderDefaultValue = guard(
95135
schema && schema.items
96136
? schema.items.default
@@ -158,6 +198,7 @@ function ParamsItem({
158198
{renderSchema}
159199
{renderDefaultValue}
160200
{renderDescription}
201+
{renderEnumDescriptions}
161202
{renderExample}
162203
{renderExamples}
163204
</div>

packages/docusaurus-theme-openapi-docs/src/theme/SchemaItem/index.tsx

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import CodeBlock from "@theme/CodeBlock";
1111
import clsx from "clsx";
1212
import ReactMarkdown from "react-markdown";
1313
import rehypeRaw from "rehype-raw";
14+
import remarkGfm from "remark-gfm";
1415

1516
import { createDescription } from "../../markdown/createDescription";
1617
import { guard } from "../../markdown/utils";
@@ -27,22 +28,52 @@ export interface Props {
2728
discriminator: boolean;
2829
}
2930

30-
export default function SchemaItem({
31-
children: collapsibleSchemaContent,
32-
collapsible,
33-
name,
34-
qualifierMessage,
35-
required,
36-
schemaName,
37-
schema,
38-
}: Props) {
31+
const transformEnumDescriptions = (
32+
enumDescriptions?: Record<string, string>
33+
) => {
34+
if (enumDescriptions) {
35+
return Object.entries(enumDescriptions);
36+
}
37+
38+
return [];
39+
};
40+
41+
const getEnumDescriptionMarkdown = (enumDescriptions?: [string, string][]) => {
42+
if (enumDescriptions?.length) {
43+
return `| Enum | Description |
44+
| ---- | ----- |
45+
${enumDescriptions
46+
.map((desc) => {
47+
return `| ${desc[0]} | ${desc[1]} | `.replaceAll("\n", "<br/>");
48+
})
49+
.join("\n")}
50+
`;
51+
}
52+
53+
return "";
54+
};
55+
56+
export default function SchemaItem(props: Props) {
57+
const {
58+
children: collapsibleSchemaContent,
59+
collapsible,
60+
name,
61+
qualifierMessage,
62+
required,
63+
schemaName,
64+
schema,
65+
} = props;
66+
console.log({ props });
3967
let deprecated;
4068
let schemaDescription;
4169
let defaultValue;
4270
let nullable;
71+
let enumDescriptions: [string, string][] = [];
72+
4373
if (schema) {
4474
deprecated = schema.deprecated;
4575
schemaDescription = schema.description;
76+
enumDescriptions = transformEnumDescriptions(schema["x-enumDescriptions"]);
4677
defaultValue = schema.default;
4778
nullable = schema.nullable;
4879
}
@@ -60,6 +91,19 @@ export default function SchemaItem({
6091
<span className="openapi-schema__nullable">nullable</span>
6192
));
6293

94+
const renderEnumDescriptions = guard(
95+
getEnumDescriptionMarkdown(enumDescriptions),
96+
(value) => {
97+
return (
98+
<ReactMarkdown
99+
remarkPlugins={[remarkGfm]}
100+
rehypePlugins={[rehypeRaw]}
101+
children={value}
102+
/>
103+
);
104+
}
105+
);
106+
63107
const renderSchemaDescription = guard(schemaDescription, (description) => (
64108
<div>
65109
<ReactMarkdown
@@ -117,6 +161,7 @@ export default function SchemaItem({
117161
{renderQualifierMessage}
118162
{renderDefaultValue}
119163
{renderSchemaDescription}
164+
{renderEnumDescriptions}
120165
{collapsibleSchemaContent ?? collapsibleSchemaContent}
121166
</div>
122167
);

0 commit comments

Comments
 (0)