Skip to content

Implement the x-tags extension for schema objects #837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions demo/docs/customization/styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ The demo site uses the following CSS to add coloured labels to each request incl

```css
/* API Menu Items */
.api-method > .menu__link {
.api-method > .menu__link,
.schema > .menu__link {
align-items: center;
justify-content: start;
}

.api-method > .menu__link::before {
width: 50px;
.api-method > .menu__link::before,
.schema > .menu__link::before {
width: 55px;
height: 20px;
font-size: 12px;
line-height: 20px;
Expand Down Expand Up @@ -68,6 +70,16 @@ The demo site uses the following CSS to add coloured labels to each request incl
content: "head";
background-color: var(--ifm-color-secondary-darkest);
}

.event > .menu__link::before {
content: "event";
background-color: var(--ifm-color-secondary-darkest);
}

.schema > .menu__link::before {
content: "schema";
background-color: var(--ifm-color-secondary-darkest);
}
```

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

```css
/* Sidebar Method labels */
.api-method > .menu__link {
.api-method > .menu__link,
.schema > .menu__link {
align-items: center;
justify-content: start;
}

.api-method > .menu__link::before {
width: 50px;
.api-method > .menu__link::before,
.schema > .menu__link::before {
width: 55px;
height: 20px;
font-size: 12px;
line-height: 20px;
Expand Down Expand Up @@ -137,4 +151,18 @@ In [this issue](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/issu
color: var(--ifm-color-secondary-contrast-foreground);
border-color: var(--ifm-color-secondary-dark);
}

.event > .menu__link::before {
content: "event";
background-color: var(--ifm-color-secondary-contrast-background);
color: var(--ifm-color-secondary-contrast-foreground);
border-color: var(--ifm-color-secondary-dark);
}

.schema > .menu__link::before {
content: "schema";
background-color: var(--ifm-color-secondary-contrast-background);
color: var(--ifm-color-secondary-contrast-foreground);
border-color: var(--ifm-color-secondary-dark);
}
```
6 changes: 6 additions & 0 deletions demo/docs/sidebars.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,9 @@ The OpenAPI Docs plugin can leverage this feature in a number of ways, including
- Using the `generated-index` feature to create an index of all paths/endpoints available under a tag.
- Setting the `tag` description of an OpenAPI specification as the content that displays when a category is clicked.
- Setting the `info` section of an OpenAPI specification as the page that displays when a category is clicked (reserved primarily for micro-specs).

### Grouping Schemas by `x-tags`

The OpenAPI plugin provides out-of-the-box support for grouping schema objects into tags alongside path objects grouped by that same tag.

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.
4 changes: 3 additions & 1 deletion demo/examples/petstore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ info:
Petstore offers two forms of authentication:
- API Key
- OAuth2

OAuth2 - an open protocol to allow secure authorization in a simple
and standard method from web, mobile and desktop applications.

Expand Down Expand Up @@ -934,6 +934,8 @@ components:
message:
type: string
Cat:
x-tags:
- pet
description: A representation of a cat
allOf:
- $ref: "#/components/schemas/Pet"
Expand Down
13 changes: 10 additions & 3 deletions demo/src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ a:any-link:hover {
}

/* Sidebar Method labels */
.api-method > .menu__link {
.api-method > .menu__link,
.schema > .menu__link {
align-items: center;
justify-content: start;
}

.api-method > .menu__link::before {
width: 50px;
.api-method > .menu__link::before,
.schema > .menu__link::before {
width: 55px;
height: 20px;
font-size: 12px;
line-height: 20px;
Expand Down Expand Up @@ -93,6 +95,11 @@ a:any-link:hover {
background-color: var(--ifm-color-secondary-darkest);
}

.schema > .menu__link::before {
content: "schema";
background-color: var(--ifm-color-secondary-darkest);
}

/* GitHub Header Link */
.header-github-link:hover {
opacity: 0.6;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { SchemaObject } from "../openapi/types";
describe("createNodes", () => {
it("should create readable MODs for oneOf primitive properties", () => {
const schema: SchemaObject = {
"x-tags": ["clown"],
type: "object",
properties: {
oneOfProperty: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ x-tagGroups:
tags:
- tag3
- tag4

components:
schemas:
HelloString:
x-tags:
- tag1
type: string
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ describe("openapi", () => {

expect(yaml?.data.tags).toBeDefined();
expect(yaml?.data["x-tagGroups"]).toBeDefined();

expect(
yaml?.data.components?.schemas?.HelloString["x-tags"]
).toBeDefined();
});
});
});
70 changes: 40 additions & 30 deletions packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,43 +410,53 @@ function createItems(
}
}

if (options?.showSchemas === true) {
if (
options?.showSchemas === true ||
Object.entries(openapiData?.components?.schemas ?? {})
.flatMap(([_, s]) => s["x-tags"])
.filter((item) => !!item).length > 0
) {
// Gather schemas
for (let [schema, schemaObject] of Object.entries(
openapiData?.components?.schemas ?? {}
)) {
const baseIdSpaces =
schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
const baseId = kebabCase(baseIdSpaces);

const schemaDescription = schemaObject.description;
let splitDescription: any;
if (schemaDescription) {
splitDescription = schemaDescription.match(/[^\r\n]+/g);
}
if (options?.showSchemas === true || schemaObject["x-tags"]) {
const baseIdSpaces =
schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
const baseId = kebabCase(baseIdSpaces);

const schemaDescription = schemaObject.description;
let splitDescription: any;
if (schemaDescription) {
splitDescription = schemaDescription.match(/[^\r\n]+/g);
}

const schemaPage: PartialPage<SchemaPageMetadata> = {
type: "schema",
id: baseId,
infoId: infoId ?? "",
unversionedId: baseId,
title: schemaObject.title
? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
: schema,
description: schemaObject.description
? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
: "",
frontMatter: {
description: splitDescription
? splitDescription[0]
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
.replace(/\s+$/, "")
const schemaPage: PartialPage<SchemaPageMetadata> = {
type: "schema",
id: baseId,
infoId: infoId ?? "",
unversionedId: baseId,
title: schemaObject.title
? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
: schema,
description: schemaObject.description
? schemaObject.description.replace(
/((?:^|[^\\])(?:\\{2})*)"/g,
"$1'"
)
: "",
},
schema: schemaObject,
};
frontMatter: {
description: splitDescription
? splitDescription[0]
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
.replace(/\s+$/, "")
: "",
},
schema: schemaObject,
};

items.push(schemaPage);
items.push(schemaPage);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ export type SchemaObject = Omit<
externalDocs?: ExternalDocumentationObject;
example?: any;
deprecated?: boolean;
"x-tags"?: string[];
};

export type SchemaObjectWithRef = Omit<
Expand Down
Loading
Loading