docusaurus-plugin-openapi-docs 2.0.4 → 2.1.0

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.
Files changed (47) hide show
  1. package/README.md +2 -0
  2. package/lib/index.js +61 -8
  3. package/lib/markdown/createStatusCodes.js +1 -1
  4. package/lib/markdown/index.d.ts +2 -1
  5. package/lib/markdown/index.js +18 -2
  6. package/lib/markdown/utils.d.ts +2 -2
  7. package/lib/openapi/openapi.d.ts +3 -3
  8. package/lib/openapi/openapi.js +60 -7
  9. package/lib/openapi/openapi.test.js +2 -0
  10. package/lib/openapi/types.d.ts +18 -13
  11. package/lib/openapi/utils/services/OpenAPIParser.d.ts +1 -1
  12. package/lib/openapi/utils/services/OpenAPIParser.js +2 -1
  13. package/lib/openapi/utils/services/RedocNormalizedOptions.js +49 -49
  14. package/lib/openapi/utils/types/index.d.ts +1 -1
  15. package/lib/openapi/utils/types/open-api.d.ts +4 -4
  16. package/lib/openapi/utils/types.d.ts +5 -5
  17. package/lib/options.js +2 -1
  18. package/lib/sidebars/index.d.ts +2 -2
  19. package/lib/sidebars/index.js +50 -10
  20. package/lib/types.d.ts +16 -3
  21. package/package.json +2 -2
  22. package/src/index.ts +113 -10
  23. package/src/markdown/createAuthentication.ts +1 -1
  24. package/src/markdown/createCallbacks.ts +2 -2
  25. package/src/markdown/createContactInfo.ts +1 -1
  26. package/src/markdown/createLicense.ts +1 -1
  27. package/src/markdown/createLogo.ts +1 -1
  28. package/src/markdown/createParamsDetails.ts +1 -1
  29. package/src/markdown/createRequestBodyDetails.ts +1 -1
  30. package/src/markdown/createRequestSchema.ts +1 -1
  31. package/src/markdown/createResponseSchema.ts +1 -1
  32. package/src/markdown/createSchema.test.ts +1 -1
  33. package/src/markdown/createSchema.ts +1 -1
  34. package/src/markdown/createStatusCodes.ts +2 -2
  35. package/src/markdown/index.ts +30 -9
  36. package/src/openapi/__fixtures__/examples/openapi.yaml +29 -0
  37. package/src/openapi/createRequestExample.ts +1 -1
  38. package/src/openapi/createResponseExample.ts +1 -1
  39. package/src/openapi/openapi.test.ts +3 -0
  40. package/src/openapi/openapi.ts +77 -9
  41. package/src/openapi/types.ts +6 -0
  42. package/src/openapi/utils/loadAndResolveSpec.ts +1 -1
  43. package/src/openapi/utils/services/OpenAPIParser.ts +1 -1
  44. package/src/openapi/utils/utils/openapi.ts +7 -7
  45. package/src/options.ts +2 -1
  46. package/src/sidebars/index.ts +71 -16
  47. package/src/types.ts +21 -1
@@ -1,4 +1,4 @@
1
- declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
1
+ type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
2
2
  export interface OpenAPISpec {
3
3
  openapi: string;
4
4
  info: OpenAPIInfo;
@@ -38,7 +38,7 @@ export interface OpenAPIPaths {
38
38
  export interface OpenAPIRef {
39
39
  $ref: string;
40
40
  }
41
- export declare type Referenced<T> = OpenAPIRef | T;
41
+ export type Referenced<T> = OpenAPIRef | T;
42
42
  export interface OpenAPIPath {
43
43
  summary?: string;
44
44
  description?: string;
@@ -182,8 +182,8 @@ export interface OpenAPIEncoding {
182
182
  explode: boolean;
183
183
  allowReserved: boolean;
184
184
  }
185
- export declare type OpenAPIParameterLocation = "query" | "header" | "path" | "cookie";
186
- export declare type OpenAPIParameterStyle = "matrix" | "label" | "form" | "simple" | "spaceDelimited" | "pipeDelimited" | "deepObject";
185
+ export type OpenAPIParameterLocation = "query" | "header" | "path" | "cookie";
186
+ export type OpenAPIParameterStyle = "matrix" | "label" | "form" | "simple" | "spaceDelimited" | "pipeDelimited" | "deepObject";
187
187
  export interface OpenAPIRequestBody {
188
188
  description?: string;
189
189
  required?: boolean;
@@ -216,7 +216,7 @@ export interface OpenAPIResponse extends Pick<OpenAPIRequestBody, "description"
216
216
  export interface OpenAPILink {
217
217
  $ref?: string;
218
218
  }
219
- export declare type OpenAPIHeader = Omit<OpenAPIParameter, "in" | "name">;
219
+ export type OpenAPIHeader = Omit<OpenAPIParameter, "in" | "name">;
220
220
  export interface OpenAPICallback {
221
221
  [name: string]: OpenAPIPath;
222
222
  }
package/lib/options.js CHANGED
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.OptionsSchema = void 0;
10
10
  const utils_validation_1 = require("@docusaurus/utils-validation");
11
11
  const sidebarOptions = utils_validation_1.Joi.object({
12
- groupPathsBy: utils_validation_1.Joi.string().valid("tag"),
12
+ groupPathsBy: utils_validation_1.Joi.string().valid("tag", "tagGroup"),
13
13
  categoryLinkSource: utils_validation_1.Joi.string().valid("tag", "info", "auto"),
14
14
  customProps: utils_validation_1.Joi.object(),
15
15
  sidebarCollapsible: utils_validation_1.Joi.boolean(),
@@ -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(),
@@ -1,4 +1,4 @@
1
1
  import { ProcessedSidebar } from "@docusaurus/plugin-content-docs/src/sidebars/types";
2
- import { TagObject } from "../openapi/types";
2
+ import { TagGroupObject, TagObject } from "../openapi/types";
3
3
  import type { SidebarOptions, APIOptions, ApiMetadata } from "../types";
4
- export default function generateSidebarSlice(sidebarOptions: SidebarOptions, options: APIOptions, api: ApiMetadata[], tags: TagObject[][], docPath: string): ProcessedSidebar;
4
+ export default function generateSidebarSlice(sidebarOptions: SidebarOptions, options: APIOptions, api: ApiMetadata[], tags: TagObject[][], docPath: string, tagGroups?: TagGroupObject[]): ProcessedSidebar;
@@ -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,
@@ -48,7 +52,7 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
48
52
  apiTags.push(tag.name);
49
53
  }
50
54
  });
51
- apiTags = (0, uniq_1.default)(apiTags.concat(operationTags));
55
+ // apiTags = uniq(apiTags.concat(operationTags));
52
56
  const basePath = docPath
53
57
  ? outputDir.split(docPath)[1].replace(/^\/+/g, "")
54
58
  : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
@@ -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 ? `${item.id}` : `${basePath}/${item.id}`,
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: (0, clsx_1.default)({
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,16 +156,47 @@ 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
- function generateSidebarSlice(sidebarOptions, options, api, tags, docPath) {
178
+ function generateSidebarSlice(sidebarOptions, options, api, tags, docPath, tagGroups) {
158
179
  let sidebarSlice = [];
159
- if (sidebarOptions.groupPathsBy === "tag") {
180
+ if (sidebarOptions.groupPathsBy === "tagGroup") {
181
+ tagGroups === null || tagGroups === void 0 ? void 0 : tagGroups.forEach((tagGroup) => {
182
+ //filter tags only included in group
183
+ const filteredTags = [];
184
+ tags[0].forEach((tag) => {
185
+ if (tagGroup.tags.includes(tag.name)) {
186
+ filteredTags.push(tag);
187
+ }
188
+ });
189
+ const groupCategory = {
190
+ type: "category",
191
+ label: tagGroup.name,
192
+ collapsible: true,
193
+ collapsed: true,
194
+ items: groupByTags(api, sidebarOptions, options, [filteredTags], docPath),
195
+ };
196
+ sidebarSlice.push(groupCategory);
197
+ });
198
+ }
199
+ else if (sidebarOptions.groupPathsBy === "tag") {
160
200
  sidebarSlice = groupByTags(api, sidebarOptions, options, tags, docPath);
161
201
  }
162
202
  return 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 type ApiMetadata = ApiPageMetadata | InfoPageMetadata | TagPageMetadata | SchemaPageMetadata;
52
54
  export interface ApiMetadataBase {
53
55
  sidebar?: string;
54
56
  previous?: ApiNavLink;
@@ -100,7 +102,18 @@ export interface TagPageMetadata extends ApiMetadataBase {
100
102
  tag: TagObject;
101
103
  markdown?: string;
102
104
  }
103
- export declare type ApiInfo = InfoObject;
105
+ export interface SchemaPageMetadata extends ApiMetadataBase {
106
+ type: "schema";
107
+ schema: SchemaObject;
108
+ markdown?: string;
109
+ }
110
+ export interface TagGroupPageMetadata extends ApiMetadataBase {
111
+ type: "tagGroup";
112
+ name: string;
113
+ tags: TagObject[];
114
+ markdown?: string;
115
+ }
116
+ export type ApiInfo = InfoObject;
104
117
  export interface ApiNavLink {
105
118
  title: string;
106
119
  permalink: 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": "2.0.4",
4
+ "version": "2.1.0",
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": "71012fa9a8e21d7d83beaf6368b93381298a3e2e"
63
+ "gitHead": "9064dd22c8e18125f838fd88caba6364e5484b68"
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 { createApiPageMD, createInfoPageMD, createTagPageMD } from "./markdown";
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 { PluginOptions, LoadedContent, APIOptions } from "./types";
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);
@@ -117,7 +131,7 @@ export default function pluginOpenAPIDocs(
117
131
 
118
132
  try {
119
133
  const openapiFiles = await readOpenapiFiles(contentPath);
120
- const [loadedApi, tags] = await processOpenapiFiles(
134
+ const [loadedApi, tags, tagGroups] = await processOpenapiFiles(
121
135
  openapiFiles,
122
136
  options,
123
137
  sidebarOptions!
@@ -141,7 +155,8 @@ export default function pluginOpenAPIDocs(
141
155
  options,
142
156
  loadedApi,
143
157
  tags,
144
- docPath
158
+ docPath,
159
+ tagGroups
145
160
  );
146
161
 
147
162
  const sidebarSliceTemplate = `module.exports = {{{slice}}};`;
@@ -244,12 +259,43 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
244
259
  \`\`\`
245
260
  `;
246
261
 
262
+ const schemaMdTemplate = `---
263
+ id: {{{id}}}
264
+ title: "{{{title}}}"
265
+ description: "{{{frontMatter.description}}}"
266
+ sidebar_label: "{{{title}}}"
267
+ hide_title: true
268
+ schema: true
269
+ custom_edit_url: null
270
+ ---
271
+
272
+ {{{markdown}}}
273
+ `;
274
+
247
275
  const apiPageGenerator =
248
276
  markdownGenerators?.createApiPageMD ?? createApiPageMD;
249
277
  const infoPageGenerator =
250
278
  markdownGenerators?.createInfoPageMD ?? createInfoPageMD;
251
279
  const tagPageGenerator =
252
280
  markdownGenerators?.createTagPageMD ?? createTagPageMD;
281
+ const schemaPageGenerator =
282
+ markdownGenerators?.createSchemaPageMD ?? createSchemaPageMD;
283
+
284
+ const pageGeneratorByType: {
285
+ [key in ApiMetadata["type"]]: (
286
+ pageData: {
287
+ api: ApiPageMetadata;
288
+ info: InfoPageMetadata;
289
+ tag: TagPageMetadata;
290
+ schema: SchemaPageMetadata;
291
+ }[key]
292
+ ) => string;
293
+ } = {
294
+ api: apiPageGenerator,
295
+ info: infoPageGenerator,
296
+ tag: tagPageGenerator,
297
+ schema: schemaPageGenerator,
298
+ };
253
299
 
254
300
  loadedApi.map(async (item) => {
255
301
  if (item.type === "info") {
@@ -257,12 +303,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
257
303
  item.downloadUrl = downloadUrl;
258
304
  }
259
305
  }
260
- const markdown =
261
- item.type === "api"
262
- ? apiPageGenerator(item)
263
- : item.type === "info"
264
- ? infoPageGenerator(item)
265
- : tagPageGenerator(item);
306
+ const markdown = pageGeneratorByType[item.type](item as any);
266
307
  item.markdown = markdown;
267
308
  if (item.type === "api") {
268
309
  // opportunity to compress JSON
@@ -363,6 +404,49 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
363
404
  }
364
405
  }
365
406
  }
407
+
408
+ if (item.type === "schema") {
409
+ if (!fs.existsSync(`${outputDir}/schemas/${item.id}.schema.mdx`)) {
410
+ if (!fs.existsSync(`${outputDir}/schemas`)) {
411
+ try {
412
+ fs.mkdirSync(`${outputDir}/schemas`, { recursive: true });
413
+ console.log(
414
+ chalk.green(`Successfully created "${outputDir}/schemas"`)
415
+ );
416
+ } catch (err) {
417
+ console.error(
418
+ chalk.red(`Failed to create "${outputDir}/schemas"`),
419
+ chalk.yellow(err)
420
+ );
421
+ }
422
+ }
423
+ try {
424
+ // kebabCase(arg) returns 0-length string when arg is undefined
425
+ if (item.id.length === 0) {
426
+ throw Error("Schema must have title defined");
427
+ }
428
+ // eslint-disable-next-line testing-library/render-result-naming-convention
429
+ const schemaView = render(schemaMdTemplate, item);
430
+ fs.writeFileSync(
431
+ `${outputDir}/schemas/${item.id}.schema.mdx`,
432
+ schemaView,
433
+ "utf8"
434
+ );
435
+ console.log(
436
+ chalk.green(
437
+ `Successfully created "${outputDir}/${item.id}.schema.mdx"`
438
+ )
439
+ );
440
+ } catch (err) {
441
+ console.error(
442
+ chalk.red(
443
+ `Failed to write "${outputDir}/${item.id}.schema.mdx"`
444
+ ),
445
+ chalk.yellow(err)
446
+ );
447
+ }
448
+ }
449
+ }
366
450
  return;
367
451
  });
368
452
 
@@ -380,6 +464,10 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
380
464
  cwd: path.resolve(apiDir),
381
465
  deep: 1,
382
466
  });
467
+ const schemaMdxFiles = await Globby(["*.schema.mdx"], {
468
+ cwd: path.resolve(apiDir, "schemas"),
469
+ deep: 1,
470
+ });
383
471
  const sidebarFile = await Globby(["sidebar.js"], {
384
472
  cwd: path.resolve(apiDir),
385
473
  deep: 1,
@@ -397,6 +485,21 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
397
485
  })
398
486
  );
399
487
 
488
+ schemaMdxFiles.map((mdx) =>
489
+ fs.unlink(`${apiDir}/schemas/${mdx}`, (err) => {
490
+ if (err) {
491
+ console.error(
492
+ chalk.red(`Cleanup failed for "${apiDir}/schemas/${mdx}"`),
493
+ chalk.yellow(err)
494
+ );
495
+ } else {
496
+ console.log(
497
+ chalk.green(`Cleanup succeeded for "${apiDir}/schemas/${mdx}"`)
498
+ );
499
+ }
500
+ })
501
+ );
502
+
400
503
  sidebarFile.map((sidebar) =>
401
504
  fs.unlink(`${apiDir}/${sidebar}`, (err) => {
402
505
  if (err) {
@@ -5,9 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { OAuthFlowObject, SecuritySchemeObject } from "../openapi/types";
9
8
  import { createDescription } from "./createDescription";
10
9
  import { create, guard } from "./utils";
10
+ import { OAuthFlowObject, SecuritySchemeObject } from "../openapi/types";
11
11
 
12
12
  export function createAuthentication(securitySchemes: SecuritySchemeObject) {
13
13
  if (!securitySchemes || !Object.keys(securitySchemes).length) return "";
@@ -5,13 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { MediaTypeObject } from "../openapi/types";
9
- import { ApiItem } from "../types";
10
8
  import { createDescription } from "./createDescription";
11
9
  import { createMethodEndpoint } from "./createMethodEndpoint";
12
10
  import { createRequestBodyDetails } from "./createRequestBodyDetails";
13
11
  import { createStatusCodes } from "./createStatusCodes";
14
12
  import { create } from "./utils";
13
+ import { MediaTypeObject } from "../openapi/types";
14
+ import { ApiItem } from "../types";
15
15
 
16
16
  interface Props {
17
17
  callbacks: ApiItem["callbacks"];
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { ContactObject } from "../openapi/types";
9
8
  import { create, guard } from "./utils";
9
+ import { ContactObject } from "../openapi/types";
10
10
 
11
11
  export function createContactInfo(contact: ContactObject) {
12
12
  if (!contact || !Object.keys(contact).length) return "";
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { LicenseObject } from "../openapi/types";
9
8
  import { create, guard } from "./utils";
9
+ import { LicenseObject } from "../openapi/types";
10
10
 
11
11
  export function createLicense(license: LicenseObject) {
12
12
  if (!license || !Object.keys(license).length) return "";
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { LogoObject } from "../openapi/types";
9
8
  import { create, guard } from "./utils";
9
+ import { LogoObject } from "../openapi/types";
10
10
 
11
11
  export function createLogo(
12
12
  logo: LogoObject | undefined,
@@ -5,10 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { ApiItem } from "../types";
9
8
  import { createDetails } from "./createDetails";
10
9
  import { createDetailsSummary } from "./createDetailsSummary";
11
10
  import { create } from "./utils";
11
+ import { ApiItem } from "../types";
12
12
 
13
13
  interface Props {
14
14
  parameters: ApiItem["parameters"];
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { MediaTypeObject } from "../openapi/types";
9
8
  import { createRequestSchema } from "./createRequestSchema";
9
+ import { MediaTypeObject } from "../openapi/types";
10
10
 
11
11
  interface Props {
12
12
  title: string;
@@ -5,12 +5,12 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { MediaTypeObject } from "../openapi/types";
9
8
  import { createDescription } from "./createDescription";
10
9
  import { createDetails } from "./createDetails";
11
10
  import { createDetailsSummary } from "./createDetailsSummary";
12
11
  import { createNodes } from "./createSchema";
13
12
  import { create, guard } from "./utils";
13
+ import { MediaTypeObject } from "../openapi/types";
14
14
 
15
15
  interface Props {
16
16
  style?: any;
@@ -5,7 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import { MediaTypeObject } from "../openapi/types";
9
8
  import { createDescription } from "./createDescription";
10
9
  import { createDetails } from "./createDetails";
11
10
  import { createDetailsSummary } from "./createDetailsSummary";
@@ -16,6 +15,7 @@ import {
16
15
  createResponseExamples,
17
16
  } from "./createStatusCodes";
18
17
  import { create, guard } from "./utils";
18
+ import { MediaTypeObject } from "../openapi/types";
19
19
 
20
20
  interface Props {
21
21
  style?: any;
@@ -7,8 +7,8 @@
7
7
 
8
8
  import * as prettier from "prettier";
9
9
 
10
- import { SchemaObject } from "../openapi/types";
11
10
  import { createNodes } from "./createSchema";
11
+ import { SchemaObject } from "../openapi/types";
12
12
 
13
13
  describe("createNodes", () => {
14
14
  it("should create readable MODs for oneOf primitive properties", () => {
@@ -7,7 +7,6 @@
7
7
 
8
8
  import clsx from "clsx";
9
9
 
10
- import { SchemaObject } from "../openapi/types";
11
10
  import {
12
11
  createClosingArrayBracket,
13
12
  createOpeningArrayBracket,
@@ -17,6 +16,7 @@ import { createDetails } from "./createDetails";
17
16
  import { createDetailsSummary } from "./createDetailsSummary";
18
17
  import { getQualifierMessage, getSchemaName } from "./schema";
19
18
  import { create, guard } from "./utils";
19
+ import { SchemaObject } from "../openapi/types";
20
20
 
21
21
  const jsonSchemaMergeAllOf = require("json-schema-merge-allof");
22
22
 
@@ -7,14 +7,14 @@
7
7
 
8
8
  import format from "xml-formatter";
9
9
 
10
- import { sampleResponseFromSchema } from "../openapi/createResponseExample";
11
- import { ApiItem } from "../types";
12
10
  import { createDescription } from "./createDescription";
13
11
  import { createDetails } from "./createDetails";
14
12
  import { createDetailsSummary } from "./createDetailsSummary";
15
13
  import { createResponseSchema } from "./createResponseSchema";
16
14
  import { create } from "./utils";
17
15
  import { guard } from "./utils";
16
+ import { sampleResponseFromSchema } from "../openapi/createResponseExample";
17
+ import { ApiItem } from "../types";
18
18
 
19
19
  export default function json2xml(o: any, tab: any) {
20
20
  var toXml = function (v: any, name: string, ind: any) {
@@ -5,13 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  * ========================================================================== */
7
7
 
8
- import {
9
- ContactObject,
10
- LicenseObject,
11
- MediaTypeObject,
12
- SecuritySchemeObject,
13
- } from "../openapi/types";
14
- import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
15
8
  import { createAuthentication } from "./createAuthentication";
16
9
  import { createAuthorization } from "./createAuthorization";
17
10
  import { createCallbacks } from "./createCallbacks";
@@ -26,11 +19,24 @@ import { createMethodEndpoint } from "./createMethodEndpoint";
26
19
  import { createParamsDetails } from "./createParamsDetails";
27
20
  import { createRequestBodyDetails } from "./createRequestBodyDetails";
28
21
  import { createRequestHeader } from "./createRequestHeader";
22
+ import { createNodes } from "./createSchema";
29
23
  import { createStatusCodes } from "./createStatusCodes";
30
24
  import { createTermsOfService } from "./createTermsOfService";
31
25
  import { createVendorExtensions } from "./createVendorExtensions";
32
26
  import { createVersionBadge } from "./createVersionBadge";
33
- import { greaterThan, lessThan, render } from "./utils";
27
+ import { create, greaterThan, lessThan, render } from "./utils";
28
+ import {
29
+ ContactObject,
30
+ LicenseObject,
31
+ MediaTypeObject,
32
+ SecuritySchemeObject,
33
+ } from "../openapi/types";
34
+ import {
35
+ ApiPageMetadata,
36
+ InfoPageMetadata,
37
+ SchemaPageMetadata,
38
+ TagPageMetadata,
39
+ } from "../types";
34
40
 
35
41
  interface RequestBodyProps {
36
42
  title: string;
@@ -81,7 +87,7 @@ export function createApiPageMD({
81
87
  : undefined,
82
88
  createDeprecationNotice({ deprecated, description: deprecatedDescription }),
83
89
  createDescription(description),
84
- createRequestHeader("Request"),
90
+ requestBody || parameters ? createRequestHeader("Request") : undefined,
85
91
  createParamsDetails({ parameters, type: "path" }),
86
92
  createParamsDetails({ parameters, type: "query" }),
87
93
  createParamsDetails({ parameters, type: "header" }),
@@ -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, "&lt;").replace(greaterThan, "&gt;")),
148
+ createDescription(description),
149
+ create("ul", {
150
+ children: createNodes(schema, "response"),
151
+ }),
152
+ ]);
153
+ }