Skip to content

Commit 3056787

Browse files
ElliotFriendsserrata
authored andcommitted
Implement the x-tags extension for schema objects (#837)
* introduce x-tags onto SchemaObject type, and revise sidebar types A few of the types in the `sidebars/index.ts` page have been changed to allow for more proper typing of both api items and schema items. * add schemas with x-tags into the tag category sidebar slice * add schemas with x-tags even if showSchemas is not true * add a badge and some styling for schema sidebar labels * add some test coverage * add some x-tags documentation to `sidebars.md` * update documentation on styling sidebar items * include schema-only tags, just like operation-only ones * add the pet x-tag to the Cat schema for demo purposes * filter out x-tagged schemas from the "Schemas" category they'll already be displayed elsewhere
1 parent 10cda3c commit 3056787

File tree

10 files changed

+141
-65
lines changed

10 files changed

+141
-65
lines changed

demo/docs/customization/styling.mdx

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ The demo site uses the following CSS to add coloured labels to each request incl
1818

1919
```css
2020
/* API Menu Items */
21-
.api-method > .menu__link {
21+
.api-method > .menu__link,
22+
.schema > .menu__link {
2223
align-items: center;
2324
justify-content: start;
2425
}
2526

26-
.api-method > .menu__link::before {
27-
width: 50px;
27+
.api-method > .menu__link::before,
28+
.schema > .menu__link::before {
29+
width: 55px;
2830
height: 20px;
2931
font-size: 12px;
3032
line-height: 20px;
@@ -68,6 +70,16 @@ The demo site uses the following CSS to add coloured labels to each request incl
6870
content: "head";
6971
background-color: var(--ifm-color-secondary-darkest);
7072
}
73+
74+
.event > .menu__link::before {
75+
content: "event";
76+
background-color: var(--ifm-color-secondary-darkest);
77+
}
78+
79+
.schema > .menu__link::before {
80+
content: "schema";
81+
background-color: var(--ifm-color-secondary-darkest);
82+
}
7183
```
7284

7385
## Alternative Styling
@@ -76,13 +88,15 @@ In [this issue](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/issu
7688

7789
```css
7890
/* Sidebar Method labels */
79-
.api-method > .menu__link {
91+
.api-method > .menu__link,
92+
.schema > .menu__link {
8093
align-items: center;
8194
justify-content: start;
8295
}
8396

84-
.api-method > .menu__link::before {
85-
width: 50px;
97+
.api-method > .menu__link::before,
98+
.schema > .menu__link::before {
99+
width: 55px;
86100
height: 20px;
87101
font-size: 12px;
88102
line-height: 20px;
@@ -137,4 +151,18 @@ In [this issue](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/issu
137151
color: var(--ifm-color-secondary-contrast-foreground);
138152
border-color: var(--ifm-color-secondary-dark);
139153
}
154+
155+
.event > .menu__link::before {
156+
content: "event";
157+
background-color: var(--ifm-color-secondary-contrast-background);
158+
color: var(--ifm-color-secondary-contrast-foreground);
159+
border-color: var(--ifm-color-secondary-dark);
160+
}
161+
162+
.schema > .menu__link::before {
163+
content: "schema";
164+
background-color: var(--ifm-color-secondary-contrast-background);
165+
color: var(--ifm-color-secondary-contrast-foreground);
166+
border-color: var(--ifm-color-secondary-dark);
167+
}
140168
```

demo/docs/sidebars.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,9 @@ The OpenAPI Docs plugin can leverage this feature in a number of ways, including
6666
- Using the `generated-index` feature to create an index of all paths/endpoints available under a tag.
6767
- Setting the `tag` description of an OpenAPI specification as the content that displays when a category is clicked.
6868
- Setting the `info` section of an OpenAPI specification as the page that displays when a category is clicked (reserved primarily for micro-specs).
69+
70+
### Grouping Schemas by `x-tags`
71+
72+
The OpenAPI plugin provides out-of-the-box support for grouping schema objects into tags alongside path objects grouped by that same tag.
73+
74+
What this means is that when the `groupPathsBy` sidebar option is set to `tag`, any `x-tag`ged schema objects will be gathered together with the tagged paths in that sidebar category. In the event that `showSchemas` is not configured, and `x-tags` is found on a schema object, the schema **will be included** in the relevant tag's category sidebar.

demo/examples/petstore.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ info:
3737
Petstore offers two forms of authentication:
3838
- API Key
3939
- OAuth2
40-
40+
4141
OAuth2 - an open protocol to allow secure authorization in a simple
4242
and standard method from web, mobile and desktop applications.
4343
@@ -934,6 +934,8 @@ components:
934934
message:
935935
type: string
936936
Cat:
937+
x-tags:
938+
- pet
937939
description: A representation of a cat
938940
allOf:
939941
- $ref: "#/components/schemas/Pet"

demo/src/css/custom.css

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@ a:any-link:hover {
3737
}
3838

3939
/* Sidebar Method labels */
40-
.api-method > .menu__link {
40+
.api-method > .menu__link,
41+
.schema > .menu__link {
4142
align-items: center;
4243
justify-content: start;
4344
}
4445

45-
.api-method > .menu__link::before {
46-
width: 50px;
46+
.api-method > .menu__link::before,
47+
.schema > .menu__link::before {
48+
width: 55px;
4749
height: 20px;
4850
font-size: 12px;
4951
line-height: 20px;
@@ -93,6 +95,11 @@ a:any-link:hover {
9395
background-color: var(--ifm-color-secondary-darkest);
9496
}
9597

98+
.schema > .menu__link::before {
99+
content: "schema";
100+
background-color: var(--ifm-color-secondary-darkest);
101+
}
102+
96103
/* GitHub Header Link */
97104
.header-github-link:hover {
98105
opacity: 0.6;

packages/docusaurus-plugin-openapi-docs/src/markdown/createSchema.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { SchemaObject } from "../openapi/types";
1313
describe("createNodes", () => {
1414
it("should create readable MODs for oneOf primitive properties", async () => {
1515
const schema: SchemaObject = {
16+
"x-tags": ["clown"],
1617
type: "object",
1718
properties: {
1819
oneOfProperty: {

packages/docusaurus-plugin-openapi-docs/src/openapi/__fixtures__/examples/openapi.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,10 @@ x-tagGroups:
4040
tags:
4141
- tag3
4242
- tag4
43+
44+
components:
45+
schemas:
46+
HelloString:
47+
x-tags:
48+
- tag1
49+
type: string

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ describe("openapi", () => {
3131

3232
expect(yaml?.data.tags).toBeDefined();
3333
expect(yaml?.data["x-tagGroups"]).toBeDefined();
34+
35+
expect(
36+
yaml?.data.components?.schemas?.HelloString["x-tags"]
37+
).toBeDefined();
3438
});
3539
});
3640
});

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

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -410,43 +410,53 @@ function createItems(
410410
}
411411
}
412412

413-
if (options?.showSchemas === true) {
413+
if (
414+
options?.showSchemas === true ||
415+
Object.entries(openapiData?.components?.schemas ?? {})
416+
.flatMap(([_, s]) => s["x-tags"])
417+
.filter((item) => !!item).length > 0
418+
) {
414419
// Gather schemas
415420
for (let [schema, schemaObject] of Object.entries(
416421
openapiData?.components?.schemas ?? {}
417422
)) {
418-
const baseIdSpaces =
419-
schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
420-
const baseId = kebabCase(baseIdSpaces);
421-
422-
const schemaDescription = schemaObject.description;
423-
let splitDescription: any;
424-
if (schemaDescription) {
425-
splitDescription = schemaDescription.match(/[^\r\n]+/g);
426-
}
423+
if (options?.showSchemas === true || schemaObject["x-tags"]) {
424+
const baseIdSpaces =
425+
schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
426+
const baseId = kebabCase(baseIdSpaces);
427+
428+
const schemaDescription = schemaObject.description;
429+
let splitDescription: any;
430+
if (schemaDescription) {
431+
splitDescription = schemaDescription.match(/[^\r\n]+/g);
432+
}
427433

428-
const schemaPage: PartialPage<SchemaPageMetadata> = {
429-
type: "schema",
430-
id: baseId,
431-
infoId: infoId ?? "",
432-
unversionedId: baseId,
433-
title: schemaObject.title
434-
? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
435-
: schema,
436-
description: schemaObject.description
437-
? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
438-
: "",
439-
frontMatter: {
440-
description: splitDescription
441-
? splitDescription[0]
442-
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
443-
.replace(/\s+$/, "")
434+
const schemaPage: PartialPage<SchemaPageMetadata> = {
435+
type: "schema",
436+
id: baseId,
437+
infoId: infoId ?? "",
438+
unversionedId: baseId,
439+
title: schemaObject.title
440+
? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
441+
: schema,
442+
description: schemaObject.description
443+
? schemaObject.description.replace(
444+
/((?:^|[^\\])(?:\\{2})*)"/g,
445+
"$1'"
446+
)
444447
: "",
445-
},
446-
schema: schemaObject,
447-
};
448+
frontMatter: {
449+
description: splitDescription
450+
? splitDescription[0]
451+
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
452+
.replace(/\s+$/, "")
453+
: "",
454+
},
455+
schema: schemaObject,
456+
};
448457

449-
items.push(schemaPage);
458+
items.push(schemaPage);
459+
}
450460
}
451461
}
452462

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ export type SchemaObject = Omit<
352352
externalDocs?: ExternalDocumentationObject;
353353
example?: any;
354354
deprecated?: boolean;
355+
"x-tags"?: string[];
355356
};
356357

357358
export type SchemaObjectWithRef = Omit<

0 commit comments

Comments
 (0)