radiant-docs 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +32 -6
- package/package.json +3 -3
- package/template/astro.config.mjs +76 -3
- package/template/package-lock.json +924 -737
- package/template/package.json +7 -5
- package/template/scripts/generate-og-images.mjs +335 -0
- package/template/scripts/generate-og-metadata.mjs +173 -0
- package/template/scripts/rewrite-static-asset-host.mjs +408 -0
- package/template/scripts/stamp-image-versions.mjs +277 -0
- package/template/scripts/stamp-og-image-versions.mjs +199 -0
- package/template/scripts/stamp-pagefind-runtime-version.mjs +140 -0
- package/template/src/assets/fonts/geist-mono/cyrillic.woff2 +0 -0
- package/template/src/assets/fonts/geist-mono/latin-ext.woff2 +0 -0
- package/template/src/assets/fonts/geist-mono/latin.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/canadian-aboriginal.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/cherokee.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/latin-ext.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/latin.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/math.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/nushu.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/symbols.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/syriac.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/tifinagh.woff2 +0 -0
- package/template/src/assets/fonts/google-sans-flex/vietnamese.woff2 +0 -0
- package/template/src/components/Footer.astro +94 -0
- package/template/src/components/Header.astro +11 -66
- package/template/src/components/LogoLink.astro +103 -0
- package/template/src/components/MdxPage.astro +126 -11
- package/template/src/components/OpenApiPage.astro +1036 -69
- package/template/src/components/Search.astro +0 -2
- package/template/src/components/SidebarDropdown.astro +34 -14
- package/template/src/components/SidebarGroup.astro +3 -6
- package/template/src/components/SidebarLink.astro +22 -12
- package/template/src/components/SidebarMenu.astro +19 -16
- package/template/src/components/SidebarSegmented.astro +99 -0
- package/template/src/components/SidebarSubgroup.astro +12 -12
- package/template/src/components/ThemeSwitcher.astro +30 -7
- package/template/src/components/endpoint/PlaygroundBar.astro +32 -36
- package/template/src/components/endpoint/PlaygroundButton.astro +40 -4
- package/template/src/components/endpoint/PlaygroundField.astro +1068 -22
- package/template/src/components/endpoint/PlaygroundForm.astro +559 -61
- package/template/src/components/endpoint/RequestSnippets.astro +342 -193
- package/template/src/components/endpoint/ResponseDisplay.astro +161 -147
- package/template/src/components/endpoint/ResponseFieldTree.astro +134 -0
- package/template/src/components/endpoint/ResponseFields.astro +711 -68
- package/template/src/components/endpoint/ResponseSnippets.astro +299 -173
- package/template/src/components/sidebar/SidebarEndpointLink.astro +1 -1
- package/template/src/components/ui/CodeLanguageIcon.astro +19 -0
- package/template/src/components/ui/CodeTabEdge.astro +79 -0
- package/template/src/components/ui/Field.astro +103 -20
- package/template/src/components/ui/Icon.astro +32 -0
- package/template/src/components/ui/ListChevronsToggle.astro +31 -0
- package/template/src/components/ui/Tag.astro +1 -1
- package/template/src/components/user/{Accordian.astro → Accordion.astro} +6 -6
- package/template/src/components/user/Callout.astro +5 -9
- package/template/src/components/user/CodeBlock.astro +400 -0
- package/template/src/components/user/CodeGroup.astro +225 -0
- package/template/src/components/user/ComponentPreview.astro +1 -0
- package/template/src/components/user/ComponentPreviewBlock.astro +181 -0
- package/template/src/components/user/Image.astro +132 -0
- package/template/src/components/user/Steps.astro +1 -3
- package/template/src/components/user/Tabs.astro +2 -2
- package/template/src/content.config.ts +1 -0
- package/template/src/layouts/Layout.astro +109 -8
- package/template/src/lib/code/code-block.ts +546 -0
- package/template/src/lib/frontmatter-schema.ts +8 -7
- package/template/src/lib/mdx/remark-code-block-component.ts +342 -0
- package/template/src/lib/mdx/remark-demote-h1.ts +16 -0
- package/template/src/lib/pagefind.ts +19 -5
- package/template/src/lib/routes.ts +49 -31
- package/template/src/lib/utils.ts +20 -0
- package/template/src/lib/validation.ts +638 -200
- package/template/src/pages/[...slug].astro +18 -5
- package/template/src/styles/geist-mono.css +33 -0
- package/template/src/styles/global.css +89 -84
- package/template/src/styles/google-sans-flex.css +143 -0
- package/template/ec.config.mjs +0 -51
- /package/template/src/components/user/{AccordianGroup.astro → AccordionGroup.astro} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { OpenAPIV3, OpenAPIV3_1 } from "openapi-types";
|
|
3
|
-
import
|
|
3
|
+
import ListChevronsToggle from "../ui/ListChevronsToggle.astro";
|
|
4
|
+
import ResponseFieldTree from "./ResponseFieldTree.astro";
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
responses: OpenAPIV3.ResponsesObject | OpenAPIV3_1.ResponsesObject;
|
|
@@ -8,37 +9,490 @@ interface Props {
|
|
|
8
9
|
|
|
9
10
|
const { responses } = Astro.props;
|
|
10
11
|
|
|
12
|
+
interface ResponseFieldVariant {
|
|
13
|
+
label: string;
|
|
14
|
+
fields: ResponseField[];
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
interface ResponseField {
|
|
12
18
|
name: string;
|
|
13
19
|
required: boolean;
|
|
14
20
|
type: string;
|
|
15
21
|
description: string;
|
|
16
22
|
nested?: ResponseField[]; // For nested objects
|
|
17
|
-
enum?: string[];
|
|
23
|
+
enum?: (string | number)[];
|
|
24
|
+
minLength?: number;
|
|
25
|
+
maxLength?: number;
|
|
26
|
+
minimum?: number;
|
|
27
|
+
maximum?: number;
|
|
28
|
+
exclusiveMinimum?: number;
|
|
29
|
+
exclusiveMaximum?: number;
|
|
30
|
+
variants?: ResponseFieldVariant[];
|
|
31
|
+
variantType?: "oneOf" | "anyOf";
|
|
18
32
|
}
|
|
19
33
|
|
|
34
|
+
type ResponseVariant = ResponseFieldVariant;
|
|
35
|
+
|
|
20
36
|
interface ResponseData {
|
|
21
37
|
statusCode: string;
|
|
22
38
|
description?: string;
|
|
23
39
|
fields: ResponseField[];
|
|
40
|
+
variants?: ResponseVariant[];
|
|
41
|
+
variantType?: "oneOf" | "anyOf";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getStatusCodeDotClass(statusCode: string): string {
|
|
45
|
+
const family = statusCode[0];
|
|
46
|
+
if (family === "2") return "bg-green-700/70";
|
|
47
|
+
if (family === "3") return "bg-blue-700/70";
|
|
48
|
+
if (family === "4") return "bg-yellow-500/80";
|
|
49
|
+
if (family === "5") return "bg-red-700/70";
|
|
50
|
+
return "bg-neutral-400";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getSchemaVariants(schema: any): any[] {
|
|
54
|
+
if (!schema) return [];
|
|
55
|
+
if (Array.isArray(schema.oneOf)) return schema.oneOf;
|
|
56
|
+
if (Array.isArray(schema.anyOf)) return schema.anyOf;
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getSchemaEnumValues(schema: any): (string | number)[] | undefined {
|
|
61
|
+
if (!schema) return undefined;
|
|
62
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) {
|
|
63
|
+
const values = schema.enum.filter(
|
|
64
|
+
(value: unknown): value is string | number =>
|
|
65
|
+
typeof value === "string" || typeof value === "number",
|
|
66
|
+
);
|
|
67
|
+
return values.length > 0 ? values : undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const variantSchemas: any[] = getSchemaVariants(schema);
|
|
71
|
+
if (variantSchemas.length === 0) return undefined;
|
|
72
|
+
|
|
73
|
+
const deduped = new Map<string, string | number>();
|
|
74
|
+
variantSchemas.forEach((variant) => {
|
|
75
|
+
const variantEnum = getSchemaEnumValues(variant);
|
|
76
|
+
variantEnum?.forEach((value) => {
|
|
77
|
+
deduped.set(`${typeof value}:${String(value)}`, value);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return deduped.size > 0 ? Array.from(deduped.values()) : undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function parseFiniteNumber(value: unknown): number | undefined {
|
|
85
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function parseNonNegativeInteger(value: unknown): number | undefined {
|
|
89
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
|
|
90
|
+
if (!Number.isInteger(value) || value < 0) return undefined;
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getDirectSchemaNumericConstraints(schema: any): {
|
|
95
|
+
minimum?: number;
|
|
96
|
+
maximum?: number;
|
|
97
|
+
exclusiveMinimum?: number;
|
|
98
|
+
exclusiveMaximum?: number;
|
|
99
|
+
} {
|
|
100
|
+
const minimum = parseFiniteNumber(schema?.minimum);
|
|
101
|
+
const maximum = parseFiniteNumber(schema?.maximum);
|
|
102
|
+
const exclusiveMinimumValue = parseFiniteNumber(schema?.exclusiveMinimum);
|
|
103
|
+
const exclusiveMaximumValue = parseFiniteNumber(schema?.exclusiveMaximum);
|
|
104
|
+
|
|
105
|
+
const exclusiveMinimum =
|
|
106
|
+
exclusiveMinimumValue !== undefined
|
|
107
|
+
? exclusiveMinimumValue
|
|
108
|
+
: schema?.exclusiveMinimum === true
|
|
109
|
+
? minimum
|
|
110
|
+
: undefined;
|
|
111
|
+
const exclusiveMaximum =
|
|
112
|
+
exclusiveMaximumValue !== undefined
|
|
113
|
+
? exclusiveMaximumValue
|
|
114
|
+
: schema?.exclusiveMaximum === true
|
|
115
|
+
? maximum
|
|
116
|
+
: undefined;
|
|
117
|
+
|
|
118
|
+
const constraints: {
|
|
119
|
+
minimum?: number;
|
|
120
|
+
maximum?: number;
|
|
121
|
+
exclusiveMinimum?: number;
|
|
122
|
+
exclusiveMaximum?: number;
|
|
123
|
+
} = {};
|
|
124
|
+
|
|
125
|
+
if (exclusiveMinimum !== undefined) {
|
|
126
|
+
constraints.exclusiveMinimum = exclusiveMinimum;
|
|
127
|
+
} else if (minimum !== undefined) {
|
|
128
|
+
constraints.minimum = minimum;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (exclusiveMaximum !== undefined) {
|
|
132
|
+
constraints.exclusiveMaximum = exclusiveMaximum;
|
|
133
|
+
} else if (maximum !== undefined) {
|
|
134
|
+
constraints.maximum = maximum;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return constraints;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function mergeConjunctiveNumericConstraints(
|
|
141
|
+
base: {
|
|
142
|
+
minimum?: number;
|
|
143
|
+
maximum?: number;
|
|
144
|
+
exclusiveMinimum?: number;
|
|
145
|
+
exclusiveMaximum?: number;
|
|
146
|
+
},
|
|
147
|
+
next: {
|
|
148
|
+
minimum?: number;
|
|
149
|
+
maximum?: number;
|
|
150
|
+
exclusiveMinimum?: number;
|
|
151
|
+
exclusiveMaximum?: number;
|
|
152
|
+
},
|
|
153
|
+
): {
|
|
154
|
+
minimum?: number;
|
|
155
|
+
maximum?: number;
|
|
156
|
+
exclusiveMinimum?: number;
|
|
157
|
+
exclusiveMaximum?: number;
|
|
158
|
+
} {
|
|
159
|
+
const toLowerBound = (constraint: typeof base) => {
|
|
160
|
+
if (constraint.exclusiveMinimum !== undefined) {
|
|
161
|
+
return { value: constraint.exclusiveMinimum, exclusive: true };
|
|
162
|
+
}
|
|
163
|
+
if (constraint.minimum !== undefined) {
|
|
164
|
+
return { value: constraint.minimum, exclusive: false };
|
|
165
|
+
}
|
|
166
|
+
return undefined;
|
|
167
|
+
};
|
|
168
|
+
const toUpperBound = (constraint: typeof base) => {
|
|
169
|
+
if (constraint.exclusiveMaximum !== undefined) {
|
|
170
|
+
return { value: constraint.exclusiveMaximum, exclusive: true };
|
|
171
|
+
}
|
|
172
|
+
if (constraint.maximum !== undefined) {
|
|
173
|
+
return { value: constraint.maximum, exclusive: false };
|
|
174
|
+
}
|
|
175
|
+
return undefined;
|
|
176
|
+
};
|
|
177
|
+
const pickStricterLower = (
|
|
178
|
+
first?: { value: number; exclusive: boolean },
|
|
179
|
+
second?: { value: number; exclusive: boolean },
|
|
180
|
+
) => {
|
|
181
|
+
if (!first) return second;
|
|
182
|
+
if (!second) return first;
|
|
183
|
+
if (first.value > second.value) return first;
|
|
184
|
+
if (second.value > first.value) return second;
|
|
185
|
+
return { value: first.value, exclusive: first.exclusive || second.exclusive };
|
|
186
|
+
};
|
|
187
|
+
const pickStricterUpper = (
|
|
188
|
+
first?: { value: number; exclusive: boolean },
|
|
189
|
+
second?: { value: number; exclusive: boolean },
|
|
190
|
+
) => {
|
|
191
|
+
if (!first) return second;
|
|
192
|
+
if (!second) return first;
|
|
193
|
+
if (first.value < second.value) return first;
|
|
194
|
+
if (second.value < first.value) return second;
|
|
195
|
+
return { value: first.value, exclusive: first.exclusive || second.exclusive };
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const lower = pickStricterLower(toLowerBound(base), toLowerBound(next));
|
|
199
|
+
const upper = pickStricterUpper(toUpperBound(base), toUpperBound(next));
|
|
200
|
+
|
|
201
|
+
const merged: {
|
|
202
|
+
minimum?: number;
|
|
203
|
+
maximum?: number;
|
|
204
|
+
exclusiveMinimum?: number;
|
|
205
|
+
exclusiveMaximum?: number;
|
|
206
|
+
} = {};
|
|
207
|
+
if (lower) {
|
|
208
|
+
if (lower.exclusive) merged.exclusiveMinimum = lower.value;
|
|
209
|
+
else merged.minimum = lower.value;
|
|
210
|
+
}
|
|
211
|
+
if (upper) {
|
|
212
|
+
if (upper.exclusive) merged.exclusiveMaximum = upper.value;
|
|
213
|
+
else merged.maximum = upper.value;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return merged;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function getSchemaNumericConstraints(
|
|
220
|
+
schema: any,
|
|
221
|
+
seen = new Set<any>(),
|
|
222
|
+
): {
|
|
223
|
+
minimum?: number;
|
|
224
|
+
maximum?: number;
|
|
225
|
+
exclusiveMinimum?: number;
|
|
226
|
+
exclusiveMaximum?: number;
|
|
227
|
+
} {
|
|
228
|
+
if (!schema || typeof schema !== "object") return {};
|
|
229
|
+
if (seen.has(schema)) return {};
|
|
230
|
+
|
|
231
|
+
const nextSeen = new Set(seen);
|
|
232
|
+
nextSeen.add(schema);
|
|
233
|
+
|
|
234
|
+
let constraints = getDirectSchemaNumericConstraints(schema);
|
|
235
|
+
|
|
236
|
+
if (Array.isArray(schema.allOf)) {
|
|
237
|
+
schema.allOf.forEach((part: any) => {
|
|
238
|
+
constraints = mergeConjunctiveNumericConstraints(
|
|
239
|
+
constraints,
|
|
240
|
+
getSchemaNumericConstraints(part, nextSeen),
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const variants = getSchemaVariants(schema);
|
|
246
|
+
if (variants.length > 0) {
|
|
247
|
+
const variantConstraints = variants.map((variant) =>
|
|
248
|
+
getSchemaNumericConstraints(variant, nextSeen),
|
|
249
|
+
);
|
|
250
|
+
const shared: {
|
|
251
|
+
minimum?: number;
|
|
252
|
+
maximum?: number;
|
|
253
|
+
exclusiveMinimum?: number;
|
|
254
|
+
exclusiveMaximum?: number;
|
|
255
|
+
} = {};
|
|
256
|
+
const keys = [
|
|
257
|
+
"minimum",
|
|
258
|
+
"maximum",
|
|
259
|
+
"exclusiveMinimum",
|
|
260
|
+
"exclusiveMaximum",
|
|
261
|
+
] as const;
|
|
262
|
+
|
|
263
|
+
keys.forEach((key) => {
|
|
264
|
+
const firstValue = variantConstraints[0]?.[key];
|
|
265
|
+
if (firstValue === undefined) return;
|
|
266
|
+
const allMatch = variantConstraints.every(
|
|
267
|
+
(variantConstraint) => variantConstraint[key] === firstValue,
|
|
268
|
+
);
|
|
269
|
+
if (allMatch) {
|
|
270
|
+
shared[key] = firstValue;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
constraints = mergeConjunctiveNumericConstraints(constraints, shared);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return constraints;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function getDirectSchemaStringLengthConstraints(schema: any): {
|
|
281
|
+
minLength?: number;
|
|
282
|
+
maxLength?: number;
|
|
283
|
+
} {
|
|
284
|
+
const minLength = parseNonNegativeInteger(schema?.minLength);
|
|
285
|
+
const maxLength = parseNonNegativeInteger(schema?.maxLength);
|
|
286
|
+
|
|
287
|
+
const constraints: {
|
|
288
|
+
minLength?: number;
|
|
289
|
+
maxLength?: number;
|
|
290
|
+
} = {};
|
|
291
|
+
if (minLength !== undefined) constraints.minLength = minLength;
|
|
292
|
+
if (maxLength !== undefined) constraints.maxLength = maxLength;
|
|
293
|
+
|
|
294
|
+
return constraints;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function mergeConjunctiveStringLengthConstraints(
|
|
298
|
+
base: {
|
|
299
|
+
minLength?: number;
|
|
300
|
+
maxLength?: number;
|
|
301
|
+
},
|
|
302
|
+
next: {
|
|
303
|
+
minLength?: number;
|
|
304
|
+
maxLength?: number;
|
|
305
|
+
},
|
|
306
|
+
): {
|
|
307
|
+
minLength?: number;
|
|
308
|
+
maxLength?: number;
|
|
309
|
+
} {
|
|
310
|
+
const merged: {
|
|
311
|
+
minLength?: number;
|
|
312
|
+
maxLength?: number;
|
|
313
|
+
} = {};
|
|
314
|
+
|
|
315
|
+
const minLengthCandidates = [base.minLength, next.minLength].filter(
|
|
316
|
+
(value): value is number => value !== undefined,
|
|
317
|
+
);
|
|
318
|
+
const maxLengthCandidates = [base.maxLength, next.maxLength].filter(
|
|
319
|
+
(value): value is number => value !== undefined,
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
if (minLengthCandidates.length > 0) {
|
|
323
|
+
merged.minLength = Math.max(...minLengthCandidates);
|
|
324
|
+
}
|
|
325
|
+
if (maxLengthCandidates.length > 0) {
|
|
326
|
+
merged.maxLength = Math.min(...maxLengthCandidates);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return merged;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function getSchemaStringLengthConstraints(
|
|
333
|
+
schema: any,
|
|
334
|
+
seen = new Set<any>(),
|
|
335
|
+
): {
|
|
336
|
+
minLength?: number;
|
|
337
|
+
maxLength?: number;
|
|
338
|
+
} {
|
|
339
|
+
if (!schema || typeof schema !== "object") return {};
|
|
340
|
+
if (seen.has(schema)) return {};
|
|
341
|
+
|
|
342
|
+
const nextSeen = new Set(seen);
|
|
343
|
+
nextSeen.add(schema);
|
|
344
|
+
|
|
345
|
+
let constraints = getDirectSchemaStringLengthConstraints(schema);
|
|
346
|
+
|
|
347
|
+
if (Array.isArray(schema.allOf)) {
|
|
348
|
+
schema.allOf.forEach((part: any) => {
|
|
349
|
+
constraints = mergeConjunctiveStringLengthConstraints(
|
|
350
|
+
constraints,
|
|
351
|
+
getSchemaStringLengthConstraints(part, nextSeen),
|
|
352
|
+
);
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const variants = getSchemaVariants(schema);
|
|
357
|
+
if (variants.length > 0) {
|
|
358
|
+
const variantConstraints = variants.map((variant) =>
|
|
359
|
+
getSchemaStringLengthConstraints(variant, nextSeen),
|
|
360
|
+
);
|
|
361
|
+
const shared: {
|
|
362
|
+
minLength?: number;
|
|
363
|
+
maxLength?: number;
|
|
364
|
+
} = {};
|
|
365
|
+
|
|
366
|
+
(["minLength", "maxLength"] as const).forEach((key) => {
|
|
367
|
+
const firstValue = variantConstraints[0]?.[key];
|
|
368
|
+
if (firstValue === undefined) return;
|
|
369
|
+
const allMatch = variantConstraints.every(
|
|
370
|
+
(variantConstraint) => variantConstraint[key] === firstValue,
|
|
371
|
+
);
|
|
372
|
+
if (allMatch) {
|
|
373
|
+
shared[key] = firstValue;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
constraints = mergeConjunctiveStringLengthConstraints(constraints, shared);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return constraints;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function getSchemaTypeLabel(schema: any): string {
|
|
384
|
+
if (!schema) return "unknown";
|
|
385
|
+
|
|
386
|
+
const variantSchemas: any[] = getSchemaVariants(schema);
|
|
387
|
+
if (variantSchemas.length > 0) {
|
|
388
|
+
const labels = Array.from(
|
|
389
|
+
new Set(
|
|
390
|
+
variantSchemas
|
|
391
|
+
.map((variant) => getSchemaTypeLabel(variant))
|
|
392
|
+
.filter((label) => label.length > 0),
|
|
393
|
+
),
|
|
394
|
+
);
|
|
395
|
+
if (labels.length === 0) return "unknown";
|
|
396
|
+
return labels.length === 1 ? labels[0] : labels.join(" | ");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (schema.type === "array") {
|
|
400
|
+
const itemType = getSchemaTypeLabel(schema.items);
|
|
401
|
+
return itemType.includes(" | ") ? `(${itemType})[]` : `${itemType}[]`;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) {
|
|
405
|
+
return `enum<${schema.type || "string"}>`;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (schema.format && schema.type) {
|
|
409
|
+
return `${schema.type} (${schema.format})`;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (schema.type) return schema.type;
|
|
413
|
+
if (schema.properties || schema.allOf || schema.oneOf || schema.anyOf) {
|
|
414
|
+
return "object";
|
|
415
|
+
}
|
|
416
|
+
return "unknown";
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function getSchemaVariantType(schema: any): "oneOf" | "anyOf" | undefined {
|
|
420
|
+
if (Array.isArray(schema?.oneOf) && schema.oneOf.length > 0) return "oneOf";
|
|
421
|
+
if (Array.isArray(schema?.anyOf) && schema.anyOf.length > 0) return "anyOf";
|
|
422
|
+
return undefined;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function getAdditionalPropertiesSchema(schema: any): any {
|
|
426
|
+
if (!schema || typeof schema !== "object") return undefined;
|
|
427
|
+
|
|
428
|
+
let additionalProperties = schema.additionalProperties;
|
|
429
|
+
if (Array.isArray(schema.allOf)) {
|
|
430
|
+
schema.allOf.forEach((part: any) => {
|
|
431
|
+
const partAdditional = getAdditionalPropertiesSchema(part);
|
|
432
|
+
if (partAdditional !== undefined) {
|
|
433
|
+
additionalProperties = partAdditional;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return additionalProperties;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function extractVariantData(
|
|
442
|
+
schema: any,
|
|
443
|
+
parentName: string,
|
|
444
|
+
fallbackRequired: string[] = [],
|
|
445
|
+
): {
|
|
446
|
+
variants?: ResponseFieldVariant[];
|
|
447
|
+
variantType?: "oneOf" | "anyOf";
|
|
448
|
+
} {
|
|
449
|
+
const variantType = getSchemaVariantType(schema);
|
|
450
|
+
const variantSchemas =
|
|
451
|
+
variantType === "oneOf"
|
|
452
|
+
? schema?.oneOf || []
|
|
453
|
+
: variantType === "anyOf"
|
|
454
|
+
? schema?.anyOf || []
|
|
455
|
+
: [];
|
|
456
|
+
|
|
457
|
+
if (!variantType || variantSchemas.length === 0) return {};
|
|
458
|
+
|
|
459
|
+
const variants = variantSchemas
|
|
460
|
+
.map((variantSchema: any, index: number) => ({
|
|
461
|
+
label: `Variant ${index + 1}`,
|
|
462
|
+
fields: extractFieldsFromSchema(
|
|
463
|
+
variantSchema,
|
|
464
|
+
parentName,
|
|
465
|
+
Array.isArray(variantSchema?.required)
|
|
466
|
+
? variantSchema.required
|
|
467
|
+
: fallbackRequired,
|
|
468
|
+
),
|
|
469
|
+
}))
|
|
470
|
+
.filter((variant) => variant.fields.length > 0);
|
|
471
|
+
|
|
472
|
+
if (variants.length === 0) return {};
|
|
473
|
+
return { variants, variantType };
|
|
24
474
|
}
|
|
25
475
|
|
|
26
|
-
// Helper function to extract fields from a schema recursively
|
|
27
476
|
function extractFieldsFromSchema(
|
|
28
477
|
schema: any,
|
|
29
478
|
parentName: string = "",
|
|
30
|
-
required: string[] = []
|
|
479
|
+
required: string[] = [],
|
|
31
480
|
): ResponseField[] {
|
|
32
481
|
if (!schema) return [];
|
|
33
482
|
|
|
34
483
|
const fields: ResponseField[] = [];
|
|
484
|
+
const baseSchema = { ...schema };
|
|
485
|
+
delete baseSchema.oneOf;
|
|
486
|
+
delete baseSchema.anyOf;
|
|
35
487
|
|
|
36
488
|
// Handle allOf - merge properties and required arrays
|
|
37
|
-
let properties =
|
|
38
|
-
let schemaRequired =
|
|
489
|
+
let properties = baseSchema.properties || {};
|
|
490
|
+
let schemaRequired = Array.isArray(baseSchema.required)
|
|
491
|
+
? baseSchema.required
|
|
492
|
+
: [];
|
|
39
493
|
|
|
40
|
-
if (
|
|
41
|
-
|
|
494
|
+
if (Array.isArray(baseSchema.allOf)) {
|
|
495
|
+
baseSchema.allOf.forEach((s: any) => {
|
|
42
496
|
if (s.properties) {
|
|
43
497
|
properties = { ...properties, ...s.properties };
|
|
44
498
|
}
|
|
@@ -50,22 +504,37 @@ function extractFieldsFromSchema(
|
|
|
50
504
|
|
|
51
505
|
// Handle array types - extract fields from items
|
|
52
506
|
if (schema.type === "array" && schema.items) {
|
|
507
|
+
const itemSchema = schema.items;
|
|
508
|
+
const baseItemSchema = { ...itemSchema };
|
|
509
|
+
delete baseItemSchema.oneOf;
|
|
510
|
+
delete baseItemSchema.anyOf;
|
|
511
|
+
|
|
53
512
|
const itemFields = extractFieldsFromSchema(
|
|
54
|
-
|
|
513
|
+
baseItemSchema,
|
|
55
514
|
"",
|
|
56
|
-
|
|
515
|
+
Array.isArray(baseItemSchema.required) ? baseItemSchema.required : [],
|
|
57
516
|
);
|
|
58
|
-
|
|
517
|
+
const itemVariantData = extractVariantData(
|
|
518
|
+
itemSchema,
|
|
519
|
+
"",
|
|
520
|
+
Array.isArray(itemSchema?.required) ? itemSchema.required : [],
|
|
521
|
+
);
|
|
522
|
+
if (itemFields.length > 0 || itemVariantData.variants) {
|
|
59
523
|
fields.push({
|
|
60
524
|
name: parentName || "items",
|
|
61
525
|
required: required.includes(parentName) || false,
|
|
62
|
-
type:
|
|
526
|
+
type: getSchemaTypeLabel(schema),
|
|
63
527
|
description: schema.description || "",
|
|
64
|
-
|
|
528
|
+
...getSchemaStringLengthConstraints(schema),
|
|
529
|
+
...getSchemaNumericConstraints(schema),
|
|
530
|
+
nested: itemFields.length > 0 ? itemFields : undefined,
|
|
531
|
+
variants: itemVariantData.variants,
|
|
532
|
+
variantType: itemVariantData.variantType,
|
|
65
533
|
});
|
|
66
534
|
}
|
|
67
535
|
return fields;
|
|
68
536
|
}
|
|
537
|
+
|
|
69
538
|
// Extract object properties
|
|
70
539
|
if (properties && Object.keys(properties).length > 0) {
|
|
71
540
|
Object.entries(properties)
|
|
@@ -79,66 +548,126 @@ function extractFieldsFromSchema(
|
|
|
79
548
|
.forEach(([name, propSchema]: [string, any]) => {
|
|
80
549
|
const fullName = parentName ? `${parentName}.${name}` : name;
|
|
81
550
|
const isRequired = schemaRequired.includes(name);
|
|
551
|
+
const variantData = extractVariantData(
|
|
552
|
+
propSchema,
|
|
553
|
+
fullName,
|
|
554
|
+
Array.isArray(propSchema?.required) ? propSchema.required : [],
|
|
555
|
+
);
|
|
82
556
|
|
|
83
|
-
// Determine type
|
|
84
|
-
let type = propSchema.type || "object";
|
|
85
|
-
if (propSchema.format) {
|
|
86
|
-
type = `${type} (${propSchema.format})`;
|
|
87
|
-
} else if (propSchema.enum) {
|
|
88
|
-
type = `enum<${propSchema.type || "string"}>`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Handle nested objects
|
|
92
557
|
if (
|
|
93
558
|
propSchema.type === "object" ||
|
|
94
559
|
propSchema.properties ||
|
|
95
|
-
propSchema.allOf
|
|
560
|
+
propSchema.allOf ||
|
|
561
|
+
propSchema.oneOf ||
|
|
562
|
+
propSchema.anyOf
|
|
96
563
|
) {
|
|
564
|
+
const basePropSchema = { ...propSchema };
|
|
565
|
+
delete basePropSchema.oneOf;
|
|
566
|
+
delete basePropSchema.anyOf;
|
|
567
|
+
|
|
97
568
|
const nestedFields = extractFieldsFromSchema(
|
|
98
|
-
|
|
569
|
+
basePropSchema,
|
|
99
570
|
fullName,
|
|
100
|
-
|
|
571
|
+
Array.isArray(basePropSchema.required) ? basePropSchema.required : [],
|
|
101
572
|
);
|
|
102
573
|
fields.push({
|
|
103
574
|
name: fullName,
|
|
104
575
|
required: isRequired,
|
|
105
|
-
type:
|
|
576
|
+
type: getSchemaTypeLabel(propSchema),
|
|
106
577
|
description: propSchema.description || "",
|
|
578
|
+
...getSchemaStringLengthConstraints(propSchema),
|
|
579
|
+
...getSchemaNumericConstraints(propSchema),
|
|
107
580
|
nested: nestedFields.length > 0 ? nestedFields : undefined,
|
|
581
|
+
variants: variantData.variants,
|
|
582
|
+
variantType: variantData.variantType,
|
|
108
583
|
enum: propSchema.enum,
|
|
109
584
|
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
585
|
+
} else if (propSchema.type === "array" && propSchema.items) {
|
|
586
|
+
const itemSchema = propSchema.items;
|
|
587
|
+
const baseItemSchema = { ...itemSchema };
|
|
588
|
+
delete baseItemSchema.oneOf;
|
|
589
|
+
delete baseItemSchema.anyOf;
|
|
590
|
+
|
|
113
591
|
const itemFields = extractFieldsFromSchema(
|
|
114
|
-
|
|
592
|
+
baseItemSchema,
|
|
115
593
|
`${fullName}[]`,
|
|
116
|
-
|
|
594
|
+
Array.isArray(baseItemSchema.required) ? baseItemSchema.required : [],
|
|
595
|
+
);
|
|
596
|
+
const itemVariantData = extractVariantData(
|
|
597
|
+
itemSchema,
|
|
598
|
+
`${fullName}[]`,
|
|
599
|
+
Array.isArray(itemSchema?.required) ? itemSchema.required : [],
|
|
117
600
|
);
|
|
118
601
|
fields.push({
|
|
119
602
|
name: fullName,
|
|
120
603
|
required: isRequired,
|
|
121
|
-
type: propSchema
|
|
122
|
-
? `enum<${propSchema.items?.type || "object"}>[]`
|
|
123
|
-
: `${propSchema.items.type || "object"}[]`,
|
|
604
|
+
type: getSchemaTypeLabel(propSchema),
|
|
124
605
|
description: propSchema.description || "",
|
|
606
|
+
...getSchemaStringLengthConstraints(propSchema),
|
|
607
|
+
...getSchemaNumericConstraints(propSchema),
|
|
125
608
|
nested: itemFields.length > 0 ? itemFields : undefined,
|
|
126
|
-
|
|
609
|
+
variants: itemVariantData.variants,
|
|
610
|
+
variantType: itemVariantData.variantType,
|
|
611
|
+
enum: itemSchema?.enum,
|
|
127
612
|
});
|
|
128
|
-
}
|
|
129
|
-
// Handle primitive types
|
|
130
|
-
else {
|
|
613
|
+
} else {
|
|
131
614
|
fields.push({
|
|
132
615
|
name: fullName,
|
|
133
616
|
required: isRequired,
|
|
134
|
-
type:
|
|
617
|
+
type: getSchemaTypeLabel(propSchema),
|
|
135
618
|
description: propSchema.description || "",
|
|
619
|
+
...getSchemaStringLengthConstraints(propSchema),
|
|
620
|
+
...getSchemaNumericConstraints(propSchema),
|
|
136
621
|
enum: propSchema.enum,
|
|
137
622
|
});
|
|
138
623
|
}
|
|
139
624
|
});
|
|
140
625
|
}
|
|
141
626
|
|
|
627
|
+
const additionalProperties = getAdditionalPropertiesSchema(baseSchema);
|
|
628
|
+
const supportsAdditionalProperties =
|
|
629
|
+
additionalProperties === true ||
|
|
630
|
+
(additionalProperties &&
|
|
631
|
+
typeof additionalProperties === "object" &&
|
|
632
|
+
!Array.isArray(additionalProperties));
|
|
633
|
+
|
|
634
|
+
if (supportsAdditionalProperties) {
|
|
635
|
+
const additionalSchema =
|
|
636
|
+
additionalProperties && typeof additionalProperties === "object"
|
|
637
|
+
? additionalProperties
|
|
638
|
+
: null;
|
|
639
|
+
const mapFieldName = parentName
|
|
640
|
+
? `${parentName}.[key: string]`
|
|
641
|
+
: "[key: string]";
|
|
642
|
+
const additionalContent = additionalSchema
|
|
643
|
+
? extractFieldsFromSchema(
|
|
644
|
+
additionalSchema,
|
|
645
|
+
mapFieldName,
|
|
646
|
+
Array.isArray(additionalSchema?.required) ? additionalSchema.required : [],
|
|
647
|
+
)
|
|
648
|
+
: [];
|
|
649
|
+
const additionalVariantData = additionalSchema
|
|
650
|
+
? extractVariantData(
|
|
651
|
+
additionalSchema,
|
|
652
|
+
mapFieldName,
|
|
653
|
+
Array.isArray(additionalSchema?.required) ? additionalSchema.required : [],
|
|
654
|
+
)
|
|
655
|
+
: {};
|
|
656
|
+
|
|
657
|
+
fields.push({
|
|
658
|
+
name: mapFieldName,
|
|
659
|
+
required: false,
|
|
660
|
+
type: additionalSchema ? getSchemaTypeLabel(additionalSchema) : "any",
|
|
661
|
+
description: additionalSchema?.description || "",
|
|
662
|
+
...getSchemaStringLengthConstraints(additionalSchema),
|
|
663
|
+
...getSchemaNumericConstraints(additionalSchema),
|
|
664
|
+
nested: additionalContent.length > 0 ? additionalContent : undefined,
|
|
665
|
+
variants: additionalVariantData.variants,
|
|
666
|
+
variantType: additionalVariantData.variantType,
|
|
667
|
+
enum: additionalSchema ? getSchemaEnumValues(additionalSchema) : undefined,
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
142
671
|
return fields;
|
|
143
672
|
}
|
|
144
673
|
|
|
@@ -167,14 +696,49 @@ Object.entries(responses)
|
|
|
167
696
|
const mediaType = contentType ? response.content?.[contentType] : null;
|
|
168
697
|
const schema = mediaType?.schema;
|
|
169
698
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
699
|
+
let fields: ResponseField[] = [];
|
|
700
|
+
let variants: ResponseVariant[] | undefined;
|
|
701
|
+
let variantType: "oneOf" | "anyOf" | undefined;
|
|
702
|
+
|
|
703
|
+
if (schema) {
|
|
704
|
+
const hasOneOf = Array.isArray(schema.oneOf) && schema.oneOf.length > 0;
|
|
705
|
+
const hasAnyOf = Array.isArray(schema.anyOf) && schema.anyOf.length > 0;
|
|
706
|
+
|
|
707
|
+
if (hasOneOf || hasAnyOf) {
|
|
708
|
+
variantType = hasOneOf ? "oneOf" : "anyOf";
|
|
709
|
+
const variantSchemas: any[] = hasOneOf ? schema.oneOf : schema.anyOf;
|
|
710
|
+
|
|
711
|
+
const baseSchema = { ...schema };
|
|
712
|
+
delete baseSchema.oneOf;
|
|
713
|
+
delete baseSchema.anyOf;
|
|
714
|
+
|
|
715
|
+
fields = extractFieldsFromSchema(
|
|
716
|
+
baseSchema,
|
|
717
|
+
"",
|
|
718
|
+
baseSchema.required || [],
|
|
719
|
+
);
|
|
720
|
+
|
|
721
|
+
variants = variantSchemas
|
|
722
|
+
.map((variantSchema, index) => ({
|
|
723
|
+
label: `Variant ${index + 1}`,
|
|
724
|
+
fields: extractFieldsFromSchema(
|
|
725
|
+
variantSchema,
|
|
726
|
+
"",
|
|
727
|
+
variantSchema?.required || [],
|
|
728
|
+
),
|
|
729
|
+
}))
|
|
730
|
+
.filter((variant) => variant.fields.length > 0);
|
|
731
|
+
} else {
|
|
732
|
+
fields = extractFieldsFromSchema(schema, "", schema.required || []);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
173
735
|
|
|
174
736
|
responseFields.push({
|
|
175
737
|
statusCode,
|
|
176
738
|
description: response.description,
|
|
177
739
|
fields,
|
|
740
|
+
variants,
|
|
741
|
+
variantType,
|
|
178
742
|
});
|
|
179
743
|
});
|
|
180
744
|
---
|
|
@@ -184,40 +748,119 @@ Object.entries(responses)
|
|
|
184
748
|
{
|
|
185
749
|
responseFields.map((response) => (
|
|
186
750
|
<div class="mt-6">
|
|
187
|
-
<div class="flex items-
|
|
188
|
-
<
|
|
751
|
+
<div class="flex items-start gap-2 mb-4">
|
|
752
|
+
<div class="mt-1.5 flex items-center gap-1.5">
|
|
753
|
+
<span
|
|
754
|
+
class:list={[
|
|
755
|
+
"size-[7px] shrink-0 rounded-full",
|
|
756
|
+
getStatusCodeDotClass(response.statusCode),
|
|
757
|
+
]}
|
|
758
|
+
/>
|
|
759
|
+
<h5 class="text-lg font-medium leading-none">
|
|
760
|
+
{response.statusCode}
|
|
761
|
+
</h5>
|
|
762
|
+
</div>
|
|
189
763
|
{response.description && (
|
|
190
|
-
<span class="text-sm text-neutral-
|
|
764
|
+
<span class="mt-1 text-sm text-neutral-500">
|
|
765
|
+
{response.description}
|
|
766
|
+
</span>
|
|
191
767
|
)}
|
|
192
768
|
</div>
|
|
193
|
-
{response.fields.length > 0
|
|
194
|
-
|
|
195
|
-
{response.
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
769
|
+
{response.fields.length > 0 && (
|
|
770
|
+
<>
|
|
771
|
+
{response.variants && response.variants.length > 0 && (
|
|
772
|
+
<p class="mb-2 text-xs text-neutral-500">Common fields</p>
|
|
773
|
+
)}
|
|
774
|
+
<div x-data="{ expanded: false }">
|
|
775
|
+
<div
|
|
776
|
+
class="w-full overflow-hidden rounded-xl border border-neutral-200 bg-white transition-colors duration-200"
|
|
777
|
+
x-bind:class="expanded ? 'border-neutral-300' : 'border-neutral-200'"
|
|
778
|
+
>
|
|
779
|
+
<button
|
|
780
|
+
type="button"
|
|
781
|
+
x-on:click="expanded = !expanded"
|
|
782
|
+
x-bind:aria-expanded="expanded"
|
|
783
|
+
class="group flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm font-medium text-neutral-700 hover:bg-neutral-50 cursor-pointer transition-colors duration-200"
|
|
784
|
+
>
|
|
785
|
+
<span class="inline-flex items-center gap-2">
|
|
786
|
+
<ListChevronsToggle class="size-4 shrink-0 text-neutral-500 group-hover:text-neutral-600 transition duration-200" />
|
|
787
|
+
<span>
|
|
788
|
+
{response.fields.length}{" "}
|
|
789
|
+
{response.fields.length === 1
|
|
790
|
+
? "field"
|
|
791
|
+
: "fields"}
|
|
792
|
+
</span>
|
|
793
|
+
</span>
|
|
794
|
+
</button>
|
|
795
|
+
<div x-show="expanded" x-collapse x-cloak>
|
|
796
|
+
<div class="border-t border-neutral-100 p-3">
|
|
797
|
+
<ResponseFieldTree fields={response.fields} />
|
|
213
798
|
</div>
|
|
214
|
-
|
|
799
|
+
</div>
|
|
215
800
|
</div>
|
|
801
|
+
</div>
|
|
802
|
+
</>
|
|
803
|
+
)}
|
|
804
|
+
{response.variants && response.variants.length > 0 && (
|
|
805
|
+
<div class="mt-3 space-y-2">
|
|
806
|
+
<p class="text-xs text-neutral-500">
|
|
807
|
+
{response.variantType === "anyOf"
|
|
808
|
+
? "One or more response variants may apply."
|
|
809
|
+
: "Returns one of these response variants."}
|
|
810
|
+
</p>
|
|
811
|
+
{response.variants.map((variant, index) => (
|
|
812
|
+
<>
|
|
813
|
+
<div class="rounded-xl border border-neutral-200 bg-white p-3">
|
|
814
|
+
<div class="mb-2 text-xs font-medium text-neutral-600">
|
|
815
|
+
{variant.label}
|
|
816
|
+
</div>
|
|
817
|
+
<div x-data="{ expanded: false }">
|
|
818
|
+
<div
|
|
819
|
+
class="w-full overflow-hidden rounded-lg border border-neutral-200 bg-white transition-colors duration-200"
|
|
820
|
+
x-bind:class="expanded ? 'border-neutral-300' : 'border-neutral-200'"
|
|
821
|
+
>
|
|
822
|
+
<button
|
|
823
|
+
type="button"
|
|
824
|
+
x-on:click="expanded = !expanded"
|
|
825
|
+
x-bind:aria-expanded="expanded"
|
|
826
|
+
class="group flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-xs font-medium text-neutral-700 hover:bg-neutral-50 cursor-pointer transition-colors duration-200"
|
|
827
|
+
>
|
|
828
|
+
<span class="inline-flex items-center gap-2">
|
|
829
|
+
<ListChevronsToggle class="size-4 shrink-0 text-neutral-400 group-hover:text-neutral-600 transition duration-200" />
|
|
830
|
+
<span>
|
|
831
|
+
{variant.fields.length}{" "}
|
|
832
|
+
{variant.fields.length === 1
|
|
833
|
+
? "field"
|
|
834
|
+
: "fields"}
|
|
835
|
+
</span>
|
|
836
|
+
</span>
|
|
837
|
+
</button>
|
|
838
|
+
<div x-show="expanded" x-collapse x-cloak>
|
|
839
|
+
<div class="border-t border-neutral-100 px-3 py-3">
|
|
840
|
+
<ResponseFieldTree fields={variant.fields} />
|
|
841
|
+
</div>
|
|
842
|
+
</div>
|
|
843
|
+
</div>
|
|
844
|
+
</div>
|
|
845
|
+
</div>
|
|
846
|
+
{response.variantType === "oneOf" &&
|
|
847
|
+
index < response.variants.length - 1 && (
|
|
848
|
+
<div class="flex items-center gap-2 py-0">
|
|
849
|
+
<div class="h-px flex-1 bg-neutral-200" />
|
|
850
|
+
<span class="px-1 text-[10px] uppercase tracking-wide text-neutral-500">
|
|
851
|
+
OR
|
|
852
|
+
</span>
|
|
853
|
+
<div class="h-px flex-1 bg-neutral-200" />
|
|
854
|
+
</div>
|
|
855
|
+
)}
|
|
856
|
+
</>
|
|
216
857
|
))}
|
|
217
858
|
</div>
|
|
218
|
-
) : (
|
|
219
|
-
<p class="text-sm text-neutral-500 ml-2">No response body fields</p>
|
|
220
859
|
)}
|
|
860
|
+
{response.fields.length === 0 &&
|
|
861
|
+
(!response.variants || response.variants.length === 0) ? (
|
|
862
|
+
<p class="text-sm text-neutral-500 ml-2">No response body fields</p>
|
|
863
|
+
) : null}
|
|
221
864
|
</div>
|
|
222
865
|
))
|
|
223
866
|
}
|