Skip to content

Commit 96efe71

Browse files
handle oneOf cases
1 parent 2365dd1 commit 96efe71

File tree

8 files changed

+585
-450
lines changed

8 files changed

+585
-450
lines changed

apps/portal/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"nextjs-toploader": "^1.6.12",
2525
"node-html-markdown": "^1.3.0",
2626
"node-html-parser": "^6.1.13",
27+
"openapi-types": "12.1.3",
2728
"posthog-js": "1.256.1",
2829
"prettier": "3.6.2",
2930
"react": "19.1.0",

apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx

Lines changed: 114 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { cn } from "../../../lib/utils";
33
import { CodeBlock } from "../Code";
44
import { Details } from "../Details";
55
import { Heading } from "../Heading";
6+
import { DynamicRequestExample } from "./DynamicRequestExample";
67
import { RequestExample } from "./RequestExample";
78

89
export type APIParameter = {
@@ -18,6 +19,11 @@ export type APIParameter = {
1819
| Array<string | boolean | number | object>;
1920
};
2021

22+
export type RequestExampleType = {
23+
title: string;
24+
bodyParameters: APIParameter[];
25+
};
26+
2127
export type ApiEndpointMeta = {
2228
title: string;
2329
description: React.ReactNode;
@@ -29,33 +35,74 @@ export type ApiEndpointMeta = {
2935
headers: APIParameter[];
3036
queryParameters: APIParameter[];
3137
bodyParameters: APIParameter[];
38+
// Support for multiple request examples (oneOf schemas)
39+
requestExamples?: RequestExampleType[];
3240
};
3341
responseExamples: Record<string, string>;
3442
};
3543

3644
export function ApiEndpoint(props: { metadata: ApiEndpointMeta }) {
3745
const { responseExamples, request } = props.metadata;
3846

47+
// If we have multiple request examples (oneOf schemas), create code examples for each
3948
const requestExamples: Array<{
4049
lang: "javascript" | "bash";
4150
code: string;
4251
label: string;
43-
}> = [
44-
{
45-
code: createFetchCommand({
46-
metadata: props.metadata,
47-
}),
48-
label: "Fetch",
49-
lang: "javascript",
50-
},
51-
{
52-
code: createCurlCommand({
53-
metadata: props.metadata,
54-
}),
55-
label: "Curl",
56-
lang: "bash",
57-
},
58-
];
52+
format: "fetch" | "curl";
53+
exampleType?: string;
54+
bodyParameters?: APIParameter[];
55+
}> = [];
56+
57+
if (request.requestExamples && request.requestExamples.length > 0) {
58+
// Create examples for each oneOf schema
59+
for (const requestExample of request.requestExamples) {
60+
const metadataWithExample = {
61+
...props.metadata,
62+
request: {
63+
...request,
64+
bodyParameters: requestExample.bodyParameters,
65+
},
66+
};
67+
68+
requestExamples.push(
69+
{
70+
code: createFetchCommand({ metadata: metadataWithExample }),
71+
label: `Fetch - ${requestExample.title}`,
72+
lang: "javascript",
73+
format: "fetch",
74+
exampleType: requestExample.title,
75+
bodyParameters: requestExample.bodyParameters,
76+
},
77+
{
78+
code: createCurlCommand({ metadata: metadataWithExample }),
79+
label: `Curl - ${requestExample.title}`,
80+
lang: "bash",
81+
format: "curl",
82+
exampleType: requestExample.title,
83+
bodyParameters: requestExample.bodyParameters,
84+
},
85+
);
86+
}
87+
} else {
88+
// Default single example
89+
requestExamples.push(
90+
{
91+
code: createFetchCommand({ metadata: props.metadata }),
92+
label: "Fetch",
93+
lang: "javascript",
94+
format: "fetch",
95+
bodyParameters: request.bodyParameters,
96+
},
97+
{
98+
code: createCurlCommand({ metadata: props.metadata }),
99+
label: "Curl",
100+
lang: "bash",
101+
format: "curl",
102+
bodyParameters: request.bodyParameters,
103+
},
104+
);
105+
}
59106

60107
const responseKeys = Object.keys(responseExamples);
61108

@@ -65,11 +112,22 @@ export function ApiEndpoint(props: { metadata: ApiEndpointMeta }) {
65112
<Heading anchorId="request" className="text-lg lg:text-lg" level={3}>
66113
Request
67114
</Heading>
68-
<div className="rounded-lg border">
69-
<RequestExample
70-
// render <CodeBlock /> on server and pass it to client
71-
codeExamples={requestExamples.map((example) => {
72-
return {
115+
116+
{/* Use DynamicRequestExample for multiple examples, regular for single */}
117+
{request.requestExamples && request.requestExamples.length > 0 ? (
118+
<DynamicRequestExample
119+
requestExamples={requestExamples}
120+
endpointUrl={props.metadata.path}
121+
method={props.metadata.method}
122+
pathParameters={request.pathParameters}
123+
headers={request.headers}
124+
queryParameters={request.queryParameters}
125+
hasMultipleExamples={true}
126+
/>
127+
) : (
128+
<div className="rounded-lg border">
129+
<RequestExample
130+
codeExamples={requestExamples.map((example) => ({
73131
code: (
74132
<CodeBlock
75133
className="rounded-none border-none"
@@ -79,40 +137,43 @@ export function ApiEndpoint(props: { metadata: ApiEndpointMeta }) {
79137
/>
80138
),
81139
label: example.label,
82-
};
83-
})}
84-
endpointUrl={props.metadata.path}
85-
method={props.metadata.method}
86-
/>
140+
}))}
141+
endpointUrl={props.metadata.path}
142+
method={props.metadata.method}
143+
/>
144+
145+
{/* Parameters section inside the card */}
146+
<div className="border-t">
147+
{request.headers.length > 0 && (
148+
<ParameterSection
149+
parameters={request.headers}
150+
title="Headers"
151+
/>
152+
)}
153+
154+
{request.pathParameters.length > 0 && (
155+
<ParameterSection
156+
parameters={request.pathParameters}
157+
title="Path Parameters"
158+
/>
159+
)}
87160

88-
{/* Parameters section inside the card */}
89-
<div className="border-t">
90-
{request.headers.length > 0 && (
91-
<ParameterSection parameters={request.headers} title="Headers" />
92-
)}
93-
94-
{request.pathParameters.length > 0 && (
95-
<ParameterSection
96-
parameters={request.pathParameters}
97-
title="Path Parameters"
98-
/>
99-
)}
100-
101-
{request.queryParameters.length > 0 && (
102-
<ParameterSection
103-
parameters={request.queryParameters}
104-
title="Query Parameters"
105-
/>
106-
)}
107-
108-
{request.bodyParameters.length > 0 && (
109-
<ParameterSection
110-
parameters={request.bodyParameters}
111-
title="Request Body"
112-
/>
113-
)}
161+
{request.queryParameters.length > 0 && (
162+
<ParameterSection
163+
parameters={request.queryParameters}
164+
title="Query Parameters"
165+
/>
166+
)}
167+
168+
{request.bodyParameters.length > 0 && (
169+
<ParameterSection
170+
parameters={request.bodyParameters}
171+
title="Request Body"
172+
/>
173+
)}
174+
</div>
114175
</div>
115-
</div>
176+
)}
116177
</div>
117178

118179
<div>

0 commit comments

Comments
 (0)