Skip to content

Commit 1d067a5

Browse files
Add Callbacks support (#691)
* add support to callbacks in openapi specs * set package manager in package json * implement operations as tabs within request panel * render callbacks below Request and Responses * remove unwanted files * rename create file * restore json settings
1 parent 7f95285 commit 1d067a5

File tree

9 files changed

+379
-9
lines changed

9 files changed

+379
-9
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,6 @@
7676
},
7777
"engines": {
7878
"node": ">=14"
79-
}
79+
},
80+
"packageManager": "yarn@1.22.1"
8081
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/* ============================================================================
2+
* Copyright (c) Palo Alto Networks
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* ========================================================================== */
7+
8+
import { MediaTypeObject } from "../openapi/types";
9+
import { ApiItem } from "../types";
10+
import { createDescription } from "./createDescription";
11+
import { createMethodEndpoint } from "./createMethodEndpoint";
12+
import { createRequestBodyDetails } from "./createRequestBodyDetails";
13+
import { createStatusCodes } from "./createStatusCodes";
14+
import { create } from "./utils";
15+
16+
interface Props {
17+
callbacks: ApiItem["callbacks"];
18+
}
19+
20+
interface RequestBodyProps {
21+
title: string;
22+
body: {
23+
content?: {
24+
[key: string]: MediaTypeObject;
25+
};
26+
description?: string;
27+
required?: boolean;
28+
};
29+
}
30+
31+
export function createCallbacks({ callbacks }: Props) {
32+
if (callbacks === undefined) {
33+
return undefined;
34+
}
35+
36+
const callbacksNames = Object.keys(callbacks);
37+
if (callbacksNames.length === 0) {
38+
return undefined;
39+
}
40+
41+
return create("div", {
42+
children: [
43+
create("div", {
44+
className: "openapi__divider",
45+
}),
46+
create("h2", {
47+
children: "Callbacks",
48+
id: "callbacks",
49+
}),
50+
create("OperationTabs", {
51+
className: "openapi-tabs__operation",
52+
children: callbacksNames.flatMap((name) => {
53+
const path = Object.keys(callbacks[name])[0];
54+
const methods = new Map([
55+
["delete", callbacks[name][path].delete],
56+
["get", callbacks[name][path].get],
57+
["head", callbacks[name][path].head],
58+
["options", callbacks[name][path].options],
59+
["patch", callbacks[name][path].patch],
60+
["post", callbacks[name][path].post],
61+
["put", callbacks[name][path].put],
62+
["trace", callbacks[name][path].trace],
63+
]);
64+
65+
return Array.from(methods).flatMap(([method, operationObject]) => {
66+
if (!operationObject) return [];
67+
68+
const { description, requestBody, responses } = operationObject;
69+
70+
return [
71+
create("TabItem", {
72+
label: `${method.toUpperCase()} ${name}`,
73+
value: `${method}-${name}`,
74+
children: [
75+
createMethodEndpoint(method, path),
76+
// TODO: add `deprecation notice` when markdown support is added
77+
createDescription(description),
78+
createRequestBodyDetails({
79+
title: "Body",
80+
body: requestBody,
81+
} as RequestBodyProps),
82+
createStatusCodes({
83+
id: "callbacks-responses",
84+
label: "Callbacks Responses",
85+
responses,
86+
}),
87+
],
88+
}),
89+
];
90+
});
91+
}),
92+
}),
93+
],
94+
});
95+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ interface Props {
1919
};
2020
}
2121

22-
export function createRequestBodyDetails({ title, body }: Props): any {
22+
export function createRequestBodyDetails({ title, body }: Props) {
2323
return createRequestSchema({ title, body });
2424
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ export default function json2xml(o: any, tab: any) {
5454
}
5555

5656
interface Props {
57+
id?: string;
58+
label?: string;
5759
responses: ApiItem["responses"];
5860
}
5961

@@ -254,7 +256,7 @@ export function createExampleFromSchema(schema: any, mimeType: string) {
254256
return undefined;
255257
}
256258

257-
export function createStatusCodes({ responses }: Props) {
259+
export function createStatusCodes({ label, id, responses }: Props) {
258260
if (responses === undefined) {
259261
return undefined;
260262
}
@@ -269,6 +271,8 @@ export function createStatusCodes({ responses }: Props) {
269271
create("div", {
270272
children: [
271273
create("ApiTabs", {
274+
label,
275+
id,
272276
children: codes.map((code) => {
273277
const responseHeaders: any = responses[code].headers;
274278
return create("TabItem", {

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
1515
import { createAuthentication } from "./createAuthentication";
1616
import { createAuthorization } from "./createAuthorization";
17+
import { createCallbacks } from "./createCallbacks";
1718
import { createContactInfo } from "./createContactInfo";
1819
import { createDeprecationNotice } from "./createDeprecationNotice";
1920
import { createDescription } from "./createDescription";
@@ -31,7 +32,7 @@ import { createVendorExtensions } from "./createVendorExtensions";
3132
import { createVersionBadge } from "./createVersionBadge";
3233
import { greaterThan, lessThan, render } from "./utils";
3334

34-
interface Props {
35+
interface RequestBodyProps {
3536
title: string;
3637
body: {
3738
content?: {
@@ -54,6 +55,7 @@ export function createApiPageMD({
5455
parameters,
5556
requestBody,
5657
responses,
58+
callbacks,
5759
},
5860
infoPath,
5961
frontMatter,
@@ -68,11 +70,14 @@ export function createApiPageMD({
6870
`import ResponseSamples from "@theme/ResponseSamples";\n`,
6971
`import SchemaItem from "@theme/SchemaItem";\n`,
7072
`import SchemaTabs from "@theme/SchemaTabs";\n`,
73+
`import OperationTabs from "@theme/OperationTabs";\n`,
7174
`import TabItem from "@theme/TabItem";\n\n`,
7275
createHeading(title.replace(lessThan, "<").replace(greaterThan, ">")),
7376
createMethodEndpoint(method, path),
7477
infoPath && createAuthorization(infoPath),
75-
frontMatter.show_extensions && createVendorExtensions(extensions),
78+
frontMatter.show_extensions
79+
? createVendorExtensions(extensions)
80+
: undefined,
7681
createDeprecationNotice({ deprecated, description: deprecatedDescription }),
7782
createDescription(description),
7883
createRequestHeader("Request"),
@@ -83,8 +88,9 @@ export function createApiPageMD({
8388
createRequestBodyDetails({
8489
title: "Body",
8590
body: requestBody,
86-
} as Props),
91+
} as RequestBodyProps),
8792
createStatusCodes({ responses }),
93+
createCallbacks({ callbacks }),
8894
]);
8995
}
9096

packages/docusaurus-theme-openapi-docs/src/theme/ApiTabs/index.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ import useIsBrowser from "@docusaurus/useIsBrowser";
1515
import Heading from "@theme/Heading";
1616
import clsx from "clsx";
1717

18-
function TabList({ className, block, selectedValue, selectValue, tabValues }) {
18+
function TabList({
19+
className,
20+
block,
21+
selectedValue,
22+
selectValue,
23+
tabValues,
24+
label = "Responses",
25+
id = "responses",
26+
}) {
1927
const tabRefs = [];
2028
const { blockElementScrollPositionUntilNextRender } =
2129
useScrollPositionBlocker();
@@ -84,8 +92,8 @@ function TabList({ className, block, selectedValue, selectValue, tabValues }) {
8492

8593
return (
8694
<div className="openapi-tabs__response-header-section">
87-
<Heading as="h2" id="responses" className="openapi-tabs__response-header">
88-
Responses
95+
<Heading as="h2" id={id} className="openapi-tabs__response-header">
96+
{label}
8997
</Heading>
9098
<div className="openapi-tabs__response-container">
9199
{showTabArrows && (
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
.openapi-tabs__operation-container {
9+
display: flex;
10+
align-items: center;
11+
margin-top: 1rem;
12+
overflow: hidden;
13+
}
14+
15+
.openapi-tabs__operation-item {
16+
display: flex;
17+
align-items: center;
18+
justify-content: center;
19+
padding: 0.35rem 0.7rem;
20+
border: 1px solid transparent;
21+
margin-top: 0 !important;
22+
margin-right: 0.5rem;
23+
font-weight: var(--ifm-font-weight-bold);
24+
font-size: 12px;
25+
white-space: nowrap;
26+
transition: 300ms;
27+
28+
&:hover {
29+
background-color: transparent;
30+
border: 1px solid var(--ifm-toc-border-color);
31+
}
32+
33+
&.active {
34+
border: 1px solid var(--ifm-tabs-color-active-border);
35+
color: var(--ifm-tabs-color-active);
36+
}
37+
38+
&:last-child {
39+
margin-right: 0 !important;
40+
}
41+
}
42+
43+
.openapi-tabs__operation-list-container {
44+
overflow-y: hidden;
45+
overflow-x: scroll;
46+
scroll-behavior: smooth;
47+
48+
&::-webkit-scrollbar {
49+
display: none;
50+
}
51+
}
52+
53+
.openapi-tabs__operation-schema-container {
54+
max-width: 600px;
55+
}
56+
57+
@media screen and (max-width: 500px) {
58+
.operationTabsTopSection {
59+
flex-direction: column;
60+
align-items: flex-start;
61+
}
62+
63+
.operationTabsContainer {
64+
width: 100%;
65+
margin-top: var(--ifm-spacing-vertical);
66+
padding: 0;
67+
}
68+
}

0 commit comments

Comments
 (0)