docusaurus-plugin-openapi-docs 0.0.0-697 → 0.0.0-699
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 -0
- package/lib/index.js +59 -6
- package/lib/markdown/index.d.ts +2 -1
- package/lib/markdown/index.js +17 -1
- package/lib/openapi/openapi.js +38 -3
- package/lib/options.js +1 -0
- package/lib/sidebars/index.js +28 -7
- package/lib/types.d.ts +9 -2
- package/package.json +2 -2
- package/src/index.ts +110 -8
- package/src/markdown/index.ts +23 -2
- package/src/openapi/openapi.ts +46 -1
- package/src/options.ts +1 -0
- package/src/sidebars/index.ts +38 -12
- package/src/types.ts +14 -1
package/README.md
CHANGED
|
@@ -159,6 +159,7 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
|
|
|
159
159
|
| `baseUrl` | `string` | `null` | _Optional:_ Version base URL used when generating version selector dropdown menu. |
|
|
160
160
|
| `versions` | `object` | `null` | _Optional:_ Set of options for versioning configuration. See below for a list of supported options. |
|
|
161
161
|
| `markdownGenerators` | `object` | `null` | _Optional:_ Customize MDX content with a set of options for specifying markdown generator functions. See below for a list of supported options. |
|
|
162
|
+
| `showSchemas` | `boolean` | `null` | _Optional:_ If set to `true`, generates schema pages and adds them to the sidebar. |
|
|
162
163
|
|
|
163
164
|
`sidebarOptions` can be configured with the following options:
|
|
164
165
|
|
package/lib/index.js
CHANGED
|
@@ -77,7 +77,7 @@ function pluginOpenAPIDocs(context, options) {
|
|
|
77
77
|
let docRouteBasePath = docData ? docData.routeBasePath : undefined;
|
|
78
78
|
let docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
|
|
79
79
|
async function generateApiDocs(options, pluginId) {
|
|
80
|
-
var _a, _b, _c;
|
|
80
|
+
var _a, _b, _c, _d;
|
|
81
81
|
let { specPath, outputDir, template, markdownGenerators, downloadUrl, sidebarOptions, } = options;
|
|
82
82
|
// Remove trailing slash before proceeding
|
|
83
83
|
outputDir = outputDir.replace(/\/$/, "");
|
|
@@ -195,20 +195,35 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
195
195
|
<DocCardList items={useCurrentSidebarCategory().items}/>
|
|
196
196
|
\`\`\`
|
|
197
197
|
`;
|
|
198
|
+
const schemaMdTemplate = `---
|
|
199
|
+
id: {{{id}}}
|
|
200
|
+
title: "{{{title}}}"
|
|
201
|
+
description: "{{{frontMatter.description}}}"
|
|
202
|
+
sidebar_label: "{{{title}}}"
|
|
203
|
+
hide_title: true
|
|
204
|
+
schema: true
|
|
205
|
+
custom_edit_url: null
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
{{{markdown}}}
|
|
209
|
+
`;
|
|
198
210
|
const apiPageGenerator = (_a = markdownGenerators === null || markdownGenerators === void 0 ? void 0 : markdownGenerators.createApiPageMD) !== null && _a !== void 0 ? _a : markdown_1.createApiPageMD;
|
|
199
211
|
const infoPageGenerator = (_b = markdownGenerators === null || markdownGenerators === void 0 ? void 0 : markdownGenerators.createInfoPageMD) !== null && _b !== void 0 ? _b : markdown_1.createInfoPageMD;
|
|
200
212
|
const tagPageGenerator = (_c = markdownGenerators === null || markdownGenerators === void 0 ? void 0 : markdownGenerators.createTagPageMD) !== null && _c !== void 0 ? _c : markdown_1.createTagPageMD;
|
|
213
|
+
const schemaPageGenerator = (_d = markdownGenerators === null || markdownGenerators === void 0 ? void 0 : markdownGenerators.createSchemaPageMD) !== null && _d !== void 0 ? _d : markdown_1.createSchemaPageMD;
|
|
214
|
+
const pageGeneratorByType = {
|
|
215
|
+
api: apiPageGenerator,
|
|
216
|
+
info: infoPageGenerator,
|
|
217
|
+
tag: tagPageGenerator,
|
|
218
|
+
schema: schemaPageGenerator,
|
|
219
|
+
};
|
|
201
220
|
loadedApi.map(async (item) => {
|
|
202
221
|
if (item.type === "info") {
|
|
203
222
|
if (downloadUrl && isURL(downloadUrl)) {
|
|
204
223
|
item.downloadUrl = downloadUrl;
|
|
205
224
|
}
|
|
206
225
|
}
|
|
207
|
-
const markdown = item.type
|
|
208
|
-
? apiPageGenerator(item)
|
|
209
|
-
: item.type === "info"
|
|
210
|
-
? infoPageGenerator(item)
|
|
211
|
-
: tagPageGenerator(item);
|
|
226
|
+
const markdown = pageGeneratorByType[item.type](item);
|
|
212
227
|
item.markdown = markdown;
|
|
213
228
|
if (item.type === "api") {
|
|
214
229
|
// opportunity to compress JSON
|
|
@@ -274,6 +289,32 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
274
289
|
}
|
|
275
290
|
}
|
|
276
291
|
}
|
|
292
|
+
if (item.type === "schema") {
|
|
293
|
+
if (!fs_1.default.existsSync(`${outputDir}/schemas/${item.id}.schema.mdx`)) {
|
|
294
|
+
if (!fs_1.default.existsSync(`${outputDir}/schemas`)) {
|
|
295
|
+
try {
|
|
296
|
+
fs_1.default.mkdirSync(`${outputDir}/schemas`, { recursive: true });
|
|
297
|
+
console.log(chalk_1.default.green(`Successfully created "${outputDir}/schemas"`));
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
console.error(chalk_1.default.red(`Failed to create "${outputDir}/schemas"`), chalk_1.default.yellow(err));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
// kebabCase(arg) returns 0-length string when arg is undefined
|
|
305
|
+
if (item.id.length === 0) {
|
|
306
|
+
throw Error("Schema must have title defined");
|
|
307
|
+
}
|
|
308
|
+
// eslint-disable-next-line testing-library/render-result-naming-convention
|
|
309
|
+
const schemaView = (0, mustache_1.render)(schemaMdTemplate, item);
|
|
310
|
+
fs_1.default.writeFileSync(`${outputDir}/schemas/${item.id}.schema.mdx`, schemaView, "utf8");
|
|
311
|
+
console.log(chalk_1.default.green(`Successfully created "${outputDir}/${item.id}.schema.mdx"`));
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
console.error(chalk_1.default.red(`Failed to write "${outputDir}/${item.id}.schema.mdx"`), chalk_1.default.yellow(err));
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
277
318
|
return;
|
|
278
319
|
});
|
|
279
320
|
return;
|
|
@@ -290,6 +331,10 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
290
331
|
cwd: path_1.default.resolve(apiDir),
|
|
291
332
|
deep: 1,
|
|
292
333
|
});
|
|
334
|
+
const schemaMdxFiles = await (0, utils_1.Globby)(["*.schema.mdx"], {
|
|
335
|
+
cwd: path_1.default.resolve(apiDir, "schemas"),
|
|
336
|
+
deep: 1,
|
|
337
|
+
});
|
|
293
338
|
const sidebarFile = await (0, utils_1.Globby)(["sidebar.js"], {
|
|
294
339
|
cwd: path_1.default.resolve(apiDir),
|
|
295
340
|
deep: 1,
|
|
@@ -302,6 +347,14 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
302
347
|
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/${mdx}"`));
|
|
303
348
|
}
|
|
304
349
|
}));
|
|
350
|
+
schemaMdxFiles.map((mdx) => fs_1.default.unlink(`${apiDir}/schemas/${mdx}`, (err) => {
|
|
351
|
+
if (err) {
|
|
352
|
+
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/schemas/${mdx}"`), chalk_1.default.yellow(err));
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
console.log(chalk_1.default.green(`Cleanup succeeded for "${apiDir}/schemas/${mdx}"`));
|
|
356
|
+
}
|
|
357
|
+
}));
|
|
305
358
|
sidebarFile.map((sidebar) => fs_1.default.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
306
359
|
if (err) {
|
|
307
360
|
console.error(chalk_1.default.red(`Cleanup failed for "${apiDir}/${sidebar}"`), chalk_1.default.yellow(err));
|
package/lib/markdown/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
|
|
1
|
+
import { ApiPageMetadata, InfoPageMetadata, SchemaPageMetadata, TagPageMetadata } from "../types";
|
|
2
2
|
export declare function createApiPageMD({ title, api: { deprecated, "x-deprecated-description": deprecatedDescription, description, method, path, extensions, parameters, requestBody, responses, callbacks, }, infoPath, frontMatter, }: ApiPageMetadata): string;
|
|
3
3
|
export declare function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService, logo, darkLogo, }, securitySchemes, downloadUrl, }: InfoPageMetadata): string;
|
|
4
4
|
export declare function createTagPageMD({ tag: { description } }: TagPageMetadata): string;
|
|
5
|
+
export declare function createSchemaPageMD({ schema }: SchemaPageMetadata): string;
|
package/lib/markdown/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
* ========================================================================== */
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.createTagPageMD = exports.createInfoPageMD = exports.createApiPageMD = void 0;
|
|
9
|
+
exports.createSchemaPageMD = exports.createTagPageMD = exports.createInfoPageMD = exports.createApiPageMD = void 0;
|
|
10
10
|
const createAuthentication_1 = require("./createAuthentication");
|
|
11
11
|
const createAuthorization_1 = require("./createAuthorization");
|
|
12
12
|
const createCallbacks_1 = require("./createCallbacks");
|
|
@@ -21,6 +21,7 @@ const createMethodEndpoint_1 = require("./createMethodEndpoint");
|
|
|
21
21
|
const createParamsDetails_1 = require("./createParamsDetails");
|
|
22
22
|
const createRequestBodyDetails_1 = require("./createRequestBodyDetails");
|
|
23
23
|
const createRequestHeader_1 = require("./createRequestHeader");
|
|
24
|
+
const createSchema_1 = require("./createSchema");
|
|
24
25
|
const createStatusCodes_1 = require("./createStatusCodes");
|
|
25
26
|
const createTermsOfService_1 = require("./createTermsOfService");
|
|
26
27
|
const createVendorExtensions_1 = require("./createVendorExtensions");
|
|
@@ -84,3 +85,18 @@ function createTagPageMD({ tag: { description } }) {
|
|
|
84
85
|
return (0, utils_1.render)([(0, createDescription_1.createDescription)(description)]);
|
|
85
86
|
}
|
|
86
87
|
exports.createTagPageMD = createTagPageMD;
|
|
88
|
+
function createSchemaPageMD({ schema }) {
|
|
89
|
+
const { title = "", description } = schema;
|
|
90
|
+
return (0, utils_1.render)([
|
|
91
|
+
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
|
|
92
|
+
`import SchemaItem from "@theme/SchemaItem";\n`,
|
|
93
|
+
`import SchemaTabs from "@theme/SchemaTabs";\n`,
|
|
94
|
+
`import TabItem from "@theme/TabItem";\n\n`,
|
|
95
|
+
(0, createHeading_1.createHeading)(title.replace(utils_1.lessThan, "<").replace(utils_1.greaterThan, ">")),
|
|
96
|
+
(0, createDescription_1.createDescription)(description),
|
|
97
|
+
(0, utils_1.create)("ul", {
|
|
98
|
+
children: (0, createSchema_1.createNodes)(schema, "response"),
|
|
99
|
+
}),
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
exports.createSchemaPageMD = createSchemaPageMD;
|
package/lib/openapi/openapi.js
CHANGED
|
@@ -61,7 +61,7 @@ async function createPostmanCollection(openapiData) {
|
|
|
61
61
|
return await jsonToCollection(data);
|
|
62
62
|
}
|
|
63
63
|
function createItems(openapiData, options, sidebarOptions) {
|
|
64
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
64
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
|
|
65
65
|
// TODO: Find a better way to handle this
|
|
66
66
|
let items = [];
|
|
67
67
|
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
|
|
@@ -324,9 +324,42 @@ function createItems(openapiData, options, sidebarOptions) {
|
|
|
324
324
|
items.push(apiPage);
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
|
+
if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true) {
|
|
328
|
+
// Gather schemas
|
|
329
|
+
for (let [schema, schemaObject] of Object.entries((_1 = (_0 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _0 === void 0 ? void 0 : _0.schemas) !== null && _1 !== void 0 ? _1 : {})) {
|
|
330
|
+
const baseIdSpaces = (_3 = (_2 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _2 === void 0 ? void 0 : _2.replace(" ", "-").toLowerCase()) !== null && _3 !== void 0 ? _3 : "";
|
|
331
|
+
const baseId = (0, kebabCase_1.default)(baseIdSpaces);
|
|
332
|
+
const schemaDescription = schemaObject.description;
|
|
333
|
+
let splitDescription;
|
|
334
|
+
if (schemaDescription) {
|
|
335
|
+
splitDescription = schemaDescription.match(/[^\r\n]+/g);
|
|
336
|
+
}
|
|
337
|
+
const schemaPage = {
|
|
338
|
+
type: "schema",
|
|
339
|
+
id: baseId,
|
|
340
|
+
infoId: infoId !== null && infoId !== void 0 ? infoId : "",
|
|
341
|
+
unversionedId: baseId,
|
|
342
|
+
title: schemaObject.title
|
|
343
|
+
? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
344
|
+
: schema,
|
|
345
|
+
description: schemaObject.description
|
|
346
|
+
? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
347
|
+
: "",
|
|
348
|
+
frontMatter: {
|
|
349
|
+
description: splitDescription
|
|
350
|
+
? splitDescription[0]
|
|
351
|
+
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
352
|
+
.replace(/\s+$/, "")
|
|
353
|
+
: "",
|
|
354
|
+
},
|
|
355
|
+
schema: schemaObject,
|
|
356
|
+
};
|
|
357
|
+
items.push(schemaPage);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
327
360
|
if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
|
|
328
361
|
// Get global tags
|
|
329
|
-
const tags = (
|
|
362
|
+
const tags = (_4 = openapiData.tags) !== null && _4 !== void 0 ? _4 : [];
|
|
330
363
|
// Get operation tags
|
|
331
364
|
const apiItems = items.filter((item) => {
|
|
332
365
|
return item.type === "api";
|
|
@@ -375,7 +408,9 @@ function bindCollectionToApiItems(items, postmanCollection) {
|
|
|
375
408
|
.getPath({ unresolved: true }) // unresolved returns "/:variableName" instead of "/<type>"
|
|
376
409
|
.replace(/(?<![a-z0-9-_]+):([a-z0-9-_]+)/gi, "{$1}"); // replace "/:variableName" with "/{variableName}"
|
|
377
410
|
const apiItem = items.find((item) => {
|
|
378
|
-
if (item.type === "info" ||
|
|
411
|
+
if (item.type === "info" ||
|
|
412
|
+
item.type === "tag" ||
|
|
413
|
+
item.type === "schema") {
|
|
379
414
|
return false;
|
|
380
415
|
}
|
|
381
416
|
return item.api.path === path && item.api.method === method;
|
package/lib/options.js
CHANGED
|
@@ -34,6 +34,7 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
|
|
|
34
34
|
showExtensions: utils_validation_1.Joi.boolean(),
|
|
35
35
|
sidebarOptions: sidebarOptions,
|
|
36
36
|
markdownGenerators: markdownGenerators,
|
|
37
|
+
showSchemas: utils_validation_1.Joi.boolean(),
|
|
37
38
|
version: utils_validation_1.Joi.string().when("versions", {
|
|
38
39
|
is: utils_validation_1.Joi.exist(),
|
|
39
40
|
then: utils_validation_1.Joi.required(),
|
package/lib/sidebars/index.js
CHANGED
|
@@ -20,6 +20,9 @@ function isApiItem(item) {
|
|
|
20
20
|
function isInfoItem(item) {
|
|
21
21
|
return item.type === "info";
|
|
22
22
|
}
|
|
23
|
+
function isSchemaItem(item) {
|
|
24
|
+
return item.type === "schema";
|
|
25
|
+
}
|
|
23
26
|
function groupByTags(items, sidebarOptions, options, tags, docPath) {
|
|
24
27
|
let { outputDir, label } = options;
|
|
25
28
|
// Remove trailing slash before proceeding
|
|
@@ -27,6 +30,7 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
|
|
|
27
30
|
const { sidebarCollapsed, sidebarCollapsible, customProps, categoryLinkSource, } = sidebarOptions;
|
|
28
31
|
const apiItems = items.filter(isApiItem);
|
|
29
32
|
const infoItems = items.filter(isInfoItem);
|
|
33
|
+
const schemaItems = items.filter(isSchemaItem);
|
|
30
34
|
const intros = infoItems.map((item) => {
|
|
31
35
|
return {
|
|
32
36
|
id: item.id,
|
|
@@ -56,16 +60,21 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
|
|
|
56
60
|
var _a, _b;
|
|
57
61
|
const sidebar_label = item.frontMatter.sidebar_label;
|
|
58
62
|
const title = item.title;
|
|
59
|
-
const id = item.id;
|
|
63
|
+
const id = item.type === "schema" ? `schemas/${item.id}` : item.id;
|
|
64
|
+
const className = item.type === "api"
|
|
65
|
+
? (0, clsx_1.default)({
|
|
66
|
+
"menu__list-item--deprecated": item.api.deprecated,
|
|
67
|
+
"api-method": !!item.api.method,
|
|
68
|
+
}, item.api.method)
|
|
69
|
+
: (0, clsx_1.default)({
|
|
70
|
+
"menu__list-item--deprecated": item.schema.deprecated,
|
|
71
|
+
});
|
|
60
72
|
return {
|
|
61
73
|
type: "doc",
|
|
62
|
-
id: basePath === "" || undefined ? `${
|
|
74
|
+
id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
|
|
63
75
|
label: (_b = (_a = sidebar_label) !== null && _a !== void 0 ? _a : title) !== null && _b !== void 0 ? _b : id,
|
|
64
76
|
customProps: customProps,
|
|
65
|
-
className:
|
|
66
|
-
"menu__list-item--deprecated": item.api.deprecated,
|
|
67
|
-
"api-method": !!item.api.method,
|
|
68
|
-
}, item.api.method),
|
|
77
|
+
className: className ? className : undefined,
|
|
69
78
|
};
|
|
70
79
|
}
|
|
71
80
|
let rootIntroDoc = undefined;
|
|
@@ -147,12 +156,24 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
|
|
|
147
156
|
},
|
|
148
157
|
];
|
|
149
158
|
}
|
|
159
|
+
let schemas = [];
|
|
160
|
+
if (schemaItems.length > 0) {
|
|
161
|
+
schemas = [
|
|
162
|
+
{
|
|
163
|
+
type: "category",
|
|
164
|
+
label: "Schemas",
|
|
165
|
+
collapsible: sidebarCollapsible,
|
|
166
|
+
collapsed: sidebarCollapsed,
|
|
167
|
+
items: schemaItems.map(createDocItem),
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
}
|
|
150
171
|
// Shift root intro doc to top of sidebar
|
|
151
172
|
// TODO: Add input validation for categoryLinkSource options
|
|
152
173
|
if (rootIntroDoc && categoryLinkSource !== "info") {
|
|
153
174
|
tagged.unshift(rootIntroDoc);
|
|
154
175
|
}
|
|
155
|
-
return [...tagged, ...untagged];
|
|
176
|
+
return [...tagged, ...untagged, ...schemas];
|
|
156
177
|
}
|
|
157
178
|
function generateSidebarSlice(sidebarOptions, options, api, tags, docPath) {
|
|
158
179
|
let sidebarSlice = [];
|
package/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type Request from "@paloaltonetworks/postman-collection";
|
|
2
|
-
import { InfoObject, OperationObject, SecuritySchemeObject, TagObject } from "./openapi/types";
|
|
2
|
+
import { InfoObject, OperationObject, SchemaObject, SecuritySchemeObject, TagObject } from "./openapi/types";
|
|
3
3
|
export type { PropSidebarItemCategory, SidebarItemLink, PropSidebar, PropSidebarItem, } from "@docusaurus/plugin-content-docs-types";
|
|
4
4
|
export interface PluginOptions {
|
|
5
5
|
id?: string;
|
|
@@ -24,11 +24,13 @@ export interface APIOptions {
|
|
|
24
24
|
};
|
|
25
25
|
proxy?: string;
|
|
26
26
|
markdownGenerators?: MarkdownGenerator;
|
|
27
|
+
showSchemas?: boolean;
|
|
27
28
|
}
|
|
28
29
|
export interface MarkdownGenerator {
|
|
29
30
|
createApiPageMD?: (pageData: ApiPageMetadata) => string;
|
|
30
31
|
createInfoPageMD?: (pageData: InfoPageMetadata) => string;
|
|
31
32
|
createTagPageMD?: (pageData: TagPageMetadata) => string;
|
|
33
|
+
createSchemaPageMD?: (pageData: SchemaPageMetadata) => string;
|
|
32
34
|
}
|
|
33
35
|
export interface SidebarOptions {
|
|
34
36
|
groupPathsBy?: string;
|
|
@@ -48,7 +50,7 @@ export interface APIVersionOptions {
|
|
|
48
50
|
export interface LoadedContent {
|
|
49
51
|
loadedApi: ApiMetadata[];
|
|
50
52
|
}
|
|
51
|
-
export declare type ApiMetadata = ApiPageMetadata | InfoPageMetadata | TagPageMetadata;
|
|
53
|
+
export declare type ApiMetadata = ApiPageMetadata | InfoPageMetadata | TagPageMetadata | SchemaPageMetadata;
|
|
52
54
|
export interface ApiMetadataBase {
|
|
53
55
|
sidebar?: string;
|
|
54
56
|
previous?: ApiNavLink;
|
|
@@ -100,6 +102,11 @@ export interface TagPageMetadata extends ApiMetadataBase {
|
|
|
100
102
|
tag: TagObject;
|
|
101
103
|
markdown?: string;
|
|
102
104
|
}
|
|
105
|
+
export interface SchemaPageMetadata extends ApiMetadataBase {
|
|
106
|
+
type: "schema";
|
|
107
|
+
schema: SchemaObject;
|
|
108
|
+
markdown?: string;
|
|
109
|
+
}
|
|
103
110
|
export declare type ApiInfo = InfoObject;
|
|
104
111
|
export interface ApiNavLink {
|
|
105
112
|
title: string;
|
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-699",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"engines": {
|
|
61
61
|
"node": ">=14"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "ef318267f54c34bedf50f0b309c9bb30fd665b53"
|
|
64
64
|
}
|
package/src/index.ts
CHANGED
|
@@ -14,11 +14,25 @@ import { Globby, posixPath } from "@docusaurus/utils";
|
|
|
14
14
|
import chalk from "chalk";
|
|
15
15
|
import { render } from "mustache";
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
createApiPageMD,
|
|
19
|
+
createInfoPageMD,
|
|
20
|
+
createSchemaPageMD,
|
|
21
|
+
createTagPageMD,
|
|
22
|
+
} from "./markdown";
|
|
18
23
|
import { readOpenapiFiles, processOpenapiFiles } from "./openapi";
|
|
19
24
|
import { OptionsSchema } from "./options";
|
|
20
25
|
import generateSidebarSlice from "./sidebars";
|
|
21
|
-
import type {
|
|
26
|
+
import type {
|
|
27
|
+
PluginOptions,
|
|
28
|
+
LoadedContent,
|
|
29
|
+
APIOptions,
|
|
30
|
+
ApiMetadata,
|
|
31
|
+
ApiPageMetadata,
|
|
32
|
+
InfoPageMetadata,
|
|
33
|
+
TagPageMetadata,
|
|
34
|
+
SchemaPageMetadata,
|
|
35
|
+
} from "./types";
|
|
22
36
|
|
|
23
37
|
export function isURL(str: string): boolean {
|
|
24
38
|
return /^(https?:)\/\//m.test(str);
|
|
@@ -244,12 +258,43 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
244
258
|
\`\`\`
|
|
245
259
|
`;
|
|
246
260
|
|
|
261
|
+
const schemaMdTemplate = `---
|
|
262
|
+
id: {{{id}}}
|
|
263
|
+
title: "{{{title}}}"
|
|
264
|
+
description: "{{{frontMatter.description}}}"
|
|
265
|
+
sidebar_label: "{{{title}}}"
|
|
266
|
+
hide_title: true
|
|
267
|
+
schema: true
|
|
268
|
+
custom_edit_url: null
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
{{{markdown}}}
|
|
272
|
+
`;
|
|
273
|
+
|
|
247
274
|
const apiPageGenerator =
|
|
248
275
|
markdownGenerators?.createApiPageMD ?? createApiPageMD;
|
|
249
276
|
const infoPageGenerator =
|
|
250
277
|
markdownGenerators?.createInfoPageMD ?? createInfoPageMD;
|
|
251
278
|
const tagPageGenerator =
|
|
252
279
|
markdownGenerators?.createTagPageMD ?? createTagPageMD;
|
|
280
|
+
const schemaPageGenerator =
|
|
281
|
+
markdownGenerators?.createSchemaPageMD ?? createSchemaPageMD;
|
|
282
|
+
|
|
283
|
+
const pageGeneratorByType: {
|
|
284
|
+
[key in ApiMetadata["type"]]: (
|
|
285
|
+
pageData: {
|
|
286
|
+
api: ApiPageMetadata;
|
|
287
|
+
info: InfoPageMetadata;
|
|
288
|
+
tag: TagPageMetadata;
|
|
289
|
+
schema: SchemaPageMetadata;
|
|
290
|
+
}[key]
|
|
291
|
+
) => string;
|
|
292
|
+
} = {
|
|
293
|
+
api: apiPageGenerator,
|
|
294
|
+
info: infoPageGenerator,
|
|
295
|
+
tag: tagPageGenerator,
|
|
296
|
+
schema: schemaPageGenerator,
|
|
297
|
+
};
|
|
253
298
|
|
|
254
299
|
loadedApi.map(async (item) => {
|
|
255
300
|
if (item.type === "info") {
|
|
@@ -257,12 +302,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
257
302
|
item.downloadUrl = downloadUrl;
|
|
258
303
|
}
|
|
259
304
|
}
|
|
260
|
-
const markdown =
|
|
261
|
-
item.type === "api"
|
|
262
|
-
? apiPageGenerator(item)
|
|
263
|
-
: item.type === "info"
|
|
264
|
-
? infoPageGenerator(item)
|
|
265
|
-
: tagPageGenerator(item);
|
|
305
|
+
const markdown = pageGeneratorByType[item.type](item as any);
|
|
266
306
|
item.markdown = markdown;
|
|
267
307
|
if (item.type === "api") {
|
|
268
308
|
// opportunity to compress JSON
|
|
@@ -363,6 +403,49 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
363
403
|
}
|
|
364
404
|
}
|
|
365
405
|
}
|
|
406
|
+
|
|
407
|
+
if (item.type === "schema") {
|
|
408
|
+
if (!fs.existsSync(`${outputDir}/schemas/${item.id}.schema.mdx`)) {
|
|
409
|
+
if (!fs.existsSync(`${outputDir}/schemas`)) {
|
|
410
|
+
try {
|
|
411
|
+
fs.mkdirSync(`${outputDir}/schemas`, { recursive: true });
|
|
412
|
+
console.log(
|
|
413
|
+
chalk.green(`Successfully created "${outputDir}/schemas"`)
|
|
414
|
+
);
|
|
415
|
+
} catch (err) {
|
|
416
|
+
console.error(
|
|
417
|
+
chalk.red(`Failed to create "${outputDir}/schemas"`),
|
|
418
|
+
chalk.yellow(err)
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
// kebabCase(arg) returns 0-length string when arg is undefined
|
|
424
|
+
if (item.id.length === 0) {
|
|
425
|
+
throw Error("Schema must have title defined");
|
|
426
|
+
}
|
|
427
|
+
// eslint-disable-next-line testing-library/render-result-naming-convention
|
|
428
|
+
const schemaView = render(schemaMdTemplate, item);
|
|
429
|
+
fs.writeFileSync(
|
|
430
|
+
`${outputDir}/schemas/${item.id}.schema.mdx`,
|
|
431
|
+
schemaView,
|
|
432
|
+
"utf8"
|
|
433
|
+
);
|
|
434
|
+
console.log(
|
|
435
|
+
chalk.green(
|
|
436
|
+
`Successfully created "${outputDir}/${item.id}.schema.mdx"`
|
|
437
|
+
)
|
|
438
|
+
);
|
|
439
|
+
} catch (err) {
|
|
440
|
+
console.error(
|
|
441
|
+
chalk.red(
|
|
442
|
+
`Failed to write "${outputDir}/${item.id}.schema.mdx"`
|
|
443
|
+
),
|
|
444
|
+
chalk.yellow(err)
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
366
449
|
return;
|
|
367
450
|
});
|
|
368
451
|
|
|
@@ -380,6 +463,10 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
380
463
|
cwd: path.resolve(apiDir),
|
|
381
464
|
deep: 1,
|
|
382
465
|
});
|
|
466
|
+
const schemaMdxFiles = await Globby(["*.schema.mdx"], {
|
|
467
|
+
cwd: path.resolve(apiDir, "schemas"),
|
|
468
|
+
deep: 1,
|
|
469
|
+
});
|
|
383
470
|
const sidebarFile = await Globby(["sidebar.js"], {
|
|
384
471
|
cwd: path.resolve(apiDir),
|
|
385
472
|
deep: 1,
|
|
@@ -397,6 +484,21 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|
|
397
484
|
})
|
|
398
485
|
);
|
|
399
486
|
|
|
487
|
+
schemaMdxFiles.map((mdx) =>
|
|
488
|
+
fs.unlink(`${apiDir}/schemas/${mdx}`, (err) => {
|
|
489
|
+
if (err) {
|
|
490
|
+
console.error(
|
|
491
|
+
chalk.red(`Cleanup failed for "${apiDir}/schemas/${mdx}"`),
|
|
492
|
+
chalk.yellow(err)
|
|
493
|
+
);
|
|
494
|
+
} else {
|
|
495
|
+
console.log(
|
|
496
|
+
chalk.green(`Cleanup succeeded for "${apiDir}/schemas/${mdx}"`)
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
})
|
|
500
|
+
);
|
|
501
|
+
|
|
400
502
|
sidebarFile.map((sidebar) =>
|
|
401
503
|
fs.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
402
504
|
if (err) {
|
package/src/markdown/index.ts
CHANGED
|
@@ -11,7 +11,12 @@ import {
|
|
|
11
11
|
MediaTypeObject,
|
|
12
12
|
SecuritySchemeObject,
|
|
13
13
|
} from "../openapi/types";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
ApiPageMetadata,
|
|
16
|
+
InfoPageMetadata,
|
|
17
|
+
SchemaPageMetadata,
|
|
18
|
+
TagPageMetadata,
|
|
19
|
+
} from "../types";
|
|
15
20
|
import { createAuthentication } from "./createAuthentication";
|
|
16
21
|
import { createAuthorization } from "./createAuthorization";
|
|
17
22
|
import { createCallbacks } from "./createCallbacks";
|
|
@@ -26,11 +31,12 @@ import { createMethodEndpoint } from "./createMethodEndpoint";
|
|
|
26
31
|
import { createParamsDetails } from "./createParamsDetails";
|
|
27
32
|
import { createRequestBodyDetails } from "./createRequestBodyDetails";
|
|
28
33
|
import { createRequestHeader } from "./createRequestHeader";
|
|
34
|
+
import { createNodes } from "./createSchema";
|
|
29
35
|
import { createStatusCodes } from "./createStatusCodes";
|
|
30
36
|
import { createTermsOfService } from "./createTermsOfService";
|
|
31
37
|
import { createVendorExtensions } from "./createVendorExtensions";
|
|
32
38
|
import { createVersionBadge } from "./createVersionBadge";
|
|
33
|
-
import { greaterThan, lessThan, render } from "./utils";
|
|
39
|
+
import { create, greaterThan, lessThan, render } from "./utils";
|
|
34
40
|
|
|
35
41
|
interface RequestBodyProps {
|
|
36
42
|
title: string;
|
|
@@ -130,3 +136,18 @@ export function createInfoPageMD({
|
|
|
130
136
|
export function createTagPageMD({ tag: { description } }: TagPageMetadata) {
|
|
131
137
|
return render([createDescription(description)]);
|
|
132
138
|
}
|
|
139
|
+
|
|
140
|
+
export function createSchemaPageMD({ schema }: SchemaPageMetadata) {
|
|
141
|
+
const { title = "", description } = schema;
|
|
142
|
+
return render([
|
|
143
|
+
`import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
|
|
144
|
+
`import SchemaItem from "@theme/SchemaItem";\n`,
|
|
145
|
+
`import SchemaTabs from "@theme/SchemaTabs";\n`,
|
|
146
|
+
`import TabItem from "@theme/TabItem";\n\n`,
|
|
147
|
+
createHeading(title.replace(lessThan, "<").replace(greaterThan, ">")),
|
|
148
|
+
createDescription(description),
|
|
149
|
+
create("ul", {
|
|
150
|
+
children: createNodes(schema, "response"),
|
|
151
|
+
}),
|
|
152
|
+
]);
|
|
153
|
+
}
|
package/src/openapi/openapi.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
APIOptions,
|
|
25
25
|
ApiPageMetadata,
|
|
26
26
|
InfoPageMetadata,
|
|
27
|
+
SchemaPageMetadata,
|
|
27
28
|
SidebarOptions,
|
|
28
29
|
TagPageMetadata,
|
|
29
30
|
} from "../types";
|
|
@@ -409,6 +410,46 @@ function createItems(
|
|
|
409
410
|
}
|
|
410
411
|
}
|
|
411
412
|
|
|
413
|
+
if (options?.showSchemas === true) {
|
|
414
|
+
// Gather schemas
|
|
415
|
+
for (let [schema, schemaObject] of Object.entries(
|
|
416
|
+
openapiData?.components?.schemas ?? {}
|
|
417
|
+
)) {
|
|
418
|
+
const baseIdSpaces =
|
|
419
|
+
schemaObject?.title?.replace(" ", "-").toLowerCase() ?? "";
|
|
420
|
+
const baseId = kebabCase(baseIdSpaces);
|
|
421
|
+
|
|
422
|
+
const schemaDescription = schemaObject.description;
|
|
423
|
+
let splitDescription: any;
|
|
424
|
+
if (schemaDescription) {
|
|
425
|
+
splitDescription = schemaDescription.match(/[^\r\n]+/g);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const schemaPage: PartialPage<SchemaPageMetadata> = {
|
|
429
|
+
type: "schema",
|
|
430
|
+
id: baseId,
|
|
431
|
+
infoId: infoId ?? "",
|
|
432
|
+
unversionedId: baseId,
|
|
433
|
+
title: schemaObject.title
|
|
434
|
+
? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
435
|
+
: schema,
|
|
436
|
+
description: schemaObject.description
|
|
437
|
+
? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
438
|
+
: "",
|
|
439
|
+
frontMatter: {
|
|
440
|
+
description: splitDescription
|
|
441
|
+
? splitDescription[0]
|
|
442
|
+
.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
|
|
443
|
+
.replace(/\s+$/, "")
|
|
444
|
+
: "",
|
|
445
|
+
},
|
|
446
|
+
schema: schemaObject,
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
items.push(schemaPage);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
412
453
|
if (sidebarOptions?.categoryLinkSource === "tag") {
|
|
413
454
|
// Get global tags
|
|
414
455
|
const tags: TagObject[] = openapiData.tags ?? [];
|
|
@@ -471,7 +512,11 @@ function bindCollectionToApiItems(
|
|
|
471
512
|
.getPath({ unresolved: true }) // unresolved returns "/:variableName" instead of "/<type>"
|
|
472
513
|
.replace(/(?<![a-z0-9-_]+):([a-z0-9-_]+)/gi, "{$1}"); // replace "/:variableName" with "/{variableName}"
|
|
473
514
|
const apiItem = items.find((item) => {
|
|
474
|
-
if (
|
|
515
|
+
if (
|
|
516
|
+
item.type === "info" ||
|
|
517
|
+
item.type === "tag" ||
|
|
518
|
+
item.type === "schema"
|
|
519
|
+
) {
|
|
475
520
|
return false;
|
|
476
521
|
}
|
|
477
522
|
return item.api.path === path && item.api.method === method;
|
package/src/options.ts
CHANGED
|
@@ -37,6 +37,7 @@ export const OptionsSchema = Joi.object({
|
|
|
37
37
|
showExtensions: Joi.boolean(),
|
|
38
38
|
sidebarOptions: sidebarOptions,
|
|
39
39
|
markdownGenerators: markdownGenerators,
|
|
40
|
+
showSchemas: Joi.boolean(),
|
|
40
41
|
version: Joi.string().when("versions", {
|
|
41
42
|
is: Joi.exist(),
|
|
42
43
|
then: Joi.required(),
|
package/src/sidebars/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
APIOptions,
|
|
25
25
|
ApiPageMetadata,
|
|
26
26
|
ApiMetadata,
|
|
27
|
+
SchemaPageMetadata,
|
|
27
28
|
} from "../types";
|
|
28
29
|
|
|
29
30
|
function isApiItem(item: ApiMetadata): item is ApiMetadata {
|
|
@@ -34,6 +35,10 @@ function isInfoItem(item: ApiMetadata): item is ApiMetadata {
|
|
|
34
35
|
return item.type === "info";
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
function isSchemaItem(item: ApiMetadata): item is ApiMetadata {
|
|
39
|
+
return item.type === "schema";
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
function groupByTags(
|
|
38
43
|
items: ApiPageMetadata[],
|
|
39
44
|
sidebarOptions: SidebarOptions,
|
|
@@ -55,6 +60,7 @@ function groupByTags(
|
|
|
55
60
|
|
|
56
61
|
const apiItems = items.filter(isApiItem);
|
|
57
62
|
const infoItems = items.filter(isInfoItem);
|
|
63
|
+
const schemaItems = items.filter(isSchemaItem);
|
|
58
64
|
const intros = infoItems.map((item: any) => {
|
|
59
65
|
return {
|
|
60
66
|
id: item.id,
|
|
@@ -85,23 +91,30 @@ function groupByTags(
|
|
|
85
91
|
const basePath = docPath
|
|
86
92
|
? outputDir.split(docPath!)[1].replace(/^\/+/g, "")
|
|
87
93
|
: outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
|
|
88
|
-
function createDocItem(
|
|
94
|
+
function createDocItem(
|
|
95
|
+
item: ApiPageMetadata | SchemaPageMetadata
|
|
96
|
+
): SidebarItemDoc {
|
|
89
97
|
const sidebar_label = item.frontMatter.sidebar_label;
|
|
90
98
|
const title = item.title;
|
|
91
|
-
const id = item.id;
|
|
99
|
+
const id = item.type === "schema" ? `schemas/${item.id}` : item.id;
|
|
100
|
+
const className =
|
|
101
|
+
item.type === "api"
|
|
102
|
+
? clsx(
|
|
103
|
+
{
|
|
104
|
+
"menu__list-item--deprecated": item.api.deprecated,
|
|
105
|
+
"api-method": !!item.api.method,
|
|
106
|
+
},
|
|
107
|
+
item.api.method
|
|
108
|
+
)
|
|
109
|
+
: clsx({
|
|
110
|
+
"menu__list-item--deprecated": item.schema.deprecated,
|
|
111
|
+
});
|
|
92
112
|
return {
|
|
93
113
|
type: "doc" as const,
|
|
94
|
-
id:
|
|
95
|
-
basePath === "" || undefined ? `${item.id}` : `${basePath}/${item.id}`,
|
|
114
|
+
id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
|
|
96
115
|
label: (sidebar_label as string) ?? title ?? id,
|
|
97
116
|
customProps: customProps,
|
|
98
|
-
className:
|
|
99
|
-
{
|
|
100
|
-
"menu__list-item--deprecated": item.api.deprecated,
|
|
101
|
-
"api-method": !!item.api.method,
|
|
102
|
-
},
|
|
103
|
-
item.api.method
|
|
104
|
-
),
|
|
117
|
+
className: className ? className : undefined,
|
|
105
118
|
};
|
|
106
119
|
}
|
|
107
120
|
|
|
@@ -201,13 +214,26 @@ function groupByTags(
|
|
|
201
214
|
];
|
|
202
215
|
}
|
|
203
216
|
|
|
217
|
+
let schemas: SidebarItemCategory[] = [];
|
|
218
|
+
if (schemaItems.length > 0) {
|
|
219
|
+
schemas = [
|
|
220
|
+
{
|
|
221
|
+
type: "category" as const,
|
|
222
|
+
label: "Schemas",
|
|
223
|
+
collapsible: sidebarCollapsible!,
|
|
224
|
+
collapsed: sidebarCollapsed!,
|
|
225
|
+
items: schemaItems.map(createDocItem),
|
|
226
|
+
},
|
|
227
|
+
];
|
|
228
|
+
}
|
|
229
|
+
|
|
204
230
|
// Shift root intro doc to top of sidebar
|
|
205
231
|
// TODO: Add input validation for categoryLinkSource options
|
|
206
232
|
if (rootIntroDoc && categoryLinkSource !== "info") {
|
|
207
233
|
tagged.unshift(rootIntroDoc as any);
|
|
208
234
|
}
|
|
209
235
|
|
|
210
|
-
return [...tagged, ...untagged];
|
|
236
|
+
return [...tagged, ...untagged, ...schemas];
|
|
211
237
|
}
|
|
212
238
|
|
|
213
239
|
export default function generateSidebarSlice(
|
package/src/types.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type Request from "@paloaltonetworks/postman-collection";
|
|
|
10
10
|
import {
|
|
11
11
|
InfoObject,
|
|
12
12
|
OperationObject,
|
|
13
|
+
SchemaObject,
|
|
13
14
|
SecuritySchemeObject,
|
|
14
15
|
TagObject,
|
|
15
16
|
} from "./openapi/types";
|
|
@@ -44,12 +45,14 @@ export interface APIOptions {
|
|
|
44
45
|
};
|
|
45
46
|
proxy?: string;
|
|
46
47
|
markdownGenerators?: MarkdownGenerator;
|
|
48
|
+
showSchemas?: boolean;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
export interface MarkdownGenerator {
|
|
50
52
|
createApiPageMD?: (pageData: ApiPageMetadata) => string;
|
|
51
53
|
createInfoPageMD?: (pageData: InfoPageMetadata) => string;
|
|
52
54
|
createTagPageMD?: (pageData: TagPageMetadata) => string;
|
|
55
|
+
createSchemaPageMD?: (pageData: SchemaPageMetadata) => string;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
export interface SidebarOptions {
|
|
@@ -72,7 +75,11 @@ export interface LoadedContent {
|
|
|
72
75
|
// loadedDocs: DocPageMetadata[]; TODO: cleanup
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
export type ApiMetadata =
|
|
78
|
+
export type ApiMetadata =
|
|
79
|
+
| ApiPageMetadata
|
|
80
|
+
| InfoPageMetadata
|
|
81
|
+
| TagPageMetadata
|
|
82
|
+
| SchemaPageMetadata;
|
|
76
83
|
|
|
77
84
|
export interface ApiMetadataBase {
|
|
78
85
|
sidebar?: string;
|
|
@@ -131,6 +138,12 @@ export interface TagPageMetadata extends ApiMetadataBase {
|
|
|
131
138
|
markdown?: string;
|
|
132
139
|
}
|
|
133
140
|
|
|
141
|
+
export interface SchemaPageMetadata extends ApiMetadataBase {
|
|
142
|
+
type: "schema";
|
|
143
|
+
schema: SchemaObject;
|
|
144
|
+
markdown?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
134
147
|
export type ApiInfo = InfoObject;
|
|
135
148
|
|
|
136
149
|
export interface ApiNavLink {
|