docusaurus-plugin-openapi-docs 1.0.2 → 1.0.5
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 +106 -17
- package/lib/index.d.ts +7 -1
- package/lib/index.js +228 -18
- package/lib/markdown/createAuthentication.d.ts +2 -0
- package/lib/markdown/createAuthentication.js +139 -0
- package/lib/markdown/createParamsDetails.js +2 -0
- package/lib/markdown/createSchemaDetails.js +2 -0
- package/lib/markdown/index.d.ts +3 -2
- package/lib/markdown/index.js +10 -2
- package/lib/openapi/createExample.js +59 -49
- package/lib/openapi/openapi.d.ts +3 -3
- package/lib/openapi/openapi.js +71 -41
- package/lib/openapi/openapi.test.js +0 -6
- package/lib/openapi/utils/loadAndBundleSpec.d.ts +3 -0
- package/lib/openapi/utils/loadAndBundleSpec.js +44 -0
- package/lib/openapi/utils/types.d.ts +306 -0
- package/lib/openapi/utils/types.js +8 -0
- package/lib/options.d.ts +0 -2
- package/lib/options.js +36 -7
- package/lib/sidebars/index.d.ts +1 -1
- package/lib/sidebars/index.js +33 -30
- package/lib/sidebars/utils.d.ts +2 -0
- package/lib/sidebars/utils.js +31 -0
- package/lib/types.d.ts +34 -11
- package/package.json +10 -8
- package/src/index.ts +291 -20
- package/src/markdown/createAuthentication.ts +160 -0
- package/src/markdown/createParamsDetails.ts +2 -0
- package/src/markdown/createSchemaDetails.ts +2 -0
- package/src/markdown/index.ts +15 -2
- package/src/openapi/createExample.ts +59 -50
- package/src/openapi/openapi.test.ts +0 -6
- package/src/openapi/openapi.ts +85 -39
- package/src/openapi/utils/loadAndBundleSpec.ts +62 -0
- package/src/openapi/utils/types.ts +303 -0
- package/src/options.ts +41 -8
- package/src/sidebars/index.ts +40 -30
- package/src/sidebars/utils.ts +29 -0
- package/src/types.ts +35 -9
- package/src/openapi/__fixtures__/examples/yogurtstore/_category_.json +0 -4
- package/src/openapi/__fixtures__/examples/yogurtstore/froyo.yaml +0 -13
- package/src/openapi/__fixtures__/examples/yogurtstore/nested/nested.yaml +0 -13
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
* Copyright (c) Palo Alto Networks
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
* ========================================================================== */
|
|
7
|
+
|
|
8
|
+
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
|
9
|
+
|
|
10
|
+
export interface OpenAPISpec {
|
|
11
|
+
openapi: string;
|
|
12
|
+
info: OpenAPIInfo;
|
|
13
|
+
servers?: OpenAPIServer[];
|
|
14
|
+
paths: OpenAPIPaths;
|
|
15
|
+
components?: OpenAPIComponents;
|
|
16
|
+
security?: OpenAPISecurityRequirement[];
|
|
17
|
+
tags?: OpenAPITag[];
|
|
18
|
+
externalDocs?: OpenAPIExternalDocumentation;
|
|
19
|
+
"x-webhooks"?: OpenAPIPaths;
|
|
20
|
+
webhooks?: OpenAPIPaths;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface OpenAPIInfo {
|
|
24
|
+
title: string;
|
|
25
|
+
version: string;
|
|
26
|
+
|
|
27
|
+
description?: string;
|
|
28
|
+
summary?: string;
|
|
29
|
+
termsOfService?: string;
|
|
30
|
+
contact?: OpenAPIContact;
|
|
31
|
+
license?: OpenAPILicense;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface OpenAPIServer {
|
|
35
|
+
url: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
variables?: { [name: string]: OpenAPIServerVariable };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface OpenAPIServerVariable {
|
|
41
|
+
enum?: string[];
|
|
42
|
+
default: string;
|
|
43
|
+
description?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface OpenAPIPaths {
|
|
47
|
+
[path: string]: OpenAPIPath;
|
|
48
|
+
}
|
|
49
|
+
export interface OpenAPIRef {
|
|
50
|
+
$ref: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type Referenced<T> = OpenAPIRef | T;
|
|
54
|
+
|
|
55
|
+
export interface OpenAPIPath {
|
|
56
|
+
summary?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
get?: OpenAPIOperation;
|
|
59
|
+
put?: OpenAPIOperation;
|
|
60
|
+
post?: OpenAPIOperation;
|
|
61
|
+
delete?: OpenAPIOperation;
|
|
62
|
+
options?: OpenAPIOperation;
|
|
63
|
+
head?: OpenAPIOperation;
|
|
64
|
+
patch?: OpenAPIOperation;
|
|
65
|
+
trace?: OpenAPIOperation;
|
|
66
|
+
servers?: OpenAPIServer[];
|
|
67
|
+
parameters?: Array<Referenced<OpenAPIParameter>>;
|
|
68
|
+
$ref?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface OpenAPIXCodeSample {
|
|
72
|
+
lang: string;
|
|
73
|
+
label?: string;
|
|
74
|
+
source: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface OpenAPIOperation {
|
|
78
|
+
tags?: string[];
|
|
79
|
+
summary?: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
externalDocs?: OpenAPIExternalDocumentation;
|
|
82
|
+
operationId?: string;
|
|
83
|
+
parameters?: Array<Referenced<OpenAPIParameter>>;
|
|
84
|
+
requestBody?: Referenced<OpenAPIRequestBody>;
|
|
85
|
+
responses: OpenAPIResponses;
|
|
86
|
+
callbacks?: { [name: string]: Referenced<OpenAPICallback> };
|
|
87
|
+
deprecated?: boolean;
|
|
88
|
+
security?: OpenAPISecurityRequirement[];
|
|
89
|
+
servers?: OpenAPIServer[];
|
|
90
|
+
"x-codeSamples"?: OpenAPIXCodeSample[];
|
|
91
|
+
"x-code-samples"?: OpenAPIXCodeSample[]; // deprecated
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface OpenAPIParameter {
|
|
95
|
+
name: string;
|
|
96
|
+
in?: OpenAPIParameterLocation;
|
|
97
|
+
description?: string;
|
|
98
|
+
required?: boolean;
|
|
99
|
+
deprecated?: boolean;
|
|
100
|
+
allowEmptyValue?: boolean;
|
|
101
|
+
style?: OpenAPIParameterStyle;
|
|
102
|
+
explode?: boolean;
|
|
103
|
+
allowReserved?: boolean;
|
|
104
|
+
schema?: Referenced<OpenAPISchema>;
|
|
105
|
+
example?: any;
|
|
106
|
+
examples?: { [media: string]: Referenced<OpenAPIExample> };
|
|
107
|
+
content?: { [media: string]: OpenAPIMediaType };
|
|
108
|
+
encoding?: Record<string, OpenAPIEncoding>;
|
|
109
|
+
const?: any;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface OpenAPIExample {
|
|
113
|
+
value: any;
|
|
114
|
+
summary?: string;
|
|
115
|
+
description?: string;
|
|
116
|
+
externalValue?: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface OpenAPISchema {
|
|
120
|
+
$ref?: string;
|
|
121
|
+
type?: string | string[];
|
|
122
|
+
properties?: { [name: string]: OpenAPISchema };
|
|
123
|
+
patternProperties?: { [name: string]: OpenAPISchema };
|
|
124
|
+
additionalProperties?: boolean | OpenAPISchema;
|
|
125
|
+
unevaluatedProperties?: boolean | OpenAPISchema;
|
|
126
|
+
description?: string;
|
|
127
|
+
default?: any;
|
|
128
|
+
items?: OpenAPISchema | OpenAPISchema[] | boolean;
|
|
129
|
+
required?: string[];
|
|
130
|
+
readOnly?: boolean;
|
|
131
|
+
writeOnly?: boolean;
|
|
132
|
+
deprecated?: boolean;
|
|
133
|
+
format?: string;
|
|
134
|
+
externalDocs?: OpenAPIExternalDocumentation;
|
|
135
|
+
discriminator?: OpenAPIDiscriminator;
|
|
136
|
+
nullable?: boolean;
|
|
137
|
+
oneOf?: OpenAPISchema[];
|
|
138
|
+
anyOf?: OpenAPISchema[];
|
|
139
|
+
allOf?: OpenAPISchema[];
|
|
140
|
+
not?: OpenAPISchema;
|
|
141
|
+
|
|
142
|
+
title?: string;
|
|
143
|
+
multipleOf?: number;
|
|
144
|
+
maximum?: number;
|
|
145
|
+
exclusiveMaximum?: boolean | number;
|
|
146
|
+
minimum?: number;
|
|
147
|
+
exclusiveMinimum?: boolean | number;
|
|
148
|
+
maxLength?: number;
|
|
149
|
+
minLength?: number;
|
|
150
|
+
pattern?: string;
|
|
151
|
+
maxItems?: number;
|
|
152
|
+
minItems?: number;
|
|
153
|
+
uniqueItems?: boolean;
|
|
154
|
+
maxProperties?: number;
|
|
155
|
+
minProperties?: number;
|
|
156
|
+
enum?: any[];
|
|
157
|
+
example?: any;
|
|
158
|
+
|
|
159
|
+
if?: OpenAPISchema;
|
|
160
|
+
else?: OpenAPISchema;
|
|
161
|
+
then?: OpenAPISchema;
|
|
162
|
+
examples?: any[];
|
|
163
|
+
const?: string;
|
|
164
|
+
contentEncoding?: string;
|
|
165
|
+
contentMediaType?: string;
|
|
166
|
+
prefixItems?: OpenAPISchema[];
|
|
167
|
+
additionalItems?: OpenAPISchema | boolean;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface OpenAPIDiscriminator {
|
|
171
|
+
propertyName: string;
|
|
172
|
+
mapping?: { [name: string]: string };
|
|
173
|
+
"x-explicitMappingOnly"?: boolean;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface OpenAPIMediaType {
|
|
177
|
+
schema?: Referenced<OpenAPISchema>;
|
|
178
|
+
example?: any;
|
|
179
|
+
examples?: { [name: string]: Referenced<OpenAPIExample> };
|
|
180
|
+
encoding?: { [field: string]: OpenAPIEncoding };
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface OpenAPIEncoding {
|
|
184
|
+
contentType: string;
|
|
185
|
+
headers?: { [name: string]: Referenced<OpenAPIHeader> };
|
|
186
|
+
style: OpenAPIParameterStyle;
|
|
187
|
+
explode: boolean;
|
|
188
|
+
allowReserved: boolean;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export type OpenAPIParameterLocation = "query" | "header" | "path" | "cookie";
|
|
192
|
+
export type OpenAPIParameterStyle =
|
|
193
|
+
| "matrix"
|
|
194
|
+
| "label"
|
|
195
|
+
| "form"
|
|
196
|
+
| "simple"
|
|
197
|
+
| "spaceDelimited"
|
|
198
|
+
| "pipeDelimited"
|
|
199
|
+
| "deepObject";
|
|
200
|
+
|
|
201
|
+
export interface OpenAPIRequestBody {
|
|
202
|
+
description?: string;
|
|
203
|
+
required?: boolean;
|
|
204
|
+
content: { [mime: string]: OpenAPIMediaType };
|
|
205
|
+
|
|
206
|
+
"x-examples"?: {
|
|
207
|
+
[mime: string]: { [name: string]: Referenced<OpenAPIExample> };
|
|
208
|
+
};
|
|
209
|
+
"x-example"?: { [mime: string]: any };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface OpenAPIResponses {
|
|
213
|
+
[code: string]: Referenced<OpenAPIResponse>;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface OpenAPIResponse
|
|
217
|
+
extends Pick<OpenAPIRequestBody, "description" | "x-examples" | "x-example"> {
|
|
218
|
+
headers?: { [name: string]: Referenced<OpenAPIHeader> };
|
|
219
|
+
links?: { [name: string]: Referenced<OpenAPILink> };
|
|
220
|
+
content?: { [mime: string]: OpenAPIMediaType };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface OpenAPILink {
|
|
224
|
+
$ref?: string;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export type OpenAPIHeader = Omit<OpenAPIParameter, "in" | "name">;
|
|
228
|
+
|
|
229
|
+
export interface OpenAPICallback {
|
|
230
|
+
[name: string]: OpenAPIPath;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface OpenAPIComponents {
|
|
234
|
+
schemas?: { [name: string]: Referenced<OpenAPISchema> };
|
|
235
|
+
responses?: { [name: string]: Referenced<OpenAPIResponse> };
|
|
236
|
+
parameters?: { [name: string]: Referenced<OpenAPIParameter> };
|
|
237
|
+
examples?: { [name: string]: Referenced<OpenAPIExample> };
|
|
238
|
+
requestBodies?: { [name: string]: Referenced<OpenAPIRequestBody> };
|
|
239
|
+
headers?: { [name: string]: Referenced<OpenAPIHeader> };
|
|
240
|
+
securitySchemes?: { [name: string]: Referenced<OpenAPISecurityScheme> };
|
|
241
|
+
links?: { [name: string]: Referenced<OpenAPILink> };
|
|
242
|
+
callbacks?: { [name: string]: Referenced<OpenAPICallback> };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export interface OpenAPISecurityRequirement {
|
|
246
|
+
[name: string]: string[];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface OpenAPISecurityScheme {
|
|
250
|
+
type: "apiKey" | "http" | "oauth2" | "openIdConnect";
|
|
251
|
+
description?: string;
|
|
252
|
+
name?: string;
|
|
253
|
+
in?: "query" | "header" | "cookie";
|
|
254
|
+
scheme?: string;
|
|
255
|
+
bearerFormat: string;
|
|
256
|
+
flows: {
|
|
257
|
+
implicit?: {
|
|
258
|
+
refreshUrl?: string;
|
|
259
|
+
scopes: Record<string, string>;
|
|
260
|
+
authorizationUrl: string;
|
|
261
|
+
};
|
|
262
|
+
password?: {
|
|
263
|
+
refreshUrl?: string;
|
|
264
|
+
scopes: Record<string, string>;
|
|
265
|
+
tokenUrl: string;
|
|
266
|
+
};
|
|
267
|
+
clientCredentials?: {
|
|
268
|
+
refreshUrl?: string;
|
|
269
|
+
scopes: Record<string, string>;
|
|
270
|
+
tokenUrl: string;
|
|
271
|
+
};
|
|
272
|
+
authorizationCode?: {
|
|
273
|
+
refreshUrl?: string;
|
|
274
|
+
scopes: Record<string, string>;
|
|
275
|
+
tokenUrl: string;
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
openIdConnectUrl?: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface OpenAPITag {
|
|
282
|
+
name: string;
|
|
283
|
+
description?: string;
|
|
284
|
+
externalDocs?: OpenAPIExternalDocumentation;
|
|
285
|
+
"x-displayName"?: string;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export interface OpenAPIExternalDocumentation {
|
|
289
|
+
description?: string;
|
|
290
|
+
url: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface OpenAPIContact {
|
|
294
|
+
name?: string;
|
|
295
|
+
url?: string;
|
|
296
|
+
email?: string;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface OpenAPILicense {
|
|
300
|
+
name: string;
|
|
301
|
+
url?: string;
|
|
302
|
+
identifier?: string;
|
|
303
|
+
}
|
package/src/options.ts
CHANGED
|
@@ -7,14 +7,47 @@
|
|
|
7
7
|
|
|
8
8
|
import { Joi } from "@docusaurus/utils-validation";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const sidebarOptions = Joi.object({
|
|
11
|
+
groupPathsBy: Joi.string().valid("tag"),
|
|
12
|
+
categoryLinkSource: Joi.string().valid("tag", "info"),
|
|
13
|
+
customProps: Joi.object(),
|
|
14
|
+
sidebarCollapsible: Joi.boolean(),
|
|
15
|
+
sidebarCollapsed: Joi.boolean(),
|
|
16
|
+
});
|
|
16
17
|
|
|
17
18
|
export const OptionsSchema = Joi.object({
|
|
18
|
-
id: Joi.string().
|
|
19
|
-
|
|
19
|
+
id: Joi.string().required(),
|
|
20
|
+
docPluginId: Joi.string().required(),
|
|
21
|
+
config: Joi.object()
|
|
22
|
+
.pattern(
|
|
23
|
+
/^/,
|
|
24
|
+
Joi.object({
|
|
25
|
+
specPath: Joi.string().required(),
|
|
26
|
+
outputDir: Joi.string().required(),
|
|
27
|
+
template: Joi.string(),
|
|
28
|
+
sidebarOptions: sidebarOptions,
|
|
29
|
+
version: Joi.string().when("versions", {
|
|
30
|
+
is: Joi.exist(),
|
|
31
|
+
then: Joi.required(),
|
|
32
|
+
}),
|
|
33
|
+
label: Joi.string().when("versions", {
|
|
34
|
+
is: Joi.exist(),
|
|
35
|
+
then: Joi.required(),
|
|
36
|
+
}),
|
|
37
|
+
baseUrl: Joi.string().when("versions", {
|
|
38
|
+
is: Joi.exist(),
|
|
39
|
+
then: Joi.required(),
|
|
40
|
+
}),
|
|
41
|
+
versions: Joi.object().pattern(
|
|
42
|
+
/^/,
|
|
43
|
+
Joi.object({
|
|
44
|
+
specPath: Joi.string().required(),
|
|
45
|
+
outputDir: Joi.string().required(),
|
|
46
|
+
label: Joi.string().required(),
|
|
47
|
+
baseUrl: Joi.string().required(),
|
|
48
|
+
})
|
|
49
|
+
),
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
.required(),
|
|
20
53
|
});
|
package/src/sidebars/index.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
ProcessedSidebar,
|
|
10
|
+
SidebarItemCategory,
|
|
10
11
|
SidebarItemCategoryLinkConfig,
|
|
11
12
|
SidebarItemDoc,
|
|
12
13
|
} from "@docusaurus/plugin-content-docs/src/sidebars/types";
|
|
@@ -34,7 +35,8 @@ function groupByTags(
|
|
|
34
35
|
items: ApiPageMetadata[],
|
|
35
36
|
sidebarOptions: SidebarOptions,
|
|
36
37
|
options: APIOptions,
|
|
37
|
-
tags: TagObject[]
|
|
38
|
+
tags: TagObject[],
|
|
39
|
+
docPath: string
|
|
38
40
|
): ProcessedSidebar {
|
|
39
41
|
const { outputDir } = options;
|
|
40
42
|
const {
|
|
@@ -62,10 +64,9 @@ function groupByTags(
|
|
|
62
64
|
.filter((item): item is string => !!item)
|
|
63
65
|
);
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
.slice(outputDir.indexOf("/", 1))
|
|
68
|
-
.replace(/^\/+/g, "");
|
|
67
|
+
const basePath = docPath
|
|
68
|
+
? outputDir.split(docPath!)[1].replace(/^\/+/g, "")
|
|
69
|
+
: outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
|
|
69
70
|
|
|
70
71
|
function createDocItem(item: ApiPageMetadata): SidebarItemDoc {
|
|
71
72
|
const sidebar_label = item.frontMatter.sidebar_label;
|
|
@@ -73,7 +74,8 @@ function groupByTags(
|
|
|
73
74
|
const id = item.id;
|
|
74
75
|
return {
|
|
75
76
|
type: "doc" as const,
|
|
76
|
-
id:
|
|
77
|
+
id:
|
|
78
|
+
basePath === "" || undefined ? `${item.id}` : `${basePath}/${item.id}`,
|
|
77
79
|
label: (sidebar_label as string) ?? title ?? id,
|
|
78
80
|
customProps: customProps,
|
|
79
81
|
className: clsx(
|
|
@@ -99,7 +101,9 @@ function groupByTags(
|
|
|
99
101
|
const tagged = apiTags
|
|
100
102
|
.map((tag) => {
|
|
101
103
|
// Map info object to tag
|
|
102
|
-
const
|
|
104
|
+
const taggedInfoObject = intros.find((i) =>
|
|
105
|
+
i.tags ? i.tags.includes(tag) : undefined
|
|
106
|
+
);
|
|
103
107
|
const tagObject = tags.flat().find(
|
|
104
108
|
(t) =>
|
|
105
109
|
(tag === t.name || tag === t["x-displayName"]) ?? {
|
|
@@ -110,21 +114,19 @@ function groupByTags(
|
|
|
110
114
|
|
|
111
115
|
// TODO: perhaps move this into a getLinkConfig() function
|
|
112
116
|
let linkConfig = undefined;
|
|
113
|
-
if (
|
|
117
|
+
if (taggedInfoObject !== undefined && categoryLinkSource === "info") {
|
|
114
118
|
linkConfig = {
|
|
115
119
|
type: "doc",
|
|
116
|
-
id: `${basePath}/${
|
|
120
|
+
id: `${basePath}/${taggedInfoObject.id}`,
|
|
117
121
|
} as SidebarItemCategoryLinkConfig;
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
// TODO: perhaps move this into a getLinkConfig() function
|
|
121
125
|
if (tagObject !== undefined && categoryLinkSource === "tag") {
|
|
122
|
-
const
|
|
126
|
+
const tagId = kebabCase(tagObject.name);
|
|
123
127
|
linkConfig = {
|
|
124
|
-
type: "
|
|
125
|
-
|
|
126
|
-
description: linkDescription,
|
|
127
|
-
slug: "/category/" + kebabCase(tag),
|
|
128
|
+
type: "doc",
|
|
129
|
+
id: `${basePath}/${tagId}`,
|
|
128
130
|
} as SidebarItemCategoryLinkConfig;
|
|
129
131
|
}
|
|
130
132
|
|
|
@@ -150,18 +152,24 @@ function groupByTags(
|
|
|
150
152
|
})
|
|
151
153
|
.filter((item) => item.items.length > 0); // Filter out any categories with no items.
|
|
152
154
|
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
// Handle items with no tag
|
|
156
|
+
const untaggedItems = apiItems
|
|
157
|
+
.filter(({ api }) => api.tags === undefined || api.tags.length === 0)
|
|
158
|
+
.map(createDocItem);
|
|
159
|
+
let untagged: SidebarItemCategory[] = [];
|
|
160
|
+
if (untaggedItems.length > 0) {
|
|
161
|
+
untagged = [
|
|
162
|
+
{
|
|
163
|
+
type: "category" as const,
|
|
164
|
+
label: "UNTAGGED",
|
|
165
|
+
collapsible: sidebarCollapsible!,
|
|
166
|
+
collapsed: sidebarCollapsed!,
|
|
167
|
+
items: apiItems
|
|
168
|
+
.filter(({ api }) => api.tags === undefined || api.tags.length === 0)
|
|
169
|
+
.map(createDocItem),
|
|
170
|
+
},
|
|
171
|
+
];
|
|
172
|
+
}
|
|
165
173
|
|
|
166
174
|
// Shift root intro doc to top of sidebar
|
|
167
175
|
// TODO: Add input validation for categoryLinkSource options
|
|
@@ -169,22 +177,24 @@ function groupByTags(
|
|
|
169
177
|
tagged.unshift(rootIntroDoc as any);
|
|
170
178
|
}
|
|
171
179
|
|
|
172
|
-
return [...tagged];
|
|
180
|
+
return [...tagged, ...untagged];
|
|
173
181
|
}
|
|
174
182
|
|
|
175
183
|
export default function generateSidebarSlice(
|
|
176
184
|
sidebarOptions: SidebarOptions,
|
|
177
185
|
options: APIOptions,
|
|
178
186
|
api: ApiMetadata[],
|
|
179
|
-
tags: TagObject[]
|
|
187
|
+
tags: TagObject[],
|
|
188
|
+
docPath: string
|
|
180
189
|
) {
|
|
181
190
|
let sidebarSlice: ProcessedSidebar = [];
|
|
182
|
-
if (sidebarOptions.groupPathsBy === "
|
|
191
|
+
if (sidebarOptions.groupPathsBy === "tag") {
|
|
183
192
|
sidebarSlice = groupByTags(
|
|
184
193
|
api as ApiPageMetadata[],
|
|
185
194
|
sidebarOptions,
|
|
186
195
|
options,
|
|
187
|
-
tags
|
|
196
|
+
tags,
|
|
197
|
+
docPath
|
|
188
198
|
);
|
|
189
199
|
}
|
|
190
200
|
return sidebarSlice;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
* Copyright (c) Palo Alto Networks
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
* ========================================================================== */
|
|
7
|
+
|
|
8
|
+
import { render } from "mustache";
|
|
9
|
+
|
|
10
|
+
export function versionSelector(versions: object[]) {
|
|
11
|
+
const template = `<div class="dropdown dropdown--hoverable dropdown--right">
|
|
12
|
+
<button class="button button--block button--sm button--secondary"><span>Select API Version</span></button>
|
|
13
|
+
<ul class="dropdown__menu">
|
|
14
|
+
{{#.}}<li><a class="dropdown__link" href="{{{baseUrl}}}">{{{label}}}</a></li>{{/.}}
|
|
15
|
+
</ul>
|
|
16
|
+
</div>
|
|
17
|
+
`;
|
|
18
|
+
const view = render(template, versions);
|
|
19
|
+
return view;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function versionCrumb(version: string) {
|
|
23
|
+
const template = `<ul style="display: flex;" class="breadcrumbs breadcrumbs--sm">
|
|
24
|
+
<li style="margin-left: auto; margin-right: 0;" class="breadcrumbs__item breadcrumbs__item--active">
|
|
25
|
+
<a class="breadcrumbs__link"><span>{{{.}}}</span></a></li></ul>
|
|
26
|
+
`;
|
|
27
|
+
const view = render(template, version);
|
|
28
|
+
return view;
|
|
29
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
InfoObject,
|
|
12
12
|
OperationObject,
|
|
13
13
|
SecuritySchemeObject,
|
|
14
|
+
TagObject,
|
|
14
15
|
} from "./openapi/types";
|
|
15
16
|
|
|
16
17
|
export type {
|
|
@@ -21,6 +22,7 @@ export type {
|
|
|
21
22
|
} from "@docusaurus/plugin-content-docs-types";
|
|
22
23
|
export interface PluginOptions {
|
|
23
24
|
id?: string;
|
|
25
|
+
docPluginId: string;
|
|
24
26
|
config: {
|
|
25
27
|
[key: string]: APIOptions;
|
|
26
28
|
};
|
|
@@ -31,6 +33,27 @@ export interface APIOptions {
|
|
|
31
33
|
outputDir: string;
|
|
32
34
|
template?: string;
|
|
33
35
|
sidebarOptions?: SidebarOptions;
|
|
36
|
+
version?: string;
|
|
37
|
+
label?: string;
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
versions?: {
|
|
40
|
+
[key: string]: APIVersionOptions;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface SidebarOptions {
|
|
45
|
+
groupPathsBy?: string;
|
|
46
|
+
categoryLinkSource?: string;
|
|
47
|
+
customProps?: { [key: string]: unknown };
|
|
48
|
+
sidebarCollapsible?: boolean;
|
|
49
|
+
sidebarCollapsed?: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface APIVersionOptions {
|
|
53
|
+
specPath: string;
|
|
54
|
+
outputDir: string;
|
|
55
|
+
label: string;
|
|
56
|
+
baseUrl: string;
|
|
34
57
|
}
|
|
35
58
|
|
|
36
59
|
export interface LoadedContent {
|
|
@@ -38,7 +61,7 @@ export interface LoadedContent {
|
|
|
38
61
|
// loadedDocs: DocPageMetadata[]; TODO: cleanup
|
|
39
62
|
}
|
|
40
63
|
|
|
41
|
-
export type ApiMetadata = ApiPageMetadata | InfoPageMetadata;
|
|
64
|
+
export type ApiMetadata = ApiPageMetadata | InfoPageMetadata | TagPageMetadata;
|
|
42
65
|
|
|
43
66
|
export interface ApiMetadataBase {
|
|
44
67
|
sidebar?: string;
|
|
@@ -47,6 +70,8 @@ export interface ApiMetadataBase {
|
|
|
47
70
|
//
|
|
48
71
|
id: string; // TODO legacy versioned id => try to remove
|
|
49
72
|
unversionedId: string; // TODO new unversioned id => try to rename to "id"
|
|
73
|
+
infoId?: string;
|
|
74
|
+
infoPath?: string;
|
|
50
75
|
title: string;
|
|
51
76
|
description: string;
|
|
52
77
|
source: string; // @site aliased source => "@site/docs/folder/subFolder/subSubFolder/myDoc.md"
|
|
@@ -79,6 +104,15 @@ export interface InfoPageMetadata extends ApiMetadataBase {
|
|
|
79
104
|
type: "info";
|
|
80
105
|
info: ApiInfo;
|
|
81
106
|
markdown?: string;
|
|
107
|
+
securitySchemes?: {
|
|
108
|
+
[key: string]: SecuritySchemeObject;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface TagPageMetadata extends ApiMetadataBase {
|
|
113
|
+
type: "tag";
|
|
114
|
+
tag: TagObject;
|
|
115
|
+
markdown?: string;
|
|
82
116
|
}
|
|
83
117
|
|
|
84
118
|
export type ApiInfo = InfoObject;
|
|
@@ -87,11 +121,3 @@ export interface ApiNavLink {
|
|
|
87
121
|
title: string;
|
|
88
122
|
permalink: string;
|
|
89
123
|
}
|
|
90
|
-
|
|
91
|
-
export interface SidebarOptions {
|
|
92
|
-
groupPathsBy?: string;
|
|
93
|
-
categoryLinkSource?: string;
|
|
94
|
-
customProps?: { [key: string]: unknown };
|
|
95
|
-
sidebarCollapsible?: boolean;
|
|
96
|
-
sidebarCollapsed?: boolean;
|
|
97
|
-
}
|