docusaurus-plugin-openapi-docs 1.1.0 → 1.1.3
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/README.md +1 -2
- package/lib/markdown/createLogo.d.ts +2 -0
- package/lib/markdown/createLogo.js +19 -0
- package/lib/markdown/createSchemaDetails.js +156 -1
- package/lib/markdown/createStatusCodes.js +112 -2
- package/lib/markdown/index.d.ts +1 -1
- package/lib/markdown/index.js +7 -2
- package/lib/markdown/schema.js +50 -14
- package/lib/markdown/schema.test.js +18 -18
- package/lib/openapi/openapi.js +11 -8
- package/lib/openapi/types.d.ts +7 -0
- 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 +8 -8
- package/src/markdown/createLogo.ts +21 -0
- package/src/markdown/createSchemaDetails.ts +202 -1
- package/src/markdown/createStatusCodes.ts +142 -8
- package/src/markdown/index.ts +17 -2
- package/src/markdown/schema.test.ts +18 -18
- package/src/markdown/schema.ts +60 -14
- package/src/openapi/openapi.ts +9 -6
- package/src/openapi/types.ts +8 -0
- package/src/openapi/utils/loadAndResolveSpec.ts +13 -0
- package/src/sidebars/index.ts +4 -2
- package/src/types.ts +1 -1
|
@@ -7,13 +7,86 @@
|
|
|
7
7
|
|
|
8
8
|
import { ApiItem } from "../types";
|
|
9
9
|
import { createDescription } from "./createDescription";
|
|
10
|
+
import { createDetails } from "./createDetails";
|
|
11
|
+
import { createDetailsSummary } from "./createDetailsSummary";
|
|
10
12
|
import { createSchemaDetails } from "./createSchemaDetails";
|
|
11
13
|
import { create } from "./utils";
|
|
14
|
+
import { guard } from "./utils";
|
|
12
15
|
|
|
13
16
|
interface Props {
|
|
14
17
|
responses: ApiItem["responses"];
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
function createResponseHeaders(responseHeaders: any) {
|
|
21
|
+
return guard(responseHeaders, () =>
|
|
22
|
+
create("ul", {
|
|
23
|
+
style: { marginLeft: "1rem" },
|
|
24
|
+
children: [
|
|
25
|
+
Object.entries(responseHeaders).map(([headerName, headerObj]) => {
|
|
26
|
+
const {
|
|
27
|
+
description,
|
|
28
|
+
schema: { type },
|
|
29
|
+
example,
|
|
30
|
+
}: any = headerObj;
|
|
31
|
+
|
|
32
|
+
return create("li", {
|
|
33
|
+
class: "schemaItem",
|
|
34
|
+
children: [
|
|
35
|
+
createDetailsSummary({
|
|
36
|
+
children: [
|
|
37
|
+
create("strong", { children: headerName }),
|
|
38
|
+
guard(type, () => [
|
|
39
|
+
create("span", {
|
|
40
|
+
style: { opacity: "0.6" },
|
|
41
|
+
children: ` ${type}`,
|
|
42
|
+
}),
|
|
43
|
+
]),
|
|
44
|
+
],
|
|
45
|
+
}),
|
|
46
|
+
create("div", {
|
|
47
|
+
children: [
|
|
48
|
+
guard(description, (description) =>
|
|
49
|
+
create("div", {
|
|
50
|
+
style: {
|
|
51
|
+
marginTop: ".5rem",
|
|
52
|
+
marginBottom: ".5rem",
|
|
53
|
+
},
|
|
54
|
+
children: [
|
|
55
|
+
guard(example, () => `Example: ${example}`),
|
|
56
|
+
createDescription(description),
|
|
57
|
+
],
|
|
58
|
+
})
|
|
59
|
+
),
|
|
60
|
+
],
|
|
61
|
+
}),
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
}),
|
|
65
|
+
],
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function createResponseExamples(responseExamples: any) {
|
|
71
|
+
return Object.entries(responseExamples).map(
|
|
72
|
+
([exampleName, exampleValue]: any) => {
|
|
73
|
+
const camelToSpaceName = exampleName.replace(/([A-Z])/g, " $1");
|
|
74
|
+
let finalFormattedName =
|
|
75
|
+
camelToSpaceName.charAt(0).toUpperCase() + camelToSpaceName.slice(1);
|
|
76
|
+
|
|
77
|
+
return create("TabItem", {
|
|
78
|
+
label: `${finalFormattedName}`,
|
|
79
|
+
value: `${finalFormattedName}`,
|
|
80
|
+
children: [
|
|
81
|
+
create("ResponseSamples", {
|
|
82
|
+
responseExample: JSON.stringify(exampleValue.value, null, 2),
|
|
83
|
+
}),
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
17
90
|
export function createStatusCodes({ responses }: Props) {
|
|
18
91
|
if (responses === undefined) {
|
|
19
92
|
return undefined;
|
|
@@ -28,6 +101,13 @@ export function createStatusCodes({ responses }: Props) {
|
|
|
28
101
|
children: [
|
|
29
102
|
create("ApiTabs", {
|
|
30
103
|
children: codes.map((code) => {
|
|
104
|
+
const responseHeaders: any = responses[code].headers;
|
|
105
|
+
const responseContent: any = responses[code].content;
|
|
106
|
+
const responseContentKey: any =
|
|
107
|
+
responseContent && Object.keys(responseContent)[0];
|
|
108
|
+
const responseExamples: any =
|
|
109
|
+
responseContentKey && responseContent[responseContentKey].examples;
|
|
110
|
+
|
|
31
111
|
return create("TabItem", {
|
|
32
112
|
label: code,
|
|
33
113
|
value: code,
|
|
@@ -35,14 +115,68 @@ export function createStatusCodes({ responses }: Props) {
|
|
|
35
115
|
create("div", {
|
|
36
116
|
children: createDescription(responses[code].description),
|
|
37
117
|
}),
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
118
|
+
guard(responseExamples, () =>
|
|
119
|
+
create("SchemaTabs", {
|
|
120
|
+
children: [
|
|
121
|
+
create("TabTtem", {
|
|
122
|
+
label: "Schema",
|
|
123
|
+
value: "Schema",
|
|
124
|
+
children: [
|
|
125
|
+
responseHeaders &&
|
|
126
|
+
createDetails({
|
|
127
|
+
"data-collaposed": false,
|
|
128
|
+
open: true,
|
|
129
|
+
style: { textAlign: "left" },
|
|
130
|
+
children: [
|
|
131
|
+
createDetailsSummary({
|
|
132
|
+
children: [
|
|
133
|
+
create("strong", {
|
|
134
|
+
children: "Response Headers",
|
|
135
|
+
}),
|
|
136
|
+
],
|
|
137
|
+
}),
|
|
138
|
+
createResponseHeaders(responseHeaders),
|
|
139
|
+
],
|
|
140
|
+
}),
|
|
141
|
+
create("div", {
|
|
142
|
+
children: createSchemaDetails({
|
|
143
|
+
title: "Schema",
|
|
144
|
+
body: {
|
|
145
|
+
content: responses[code].content,
|
|
146
|
+
},
|
|
147
|
+
}),
|
|
148
|
+
}),
|
|
149
|
+
],
|
|
150
|
+
}),
|
|
151
|
+
createResponseExamples(responseExamples),
|
|
152
|
+
],
|
|
153
|
+
})
|
|
154
|
+
),
|
|
155
|
+
guard(responseHeaders, () =>
|
|
156
|
+
createDetails({
|
|
157
|
+
"data-collaposed": false,
|
|
158
|
+
open: true,
|
|
159
|
+
style: { textAlign: "left" },
|
|
160
|
+
children: [
|
|
161
|
+
createDetailsSummary({
|
|
162
|
+
children: [
|
|
163
|
+
create("strong", { children: "Response Headers" }),
|
|
164
|
+
],
|
|
165
|
+
}),
|
|
166
|
+
createResponseHeaders(responseHeaders),
|
|
167
|
+
],
|
|
168
|
+
})
|
|
169
|
+
),
|
|
170
|
+
guard(!responseExamples, () =>
|
|
171
|
+
create("div", {
|
|
172
|
+
children: createSchemaDetails({
|
|
173
|
+
title: "Schema",
|
|
174
|
+
body: {
|
|
175
|
+
content: responses[code].content,
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
178
|
+
})
|
|
179
|
+
),
|
|
46
180
|
],
|
|
47
181
|
});
|
|
48
182
|
}),
|
package/src/markdown/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { createContactInfo } from "./createContactInfo";
|
|
|
18
18
|
import { createDeprecationNotice } from "./createDeprecationNotice";
|
|
19
19
|
import { createDescription } from "./createDescription";
|
|
20
20
|
import { createLicense } from "./createLicense";
|
|
21
|
+
import { createLogo } from "./createLogo";
|
|
21
22
|
import { createParamsDetails } from "./createParamsDetails";
|
|
22
23
|
import { createRequestBodyDetails } from "./createRequestBodyDetails";
|
|
23
24
|
import { createStatusCodes } from "./createStatusCodes";
|
|
@@ -37,10 +38,12 @@ export function createApiPageMD({
|
|
|
37
38
|
},
|
|
38
39
|
}: ApiPageMetadata) {
|
|
39
40
|
return render([
|
|
41
|
+
`import ApiTabs from "@theme/ApiTabs";\n`,
|
|
40
42
|
`import ParamsItem from "@theme/ParamsItem";\n`,
|
|
43
|
+
`import ResponseSamples from "@theme/ResponseSamples";\n`,
|
|
41
44
|
`import SchemaItem from "@theme/SchemaItem"\n`,
|
|
42
|
-
`import ApiTabs from "@theme/ApiTabs";\n`,
|
|
43
45
|
`import SchemaTabs from "@theme/SchemaTabs";\n`,
|
|
46
|
+
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
|
|
44
47
|
`import TabItem from "@theme/TabItem";\n\n`,
|
|
45
48
|
`## ${escape(title)}\n\n`,
|
|
46
49
|
createDeprecationNotice({ deprecated, description: deprecatedDescription }),
|
|
@@ -55,14 +58,26 @@ export function createApiPageMD({
|
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
export function createInfoPageMD({
|
|
58
|
-
info: {
|
|
61
|
+
info: {
|
|
62
|
+
title,
|
|
63
|
+
version,
|
|
64
|
+
description,
|
|
65
|
+
contact,
|
|
66
|
+
license,
|
|
67
|
+
termsOfService,
|
|
68
|
+
logo,
|
|
69
|
+
darkLogo,
|
|
70
|
+
},
|
|
59
71
|
securitySchemes,
|
|
60
72
|
}: InfoPageMetadata) {
|
|
61
73
|
return render([
|
|
74
|
+
`import ApiLogo from "@theme/ApiLogo";\n`,
|
|
62
75
|
`import Tabs from "@theme/Tabs";\n`,
|
|
63
76
|
`import TabItem from "@theme/TabItem";\n\n`,
|
|
77
|
+
|
|
64
78
|
createVersionBadge(version),
|
|
65
79
|
`# ${escape(title)}\n\n`,
|
|
80
|
+
createLogo(logo, darkLogo),
|
|
66
81
|
createDescription(description),
|
|
67
82
|
createAuthentication(securitySchemes as unknown as SecuritySchemeObject),
|
|
68
83
|
createContactInfo(contact as ContactObject),
|
|
@@ -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
|
@@ -64,7 +64,11 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
64
64
|
return undefined;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
if (
|
|
67
|
+
if (
|
|
68
|
+
schema.items &&
|
|
69
|
+
schema.minItems === undefined &&
|
|
70
|
+
schema.maxItems === undefined
|
|
71
|
+
) {
|
|
68
72
|
return getQualifierMessage(schema.items);
|
|
69
73
|
}
|
|
70
74
|
|
|
@@ -72,15 +76,38 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
72
76
|
|
|
73
77
|
let qualifierGroups = [];
|
|
74
78
|
|
|
79
|
+
if (schema.items && schema.items.enum) {
|
|
80
|
+
if (schema.items.enum) {
|
|
81
|
+
qualifierGroups.push(
|
|
82
|
+
`[${schema.items.enum.map((e) => `\`${e}\``).join(", ")}]`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
75
87
|
if (schema.minLength || schema.maxLength) {
|
|
76
88
|
let lengthQualifier = "";
|
|
77
|
-
|
|
78
|
-
|
|
89
|
+
let minLength;
|
|
90
|
+
let maxLength;
|
|
91
|
+
if (schema.minLength && schema.minLength > 1) {
|
|
92
|
+
minLength = `\`>= ${schema.minLength} characters\``;
|
|
93
|
+
}
|
|
94
|
+
if (schema.minLength && schema.minLength === 1) {
|
|
95
|
+
minLength = `\`non-empty\``;
|
|
79
96
|
}
|
|
80
|
-
lengthQualifier += "length";
|
|
81
97
|
if (schema.maxLength) {
|
|
82
|
-
|
|
98
|
+
maxLength = `\`<= ${schema.maxLength} characters\``;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (minLength && !maxLength) {
|
|
102
|
+
lengthQualifier += minLength;
|
|
103
|
+
}
|
|
104
|
+
if (maxLength && !minLength) {
|
|
105
|
+
lengthQualifier += maxLength;
|
|
83
106
|
}
|
|
107
|
+
if (minLength && maxLength) {
|
|
108
|
+
lengthQualifier += `${minLength} and ${maxLength}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
84
111
|
qualifierGroups.push(lengthQualifier);
|
|
85
112
|
}
|
|
86
113
|
|
|
@@ -91,21 +118,33 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
91
118
|
typeof schema.exclusiveMaximum === "number"
|
|
92
119
|
) {
|
|
93
120
|
let minmaxQualifier = "";
|
|
121
|
+
let minimum;
|
|
122
|
+
let maximum;
|
|
94
123
|
if (typeof schema.exclusiveMinimum === "number") {
|
|
95
|
-
|
|
124
|
+
minimum = `\`> ${schema.exclusiveMinimum}\``;
|
|
96
125
|
} else if (schema.minimum && !schema.exclusiveMinimum) {
|
|
97
|
-
|
|
126
|
+
minimum = `\`>= ${schema.minimum}\``;
|
|
98
127
|
} else if (schema.minimum && schema.exclusiveMinimum === true) {
|
|
99
|
-
|
|
128
|
+
minimum = `\`> ${schema.minimum}\``;
|
|
100
129
|
}
|
|
101
|
-
minmaxQualifier += "value";
|
|
102
130
|
if (typeof schema.exclusiveMaximum === "number") {
|
|
103
|
-
|
|
131
|
+
maximum = `\`< ${schema.exclusiveMaximum}\``;
|
|
104
132
|
} else if (schema.maximum && !schema.exclusiveMaximum) {
|
|
105
|
-
|
|
133
|
+
maximum = `\`<= ${schema.maximum}\``;
|
|
106
134
|
} else if (schema.maximum && schema.exclusiveMaximum === true) {
|
|
107
|
-
|
|
135
|
+
maximum = `\`< ${schema.maximum}\``;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (minimum && !maximum) {
|
|
139
|
+
minmaxQualifier += minimum;
|
|
140
|
+
}
|
|
141
|
+
if (maximum && !minimum) {
|
|
142
|
+
minmaxQualifier += maximum;
|
|
108
143
|
}
|
|
144
|
+
if (minimum && maximum) {
|
|
145
|
+
minmaxQualifier += `${minimum} and ${maximum}`;
|
|
146
|
+
}
|
|
147
|
+
|
|
109
148
|
qualifierGroups.push(minmaxQualifier);
|
|
110
149
|
}
|
|
111
150
|
|
|
@@ -115,16 +154,23 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
|
|
|
115
154
|
);
|
|
116
155
|
}
|
|
117
156
|
|
|
157
|
+
// Check if discriminator mapping
|
|
158
|
+
const discriminator = schema as any;
|
|
159
|
+
if (discriminator.mapping) {
|
|
160
|
+
const values = Object.keys(discriminator.mapping);
|
|
161
|
+
qualifierGroups.push(`[${values.map((e) => `\`${e}\``).join(", ")}]`);
|
|
162
|
+
}
|
|
163
|
+
|
|
118
164
|
if (schema.enum) {
|
|
119
165
|
qualifierGroups.push(`[${schema.enum.map((e) => `\`${e}\``).join(", ")}]`);
|
|
120
166
|
}
|
|
121
167
|
|
|
122
168
|
if (schema.minItems) {
|
|
123
|
-
qualifierGroups.push(
|
|
169
|
+
qualifierGroups.push(`\`>= ${schema.minItems}\``);
|
|
124
170
|
}
|
|
125
171
|
|
|
126
172
|
if (schema.maxItems) {
|
|
127
|
-
qualifierGroups.push(
|
|
173
|
+
qualifierGroups.push(`\`<= ${schema.maxItems}\``);
|
|
128
174
|
}
|
|
129
175
|
|
|
130
176
|
if (qualifierGroups.length === 0) {
|
package/src/openapi/openapi.ts
CHANGED
|
@@ -13,7 +13,8 @@ import sdk from "@paloaltonetworks/postman-collection";
|
|
|
13
13
|
import Collection from "@paloaltonetworks/postman-collection";
|
|
14
14
|
import chalk from "chalk";
|
|
15
15
|
import fs from "fs-extra";
|
|
16
|
-
import
|
|
16
|
+
import cloneDeep from "lodash/cloneDeep";
|
|
17
|
+
import kebabCase from "lodash/kebabCase";
|
|
17
18
|
|
|
18
19
|
import { isURL } from "../index";
|
|
19
20
|
import {
|
|
@@ -53,7 +54,8 @@ function jsonToCollection(data: OpenApiObject): Promise<Collection> {
|
|
|
53
54
|
async function createPostmanCollection(
|
|
54
55
|
openapiData: OpenApiObject
|
|
55
56
|
): Promise<Collection> {
|
|
56
|
-
|
|
57
|
+
// Create copy of openapiData
|
|
58
|
+
const data = cloneDeep(openapiData) as OpenApiObject;
|
|
57
59
|
|
|
58
60
|
// Including `servers` breaks postman, so delete all of them.
|
|
59
61
|
delete data.servers;
|
|
@@ -101,7 +103,6 @@ function createItems(
|
|
|
101
103
|
unversionedId: tagId,
|
|
102
104
|
title: description ?? "",
|
|
103
105
|
description: description ?? "",
|
|
104
|
-
slug: "/" + tagId,
|
|
105
106
|
frontMatter: {},
|
|
106
107
|
tag: {
|
|
107
108
|
...tag,
|
|
@@ -119,7 +120,6 @@ function createItems(
|
|
|
119
120
|
unversionedId: infoId,
|
|
120
121
|
title: openapiData.info.title,
|
|
121
122
|
description: openapiData.info.description,
|
|
122
|
-
slug: "/" + infoId,
|
|
123
123
|
frontMatter: {},
|
|
124
124
|
securitySchemes: openapiData.components?.securitySchemes,
|
|
125
125
|
info: {
|
|
@@ -128,6 +128,8 @@ function createItems(
|
|
|
128
128
|
getTagDisplayName(tagName.name!, openapiData.tags ?? [])
|
|
129
129
|
),
|
|
130
130
|
title: openapiData.info.title ?? "Introduction",
|
|
131
|
+
logo: openapiData.info["x-logo"]! as any,
|
|
132
|
+
darkLogo: openapiData.info["x-dark-logo"]! as any,
|
|
131
133
|
},
|
|
132
134
|
};
|
|
133
135
|
items.push(infoPage);
|
|
@@ -146,7 +148,9 @@ function createItems(
|
|
|
146
148
|
operationObject.summary ?? operationObject.operationId ?? "";
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
const baseId =
|
|
151
|
+
const baseId = operationObject.operationId
|
|
152
|
+
? kebabCase(operationObject.operationId)
|
|
153
|
+
: kebabCase(operationObject.summary);
|
|
150
154
|
|
|
151
155
|
const servers =
|
|
152
156
|
operationObject.servers ?? pathObject.servers ?? openapiData.servers;
|
|
@@ -181,7 +185,6 @@ function createItems(
|
|
|
181
185
|
unversionedId: baseId,
|
|
182
186
|
title: title,
|
|
183
187
|
description: description ?? "",
|
|
184
|
-
slug: "/" + baseId,
|
|
185
188
|
frontMatter: {},
|
|
186
189
|
api: {
|
|
187
190
|
...defaults,
|
package/src/openapi/types.ts
CHANGED
|
@@ -42,6 +42,14 @@ export interface InfoObject {
|
|
|
42
42
|
license?: LicenseObject;
|
|
43
43
|
version: string;
|
|
44
44
|
tags?: String[];
|
|
45
|
+
"x-logo"?: LogoObject;
|
|
46
|
+
"x-dark-logo"?: LogoObject;
|
|
47
|
+
logo?: LogoObject;
|
|
48
|
+
darkLogo?: LogoObject;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface LogoObject {
|
|
52
|
+
url?: string;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
export interface ContactObject {
|
|
@@ -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>;
|