docusaurus-plugin-openapi-docs 0.0.0-406 → 0.0.0-409
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/markdown/createSchemaDetails.js +156 -1
- package/lib/markdown/index.js +1 -0
- package/lib/markdown/schema.js +42 -13
- package/lib/markdown/schema.test.js +18 -18
- package/lib/openapi/openapi.js +0 -3
- package/lib/openapi/utils/loadAndResolveSpec.js +13 -0
- package/lib/sidebars/index.js +3 -2
- package/lib/types.d.ts +1 -1
- package/package.json +2 -2
- package/src/markdown/createSchemaDetails.ts +202 -1
- package/src/markdown/index.ts +1 -0
- package/src/markdown/schema.test.ts +18 -18
- package/src/markdown/schema.ts +47 -13
- package/src/openapi/openapi.ts +0 -3
- package/src/openapi/utils/loadAndResolveSpec.ts +13 -0
- package/src/sidebars/index.ts +4 -2
- package/src/types.ts +1 -1
|
@@ -86,12 +86,14 @@ function createAnyOneOf(schema) {
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
function createProperties(schema) {
|
|
89
|
+
const discriminator = schema.discriminator;
|
|
89
90
|
return Object.entries(schema.properties).map(([key, val]) => createEdges({
|
|
90
91
|
name: key,
|
|
91
92
|
schema: val,
|
|
92
93
|
required: Array.isArray(schema.required)
|
|
93
94
|
? schema.required.includes(key)
|
|
94
95
|
: false,
|
|
96
|
+
discriminator,
|
|
95
97
|
}));
|
|
96
98
|
}
|
|
97
99
|
function createAdditionalProperties(schema) {
|
|
@@ -228,6 +230,93 @@ function createItems(schema) {
|
|
|
228
230
|
: false,
|
|
229
231
|
}));
|
|
230
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* For handling discriminators that do not map to a same-level property
|
|
235
|
+
*/
|
|
236
|
+
function createDiscriminator(schema) {
|
|
237
|
+
var _a;
|
|
238
|
+
const discriminator = schema.discriminator;
|
|
239
|
+
const propertyName = discriminator === null || discriminator === void 0 ? void 0 : discriminator.propertyName;
|
|
240
|
+
const propertyType = "string"; // should always be string
|
|
241
|
+
const mapping = discriminator === null || discriminator === void 0 ? void 0 : discriminator.mapping;
|
|
242
|
+
// Explicit mapping is required since we can't support implicit
|
|
243
|
+
if (mapping === undefined) {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
// Attempt to get the property description we want to display
|
|
247
|
+
// TODO: how to make it predictable when handling allOf
|
|
248
|
+
let propertyDescription;
|
|
249
|
+
const firstMappingSchema = mapping[Object.keys(mapping)[0]];
|
|
250
|
+
if (firstMappingSchema.properties !== undefined) {
|
|
251
|
+
propertyDescription =
|
|
252
|
+
firstMappingSchema.properties[propertyName].description;
|
|
253
|
+
}
|
|
254
|
+
if (firstMappingSchema.allOf !== undefined) {
|
|
255
|
+
const { mergedSchemas } = mergeAllOf(firstMappingSchema.allOf);
|
|
256
|
+
if (mergedSchemas.properties !== undefined) {
|
|
257
|
+
propertyDescription =
|
|
258
|
+
(_a = mergedSchemas.properties[propertyName]) === null || _a === void 0 ? void 0 : _a.description;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (propertyDescription === undefined) {
|
|
262
|
+
if (schema.properties !== undefined &&
|
|
263
|
+
schema.properties[propertyName] !== undefined) {
|
|
264
|
+
propertyDescription = schema.properties[propertyName].description;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return (0, utils_1.create)("li", {
|
|
268
|
+
className: "discriminatorItem",
|
|
269
|
+
children: (0, utils_1.create)("div", {
|
|
270
|
+
children: [
|
|
271
|
+
(0, utils_1.create)("strong", {
|
|
272
|
+
style: { paddingLeft: "1rem" },
|
|
273
|
+
children: propertyName,
|
|
274
|
+
}),
|
|
275
|
+
(0, utils_1.guard)(propertyType, (name) => (0, utils_1.create)("span", {
|
|
276
|
+
style: { opacity: "0.6" },
|
|
277
|
+
children: ` ${propertyType}`,
|
|
278
|
+
})),
|
|
279
|
+
(0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema.discriminator), (message) => (0, utils_1.create)("div", {
|
|
280
|
+
style: {
|
|
281
|
+
paddingLeft: "1rem",
|
|
282
|
+
},
|
|
283
|
+
children: (0, createDescription_1.createDescription)(message),
|
|
284
|
+
})),
|
|
285
|
+
(0, utils_1.guard)(propertyDescription, (description) => (0, utils_1.create)("div", {
|
|
286
|
+
style: {
|
|
287
|
+
paddingLeft: "1rem",
|
|
288
|
+
},
|
|
289
|
+
children: (0, createDescription_1.createDescription)(description),
|
|
290
|
+
})),
|
|
291
|
+
(0, utils_1.create)("DiscriminatorTabs", {
|
|
292
|
+
children: Object.keys(mapping).map((key, index) => {
|
|
293
|
+
if (mapping[key].allOf !== undefined) {
|
|
294
|
+
const { mergedSchemas } = mergeAllOf(mapping[key].allOf);
|
|
295
|
+
// Cleanup duplicate property from mapping schema
|
|
296
|
+
delete mergedSchemas.properties[propertyName];
|
|
297
|
+
mapping[key] = mergedSchemas;
|
|
298
|
+
}
|
|
299
|
+
if (mapping[key].properties !== undefined) {
|
|
300
|
+
// Cleanup duplicate property from mapping schema
|
|
301
|
+
delete mapping[key].properties[propertyName];
|
|
302
|
+
}
|
|
303
|
+
const label = key;
|
|
304
|
+
return (0, utils_1.create)("TabItem", {
|
|
305
|
+
label: label,
|
|
306
|
+
value: `${index}-item-discriminator`,
|
|
307
|
+
children: [
|
|
308
|
+
(0, utils_1.create)("div", {
|
|
309
|
+
style: { marginLeft: "-4px" },
|
|
310
|
+
children: createNodes(mapping[key]),
|
|
311
|
+
}),
|
|
312
|
+
],
|
|
313
|
+
});
|
|
314
|
+
}),
|
|
315
|
+
}),
|
|
316
|
+
],
|
|
317
|
+
}),
|
|
318
|
+
});
|
|
319
|
+
}
|
|
231
320
|
function createDetailsNode(name, schemaName, schema, required) {
|
|
232
321
|
return (0, utils_1.create)("SchemaItem", {
|
|
233
322
|
collapsible: true,
|
|
@@ -272,12 +361,75 @@ function createDetailsNode(name, schemaName, schema, required) {
|
|
|
272
361
|
],
|
|
273
362
|
});
|
|
274
363
|
}
|
|
364
|
+
/**
|
|
365
|
+
* For handling discriminators that map to a same-level property (like 'petType').
|
|
366
|
+
* Note: These should only be encountered while iterating through properties.
|
|
367
|
+
*/
|
|
368
|
+
function createPropertyDiscriminator(name, schemaName, schema, discriminator, required) {
|
|
369
|
+
if (schema === undefined) {
|
|
370
|
+
return undefined;
|
|
371
|
+
}
|
|
372
|
+
if (discriminator.mapping === undefined) {
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
return (0, utils_1.create)("li", {
|
|
376
|
+
className: "discriminatorItem",
|
|
377
|
+
children: (0, utils_1.create)("div", {
|
|
378
|
+
children: [
|
|
379
|
+
(0, utils_1.create)("strong", { style: { paddingLeft: "1rem" }, children: name }),
|
|
380
|
+
(0, utils_1.guard)(schemaName, (name) => (0, utils_1.create)("span", {
|
|
381
|
+
style: { opacity: "0.6" },
|
|
382
|
+
children: ` ${schemaName}`,
|
|
383
|
+
})),
|
|
384
|
+
(0, utils_1.guard)(required, () => [
|
|
385
|
+
(0, utils_1.create)("strong", {
|
|
386
|
+
style: {
|
|
387
|
+
fontSize: "var(--ifm-code-font-size)",
|
|
388
|
+
color: "var(--openapi-required)",
|
|
389
|
+
},
|
|
390
|
+
children: " required",
|
|
391
|
+
}),
|
|
392
|
+
]),
|
|
393
|
+
(0, utils_1.guard)((0, schema_1.getQualifierMessage)(discriminator), (message) => (0, utils_1.create)("div", {
|
|
394
|
+
style: {
|
|
395
|
+
paddingLeft: "1rem",
|
|
396
|
+
},
|
|
397
|
+
children: (0, createDescription_1.createDescription)(message),
|
|
398
|
+
})),
|
|
399
|
+
(0, utils_1.guard)(schema.description, (description) => (0, utils_1.create)("div", {
|
|
400
|
+
style: {
|
|
401
|
+
paddingLeft: "1rem",
|
|
402
|
+
},
|
|
403
|
+
children: (0, createDescription_1.createDescription)(description),
|
|
404
|
+
})),
|
|
405
|
+
(0, utils_1.create)("DiscriminatorTabs", {
|
|
406
|
+
children: Object.keys(discriminator === null || discriminator === void 0 ? void 0 : discriminator.mapping).map((key, index) => {
|
|
407
|
+
const label = key;
|
|
408
|
+
return (0, utils_1.create)("TabItem", {
|
|
409
|
+
label: label,
|
|
410
|
+
value: `${index}-item-discriminator`,
|
|
411
|
+
children: [
|
|
412
|
+
(0, utils_1.create)("div", {
|
|
413
|
+
style: { marginLeft: "-4px" },
|
|
414
|
+
children: createNodes(discriminator === null || discriminator === void 0 ? void 0 : discriminator.mapping[key]),
|
|
415
|
+
}),
|
|
416
|
+
],
|
|
417
|
+
});
|
|
418
|
+
}),
|
|
419
|
+
}),
|
|
420
|
+
],
|
|
421
|
+
}),
|
|
422
|
+
});
|
|
423
|
+
}
|
|
275
424
|
/**
|
|
276
425
|
* Creates the edges or "leaves" of a schema tree. Edges can branch into sub-nodes with createDetails().
|
|
277
426
|
*/
|
|
278
|
-
function createEdges({ name, schema, required }) {
|
|
427
|
+
function createEdges({ name, schema, required, discriminator, }) {
|
|
279
428
|
var _a;
|
|
280
429
|
const schemaName = (0, schema_1.getSchemaName)(schema);
|
|
430
|
+
if (discriminator !== undefined && discriminator.propertyName === name) {
|
|
431
|
+
return createPropertyDiscriminator(name, "string", schema, discriminator, required);
|
|
432
|
+
}
|
|
281
433
|
if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
|
|
282
434
|
return createDetailsNode(name, schemaName, schema, required);
|
|
283
435
|
}
|
|
@@ -327,6 +479,9 @@ function createEdges({ name, schema, required }) {
|
|
|
327
479
|
* Creates a hierarchical level of a schema tree. Nodes produce edges that can branch into sub-nodes with edges, recursively.
|
|
328
480
|
*/
|
|
329
481
|
function createNodes(schema) {
|
|
482
|
+
if (schema.discriminator !== undefined) {
|
|
483
|
+
return createDiscriminator(schema);
|
|
484
|
+
}
|
|
330
485
|
if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
|
|
331
486
|
return createAnyOneOf(schema);
|
|
332
487
|
}
|
package/lib/markdown/index.js
CHANGED
|
@@ -25,6 +25,7 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
|
|
|
25
25
|
`import SchemaItem from "@theme/SchemaItem"\n`,
|
|
26
26
|
`import ApiTabs from "@theme/ApiTabs";\n`,
|
|
27
27
|
`import SchemaTabs from "@theme/SchemaTabs";\n`,
|
|
28
|
+
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
|
|
28
29
|
`import TabItem from "@theme/TabItem";\n\n`,
|
|
29
30
|
`## ${(0, lodash_1.escape)(title)}\n\n`,
|
|
30
31
|
(0, createDeprecationNotice_1.createDeprecationNotice)({ deprecated, description: deprecatedDescription }),
|
package/lib/markdown/schema.js
CHANGED
|
@@ -61,12 +61,25 @@ function getQualifierMessage(schema) {
|
|
|
61
61
|
let qualifierGroups = [];
|
|
62
62
|
if (schema.minLength || schema.maxLength) {
|
|
63
63
|
let lengthQualifier = "";
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
let minLength;
|
|
65
|
+
let maxLength;
|
|
66
|
+
if (schema.minLength && schema.minLength > 1) {
|
|
67
|
+
minLength = `\`>= ${schema.minLength} characters\``;
|
|
68
|
+
}
|
|
69
|
+
if (schema.minLength && schema.minLength === 1) {
|
|
70
|
+
minLength = `\`non-empty\``;
|
|
66
71
|
}
|
|
67
|
-
lengthQualifier += "length";
|
|
68
72
|
if (schema.maxLength) {
|
|
69
|
-
|
|
73
|
+
maxLength = `\`<= ${schema.maxLength} characters\``;
|
|
74
|
+
}
|
|
75
|
+
if (minLength && !maxLength) {
|
|
76
|
+
lengthQualifier += minLength;
|
|
77
|
+
}
|
|
78
|
+
if (maxLength && !minLength) {
|
|
79
|
+
lengthQualifier += maxLength;
|
|
80
|
+
}
|
|
81
|
+
if (minLength && maxLength) {
|
|
82
|
+
lengthQualifier += `${minLength} and ${maxLength}`;
|
|
70
83
|
}
|
|
71
84
|
qualifierGroups.push(lengthQualifier);
|
|
72
85
|
}
|
|
@@ -75,38 +88,54 @@ function getQualifierMessage(schema) {
|
|
|
75
88
|
typeof schema.exclusiveMinimum === "number" ||
|
|
76
89
|
typeof schema.exclusiveMaximum === "number") {
|
|
77
90
|
let minmaxQualifier = "";
|
|
91
|
+
let minimum;
|
|
92
|
+
let maximum;
|
|
78
93
|
if (typeof schema.exclusiveMinimum === "number") {
|
|
79
|
-
|
|
94
|
+
minimum = `\`> ${schema.exclusiveMinimum}\``;
|
|
80
95
|
}
|
|
81
96
|
else if (schema.minimum && !schema.exclusiveMinimum) {
|
|
82
|
-
|
|
97
|
+
minimum = `\`>= ${schema.minimum}\``;
|
|
83
98
|
}
|
|
84
99
|
else if (schema.minimum && schema.exclusiveMinimum === true) {
|
|
85
|
-
|
|
100
|
+
minimum = `\`> ${schema.minimum}\``;
|
|
86
101
|
}
|
|
87
|
-
minmaxQualifier += "value";
|
|
88
102
|
if (typeof schema.exclusiveMaximum === "number") {
|
|
89
|
-
|
|
103
|
+
maximum = `\`< ${schema.exclusiveMaximum}\``;
|
|
90
104
|
}
|
|
91
105
|
else if (schema.maximum && !schema.exclusiveMaximum) {
|
|
92
|
-
|
|
106
|
+
maximum = `\`<= ${schema.maximum}\``;
|
|
93
107
|
}
|
|
94
108
|
else if (schema.maximum && schema.exclusiveMaximum === true) {
|
|
95
|
-
|
|
109
|
+
maximum = `\`< ${schema.maximum}\``;
|
|
110
|
+
}
|
|
111
|
+
if (minimum && !maximum) {
|
|
112
|
+
minmaxQualifier += minimum;
|
|
113
|
+
}
|
|
114
|
+
if (maximum && !minimum) {
|
|
115
|
+
minmaxQualifier += maximum;
|
|
116
|
+
}
|
|
117
|
+
if (minimum && maximum) {
|
|
118
|
+
minmaxQualifier += `${minimum} and ${maximum}`;
|
|
96
119
|
}
|
|
97
120
|
qualifierGroups.push(minmaxQualifier);
|
|
98
121
|
}
|
|
99
122
|
if (schema.pattern) {
|
|
100
123
|
qualifierGroups.push(`Value must match regular expression \`${schema.pattern}\``);
|
|
101
124
|
}
|
|
125
|
+
// Check if discriminator mapping
|
|
126
|
+
const discriminator = schema;
|
|
127
|
+
if (discriminator.mapping) {
|
|
128
|
+
const values = Object.keys(discriminator.mapping);
|
|
129
|
+
qualifierGroups.push(`[${values.map((e) => `\`${e}\``).join(", ")}]`);
|
|
130
|
+
}
|
|
102
131
|
if (schema.enum) {
|
|
103
132
|
qualifierGroups.push(`[${schema.enum.map((e) => `\`${e}\``).join(", ")}]`);
|
|
104
133
|
}
|
|
105
134
|
if (schema.minItems) {
|
|
106
|
-
qualifierGroups.push(
|
|
135
|
+
qualifierGroups.push(`\`>= ${schema.minItems}\``);
|
|
107
136
|
}
|
|
108
137
|
if (schema.maxItems) {
|
|
109
|
-
qualifierGroups.push(
|
|
138
|
+
qualifierGroups.push(`\`<= ${schema.maxItems}\``);
|
|
110
139
|
}
|
|
111
140
|
if (qualifierGroups.length === 0) {
|
|
112
141
|
return undefined;
|
|
@@ -16,17 +16,17 @@ describe("getQualifierMessage", () => {
|
|
|
16
16
|
// minLength + maxLength
|
|
17
17
|
//
|
|
18
18
|
it("should render minLength", () => {
|
|
19
|
-
const expected = "**Possible values:**
|
|
19
|
+
const expected = "**Possible values:** `non-empty`";
|
|
20
20
|
const actual = (0, schema_1.getQualifierMessage)({ minLength: 1 });
|
|
21
21
|
expect(actual).toBe(expected);
|
|
22
22
|
});
|
|
23
23
|
it("should render maxLength", () => {
|
|
24
|
-
const expected = "**Possible values:**
|
|
24
|
+
const expected = "**Possible values:** `<= 40 characters`";
|
|
25
25
|
const actual = (0, schema_1.getQualifierMessage)({ maxLength: 40 });
|
|
26
26
|
expect(actual).toBe(expected);
|
|
27
27
|
});
|
|
28
28
|
it("should render minLength and maxLength", () => {
|
|
29
|
-
const expected = "**Possible values:**
|
|
29
|
+
const expected = "**Possible values:** `non-empty` and `<= 40 characters`";
|
|
30
30
|
const actual = (0, schema_1.getQualifierMessage)({ minLength: 1, maxLength: 40 });
|
|
31
31
|
expect(actual).toBe(expected);
|
|
32
32
|
});
|
|
@@ -39,7 +39,7 @@ describe("getQualifierMessage", () => {
|
|
|
39
39
|
expect(actual).toBe(expected);
|
|
40
40
|
});
|
|
41
41
|
it("should render multiple string qualifiers", () => {
|
|
42
|
-
const expected = "**Possible values:**
|
|
42
|
+
const expected = "**Possible values:** `non-empty` and `<= 40 characters`, Value must match regular expression `^[a-zA-Z0-9_-]*$`";
|
|
43
43
|
const actual = (0, schema_1.getQualifierMessage)({
|
|
44
44
|
minLength: 1,
|
|
45
45
|
maxLength: 40,
|
|
@@ -59,42 +59,42 @@ describe("getQualifierMessage", () => {
|
|
|
59
59
|
// minimum + maximum + exclusiveMinimum + exclusiveMaximum
|
|
60
60
|
//
|
|
61
61
|
it("should render minimum", () => {
|
|
62
|
-
const expected = "**Possible values:** 1
|
|
62
|
+
const expected = "**Possible values:** `>= 1`";
|
|
63
63
|
const actual = (0, schema_1.getQualifierMessage)({ minimum: 1 });
|
|
64
64
|
expect(actual).toBe(expected);
|
|
65
65
|
});
|
|
66
66
|
it("should render maximum", () => {
|
|
67
|
-
const expected = "**Possible values:**
|
|
67
|
+
const expected = "**Possible values:** `<= 40`";
|
|
68
68
|
const actual = (0, schema_1.getQualifierMessage)({ maximum: 40 });
|
|
69
69
|
expect(actual).toBe(expected);
|
|
70
70
|
});
|
|
71
71
|
it("should render numeric exclusiveMinimum", () => {
|
|
72
|
-
const expected = "**Possible values:** 1
|
|
72
|
+
const expected = "**Possible values:** `> 1`";
|
|
73
73
|
const actual = (0, schema_1.getQualifierMessage)({ exclusiveMinimum: 1 });
|
|
74
74
|
expect(actual).toBe(expected);
|
|
75
75
|
});
|
|
76
76
|
it("should render numeric exclusiveMaximum", () => {
|
|
77
|
-
const expected = "**Possible values:**
|
|
77
|
+
const expected = "**Possible values:** `< 40`";
|
|
78
78
|
const actual = (0, schema_1.getQualifierMessage)({ exclusiveMaximum: 40 });
|
|
79
79
|
expect(actual).toBe(expected);
|
|
80
80
|
});
|
|
81
81
|
it("should render boolean exclusiveMinimum", () => {
|
|
82
|
-
const expected = "**Possible values:** 1
|
|
82
|
+
const expected = "**Possible values:** `> 1`";
|
|
83
83
|
const actual = (0, schema_1.getQualifierMessage)({ minimum: 1, exclusiveMinimum: true });
|
|
84
84
|
expect(actual).toBe(expected);
|
|
85
85
|
});
|
|
86
86
|
it("should render boolean exclusiveMaximum", () => {
|
|
87
|
-
const expected = "**Possible values:**
|
|
87
|
+
const expected = "**Possible values:** `< 40`";
|
|
88
88
|
const actual = (0, schema_1.getQualifierMessage)({ maximum: 40, exclusiveMaximum: true });
|
|
89
89
|
expect(actual).toBe(expected);
|
|
90
90
|
});
|
|
91
91
|
it("should render minimum when exclusiveMinimum is false", () => {
|
|
92
|
-
const expected = "**Possible values:** 1
|
|
92
|
+
const expected = "**Possible values:** `>= 1`";
|
|
93
93
|
const actual = (0, schema_1.getQualifierMessage)({ minimum: 1, exclusiveMinimum: false });
|
|
94
94
|
expect(actual).toBe(expected);
|
|
95
95
|
});
|
|
96
96
|
it("should render maximum when exclusiveMaximum is false", () => {
|
|
97
|
-
const expected = "**Possible values:**
|
|
97
|
+
const expected = "**Possible values:** `<= 40`";
|
|
98
98
|
const actual = (0, schema_1.getQualifierMessage)({
|
|
99
99
|
maximum: 40,
|
|
100
100
|
exclusiveMaximum: false,
|
|
@@ -102,12 +102,12 @@ describe("getQualifierMessage", () => {
|
|
|
102
102
|
expect(actual).toBe(expected);
|
|
103
103
|
});
|
|
104
104
|
it("should render minimum and maximum", () => {
|
|
105
|
-
const expected = "**Possible values:** 1
|
|
105
|
+
const expected = "**Possible values:** `>= 1` and `<= 40`";
|
|
106
106
|
const actual = (0, schema_1.getQualifierMessage)({ minimum: 1, maximum: 40 });
|
|
107
107
|
expect(actual).toBe(expected);
|
|
108
108
|
});
|
|
109
109
|
it("should render boolean exclusiveMinimum and maximum", () => {
|
|
110
|
-
const expected = "**Possible values:** 1
|
|
110
|
+
const expected = "**Possible values:** `> 1` and `<= 40`";
|
|
111
111
|
const actual = (0, schema_1.getQualifierMessage)({
|
|
112
112
|
minimum: 1,
|
|
113
113
|
maximum: 40,
|
|
@@ -116,7 +116,7 @@ describe("getQualifierMessage", () => {
|
|
|
116
116
|
expect(actual).toBe(expected);
|
|
117
117
|
});
|
|
118
118
|
it("should render minimum and boolean exclusiveMaximum", () => {
|
|
119
|
-
const expected = "**Possible values:** 1
|
|
119
|
+
const expected = "**Possible values:** `>= 1` and `< 40`";
|
|
120
120
|
const actual = (0, schema_1.getQualifierMessage)({
|
|
121
121
|
minimum: 1,
|
|
122
122
|
maximum: 40,
|
|
@@ -125,7 +125,7 @@ describe("getQualifierMessage", () => {
|
|
|
125
125
|
expect(actual).toBe(expected);
|
|
126
126
|
});
|
|
127
127
|
it("should render numeric exclusiveMinimum and maximum", () => {
|
|
128
|
-
const expected = "**Possible values:** 1
|
|
128
|
+
const expected = "**Possible values:** `> 1` and `<= 40`";
|
|
129
129
|
const actual = (0, schema_1.getQualifierMessage)({
|
|
130
130
|
exclusiveMinimum: 1,
|
|
131
131
|
maximum: 40,
|
|
@@ -133,7 +133,7 @@ describe("getQualifierMessage", () => {
|
|
|
133
133
|
expect(actual).toBe(expected);
|
|
134
134
|
});
|
|
135
135
|
it("should render minimum and numeric exclusiveMaximum", () => {
|
|
136
|
-
const expected = "**Possible values:** 1
|
|
136
|
+
const expected = "**Possible values:** `>= 1` and `< 40`";
|
|
137
137
|
const actual = (0, schema_1.getQualifierMessage)({
|
|
138
138
|
minimum: 1,
|
|
139
139
|
exclusiveMaximum: 40,
|
|
@@ -141,7 +141,7 @@ describe("getQualifierMessage", () => {
|
|
|
141
141
|
expect(actual).toBe(expected);
|
|
142
142
|
});
|
|
143
143
|
it("should render numeric exclusiveMinimum and boolean exclusiveMaximum", () => {
|
|
144
|
-
const expected = "**Possible values:** 1
|
|
144
|
+
const expected = "**Possible values:** `> 1` and `< 40`";
|
|
145
145
|
const actual = (0, schema_1.getQualifierMessage)({
|
|
146
146
|
exclusiveMinimum: 1,
|
|
147
147
|
maximum: 40,
|
package/lib/openapi/openapi.js
CHANGED
|
@@ -79,7 +79,6 @@ function createItems(openapiData, sidebarOptions) {
|
|
|
79
79
|
unversionedId: tagId,
|
|
80
80
|
title: description !== null && description !== void 0 ? description : "",
|
|
81
81
|
description: description !== null && description !== void 0 ? description : "",
|
|
82
|
-
slug: "/" + tagId,
|
|
83
82
|
frontMatter: {},
|
|
84
83
|
tag: {
|
|
85
84
|
...tag,
|
|
@@ -96,7 +95,6 @@ function createItems(openapiData, sidebarOptions) {
|
|
|
96
95
|
unversionedId: infoId,
|
|
97
96
|
title: openapiData.info.title,
|
|
98
97
|
description: openapiData.info.description,
|
|
99
|
-
slug: "/" + infoId,
|
|
100
98
|
frontMatter: {},
|
|
101
99
|
securitySchemes: (_b = openapiData.components) === null || _b === void 0 ? void 0 : _b.securitySchemes,
|
|
102
100
|
info: {
|
|
@@ -144,7 +142,6 @@ function createItems(openapiData, sidebarOptions) {
|
|
|
144
142
|
unversionedId: baseId,
|
|
145
143
|
title: title,
|
|
146
144
|
description: description !== null && description !== void 0 ? description : "",
|
|
147
|
-
slug: "/" + baseId,
|
|
148
145
|
frontMatter: {},
|
|
149
146
|
api: {
|
|
150
147
|
...defaults,
|
|
@@ -15,6 +15,7 @@ const openapi_core_1 = require("@redocly/openapi-core");
|
|
|
15
15
|
const chalk_1 = __importDefault(require("chalk"));
|
|
16
16
|
// @ts-ignore
|
|
17
17
|
const swagger2openapi_1 = require("swagger2openapi");
|
|
18
|
+
const OpenAPIParser_1 = require("./services/OpenAPIParser");
|
|
18
19
|
function serializer(replacer, cycleReplacer) {
|
|
19
20
|
var stack = [], keys = [];
|
|
20
21
|
if (cycleReplacer === undefined)
|
|
@@ -24,6 +25,18 @@ function serializer(replacer, cycleReplacer) {
|
|
|
24
25
|
return value.title ? `circular(${value.title})` : "circular()";
|
|
25
26
|
};
|
|
26
27
|
return function (key, value) {
|
|
28
|
+
// Resolve discriminator ref pointers
|
|
29
|
+
if ((value === null || value === void 0 ? void 0 : value.discriminator) !== undefined) {
|
|
30
|
+
const parser = new OpenAPIParser_1.OpenAPIParser(stack[0]);
|
|
31
|
+
for (let [k, v] of Object.entries(value.discriminator.mapping)) {
|
|
32
|
+
const discriminator = k;
|
|
33
|
+
if (typeof v === "string" && v.charAt(0) === "#") {
|
|
34
|
+
const ref = v;
|
|
35
|
+
const resolvedRef = parser.byRef(ref);
|
|
36
|
+
value.discriminator.mapping[discriminator] = resolvedRef;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
27
40
|
if (stack.length > 0) {
|
|
28
41
|
// @ts-ignore
|
|
29
42
|
var thisPos = stack.indexOf(this);
|
package/lib/sidebars/index.js
CHANGED
|
@@ -9,6 +9,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
9
9
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
12
13
|
const clsx_1 = __importDefault(require("clsx"));
|
|
13
14
|
const lodash_1 = require("lodash");
|
|
14
15
|
const uniq_1 = __importDefault(require("lodash/uniq"));
|
|
@@ -98,8 +99,8 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
|
|
|
98
99
|
type: "generated-index",
|
|
99
100
|
title: tag,
|
|
100
101
|
slug: label
|
|
101
|
-
? "/category
|
|
102
|
-
: "/category
|
|
102
|
+
? path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(label), (0, lodash_1.kebabCase)(tag))
|
|
103
|
+
: path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(tag)),
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
106
|
return {
|
package/lib/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-plugin-openapi-docs",
|
|
3
3
|
"description": "OpenAPI plugin for Docusaurus.",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-409",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"engines": {
|
|
68
68
|
"node": ">=14"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "6cfbade709c0e80f79e91b3e4fa11dbf416490b5"
|
|
71
71
|
}
|
|
@@ -99,6 +99,7 @@ function createAnyOneOf(schema: SchemaObject): any {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
function createProperties(schema: SchemaObject) {
|
|
102
|
+
const discriminator = schema.discriminator;
|
|
102
103
|
return Object.entries(schema.properties!).map(([key, val]) =>
|
|
103
104
|
createEdges({
|
|
104
105
|
name: key,
|
|
@@ -106,6 +107,7 @@ function createProperties(schema: SchemaObject) {
|
|
|
106
107
|
required: Array.isArray(schema.required)
|
|
107
108
|
? schema.required.includes(key)
|
|
108
109
|
: false,
|
|
110
|
+
discriminator,
|
|
109
111
|
})
|
|
110
112
|
);
|
|
111
113
|
}
|
|
@@ -277,6 +279,110 @@ function createItems(schema: SchemaObject) {
|
|
|
277
279
|
);
|
|
278
280
|
}
|
|
279
281
|
|
|
282
|
+
/**
|
|
283
|
+
* For handling discriminators that do not map to a same-level property
|
|
284
|
+
*/
|
|
285
|
+
function createDiscriminator(schema: SchemaObject) {
|
|
286
|
+
const discriminator = schema.discriminator;
|
|
287
|
+
const propertyName = discriminator?.propertyName;
|
|
288
|
+
const propertyType = "string"; // should always be string
|
|
289
|
+
const mapping: any = discriminator?.mapping;
|
|
290
|
+
|
|
291
|
+
// Explicit mapping is required since we can't support implicit
|
|
292
|
+
if (mapping === undefined) {
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Attempt to get the property description we want to display
|
|
297
|
+
// TODO: how to make it predictable when handling allOf
|
|
298
|
+
let propertyDescription;
|
|
299
|
+
const firstMappingSchema = mapping[Object.keys(mapping)[0]];
|
|
300
|
+
if (firstMappingSchema.properties !== undefined) {
|
|
301
|
+
propertyDescription =
|
|
302
|
+
firstMappingSchema.properties![propertyName!].description;
|
|
303
|
+
}
|
|
304
|
+
if (firstMappingSchema.allOf !== undefined) {
|
|
305
|
+
const { mergedSchemas }: { mergedSchemas: SchemaObject } = mergeAllOf(
|
|
306
|
+
firstMappingSchema.allOf
|
|
307
|
+
);
|
|
308
|
+
if (mergedSchemas.properties !== undefined) {
|
|
309
|
+
propertyDescription =
|
|
310
|
+
mergedSchemas.properties[propertyName!]?.description;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (propertyDescription === undefined) {
|
|
315
|
+
if (
|
|
316
|
+
schema.properties !== undefined &&
|
|
317
|
+
schema.properties![propertyName!] !== undefined
|
|
318
|
+
) {
|
|
319
|
+
propertyDescription = schema.properties![propertyName!].description;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return create("li", {
|
|
324
|
+
className: "discriminatorItem",
|
|
325
|
+
children: create("div", {
|
|
326
|
+
children: [
|
|
327
|
+
create("strong", {
|
|
328
|
+
style: { paddingLeft: "1rem" },
|
|
329
|
+
children: propertyName,
|
|
330
|
+
}),
|
|
331
|
+
guard(propertyType, (name) =>
|
|
332
|
+
create("span", {
|
|
333
|
+
style: { opacity: "0.6" },
|
|
334
|
+
children: ` ${propertyType}`,
|
|
335
|
+
})
|
|
336
|
+
),
|
|
337
|
+
guard(getQualifierMessage(schema.discriminator as any), (message) =>
|
|
338
|
+
create("div", {
|
|
339
|
+
style: {
|
|
340
|
+
paddingLeft: "1rem",
|
|
341
|
+
},
|
|
342
|
+
children: createDescription(message),
|
|
343
|
+
})
|
|
344
|
+
),
|
|
345
|
+
guard(propertyDescription, (description) =>
|
|
346
|
+
create("div", {
|
|
347
|
+
style: {
|
|
348
|
+
paddingLeft: "1rem",
|
|
349
|
+
},
|
|
350
|
+
children: createDescription(description),
|
|
351
|
+
})
|
|
352
|
+
),
|
|
353
|
+
create("DiscriminatorTabs", {
|
|
354
|
+
children: Object.keys(mapping!).map((key, index) => {
|
|
355
|
+
if (mapping[key].allOf !== undefined) {
|
|
356
|
+
const { mergedSchemas }: { mergedSchemas: SchemaObject } =
|
|
357
|
+
mergeAllOf(mapping[key].allOf);
|
|
358
|
+
// Cleanup duplicate property from mapping schema
|
|
359
|
+
delete mergedSchemas.properties![propertyName!];
|
|
360
|
+
mapping[key] = mergedSchemas;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (mapping[key].properties !== undefined) {
|
|
364
|
+
// Cleanup duplicate property from mapping schema
|
|
365
|
+
delete mapping[key].properties![propertyName!];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const label = key;
|
|
369
|
+
return create("TabItem", {
|
|
370
|
+
label: label,
|
|
371
|
+
value: `${index}-item-discriminator`,
|
|
372
|
+
children: [
|
|
373
|
+
create("div", {
|
|
374
|
+
style: { marginLeft: "-4px" },
|
|
375
|
+
children: createNodes(mapping[key]),
|
|
376
|
+
}),
|
|
377
|
+
],
|
|
378
|
+
});
|
|
379
|
+
}),
|
|
380
|
+
}),
|
|
381
|
+
],
|
|
382
|
+
}),
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
280
386
|
function createDetailsNode(
|
|
281
387
|
name: string,
|
|
282
388
|
schemaName: string,
|
|
@@ -331,18 +437,109 @@ function createDetailsNode(
|
|
|
331
437
|
});
|
|
332
438
|
}
|
|
333
439
|
|
|
440
|
+
/**
|
|
441
|
+
* For handling discriminators that map to a same-level property (like 'petType').
|
|
442
|
+
* Note: These should only be encountered while iterating through properties.
|
|
443
|
+
*/
|
|
444
|
+
function createPropertyDiscriminator(
|
|
445
|
+
name: string,
|
|
446
|
+
schemaName: string,
|
|
447
|
+
schema: SchemaObject,
|
|
448
|
+
discriminator: any,
|
|
449
|
+
required: any
|
|
450
|
+
): any {
|
|
451
|
+
if (schema === undefined) {
|
|
452
|
+
return undefined;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (discriminator.mapping === undefined) {
|
|
456
|
+
return undefined;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return create("li", {
|
|
460
|
+
className: "discriminatorItem",
|
|
461
|
+
children: create("div", {
|
|
462
|
+
children: [
|
|
463
|
+
create("strong", { style: { paddingLeft: "1rem" }, children: name }),
|
|
464
|
+
guard(schemaName, (name) =>
|
|
465
|
+
create("span", {
|
|
466
|
+
style: { opacity: "0.6" },
|
|
467
|
+
children: ` ${schemaName}`,
|
|
468
|
+
})
|
|
469
|
+
),
|
|
470
|
+
guard(required, () => [
|
|
471
|
+
create("strong", {
|
|
472
|
+
style: {
|
|
473
|
+
fontSize: "var(--ifm-code-font-size)",
|
|
474
|
+
color: "var(--openapi-required)",
|
|
475
|
+
},
|
|
476
|
+
children: " required",
|
|
477
|
+
}),
|
|
478
|
+
]),
|
|
479
|
+
guard(getQualifierMessage(discriminator), (message) =>
|
|
480
|
+
create("div", {
|
|
481
|
+
style: {
|
|
482
|
+
paddingLeft: "1rem",
|
|
483
|
+
},
|
|
484
|
+
children: createDescription(message),
|
|
485
|
+
})
|
|
486
|
+
),
|
|
487
|
+
guard(schema.description, (description) =>
|
|
488
|
+
create("div", {
|
|
489
|
+
style: {
|
|
490
|
+
paddingLeft: "1rem",
|
|
491
|
+
},
|
|
492
|
+
children: createDescription(description),
|
|
493
|
+
})
|
|
494
|
+
),
|
|
495
|
+
create("DiscriminatorTabs", {
|
|
496
|
+
children: Object.keys(discriminator?.mapping!).map((key, index) => {
|
|
497
|
+
const label = key;
|
|
498
|
+
return create("TabItem", {
|
|
499
|
+
label: label,
|
|
500
|
+
value: `${index}-item-discriminator`,
|
|
501
|
+
children: [
|
|
502
|
+
create("div", {
|
|
503
|
+
style: { marginLeft: "-4px" },
|
|
504
|
+
children: createNodes(discriminator?.mapping[key]),
|
|
505
|
+
}),
|
|
506
|
+
],
|
|
507
|
+
});
|
|
508
|
+
}),
|
|
509
|
+
}),
|
|
510
|
+
],
|
|
511
|
+
}),
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
|
|
334
515
|
interface EdgeProps {
|
|
335
516
|
name: string;
|
|
336
517
|
schema: SchemaObject;
|
|
337
518
|
required: boolean;
|
|
519
|
+
discriminator?: any | unknown;
|
|
338
520
|
}
|
|
339
521
|
|
|
340
522
|
/**
|
|
341
523
|
* Creates the edges or "leaves" of a schema tree. Edges can branch into sub-nodes with createDetails().
|
|
342
524
|
*/
|
|
343
|
-
function createEdges({
|
|
525
|
+
function createEdges({
|
|
526
|
+
name,
|
|
527
|
+
schema,
|
|
528
|
+
required,
|
|
529
|
+
discriminator,
|
|
530
|
+
}: EdgeProps): any {
|
|
344
531
|
const schemaName = getSchemaName(schema);
|
|
345
532
|
|
|
533
|
+
if (discriminator !== undefined && discriminator.propertyName === name) {
|
|
534
|
+
return createPropertyDiscriminator(
|
|
535
|
+
name,
|
|
536
|
+
"string",
|
|
537
|
+
schema,
|
|
538
|
+
discriminator,
|
|
539
|
+
required
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
|
|
346
543
|
if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
|
|
347
544
|
return createDetailsNode(name, schemaName, schema, required);
|
|
348
545
|
}
|
|
@@ -409,6 +606,10 @@ function createEdges({ name, schema, required }: EdgeProps): any {
|
|
|
409
606
|
* Creates a hierarchical level of a schema tree. Nodes produce edges that can branch into sub-nodes with edges, recursively.
|
|
410
607
|
*/
|
|
411
608
|
function createNodes(schema: SchemaObject): any {
|
|
609
|
+
if (schema.discriminator !== undefined) {
|
|
610
|
+
return createDiscriminator(schema);
|
|
611
|
+
}
|
|
612
|
+
|
|
412
613
|
if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
|
|
413
614
|
return createAnyOneOf(schema);
|
|
414
615
|
}
|
package/src/markdown/index.ts
CHANGED
|
@@ -41,6 +41,7 @@ export function createApiPageMD({
|
|
|
41
41
|
`import SchemaItem from "@theme/SchemaItem"\n`,
|
|
42
42
|
`import ApiTabs from "@theme/ApiTabs";\n`,
|
|
43
43
|
`import SchemaTabs from "@theme/SchemaTabs";\n`,
|
|
44
|
+
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
|
|
44
45
|
`import TabItem from "@theme/TabItem";\n\n`,
|
|
45
46
|
`## ${escape(title)}\n\n`,
|
|
46
47
|
createDeprecationNotice({ deprecated, description: deprecatedDescription }),
|
|
@@ -17,19 +17,19 @@ describe("getQualifierMessage", () => {
|
|
|
17
17
|
// minLength + maxLength
|
|
18
18
|
//
|
|
19
19
|
it("should render minLength", () => {
|
|
20
|
-
const expected = "**Possible values:**
|
|
20
|
+
const expected = "**Possible values:** `non-empty`";
|
|
21
21
|
const actual = getQualifierMessage({ minLength: 1 });
|
|
22
22
|
expect(actual).toBe(expected);
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it("should render maxLength", () => {
|
|
26
|
-
const expected = "**Possible values:**
|
|
26
|
+
const expected = "**Possible values:** `<= 40 characters`";
|
|
27
27
|
const actual = getQualifierMessage({ maxLength: 40 });
|
|
28
28
|
expect(actual).toBe(expected);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
it("should render minLength and maxLength", () => {
|
|
32
|
-
const expected = "**Possible values:**
|
|
32
|
+
const expected = "**Possible values:** `non-empty` and `<= 40 characters`";
|
|
33
33
|
const actual = getQualifierMessage({ minLength: 1, maxLength: 40 });
|
|
34
34
|
expect(actual).toBe(expected);
|
|
35
35
|
});
|
|
@@ -46,7 +46,7 @@ describe("getQualifierMessage", () => {
|
|
|
46
46
|
|
|
47
47
|
it("should render multiple string qualifiers", () => {
|
|
48
48
|
const expected =
|
|
49
|
-
"**Possible values:**
|
|
49
|
+
"**Possible values:** `non-empty` and `<= 40 characters`, Value must match regular expression `^[a-zA-Z0-9_-]*$`";
|
|
50
50
|
const actual = getQualifierMessage({
|
|
51
51
|
minLength: 1,
|
|
52
52
|
maxLength: 40,
|
|
@@ -68,49 +68,49 @@ describe("getQualifierMessage", () => {
|
|
|
68
68
|
// minimum + maximum + exclusiveMinimum + exclusiveMaximum
|
|
69
69
|
//
|
|
70
70
|
it("should render minimum", () => {
|
|
71
|
-
const expected = "**Possible values:** 1
|
|
71
|
+
const expected = "**Possible values:** `>= 1`";
|
|
72
72
|
const actual = getQualifierMessage({ minimum: 1 });
|
|
73
73
|
expect(actual).toBe(expected);
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
it("should render maximum", () => {
|
|
77
|
-
const expected = "**Possible values:**
|
|
77
|
+
const expected = "**Possible values:** `<= 40`";
|
|
78
78
|
const actual = getQualifierMessage({ maximum: 40 });
|
|
79
79
|
expect(actual).toBe(expected);
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it("should render numeric exclusiveMinimum", () => {
|
|
83
|
-
const expected = "**Possible values:** 1
|
|
83
|
+
const expected = "**Possible values:** `> 1`";
|
|
84
84
|
const actual = getQualifierMessage({ exclusiveMinimum: 1 });
|
|
85
85
|
expect(actual).toBe(expected);
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
it("should render numeric exclusiveMaximum", () => {
|
|
89
|
-
const expected = "**Possible values:**
|
|
89
|
+
const expected = "**Possible values:** `< 40`";
|
|
90
90
|
const actual = getQualifierMessage({ exclusiveMaximum: 40 });
|
|
91
91
|
expect(actual).toBe(expected);
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
it("should render boolean exclusiveMinimum", () => {
|
|
95
|
-
const expected = "**Possible values:** 1
|
|
95
|
+
const expected = "**Possible values:** `> 1`";
|
|
96
96
|
const actual = getQualifierMessage({ minimum: 1, exclusiveMinimum: true });
|
|
97
97
|
expect(actual).toBe(expected);
|
|
98
98
|
});
|
|
99
99
|
|
|
100
100
|
it("should render boolean exclusiveMaximum", () => {
|
|
101
|
-
const expected = "**Possible values:**
|
|
101
|
+
const expected = "**Possible values:** `< 40`";
|
|
102
102
|
const actual = getQualifierMessage({ maximum: 40, exclusiveMaximum: true });
|
|
103
103
|
expect(actual).toBe(expected);
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
it("should render minimum when exclusiveMinimum is false", () => {
|
|
107
|
-
const expected = "**Possible values:** 1
|
|
107
|
+
const expected = "**Possible values:** `>= 1`";
|
|
108
108
|
const actual = getQualifierMessage({ minimum: 1, exclusiveMinimum: false });
|
|
109
109
|
expect(actual).toBe(expected);
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
it("should render maximum when exclusiveMaximum is false", () => {
|
|
113
|
-
const expected = "**Possible values:**
|
|
113
|
+
const expected = "**Possible values:** `<= 40`";
|
|
114
114
|
const actual = getQualifierMessage({
|
|
115
115
|
maximum: 40,
|
|
116
116
|
exclusiveMaximum: false,
|
|
@@ -119,13 +119,13 @@ describe("getQualifierMessage", () => {
|
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
it("should render minimum and maximum", () => {
|
|
122
|
-
const expected = "**Possible values:** 1
|
|
122
|
+
const expected = "**Possible values:** `>= 1` and `<= 40`";
|
|
123
123
|
const actual = getQualifierMessage({ minimum: 1, maximum: 40 });
|
|
124
124
|
expect(actual).toBe(expected);
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
it("should render boolean exclusiveMinimum and maximum", () => {
|
|
128
|
-
const expected = "**Possible values:** 1
|
|
128
|
+
const expected = "**Possible values:** `> 1` and `<= 40`";
|
|
129
129
|
const actual = getQualifierMessage({
|
|
130
130
|
minimum: 1,
|
|
131
131
|
maximum: 40,
|
|
@@ -135,7 +135,7 @@ describe("getQualifierMessage", () => {
|
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
it("should render minimum and boolean exclusiveMaximum", () => {
|
|
138
|
-
const expected = "**Possible values:** 1
|
|
138
|
+
const expected = "**Possible values:** `>= 1` and `< 40`";
|
|
139
139
|
const actual = getQualifierMessage({
|
|
140
140
|
minimum: 1,
|
|
141
141
|
maximum: 40,
|
|
@@ -145,7 +145,7 @@ describe("getQualifierMessage", () => {
|
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
it("should render numeric exclusiveMinimum and maximum", () => {
|
|
148
|
-
const expected = "**Possible values:** 1
|
|
148
|
+
const expected = "**Possible values:** `> 1` and `<= 40`";
|
|
149
149
|
const actual = getQualifierMessage({
|
|
150
150
|
exclusiveMinimum: 1,
|
|
151
151
|
maximum: 40,
|
|
@@ -154,7 +154,7 @@ describe("getQualifierMessage", () => {
|
|
|
154
154
|
});
|
|
155
155
|
|
|
156
156
|
it("should render minimum and numeric exclusiveMaximum", () => {
|
|
157
|
-
const expected = "**Possible values:** 1
|
|
157
|
+
const expected = "**Possible values:** `>= 1` and `< 40`";
|
|
158
158
|
const actual = getQualifierMessage({
|
|
159
159
|
minimum: 1,
|
|
160
160
|
exclusiveMaximum: 40,
|
|
@@ -163,7 +163,7 @@ describe("getQualifierMessage", () => {
|
|
|
163
163
|
});
|
|
164
164
|
|
|
165
165
|
it("should render numeric exclusiveMinimum and boolean exclusiveMaximum", () => {
|
|
166
|
-
const expected = "**Possible values:** 1
|
|
166
|
+
const expected = "**Possible values:** `> 1` and `< 40`";
|
|
167
167
|
const actual = getQualifierMessage({
|
|
168
168
|
exclusiveMinimum: 1,
|
|
169
169
|
maximum: 40,
|
package/src/markdown/schema.ts
CHANGED
|
@@ -74,13 +74,28 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
74
74
|
|
|
75
75
|
if (schema.minLength || schema.maxLength) {
|
|
76
76
|
let lengthQualifier = "";
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
let minLength;
|
|
78
|
+
let maxLength;
|
|
79
|
+
if (schema.minLength && schema.minLength > 1) {
|
|
80
|
+
minLength = `\`>= ${schema.minLength} characters\``;
|
|
81
|
+
}
|
|
82
|
+
if (schema.minLength && schema.minLength === 1) {
|
|
83
|
+
minLength = `\`non-empty\``;
|
|
79
84
|
}
|
|
80
|
-
lengthQualifier += "length";
|
|
81
85
|
if (schema.maxLength) {
|
|
82
|
-
|
|
86
|
+
maxLength = `\`<= ${schema.maxLength} characters\``;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (minLength && !maxLength) {
|
|
90
|
+
lengthQualifier += minLength;
|
|
91
|
+
}
|
|
92
|
+
if (maxLength && !minLength) {
|
|
93
|
+
lengthQualifier += maxLength;
|
|
83
94
|
}
|
|
95
|
+
if (minLength && maxLength) {
|
|
96
|
+
lengthQualifier += `${minLength} and ${maxLength}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
84
99
|
qualifierGroups.push(lengthQualifier);
|
|
85
100
|
}
|
|
86
101
|
|
|
@@ -91,21 +106,33 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
91
106
|
typeof schema.exclusiveMaximum === "number"
|
|
92
107
|
) {
|
|
93
108
|
let minmaxQualifier = "";
|
|
109
|
+
let minimum;
|
|
110
|
+
let maximum;
|
|
94
111
|
if (typeof schema.exclusiveMinimum === "number") {
|
|
95
|
-
|
|
112
|
+
minimum = `\`> ${schema.exclusiveMinimum}\``;
|
|
96
113
|
} else if (schema.minimum && !schema.exclusiveMinimum) {
|
|
97
|
-
|
|
114
|
+
minimum = `\`>= ${schema.minimum}\``;
|
|
98
115
|
} else if (schema.minimum && schema.exclusiveMinimum === true) {
|
|
99
|
-
|
|
116
|
+
minimum = `\`> ${schema.minimum}\``;
|
|
100
117
|
}
|
|
101
|
-
minmaxQualifier += "value";
|
|
102
118
|
if (typeof schema.exclusiveMaximum === "number") {
|
|
103
|
-
|
|
119
|
+
maximum = `\`< ${schema.exclusiveMaximum}\``;
|
|
104
120
|
} else if (schema.maximum && !schema.exclusiveMaximum) {
|
|
105
|
-
|
|
121
|
+
maximum = `\`<= ${schema.maximum}\``;
|
|
106
122
|
} else if (schema.maximum && schema.exclusiveMaximum === true) {
|
|
107
|
-
|
|
123
|
+
maximum = `\`< ${schema.maximum}\``;
|
|
108
124
|
}
|
|
125
|
+
|
|
126
|
+
if (minimum && !maximum) {
|
|
127
|
+
minmaxQualifier += minimum;
|
|
128
|
+
}
|
|
129
|
+
if (maximum && !minimum) {
|
|
130
|
+
minmaxQualifier += maximum;
|
|
131
|
+
}
|
|
132
|
+
if (minimum && maximum) {
|
|
133
|
+
minmaxQualifier += `${minimum} and ${maximum}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
109
136
|
qualifierGroups.push(minmaxQualifier);
|
|
110
137
|
}
|
|
111
138
|
|
|
@@ -115,16 +142,23 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
115
142
|
);
|
|
116
143
|
}
|
|
117
144
|
|
|
145
|
+
// Check if discriminator mapping
|
|
146
|
+
const discriminator = schema as any;
|
|
147
|
+
if (discriminator.mapping) {
|
|
148
|
+
const values = Object.keys(discriminator.mapping);
|
|
149
|
+
qualifierGroups.push(`[${values.map((e) => `\`${e}\``).join(", ")}]`);
|
|
150
|
+
}
|
|
151
|
+
|
|
118
152
|
if (schema.enum) {
|
|
119
153
|
qualifierGroups.push(`[${schema.enum.map((e) => `\`${e}\``).join(", ")}]`);
|
|
120
154
|
}
|
|
121
155
|
|
|
122
156
|
if (schema.minItems) {
|
|
123
|
-
qualifierGroups.push(
|
|
157
|
+
qualifierGroups.push(`\`>= ${schema.minItems}\``);
|
|
124
158
|
}
|
|
125
159
|
|
|
126
160
|
if (schema.maxItems) {
|
|
127
|
-
qualifierGroups.push(
|
|
161
|
+
qualifierGroups.push(`\`<= ${schema.maxItems}\``);
|
|
128
162
|
}
|
|
129
163
|
|
|
130
164
|
if (qualifierGroups.length === 0) {
|
package/src/openapi/openapi.ts
CHANGED
|
@@ -102,7 +102,6 @@ function createItems(
|
|
|
102
102
|
unversionedId: tagId,
|
|
103
103
|
title: description ?? "",
|
|
104
104
|
description: description ?? "",
|
|
105
|
-
slug: "/" + tagId,
|
|
106
105
|
frontMatter: {},
|
|
107
106
|
tag: {
|
|
108
107
|
...tag,
|
|
@@ -120,7 +119,6 @@ function createItems(
|
|
|
120
119
|
unversionedId: infoId,
|
|
121
120
|
title: openapiData.info.title,
|
|
122
121
|
description: openapiData.info.description,
|
|
123
|
-
slug: "/" + infoId,
|
|
124
122
|
frontMatter: {},
|
|
125
123
|
securitySchemes: openapiData.components?.securitySchemes,
|
|
126
124
|
info: {
|
|
@@ -184,7 +182,6 @@ function createItems(
|
|
|
184
182
|
unversionedId: baseId,
|
|
185
183
|
title: title,
|
|
186
184
|
description: description ?? "",
|
|
187
|
-
slug: "/" + baseId,
|
|
188
185
|
frontMatter: {},
|
|
189
186
|
api: {
|
|
190
187
|
...defaults,
|
|
@@ -14,6 +14,7 @@ import chalk from "chalk";
|
|
|
14
14
|
import { convertObj } from "swagger2openapi";
|
|
15
15
|
|
|
16
16
|
import { OpenApiObject } from "../types";
|
|
17
|
+
import { OpenAPIParser } from "./services/OpenAPIParser";
|
|
17
18
|
|
|
18
19
|
function serializer(replacer: any, cycleReplacer: any) {
|
|
19
20
|
var stack: any = [],
|
|
@@ -26,6 +27,18 @@ function serializer(replacer: any, cycleReplacer: any) {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
return function (key: any, value: any) {
|
|
30
|
+
// Resolve discriminator ref pointers
|
|
31
|
+
if (value?.discriminator !== undefined) {
|
|
32
|
+
const parser = new OpenAPIParser(stack[0]);
|
|
33
|
+
for (let [k, v] of Object.entries(value.discriminator.mapping)) {
|
|
34
|
+
const discriminator = k as string;
|
|
35
|
+
if (typeof v === "string" && v.charAt(0) === "#") {
|
|
36
|
+
const ref = v as string;
|
|
37
|
+
const resolvedRef = parser.byRef(ref);
|
|
38
|
+
value.discriminator.mapping[discriminator] = resolvedRef;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
29
42
|
if (stack.length > 0) {
|
|
30
43
|
// @ts-ignore
|
|
31
44
|
var thisPos = stack.indexOf(this);
|
package/src/sidebars/index.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
+
import path from "path";
|
|
9
|
+
|
|
8
10
|
import {
|
|
9
11
|
ProcessedSidebar,
|
|
10
12
|
SidebarItemCategory,
|
|
@@ -139,8 +141,8 @@ function groupByTags(
|
|
|
139
141
|
type: "generated-index" as "generated-index",
|
|
140
142
|
title: tag,
|
|
141
143
|
slug: label
|
|
142
|
-
? "/category
|
|
143
|
-
: "/category
|
|
144
|
+
? path.join("/category", basePath, kebabCase(label), kebabCase(tag))
|
|
145
|
+
: path.join("/category", basePath, kebabCase(tag)),
|
|
144
146
|
} as SidebarItemCategoryLinkConfig;
|
|
145
147
|
}
|
|
146
148
|
|
package/src/types.ts
CHANGED
|
@@ -76,7 +76,7 @@ export interface ApiMetadataBase {
|
|
|
76
76
|
description: string;
|
|
77
77
|
source: string; // @site aliased source => "@site/docs/folder/subFolder/subSubFolder/myDoc.md"
|
|
78
78
|
sourceDirName: string; // relative to the versioned docs folder (can be ".") => "folder/subFolder/subSubFolder"
|
|
79
|
-
slug
|
|
79
|
+
slug?: string;
|
|
80
80
|
permalink: string;
|
|
81
81
|
sidebarPosition?: number;
|
|
82
82
|
frontMatter: Record<string, unknown>;
|