docusaurus-theme-openapi-docs 0.0.0-1097 → 0.0.0-1099
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/lib/theme/ApiExplorer/Body/index.js +205 -150
- package/lib/theme/ApiExplorer/Body/resolveSchemaWithSelections.d.ts +13 -0
- package/lib/theme/ApiExplorer/Body/resolveSchemaWithSelections.js +133 -0
- package/lib/theme/ApiExplorer/SchemaSelection/index.d.ts +2 -0
- package/lib/theme/ApiExplorer/SchemaSelection/index.js +36 -0
- package/lib/theme/ApiExplorer/SchemaSelection/slice.d.ts +37 -0
- package/lib/theme/ApiExplorer/SchemaSelection/slice.js +39 -0
- package/lib/theme/ApiExplorer/persistenceMiddleware.d.ts +2 -0
- package/lib/theme/ApiItem/hooks.d.ts +1 -0
- package/lib/theme/ApiItem/index.js +1 -0
- package/lib/theme/ApiItem/store.d.ts +6 -0
- package/lib/theme/ApiItem/store.js +6 -2
- package/lib/theme/RequestSchema/index.js +2 -0
- package/lib/theme/Schema/index.d.ts +6 -0
- package/lib/theme/Schema/index.js +130 -9
- package/lib/theme/SchemaTabs/index.d.ts +8 -1
- package/lib/theme/SchemaTabs/index.js +10 -1
- package/lib/theme/styles.scss +10 -0
- package/package.json +3 -3
- package/src/theme/ApiExplorer/Body/index.tsx +205 -145
- package/src/theme/ApiExplorer/Body/resolveSchemaWithSelections.ts +155 -0
- package/src/theme/ApiExplorer/SchemaSelection/index.ts +13 -0
- package/src/theme/ApiExplorer/SchemaSelection/slice.ts +46 -0
- package/src/theme/ApiItem/index.tsx +1 -0
- package/src/theme/ApiItem/store.ts +2 -0
- package/src/theme/RequestSchema/index.tsx +10 -2
- package/src/theme/Schema/index.tsx +179 -27
- package/src/theme/SchemaTabs/index.tsx +15 -4
- package/src/theme/styles.scss +10 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -84,6 +84,7 @@ const createSchemaExample_1 = require("docusaurus-plugin-openapi-docs/src/openap
|
|
|
84
84
|
const xml_formatter_1 = __importDefault(require("xml-formatter"));
|
|
85
85
|
const slice_1 = require("./slice");
|
|
86
86
|
const FormBodyItem_1 = __importDefault(require("./FormBodyItem"));
|
|
87
|
+
const resolveSchemaWithSelections_1 = require("./resolveSchemaWithSelections");
|
|
87
88
|
function BodyWrap({
|
|
88
89
|
requestBodyMetadata,
|
|
89
90
|
jsonRequestBodyExample,
|
|
@@ -114,6 +115,9 @@ function Body({
|
|
|
114
115
|
const contentType = (0, hooks_1.useTypedSelector)(
|
|
115
116
|
(state) => state.contentType.value
|
|
116
117
|
);
|
|
118
|
+
const schemaSelections = (0, hooks_1.useTypedSelector)(
|
|
119
|
+
(state) => state.schemaSelection?.selections ?? {}
|
|
120
|
+
);
|
|
117
121
|
const dispatch = (0, hooks_1.useTypedDispatch)();
|
|
118
122
|
// Lot's of possible content-types:
|
|
119
123
|
// - application/json
|
|
@@ -133,11 +137,200 @@ function Body({
|
|
|
133
137
|
// Show form:
|
|
134
138
|
// - multipart/form-data
|
|
135
139
|
// - application/x-www-form-urlencoded
|
|
136
|
-
const
|
|
140
|
+
const rawSchema = requestBodyMetadata?.content?.[contentType]?.schema;
|
|
137
141
|
const example = requestBodyMetadata?.content?.[contentType]?.example;
|
|
138
142
|
const examples = requestBodyMetadata?.content?.[contentType]?.examples;
|
|
143
|
+
// Resolve the schema based on user's anyOf/oneOf tab selections
|
|
144
|
+
const schema = (0, react_1.useMemo)(() => {
|
|
145
|
+
if (!rawSchema) return rawSchema;
|
|
146
|
+
return (0, resolveSchemaWithSelections_1.resolveSchemaWithSelections)(
|
|
147
|
+
rawSchema,
|
|
148
|
+
schemaSelections,
|
|
149
|
+
"requestBody"
|
|
150
|
+
);
|
|
151
|
+
}, [rawSchema, schemaSelections]);
|
|
139
152
|
// OpenAPI 3.1 / JSON Schema: schema.examples is an array of example values
|
|
140
153
|
const schemaExamples = schema?.examples;
|
|
154
|
+
// Compute the default body based on content type and schema
|
|
155
|
+
// This needs to be computed before early returns so the useEffect can use it
|
|
156
|
+
const { defaultBody, exampleBody, examplesBodies, language } = (0,
|
|
157
|
+
react_1.useMemo)(() => {
|
|
158
|
+
let lang = "plaintext";
|
|
159
|
+
let defBody = "";
|
|
160
|
+
let exBody;
|
|
161
|
+
let exBodies = [];
|
|
162
|
+
// Skip body generation for binary and form content types
|
|
163
|
+
if (schema?.format === "binary") {
|
|
164
|
+
return {
|
|
165
|
+
defaultBody: defBody,
|
|
166
|
+
exampleBody: exBody,
|
|
167
|
+
examplesBodies: exBodies,
|
|
168
|
+
language: lang,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (
|
|
172
|
+
(contentType === "multipart/form-data" ||
|
|
173
|
+
contentType === "application/x-www-form-urlencoded") &&
|
|
174
|
+
schema?.type === "object"
|
|
175
|
+
) {
|
|
176
|
+
return {
|
|
177
|
+
defaultBody: defBody,
|
|
178
|
+
exampleBody: exBody,
|
|
179
|
+
examplesBodies: exBodies,
|
|
180
|
+
language: lang,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// Generate example from the schema for the current content type
|
|
184
|
+
let contentTypeExample;
|
|
185
|
+
if (schema) {
|
|
186
|
+
contentTypeExample = (0, createSchemaExample_1.sampleFromSchema)(schema, {
|
|
187
|
+
type: "request",
|
|
188
|
+
});
|
|
189
|
+
} else if (jsonRequestBodyExample) {
|
|
190
|
+
// Fallback to the build-time generated example if no schema is available
|
|
191
|
+
contentTypeExample = jsonRequestBodyExample;
|
|
192
|
+
}
|
|
193
|
+
if (
|
|
194
|
+
contentType?.includes("application/json") ||
|
|
195
|
+
contentType?.endsWith("+json")
|
|
196
|
+
) {
|
|
197
|
+
if (contentTypeExample) {
|
|
198
|
+
defBody = JSON.stringify(contentTypeExample, null, 2);
|
|
199
|
+
}
|
|
200
|
+
if (example) {
|
|
201
|
+
exBody = JSON.stringify(example, null, 2);
|
|
202
|
+
}
|
|
203
|
+
if (examples) {
|
|
204
|
+
for (const [key, ex] of Object.entries(examples)) {
|
|
205
|
+
let body = ex.value;
|
|
206
|
+
try {
|
|
207
|
+
// If the value is already valid JSON we shouldn't double encode the value
|
|
208
|
+
JSON.parse(ex.value);
|
|
209
|
+
} catch (e) {
|
|
210
|
+
body = JSON.stringify(ex.value, null, 2);
|
|
211
|
+
}
|
|
212
|
+
exBodies.push({
|
|
213
|
+
label: key,
|
|
214
|
+
body,
|
|
215
|
+
summary: ex.summary,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// OpenAPI 3.1: schema.examples is an array of example values
|
|
220
|
+
if (schemaExamples && Array.isArray(schemaExamples)) {
|
|
221
|
+
schemaExamples.forEach((schemaExample, index) => {
|
|
222
|
+
const body = JSON.stringify(schemaExample, null, 2);
|
|
223
|
+
exBodies.push({
|
|
224
|
+
label: `Example ${index + 1}`,
|
|
225
|
+
body,
|
|
226
|
+
summary: undefined,
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
lang = "json";
|
|
231
|
+
}
|
|
232
|
+
if (contentType === "application/xml" || contentType?.endsWith("+xml")) {
|
|
233
|
+
if (contentTypeExample) {
|
|
234
|
+
try {
|
|
235
|
+
defBody = (0, xml_formatter_1.default)(
|
|
236
|
+
(0, json2xml_1.default)(contentTypeExample, ""),
|
|
237
|
+
{
|
|
238
|
+
indentation: " ",
|
|
239
|
+
lineSeparator: "\n",
|
|
240
|
+
collapseContent: true,
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
} catch {
|
|
244
|
+
defBody = (0, json2xml_1.default)(contentTypeExample);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (example) {
|
|
248
|
+
try {
|
|
249
|
+
exBody = (0, xml_formatter_1.default)(
|
|
250
|
+
(0, json2xml_1.default)(example, ""),
|
|
251
|
+
{
|
|
252
|
+
indentation: " ",
|
|
253
|
+
lineSeparator: "\n",
|
|
254
|
+
collapseContent: true,
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
} catch {
|
|
258
|
+
exBody = (0, json2xml_1.default)(example);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (examples) {
|
|
262
|
+
for (const [key, ex] of Object.entries(examples)) {
|
|
263
|
+
let formattedXmlBody;
|
|
264
|
+
try {
|
|
265
|
+
formattedXmlBody = (0, xml_formatter_1.default)(ex.value, {
|
|
266
|
+
indentation: " ",
|
|
267
|
+
lineSeparator: "\n",
|
|
268
|
+
collapseContent: true,
|
|
269
|
+
});
|
|
270
|
+
} catch {
|
|
271
|
+
formattedXmlBody = ex.value;
|
|
272
|
+
}
|
|
273
|
+
exBodies.push({
|
|
274
|
+
label: key,
|
|
275
|
+
body: formattedXmlBody,
|
|
276
|
+
summary: ex.summary,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// OpenAPI 3.1: schema.examples is an array of example values
|
|
281
|
+
if (schemaExamples && Array.isArray(schemaExamples)) {
|
|
282
|
+
schemaExamples.forEach((schemaExample, index) => {
|
|
283
|
+
let formattedXmlBody;
|
|
284
|
+
try {
|
|
285
|
+
formattedXmlBody = (0, xml_formatter_1.default)(
|
|
286
|
+
(0, json2xml_1.default)(schemaExample, ""),
|
|
287
|
+
{
|
|
288
|
+
indentation: " ",
|
|
289
|
+
lineSeparator: "\n",
|
|
290
|
+
collapseContent: true,
|
|
291
|
+
}
|
|
292
|
+
);
|
|
293
|
+
} catch {
|
|
294
|
+
formattedXmlBody = (0, json2xml_1.default)(schemaExample);
|
|
295
|
+
}
|
|
296
|
+
exBodies.push({
|
|
297
|
+
label: `Example ${index + 1}`,
|
|
298
|
+
body: formattedXmlBody,
|
|
299
|
+
summary: undefined,
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
lang = "xml";
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
defaultBody: defBody,
|
|
307
|
+
exampleBody: exBody,
|
|
308
|
+
examplesBodies: exBodies,
|
|
309
|
+
language: lang,
|
|
310
|
+
};
|
|
311
|
+
}, [
|
|
312
|
+
schema,
|
|
313
|
+
contentType,
|
|
314
|
+
example,
|
|
315
|
+
examples,
|
|
316
|
+
schemaExamples,
|
|
317
|
+
jsonRequestBodyExample,
|
|
318
|
+
]);
|
|
319
|
+
// Create a stable key for the LiveApp component that changes when schema selection changes
|
|
320
|
+
// This forces the editor to remount and pick up the new defaultBody
|
|
321
|
+
const schemaSelectionKey = (0, react_1.useMemo)(
|
|
322
|
+
() => JSON.stringify(schemaSelections),
|
|
323
|
+
[schemaSelections]
|
|
324
|
+
);
|
|
325
|
+
// Update body in Redux when content type or schema selection changes
|
|
326
|
+
(0, react_1.useEffect)(() => {
|
|
327
|
+
if (defaultBody) {
|
|
328
|
+
dispatch((0, slice_1.setStringRawBody)(defaultBody));
|
|
329
|
+
}
|
|
330
|
+
// Re-run when contentType, schemaSelections, or defaultBody change
|
|
331
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
332
|
+
}, [contentType, schemaSelections, defaultBody]);
|
|
333
|
+
// Now handle early returns after all hooks have been called
|
|
141
334
|
if (schema?.format === "binary") {
|
|
142
335
|
return react_1.default.createElement(
|
|
143
336
|
FormItem_1.default,
|
|
@@ -190,140 +383,6 @@ function Body({
|
|
|
190
383
|
})
|
|
191
384
|
);
|
|
192
385
|
}
|
|
193
|
-
let language = "plaintext";
|
|
194
|
-
let defaultBody = ""; //"body content";
|
|
195
|
-
let exampleBody;
|
|
196
|
-
let examplesBodies = [];
|
|
197
|
-
// Generate example from the schema for the current content type
|
|
198
|
-
let contentTypeExample;
|
|
199
|
-
if (schema) {
|
|
200
|
-
contentTypeExample = (0, createSchemaExample_1.sampleFromSchema)(schema, {
|
|
201
|
-
type: "request",
|
|
202
|
-
});
|
|
203
|
-
} else if (jsonRequestBodyExample) {
|
|
204
|
-
// Fallback to the build-time generated example if no schema is available
|
|
205
|
-
contentTypeExample = jsonRequestBodyExample;
|
|
206
|
-
}
|
|
207
|
-
if (
|
|
208
|
-
contentType.includes("application/json") ||
|
|
209
|
-
contentType.endsWith("+json")
|
|
210
|
-
) {
|
|
211
|
-
if (contentTypeExample) {
|
|
212
|
-
defaultBody = JSON.stringify(contentTypeExample, null, 2);
|
|
213
|
-
}
|
|
214
|
-
if (example) {
|
|
215
|
-
exampleBody = JSON.stringify(example, null, 2);
|
|
216
|
-
}
|
|
217
|
-
if (examples) {
|
|
218
|
-
for (const [key, example] of Object.entries(examples)) {
|
|
219
|
-
let body = example.value;
|
|
220
|
-
try {
|
|
221
|
-
// If the value is already valid JSON we shouldn't double encode the value
|
|
222
|
-
JSON.parse(example.value);
|
|
223
|
-
} catch (e) {
|
|
224
|
-
body = JSON.stringify(example.value, null, 2);
|
|
225
|
-
}
|
|
226
|
-
examplesBodies.push({
|
|
227
|
-
label: key,
|
|
228
|
-
body,
|
|
229
|
-
summary: example.summary,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
// OpenAPI 3.1: schema.examples is an array of example values
|
|
234
|
-
if (schemaExamples && Array.isArray(schemaExamples)) {
|
|
235
|
-
schemaExamples.forEach((schemaExample, index) => {
|
|
236
|
-
const body = JSON.stringify(schemaExample, null, 2);
|
|
237
|
-
examplesBodies.push({
|
|
238
|
-
label: `Example ${index + 1}`,
|
|
239
|
-
body,
|
|
240
|
-
summary: undefined,
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
language = "json";
|
|
245
|
-
}
|
|
246
|
-
if (contentType === "application/xml" || contentType.endsWith("+xml")) {
|
|
247
|
-
if (contentTypeExample) {
|
|
248
|
-
try {
|
|
249
|
-
defaultBody = (0, xml_formatter_1.default)(
|
|
250
|
-
(0, json2xml_1.default)(contentTypeExample, ""),
|
|
251
|
-
{
|
|
252
|
-
indentation: " ",
|
|
253
|
-
lineSeparator: "\n",
|
|
254
|
-
collapseContent: true,
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
} catch {
|
|
258
|
-
defaultBody = (0, json2xml_1.default)(contentTypeExample);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (example) {
|
|
262
|
-
try {
|
|
263
|
-
exampleBody = (0, xml_formatter_1.default)(
|
|
264
|
-
(0, json2xml_1.default)(example, ""),
|
|
265
|
-
{
|
|
266
|
-
indentation: " ",
|
|
267
|
-
lineSeparator: "\n",
|
|
268
|
-
collapseContent: true,
|
|
269
|
-
}
|
|
270
|
-
);
|
|
271
|
-
} catch {
|
|
272
|
-
exampleBody = (0, json2xml_1.default)(example);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
if (examples) {
|
|
276
|
-
for (const [key, example] of Object.entries(examples)) {
|
|
277
|
-
let formattedXmlBody;
|
|
278
|
-
try {
|
|
279
|
-
formattedXmlBody = (0, xml_formatter_1.default)(example.value, {
|
|
280
|
-
indentation: " ",
|
|
281
|
-
lineSeparator: "\n",
|
|
282
|
-
collapseContent: true,
|
|
283
|
-
});
|
|
284
|
-
} catch {
|
|
285
|
-
formattedXmlBody = example.value;
|
|
286
|
-
}
|
|
287
|
-
examplesBodies.push({
|
|
288
|
-
label: key,
|
|
289
|
-
body: formattedXmlBody,
|
|
290
|
-
summary: example.summary,
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
// OpenAPI 3.1: schema.examples is an array of example values
|
|
295
|
-
if (schemaExamples && Array.isArray(schemaExamples)) {
|
|
296
|
-
schemaExamples.forEach((schemaExample, index) => {
|
|
297
|
-
let formattedXmlBody;
|
|
298
|
-
try {
|
|
299
|
-
formattedXmlBody = (0, xml_formatter_1.default)(
|
|
300
|
-
(0, json2xml_1.default)(schemaExample, ""),
|
|
301
|
-
{
|
|
302
|
-
indentation: " ",
|
|
303
|
-
lineSeparator: "\n",
|
|
304
|
-
collapseContent: true,
|
|
305
|
-
}
|
|
306
|
-
);
|
|
307
|
-
} catch {
|
|
308
|
-
formattedXmlBody = (0, json2xml_1.default)(schemaExample);
|
|
309
|
-
}
|
|
310
|
-
examplesBodies.push({
|
|
311
|
-
label: `Example ${index + 1}`,
|
|
312
|
-
body: formattedXmlBody,
|
|
313
|
-
summary: undefined,
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
language = "xml";
|
|
318
|
-
}
|
|
319
|
-
// Update body in Redux when content type changes
|
|
320
|
-
(0, react_1.useEffect)(() => {
|
|
321
|
-
if (defaultBody) {
|
|
322
|
-
dispatch((0, slice_1.setStringRawBody)(defaultBody));
|
|
323
|
-
}
|
|
324
|
-
// Only re-run when contentType changes, not when defaultBody changes
|
|
325
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
326
|
-
}, [contentType]);
|
|
327
386
|
if (exampleBody) {
|
|
328
387
|
return react_1.default.createElement(
|
|
329
388
|
FormItem_1.default,
|
|
@@ -344,7 +403,7 @@ function Body({
|
|
|
344
403
|
react_1.default.createElement(
|
|
345
404
|
LiveEditor_1.default,
|
|
346
405
|
{
|
|
347
|
-
key: contentType
|
|
406
|
+
key: `${contentType}-${schemaSelectionKey}`,
|
|
348
407
|
action: (code) => dispatch((0, slice_1.setStringRawBody)(code)),
|
|
349
408
|
language: language,
|
|
350
409
|
required: required,
|
|
@@ -365,7 +424,7 @@ function Body({
|
|
|
365
424
|
react_1.default.createElement(
|
|
366
425
|
LiveEditor_1.default,
|
|
367
426
|
{
|
|
368
|
-
key: contentType
|
|
427
|
+
key: `${contentType}-example`,
|
|
369
428
|
action: (code) => dispatch((0, slice_1.setStringRawBody)(code)),
|
|
370
429
|
language: language,
|
|
371
430
|
required: required,
|
|
@@ -396,7 +455,7 @@ function Body({
|
|
|
396
455
|
react_1.default.createElement(
|
|
397
456
|
LiveEditor_1.default,
|
|
398
457
|
{
|
|
399
|
-
key: contentType
|
|
458
|
+
key: `${contentType}-${schemaSelectionKey}`,
|
|
400
459
|
action: (code) => dispatch((0, slice_1.setStringRawBody)(code)),
|
|
401
460
|
language: language,
|
|
402
461
|
required: required,
|
|
@@ -404,32 +463,28 @@ function Body({
|
|
|
404
463
|
defaultBody
|
|
405
464
|
)
|
|
406
465
|
),
|
|
407
|
-
examplesBodies.map((
|
|
466
|
+
examplesBodies.map((ex) => {
|
|
408
467
|
return (
|
|
409
468
|
// @ts-ignore
|
|
410
469
|
react_1.default.createElement(
|
|
411
470
|
TabItem_1.default,
|
|
412
|
-
{
|
|
413
|
-
|
|
414
|
-
value: example.label,
|
|
415
|
-
key: example.label,
|
|
416
|
-
},
|
|
417
|
-
example.summary &&
|
|
471
|
+
{ label: ex.label, value: ex.label, key: ex.label },
|
|
472
|
+
ex.summary &&
|
|
418
473
|
react_1.default.createElement(
|
|
419
474
|
Markdown_1.default,
|
|
420
475
|
null,
|
|
421
|
-
|
|
476
|
+
ex.summary
|
|
422
477
|
),
|
|
423
|
-
|
|
478
|
+
ex.body &&
|
|
424
479
|
react_1.default.createElement(
|
|
425
480
|
LiveEditor_1.default,
|
|
426
481
|
{
|
|
427
|
-
key: `${contentType}-${
|
|
482
|
+
key: `${contentType}-${ex.label}`,
|
|
428
483
|
action: (code) =>
|
|
429
484
|
dispatch((0, slice_1.setStringRawBody)(code)),
|
|
430
485
|
language: language,
|
|
431
486
|
},
|
|
432
|
-
|
|
487
|
+
ex.body
|
|
433
488
|
)
|
|
434
489
|
)
|
|
435
490
|
);
|
|
@@ -443,7 +498,7 @@ function Body({
|
|
|
443
498
|
react_1.default.createElement(
|
|
444
499
|
LiveEditor_1.default,
|
|
445
500
|
{
|
|
446
|
-
key: contentType
|
|
501
|
+
key: `${contentType}-${schemaSelectionKey}`,
|
|
447
502
|
action: (code) => dispatch((0, slice_1.setStringRawBody)(code)),
|
|
448
503
|
language: language,
|
|
449
504
|
required: required,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/types";
|
|
2
|
+
export interface SchemaSelections {
|
|
3
|
+
[schemaPath: string]: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Resolves a schema by replacing anyOf/oneOf with the selected option based on user selections.
|
|
7
|
+
*
|
|
8
|
+
* @param schema - The original schema object
|
|
9
|
+
* @param selections - Map of schema paths to selected indices
|
|
10
|
+
* @param basePath - The base path for this schema (used for looking up selections)
|
|
11
|
+
* @returns A new schema with anyOf/oneOf resolved to selected options
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveSchemaWithSelections(schema: SchemaObject | undefined, selections: SchemaSelections, basePath?: string): SchemaObject | undefined;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ============================================================================
|
|
3
|
+
* Copyright (c) Palo Alto Networks
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
* ========================================================================== */
|
|
8
|
+
var __importDefault =
|
|
9
|
+
(this && this.__importDefault) ||
|
|
10
|
+
function (mod) {
|
|
11
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.resolveSchemaWithSelections = resolveSchemaWithSelections;
|
|
15
|
+
const merge_1 = __importDefault(require("lodash/merge"));
|
|
16
|
+
/**
|
|
17
|
+
* Resolves a schema by replacing anyOf/oneOf with the selected option based on user selections.
|
|
18
|
+
*
|
|
19
|
+
* @param schema - The original schema object
|
|
20
|
+
* @param selections - Map of schema paths to selected indices
|
|
21
|
+
* @param basePath - The base path for this schema (used for looking up selections)
|
|
22
|
+
* @returns A new schema with anyOf/oneOf resolved to selected options
|
|
23
|
+
*/
|
|
24
|
+
function resolveSchemaWithSelections(
|
|
25
|
+
schema,
|
|
26
|
+
selections,
|
|
27
|
+
basePath = "requestBody"
|
|
28
|
+
) {
|
|
29
|
+
if (!schema) {
|
|
30
|
+
return schema;
|
|
31
|
+
}
|
|
32
|
+
// Deep clone to avoid mutating the original schema
|
|
33
|
+
const schemaCopy = JSON.parse(JSON.stringify(schema));
|
|
34
|
+
return resolveSchemaRecursive(schemaCopy, selections, basePath);
|
|
35
|
+
}
|
|
36
|
+
function resolveSchemaRecursive(schema, selections, currentPath) {
|
|
37
|
+
// Handle oneOf
|
|
38
|
+
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
39
|
+
const selectedIndex = selections[currentPath] ?? 0;
|
|
40
|
+
const selectedSchema = schema.oneOf[selectedIndex];
|
|
41
|
+
if (selectedSchema) {
|
|
42
|
+
// If there are shared properties, merge them with the selected schema
|
|
43
|
+
if (schema.properties) {
|
|
44
|
+
const mergedSchema = (0, merge_1.default)({}, schema, selectedSchema);
|
|
45
|
+
delete mergedSchema.oneOf;
|
|
46
|
+
// Continue resolving nested schemas in the merged result
|
|
47
|
+
return resolveSchemaRecursive(
|
|
48
|
+
mergedSchema,
|
|
49
|
+
selections,
|
|
50
|
+
`${currentPath}.${selectedIndex}`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
// No shared properties, just use the selected schema
|
|
54
|
+
// Continue resolving in case there are nested anyOf/oneOf
|
|
55
|
+
return resolveSchemaRecursive(
|
|
56
|
+
selectedSchema,
|
|
57
|
+
selections,
|
|
58
|
+
`${currentPath}.${selectedIndex}`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Handle anyOf
|
|
63
|
+
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
64
|
+
const selectedIndex = selections[currentPath] ?? 0;
|
|
65
|
+
const selectedSchema = schema.anyOf[selectedIndex];
|
|
66
|
+
if (selectedSchema) {
|
|
67
|
+
// If there are shared properties, merge them with the selected schema
|
|
68
|
+
if (schema.properties) {
|
|
69
|
+
const mergedSchema = (0, merge_1.default)({}, schema, selectedSchema);
|
|
70
|
+
delete mergedSchema.anyOf;
|
|
71
|
+
// Continue resolving nested schemas in the merged result
|
|
72
|
+
return resolveSchemaRecursive(
|
|
73
|
+
mergedSchema,
|
|
74
|
+
selections,
|
|
75
|
+
`${currentPath}.${selectedIndex}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
// No shared properties, just use the selected schema
|
|
79
|
+
// Continue resolving in case there are nested anyOf/oneOf
|
|
80
|
+
return resolveSchemaRecursive(
|
|
81
|
+
selectedSchema,
|
|
82
|
+
selections,
|
|
83
|
+
`${currentPath}.${selectedIndex}`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Handle allOf - merge all schemas and continue resolving
|
|
88
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
89
|
+
// Process each allOf item, resolving any anyOf/oneOf within them
|
|
90
|
+
const resolvedItems = schema.allOf.map((item, index) => {
|
|
91
|
+
return resolveSchemaRecursive(
|
|
92
|
+
item,
|
|
93
|
+
selections,
|
|
94
|
+
`${currentPath}.allOf.${index}`
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
// Merge all resolved items
|
|
98
|
+
const mergedSchema = resolvedItems.reduce(
|
|
99
|
+
(acc, item) => (0, merge_1.default)(acc, item),
|
|
100
|
+
{}
|
|
101
|
+
);
|
|
102
|
+
// Preserve any top-level properties from the original schema
|
|
103
|
+
if (schema.properties) {
|
|
104
|
+
mergedSchema.properties = (0, merge_1.default)(
|
|
105
|
+
{},
|
|
106
|
+
mergedSchema.properties,
|
|
107
|
+
schema.properties
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return mergedSchema;
|
|
111
|
+
}
|
|
112
|
+
// Handle object properties recursively
|
|
113
|
+
if (schema.properties) {
|
|
114
|
+
const resolvedProperties = {};
|
|
115
|
+
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
116
|
+
resolvedProperties[propName] = resolveSchemaRecursive(
|
|
117
|
+
propSchema,
|
|
118
|
+
selections,
|
|
119
|
+
`${currentPath}.${propName}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
schema.properties = resolvedProperties;
|
|
123
|
+
}
|
|
124
|
+
// Handle array items recursively
|
|
125
|
+
if (schema.items) {
|
|
126
|
+
schema.items = resolveSchemaRecursive(
|
|
127
|
+
schema.items,
|
|
128
|
+
selections,
|
|
129
|
+
`${currentPath}.items`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
return schema;
|
|
133
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ============================================================================
|
|
3
|
+
* Copyright (c) Palo Alto Networks
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
* ========================================================================== */
|
|
8
|
+
var __importDefault =
|
|
9
|
+
(this && this.__importDefault) ||
|
|
10
|
+
function (mod) {
|
|
11
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.clearSchemaSelections =
|
|
15
|
+
exports.setSchemaSelection =
|
|
16
|
+
exports.schemaSelectionReducer =
|
|
17
|
+
void 0;
|
|
18
|
+
var slice_1 = require("./slice");
|
|
19
|
+
Object.defineProperty(exports, "schemaSelectionReducer", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return __importDefault(slice_1).default;
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "setSchemaSelection", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return slice_1.setSchemaSelection;
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "clearSchemaSelections", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () {
|
|
34
|
+
return slice_1.clearSchemaSelections;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PayloadAction } from "@reduxjs/toolkit";
|
|
2
|
+
export interface SchemaSelectionState {
|
|
3
|
+
/**
|
|
4
|
+
* Maps schema path (e.g., "requestBody", "requestBody.anyOf.0.layer3")
|
|
5
|
+
* to the selected anyOf/oneOf option index
|
|
6
|
+
*/
|
|
7
|
+
selections: {
|
|
8
|
+
[schemaPath: string]: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare const slice: import("@reduxjs/toolkit").Slice<SchemaSelectionState, {
|
|
12
|
+
/**
|
|
13
|
+
* Set the selected index for a specific schema path
|
|
14
|
+
*/
|
|
15
|
+
setSchemaSelection: (state: {
|
|
16
|
+
selections: {
|
|
17
|
+
[x: string]: number;
|
|
18
|
+
};
|
|
19
|
+
}, action: PayloadAction<{
|
|
20
|
+
path: string;
|
|
21
|
+
index: number;
|
|
22
|
+
}>) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Clear all schema selections (useful when navigating to a new API endpoint)
|
|
25
|
+
*/
|
|
26
|
+
clearSchemaSelections: (state: {
|
|
27
|
+
selections: {
|
|
28
|
+
[x: string]: number;
|
|
29
|
+
};
|
|
30
|
+
}) => void;
|
|
31
|
+
}, "schemaSelection", "schemaSelection", import("@reduxjs/toolkit").SliceSelectors<SchemaSelectionState>>;
|
|
32
|
+
export declare const setSchemaSelection: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
33
|
+
path: string;
|
|
34
|
+
index: number;
|
|
35
|
+
}, "schemaSelection/setSchemaSelection">, clearSchemaSelections: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"schemaSelection/clearSchemaSelections">;
|
|
36
|
+
declare const _default: import("redux").Reducer<SchemaSelectionState>;
|
|
37
|
+
export default _default;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* ============================================================================
|
|
3
|
+
* Copyright (c) Palo Alto Networks
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
* ========================================================================== */
|
|
8
|
+
var _a;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.clearSchemaSelections =
|
|
11
|
+
exports.setSchemaSelection =
|
|
12
|
+
exports.slice =
|
|
13
|
+
void 0;
|
|
14
|
+
const toolkit_1 = require("@reduxjs/toolkit");
|
|
15
|
+
const initialState = {
|
|
16
|
+
selections: {},
|
|
17
|
+
};
|
|
18
|
+
exports.slice = (0, toolkit_1.createSlice)({
|
|
19
|
+
name: "schemaSelection",
|
|
20
|
+
initialState,
|
|
21
|
+
reducers: {
|
|
22
|
+
/**
|
|
23
|
+
* Set the selected index for a specific schema path
|
|
24
|
+
*/
|
|
25
|
+
setSchemaSelection: (state, action) => {
|
|
26
|
+
state.selections[action.payload.path] = action.payload.index;
|
|
27
|
+
},
|
|
28
|
+
/**
|
|
29
|
+
* Clear all schema selections (useful when navigating to a new API endpoint)
|
|
30
|
+
*/
|
|
31
|
+
clearSchemaSelections: (state) => {
|
|
32
|
+
state.selections = {};
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
((_a = exports.slice.actions),
|
|
37
|
+
(exports.setSchemaSelection = _a.setSchemaSelection),
|
|
38
|
+
(exports.clearSchemaSelections = _a.clearSchemaSelections));
|
|
39
|
+
exports.default = exports.slice.reducer;
|