docusaurus-plugin-openapi-docs 1.5.2 → 1.6.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.
package/lib/index.js CHANGED
@@ -77,6 +77,8 @@ function pluginOpenAPIDocs(context, options) {
77
77
  let docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
78
78
  async function generateApiDocs(options, pluginId) {
79
79
  let { specPath, outputDir, template, downloadUrl, sidebarOptions } = options;
80
+ // Remove trailing slash before proceeding
81
+ outputDir = outputDir.replace(/\/$/, "");
80
82
  // Override docPath if pluginId provided
81
83
  if (pluginId) {
82
84
  docData = getDocsPluginConfig(presetsPlugins, pluginId);
@@ -147,6 +149,9 @@ custom_edit_url: null
147
149
  {{#frontMatter.proxy}}
148
150
  proxy: {{{frontMatter.proxy}}}
149
151
  {{/frontMatter.proxy}}
152
+ {{#frontMatter.hide_send_button}}
153
+ hide_send_button: true
154
+ {{/frontMatter.hide_send_button}}
150
155
  ---
151
156
 
152
157
  {{{markdown}}}
@@ -13,7 +13,7 @@ function createAuthentication(securitySchemes) {
13
13
  if (!securitySchemes || !Object.keys(securitySchemes).length)
14
14
  return "";
15
15
  const createAuthenticationTable = (securityScheme) => {
16
- const { bearerFormat, flows, name, scheme, type } = securityScheme;
16
+ const { bearerFormat, flows, name, scheme, type, openIdConnectUrl } = securityScheme;
17
17
  const createSecuritySchemeTypeRow = () => (0, utils_1.create)("tr", {
18
18
  children: [
19
19
  (0, utils_1.create)("th", { children: "Security Scheme Type:" }),
@@ -25,7 +25,7 @@ function createAuthentication(securitySchemes) {
25
25
  const { authorizationUrl, tokenUrl, refreshUrl, scopes } = flowObj;
26
26
  return (0, utils_1.create)("tr", {
27
27
  children: [
28
- (0, utils_1.create)("th", { children: `${flowType} OAuth Flow:` }),
28
+ (0, utils_1.create)("th", { children: `OAuth Flow (${flowType}):` }),
29
29
  (0, utils_1.create)("td", {
30
30
  children: [
31
31
  (0, utils_1.guard)(tokenUrl, () => (0, utils_1.create)("p", { children: `Token URL: ${tokenUrl}` })),
@@ -76,12 +76,12 @@ function createAuthentication(securitySchemes) {
76
76
  (0, utils_1.create)("td", { children: scheme }),
77
77
  ],
78
78
  }),
79
- (0, utils_1.create)("tr", {
79
+ (0, utils_1.guard)(bearerFormat, () => (0, utils_1.create)("tr", {
80
80
  children: [
81
81
  (0, utils_1.create)("th", { children: "Bearer format:" }),
82
82
  (0, utils_1.create)("td", { children: bearerFormat }),
83
83
  ],
84
- }),
84
+ })),
85
85
  ],
86
86
  }),
87
87
  }),
@@ -100,20 +100,51 @@ function createAuthentication(securitySchemes) {
100
100
  }),
101
101
  ],
102
102
  });
103
+ case "openIdConnect":
104
+ return (0, utils_1.create)("div", {
105
+ children: [
106
+ (0, utils_1.create)("table", {
107
+ children: (0, utils_1.create)("tbody", {
108
+ children: [
109
+ createSecuritySchemeTypeRow(),
110
+ (0, utils_1.guard)(openIdConnectUrl, () => (0, utils_1.create)("tr", {
111
+ children: [
112
+ (0, utils_1.create)("th", { children: "OpenID Connect URL:" }),
113
+ (0, utils_1.create)("td", { children: openIdConnectUrl }),
114
+ ],
115
+ })),
116
+ ],
117
+ }),
118
+ }),
119
+ ],
120
+ });
103
121
  default:
104
122
  return "";
105
123
  }
106
124
  };
107
- const formatTabLabel = (str) => {
108
- const formattedLabel = str
125
+ const formatTabLabel = (key, type, scheme) => {
126
+ const formattedLabel = key
109
127
  .replace(/(_|-)/g, " ")
110
128
  .trim()
111
129
  .replace(/\w\S*/g, (str) => str.charAt(0).toUpperCase() + str.substr(1))
112
130
  .replace(/([a-z])([A-Z])/g, "$1 $2")
113
131
  .replace(/([A-Z])([A-Z][a-z])/g, "$1 $2");
114
- const isOAuth = formattedLabel.toLowerCase().includes("oauth2");
115
- const isApiKey = formattedLabel.toLowerCase().includes("api");
116
- return isOAuth ? "OAuth 2.0" : isApiKey ? "API Key" : formattedLabel;
132
+ const isOAuth = type === "oauth2";
133
+ const isApiKey = type === "apiKey";
134
+ const isHttpBasic = type === "http" && scheme === "basic";
135
+ const isHttpBearer = type === "http" && scheme === "bearer";
136
+ const isOpenId = type === "openIdConnect";
137
+ if (isOAuth)
138
+ return `OAuth 2.0: ${key}`;
139
+ if (isApiKey)
140
+ return `API Key: ${key}`;
141
+ if (isHttpBasic)
142
+ return "HTTP: Basic Auth";
143
+ if (isHttpBearer)
144
+ return "HTTP: Bearer Auth";
145
+ if (isOpenId)
146
+ return `OpenID Connect: ${key}`;
147
+ return formattedLabel;
117
148
  };
118
149
  return (0, utils_1.create)("div", {
119
150
  children: [
@@ -122,10 +153,11 @@ function createAuthentication(securitySchemes) {
122
153
  id: "authentication",
123
154
  style: { marginBottom: "1rem" },
124
155
  }),
125
- (0, utils_1.create)("Tabs", {
126
- children: Object.entries(securitySchemes).map(([schemeType, schemeObj]) => (0, utils_1.create)("TabItem", {
127
- label: formatTabLabel(schemeType),
128
- value: `${schemeType}`,
156
+ (0, utils_1.create)("SchemaTabs", {
157
+ className: "openapi-tabs__security-schemes",
158
+ children: Object.entries(securitySchemes).map(([schemeKey, schemeObj]) => (0, utils_1.create)("TabItem", {
159
+ label: formatTabLabel(schemeKey, schemeObj.type, schemeObj.scheme),
160
+ value: `${schemeKey}`,
129
161
  children: [
130
162
  (0, createDescription_1.createDescription)(schemeObj.description),
131
163
  createAuthenticationTable(schemeObj),
@@ -373,7 +373,7 @@ function createItems(schema) {
373
373
  // }),
374
374
  // });
375
375
  // }
376
- function createDetailsNode(name, schemaName, schema, required) {
376
+ function createDetailsNode(name, schemaName, schema, required, nullable) {
377
377
  return (0, utils_1.create)("SchemaItem", {
378
378
  collapsible: true,
379
379
  className: "schemaItem",
@@ -387,7 +387,8 @@ function createDetailsNode(name, schemaName, schema, required) {
387
387
  style: { opacity: "0.6" },
388
388
  children: ` ${schemaName}`,
389
389
  }),
390
- (0, utils_1.guard)(schema.nullable && schema.nullable === true, () => [
390
+ (0, utils_1.guard)((schema.nullable && schema.nullable === true) ||
391
+ (nullable && nullable === true), () => [
391
392
  (0, utils_1.create)("strong", {
392
393
  style: {
393
394
  fontSize: "var(--ifm-code-font-size)",
@@ -498,24 +499,24 @@ function createEdges({ name, schema, required, discriminator, }) {
498
499
  return createPropertyDiscriminator(name, "string", schema, discriminator, required);
499
500
  }
500
501
  if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
501
- return createDetailsNode(name, schemaName, schema, required);
502
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
502
503
  }
503
504
  if (schema.allOf !== undefined) {
504
505
  const { mergedSchemas, required, } = mergeAllOf(schema.allOf);
505
506
  const mergedSchemaName = (0, schema_1.getSchemaName)(mergedSchemas);
506
507
  if (mergedSchemas.oneOf !== undefined ||
507
508
  mergedSchemas.anyOf !== undefined) {
508
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
509
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
509
510
  }
510
511
  if (mergedSchemas.properties !== undefined) {
511
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
512
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
512
513
  }
513
514
  if (mergedSchemas.additionalProperties !== undefined) {
514
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
515
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
515
516
  }
516
517
  // array of objects
517
518
  if (((_a = mergedSchemas.items) === null || _a === void 0 ? void 0 : _a.properties) !== undefined) {
518
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
519
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
519
520
  }
520
521
  if (mergedSchemas.readOnly && mergedSchemas.readOnly === true) {
521
522
  return undefined;
@@ -530,17 +531,17 @@ function createEdges({ name, schema, required, discriminator, }) {
530
531
  });
531
532
  }
532
533
  if (schema.properties !== undefined) {
533
- return createDetailsNode(name, schemaName, schema, required);
534
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
534
535
  }
535
536
  if (schema.additionalProperties !== undefined) {
536
- return createDetailsNode(name, schemaName, schema, required);
537
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
537
538
  }
538
539
  // array of objects
539
540
  if (((_b = schema.items) === null || _b === void 0 ? void 0 : _b.properties) !== undefined) {
540
- return createDetailsNode(name, schemaName, schema, required);
541
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
541
542
  }
542
543
  if (((_c = schema.items) === null || _c === void 0 ? void 0 : _c.anyOf) !== undefined || ((_d = schema.items) === null || _d === void 0 ? void 0 : _d.oneOf) !== undefined) {
543
- return createDetailsNode(name, schemaName, schema, required);
544
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
544
545
  }
545
546
  if (schema.readOnly && schema.readOnly === true) {
546
547
  return undefined;
@@ -610,9 +611,10 @@ function createNodes(schema) {
610
611
  }
611
612
  // Unknown node/schema type should return undefined
612
613
  // So far, haven't seen this hit in testing
613
- return undefined;
614
+ return "any";
614
615
  }
615
616
  function createRequestSchema({ title, body, ...rest }) {
617
+ var _a;
616
618
  if (body === undefined ||
617
619
  body.content === undefined ||
618
620
  Object.keys(body).length === 0 ||
@@ -681,7 +683,7 @@ function createRequestSchema({ title, body, ...rest }) {
681
683
  });
682
684
  }
683
685
  const randomFirstKey = Object.keys(body.content)[0];
684
- const firstBody = body.content[randomFirstKey].schema;
686
+ const firstBody = (_a = body.content[randomFirstKey].schema) !== null && _a !== void 0 ? _a : body.content[randomFirstKey];
685
687
  if (firstBody === undefined) {
686
688
  return undefined;
687
689
  }
@@ -374,7 +374,7 @@ function createItems(schema) {
374
374
  // }),
375
375
  // });
376
376
  // }
377
- function createDetailsNode(name, schemaName, schema, required) {
377
+ function createDetailsNode(name, schemaName, schema, required, nullable) {
378
378
  return (0, utils_1.create)("SchemaItem", {
379
379
  collapsible: true,
380
380
  className: "schemaItem",
@@ -388,7 +388,8 @@ function createDetailsNode(name, schemaName, schema, required) {
388
388
  style: { opacity: "0.6" },
389
389
  children: ` ${schemaName}`,
390
390
  }),
391
- (0, utils_1.guard)(schema.nullable && schema.nullable === true, () => [
391
+ (0, utils_1.guard)((schema.nullable && schema.nullable === true) ||
392
+ (nullable && nullable === true), () => [
392
393
  (0, utils_1.create)("strong", {
393
394
  style: {
394
395
  fontSize: "var(--ifm-code-font-size)",
@@ -397,7 +398,9 @@ function createDetailsNode(name, schemaName, schema, required) {
397
398
  children: " nullable",
398
399
  }),
399
400
  ]),
400
- (0, utils_1.guard)(schema.required && schema.required === true, () => [
401
+ (0, utils_1.guard)(Array.isArray(required)
402
+ ? required.includes(name)
403
+ : required === true, () => [
401
404
  (0, utils_1.create)("strong", {
402
405
  style: {
403
406
  fontSize: "var(--ifm-code-font-size)",
@@ -497,24 +500,24 @@ function createEdges({ name, schema, required, discriminator, }) {
497
500
  return createPropertyDiscriminator(name, "string", schema, discriminator, required);
498
501
  }
499
502
  if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
500
- return createDetailsNode(name, schemaName, schema, required);
503
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
501
504
  }
502
505
  if (schema.allOf !== undefined) {
503
506
  const { mergedSchemas, required, } = mergeAllOf(schema.allOf);
504
507
  const mergedSchemaName = (0, schema_1.getSchemaName)(mergedSchemas);
505
508
  if (mergedSchemas.oneOf !== undefined ||
506
509
  mergedSchemas.anyOf !== undefined) {
507
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
510
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
508
511
  }
509
512
  if (mergedSchemas.properties !== undefined) {
510
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
513
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
511
514
  }
512
515
  if (mergedSchemas.additionalProperties !== undefined) {
513
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
516
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
514
517
  }
515
518
  // array of objects
516
519
  if (((_a = mergedSchemas.items) === null || _a === void 0 ? void 0 : _a.properties) !== undefined) {
517
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
520
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
518
521
  }
519
522
  if (mergedSchemas.writeOnly && mergedSchemas.writeOnly === true) {
520
523
  return undefined;
@@ -529,17 +532,17 @@ function createEdges({ name, schema, required, discriminator, }) {
529
532
  });
530
533
  }
531
534
  if (schema.properties !== undefined) {
532
- return createDetailsNode(name, schemaName, schema, required);
535
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
533
536
  }
534
537
  if (schema.additionalProperties !== undefined) {
535
- return createDetailsNode(name, schemaName, schema, required);
538
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
536
539
  }
537
540
  // array of objects
538
541
  if (((_b = schema.items) === null || _b === void 0 ? void 0 : _b.properties) !== undefined) {
539
- return createDetailsNode(name, schemaName, schema, required);
542
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
540
543
  }
541
544
  if (((_c = schema.items) === null || _c === void 0 ? void 0 : _c.anyOf) !== undefined || ((_d = schema.items) === null || _d === void 0 ? void 0 : _d.oneOf) !== undefined) {
542
- return createDetailsNode(name, schemaName, schema, required);
545
+ return createDetailsNode(name, schemaName, schema, required, schema.nullable);
543
546
  }
544
547
  if (schema.writeOnly && schema.writeOnly === true) {
545
548
  return undefined;
@@ -611,7 +614,7 @@ function createNodes(schema) {
611
614
  }
612
615
  // Unknown node/schema type should return undefined
613
616
  // So far, haven't seen this hit in testing
614
- return undefined;
617
+ return "any";
615
618
  }
616
619
  function createResponseSchema({ title, body, ...rest }) {
617
620
  if (body === undefined ||
@@ -626,9 +629,10 @@ function createResponseSchema({ title, body, ...rest }) {
626
629
  return (0, utils_1.create)("MimeTabs", {
627
630
  schemaType: "response",
628
631
  children: mimeTypes.map((mimeType) => {
632
+ var _a;
629
633
  const responseExamples = body.content[mimeType].examples;
630
634
  const responseExample = body.content[mimeType].example;
631
- const firstBody = body.content[mimeType].schema;
635
+ const firstBody = (_a = body.content[mimeType].schema) !== null && _a !== void 0 ? _a : body.content[mimeType];
632
636
  if (firstBody === undefined &&
633
637
  responseExample === undefined &&
634
638
  responseExamples === undefined) {
@@ -66,7 +66,9 @@ function createResponseHeaders(responseHeaders) {
66
66
  style: { marginLeft: "1rem" },
67
67
  children: [
68
68
  Object.entries(responseHeaders).map(([headerName, headerObj]) => {
69
- const { description, schema: { type }, example, } = headerObj;
69
+ var _a, _b;
70
+ const { description, example } = headerObj;
71
+ const type = (_b = (_a = headerObj.schema) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : "any";
70
72
  return (0, utils_1.create)("li", {
71
73
  className: "schemaItem",
72
74
  children: [
@@ -48,7 +48,7 @@ exports.createApiPageMD = createApiPageMD;
48
48
  function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService, logo, darkLogo, }, securitySchemes, downloadUrl, }) {
49
49
  return (0, utils_1.render)([
50
50
  `import ApiLogo from "@theme/ApiLogo";\n`,
51
- `import Tabs from "@theme/Tabs";\n`,
51
+ `import SchemaTabs from "@theme/SchemaTabs";\n`,
52
52
  `import TabItem from "@theme/TabItem";\n`,
53
53
  `import Export from "@theme/ApiDemoPanel/Export";\n\n`,
54
54
  (0, createVersionBadge_1.createVersionBadge)(version),
@@ -18,7 +18,7 @@ const primitives = {
18
18
  default: () => "string",
19
19
  email: () => "user@example.com",
20
20
  date: () => new Date().toISOString().substring(0, 10),
21
- "date-time": () => new Date().toISOString().substring(0, 10),
21
+ "date-time": () => new Date().toISOString(),
22
22
  uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
23
23
  hostname: () => "example.com",
24
24
  ipv4: () => "198.51.100.42",
@@ -18,7 +18,7 @@ const primitives = {
18
18
  default: () => "string",
19
19
  email: () => "user@example.com",
20
20
  date: () => new Date().toISOString().substring(0, 10),
21
- "date-time": () => new Date().toISOString().substring(0, 10),
21
+ "date-time": () => new Date().toISOString(),
22
22
  uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
23
23
  hostname: () => "example.com",
24
24
  ipv4: () => "198.51.100.42",
@@ -66,7 +66,7 @@ function createItems(openapiData, options, sidebarOptions) {
66
66
  let items = [];
67
67
  const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
68
68
  const infoId = (0, kebabCase_1.default)(infoIdSpaces);
69
- if (openapiData.info.description) {
69
+ if (openapiData.info.description || openapiData.info.title) {
70
70
  // Only create an info page if we have a description.
71
71
  const infoDescription = (_a = openapiData.info) === null || _a === void 0 ? void 0 : _a.description;
72
72
  let splitDescription;
@@ -173,6 +173,9 @@ function createItems(openapiData, options, sidebarOptions) {
173
173
  .replace(/\s+$/, "")
174
174
  : "",
175
175
  ...((options === null || options === void 0 ? void 0 : options.proxy) && { proxy: options.proxy }),
176
+ ...((options === null || options === void 0 ? void 0 : options.hideSendButton) && {
177
+ hide_send_button: options.hideSendButton,
178
+ }),
176
179
  },
177
180
  api: {
178
181
  ...defaults,
@@ -264,6 +267,9 @@ function createItems(openapiData, options, sidebarOptions) {
264
267
  .replace(/\s+$/, "")
265
268
  : "",
266
269
  ...((options === null || options === void 0 ? void 0 : options.proxy) && { proxy: options.proxy }),
270
+ ...((options === null || options === void 0 ? void 0 : options.hideSendButton) && {
271
+ hide_send_button: options.hideSendButton,
272
+ }),
267
273
  },
268
274
  api: {
269
275
  ...defaults,
@@ -114,6 +114,19 @@ async function loadAndResolveSpec(specUrlOrObject) {
114
114
  // Force dereference ?
115
115
  // bundleOpts["dereference"] = true;
116
116
  const { bundle: { parsed }, } = await (0, openapi_core_1.bundle)(bundleOpts);
117
+ //Pre-processing before resolving JSON refs
118
+ if (parsed.components) {
119
+ for (let [component, type] of Object.entries(parsed.components)) {
120
+ if (component === "schemas") {
121
+ for (let [schemaKey, schemaValue] of Object.entries(type)) {
122
+ const title = schemaValue["title"];
123
+ if (!title) {
124
+ schemaValue.title = schemaKey;
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
117
130
  const resolved = await resolveJsonRefs(parsed);
118
131
  // Force serialization and replace circular $ref pointers
119
132
  // @ts-ignore
package/lib/options.js CHANGED
@@ -25,6 +25,7 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
25
25
  outputDir: utils_validation_1.Joi.string().required(),
26
26
  template: utils_validation_1.Joi.string(),
27
27
  downloadUrl: utils_validation_1.Joi.string(),
28
+ hideSendButton: utils_validation_1.Joi.boolean(),
28
29
  sidebarOptions: sidebarOptions,
29
30
  version: utils_validation_1.Joi.string().when("versions", {
30
31
  is: utils_validation_1.Joi.exist(),
@@ -21,7 +21,9 @@ function isInfoItem(item) {
21
21
  return item.type === "info";
22
22
  }
23
23
  function groupByTags(items, sidebarOptions, options, tags, docPath) {
24
- const { outputDir, label } = options;
24
+ let { outputDir, label } = options;
25
+ // Remove trailing slash before proceeding
26
+ outputDir = outputDir.replace(/\/$/, "");
25
27
  const { sidebarCollapsed, sidebarCollapsible, customProps, categoryLinkSource, } = sidebarOptions;
26
28
  const apiItems = items.filter(isApiItem);
27
29
  const infoItems = items.filter(isInfoItem);
package/lib/types.d.ts CHANGED
@@ -13,6 +13,7 @@ export interface APIOptions {
13
13
  outputDir: string;
14
14
  template?: string;
15
15
  downloadUrl?: string;
16
+ hideSendButton?: boolean;
16
17
  sidebarOptions?: SidebarOptions;
17
18
  version?: string;
18
19
  label?: 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": "1.5.2",
4
+ "version": "1.6.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "openapi",
@@ -28,8 +28,8 @@
28
28
  "watch": "tsc --watch"
29
29
  },
30
30
  "devDependencies": {
31
- "@docusaurus/module-type-aliases": "^2.0.1",
32
- "@docusaurus/types": "^2.0.1",
31
+ "@docusaurus/module-type-aliases": ">=2.0.1 <2.3.0",
32
+ "@docusaurus/types": ">=2.0.1 <2.3.0",
33
33
  "@types/fs-extra": "^9.0.13",
34
34
  "@types/js-yaml": "^4.0.5",
35
35
  "@types/json-pointer": "^1.0.31",
@@ -40,10 +40,10 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@apidevtools/json-schema-ref-parser": "^9.0.9",
43
- "@docusaurus/mdx-loader": "^2.0.1",
44
- "@docusaurus/plugin-content-docs": "^2.0.1",
45
- "@docusaurus/utils": "^2.0.1",
46
- "@docusaurus/utils-validation": "^2.0.1",
43
+ "@docusaurus/mdx-loader": ">=2.0.1 <2.3.0",
44
+ "@docusaurus/plugin-content-docs": ">=2.0.1 <2.3.0",
45
+ "@docusaurus/utils": ">=2.0.1 <2.3.0",
46
+ "@docusaurus/utils-validation": ">=2.0.1 <2.3.0",
47
47
  "@paloaltonetworks/openapi-to-postmanv2": "3.1.0-hotfix.1",
48
48
  "@paloaltonetworks/postman-collection": "^4.1.0",
49
49
  "@redocly/openapi-core": "^1.0.0-beta.103",
@@ -68,5 +68,5 @@
68
68
  "engines": {
69
69
  "node": ">=14"
70
70
  },
71
- "gitHead": "fa3096190356c0161a8e255b9950857a7b131eef"
71
+ "gitHead": "937e6543af8c1575877a0ebe7c5732e5cffaa37d"
72
72
  }
package/src/index.ts CHANGED
@@ -94,6 +94,9 @@ export default function pluginOpenAPIDocs(
94
94
  let { specPath, outputDir, template, downloadUrl, sidebarOptions } =
95
95
  options;
96
96
 
97
+ // Remove trailing slash before proceeding
98
+ outputDir = outputDir.replace(/\/$/, "");
99
+
97
100
  // Override docPath if pluginId provided
98
101
  if (pluginId) {
99
102
  docData = getDocsPluginConfig(presetsPlugins, pluginId);
@@ -187,6 +190,9 @@ custom_edit_url: null
187
190
  {{#frontMatter.proxy}}
188
191
  proxy: {{{frontMatter.proxy}}}
189
192
  {{/frontMatter.proxy}}
193
+ {{#frontMatter.hide_send_button}}
194
+ hide_send_button: true
195
+ {{/frontMatter.hide_send_button}}
190
196
  ---
191
197
 
192
198
  {{{markdown}}}
@@ -13,7 +13,8 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
13
13
  if (!securitySchemes || !Object.keys(securitySchemes).length) return "";
14
14
 
15
15
  const createAuthenticationTable = (securityScheme: any) => {
16
- const { bearerFormat, flows, name, scheme, type } = securityScheme;
16
+ const { bearerFormat, flows, name, scheme, type, openIdConnectUrl } =
17
+ securityScheme;
17
18
 
18
19
  const createSecuritySchemeTypeRow = () =>
19
20
  create("tr", {
@@ -30,7 +31,7 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
30
31
 
31
32
  return create("tr", {
32
33
  children: [
33
- create("th", { children: `${flowType} OAuth Flow:` }),
34
+ create("th", { children: `OAuth Flow (${flowType}):` }),
34
35
  create("td", {
35
36
  children: [
36
37
  guard(tokenUrl, () =>
@@ -91,12 +92,14 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
91
92
  create("td", { children: scheme }),
92
93
  ],
93
94
  }),
94
- create("tr", {
95
- children: [
96
- create("th", { children: "Bearer format:" }),
97
- create("td", { children: bearerFormat }),
98
- ],
99
- }),
95
+ guard(bearerFormat, () =>
96
+ create("tr", {
97
+ children: [
98
+ create("th", { children: "Bearer format:" }),
99
+ create("td", { children: bearerFormat }),
100
+ ],
101
+ })
102
+ ),
100
103
  ],
101
104
  }),
102
105
  }),
@@ -115,23 +118,51 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
115
118
  }),
116
119
  ],
117
120
  });
121
+ case "openIdConnect":
122
+ return create("div", {
123
+ children: [
124
+ create("table", {
125
+ children: create("tbody", {
126
+ children: [
127
+ createSecuritySchemeTypeRow(),
128
+ guard(openIdConnectUrl, () =>
129
+ create("tr", {
130
+ children: [
131
+ create("th", { children: "OpenID Connect URL:" }),
132
+ create("td", { children: openIdConnectUrl }),
133
+ ],
134
+ })
135
+ ),
136
+ ],
137
+ }),
138
+ }),
139
+ ],
140
+ });
118
141
  default:
119
142
  return "";
120
143
  }
121
144
  };
122
145
 
123
- const formatTabLabel = (str: string) => {
124
- const formattedLabel = str
146
+ const formatTabLabel = (key: string, type: string, scheme: string) => {
147
+ const formattedLabel = key
125
148
  .replace(/(_|-)/g, " ")
126
149
  .trim()
127
150
  .replace(/\w\S*/g, (str) => str.charAt(0).toUpperCase() + str.substr(1))
128
151
  .replace(/([a-z])([A-Z])/g, "$1 $2")
129
152
  .replace(/([A-Z])([A-Z][a-z])/g, "$1 $2");
153
+ const isOAuth = type === "oauth2";
154
+ const isApiKey = type === "apiKey";
155
+ const isHttpBasic = type === "http" && scheme === "basic";
156
+ const isHttpBearer = type === "http" && scheme === "bearer";
157
+ const isOpenId = type === "openIdConnect";
130
158
 
131
- const isOAuth = formattedLabel.toLowerCase().includes("oauth2");
132
- const isApiKey = formattedLabel.toLowerCase().includes("api");
159
+ if (isOAuth) return `OAuth 2.0: ${key}`;
160
+ if (isApiKey) return `API Key: ${key}`;
161
+ if (isHttpBasic) return "HTTP: Basic Auth";
162
+ if (isHttpBearer) return "HTTP: Bearer Auth";
163
+ if (isOpenId) return `OpenID Connect: ${key}`;
133
164
 
134
- return isOAuth ? "OAuth 2.0" : isApiKey ? "API Key" : formattedLabel;
165
+ return formattedLabel;
135
166
  };
136
167
 
137
168
  return create("div", {
@@ -141,12 +172,17 @@ export function createAuthentication(securitySchemes: SecuritySchemeObject) {
141
172
  id: "authentication",
142
173
  style: { marginBottom: "1rem" },
143
174
  }),
144
- create("Tabs", {
175
+ create("SchemaTabs", {
176
+ className: "openapi-tabs__security-schemes",
145
177
  children: Object.entries(securitySchemes).map(
146
- ([schemeType, schemeObj]) =>
178
+ ([schemeKey, schemeObj]) =>
147
179
  create("TabItem", {
148
- label: formatTabLabel(schemeType),
149
- value: `${schemeType}`,
180
+ label: formatTabLabel(
181
+ schemeKey,
182
+ schemeObj.type,
183
+ schemeObj.scheme
184
+ ),
185
+ value: `${schemeKey}`,
150
186
  children: [
151
187
  createDescription(schemeObj.description),
152
188
  createAuthenticationTable(schemeObj),
@@ -436,7 +436,8 @@ function createDetailsNode(
436
436
  name: string,
437
437
  schemaName: string,
438
438
  schema: SchemaObject,
439
- required: string[] | boolean
439
+ required: string[] | boolean,
440
+ nullable: boolean | unknown
440
441
  ): any {
441
442
  return create("SchemaItem", {
442
443
  collapsible: true,
@@ -451,15 +452,19 @@ function createDetailsNode(
451
452
  style: { opacity: "0.6" },
452
453
  children: ` ${schemaName}`,
453
454
  }),
454
- guard(schema.nullable && schema.nullable === true, () => [
455
- create("strong", {
456
- style: {
457
- fontSize: "var(--ifm-code-font-size)",
458
- color: "var(--openapi-nullable)",
459
- },
460
- children: " nullable",
461
- }),
462
- ]),
455
+ guard(
456
+ (schema.nullable && schema.nullable === true) ||
457
+ (nullable && nullable === true),
458
+ () => [
459
+ create("strong", {
460
+ style: {
461
+ fontSize: "var(--ifm-code-font-size)",
462
+ color: "var(--openapi-nullable)",
463
+ },
464
+ children: " nullable",
465
+ }),
466
+ ]
467
+ ),
463
468
  guard(
464
469
  Array.isArray(required)
465
470
  ? required.includes(name)
@@ -604,7 +609,13 @@ function createEdges({
604
609
  }
605
610
 
606
611
  if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
607
- return createDetailsNode(name, schemaName, schema, required);
612
+ return createDetailsNode(
613
+ name,
614
+ schemaName,
615
+ schema,
616
+ required,
617
+ schema.nullable
618
+ );
608
619
  }
609
620
 
610
621
  if (schema.allOf !== undefined) {
@@ -619,20 +630,44 @@ function createEdges({
619
630
  mergedSchemas.oneOf !== undefined ||
620
631
  mergedSchemas.anyOf !== undefined
621
632
  ) {
622
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
633
+ return createDetailsNode(
634
+ name,
635
+ mergedSchemaName,
636
+ mergedSchemas,
637
+ required,
638
+ schema.nullable
639
+ );
623
640
  }
624
641
 
625
642
  if (mergedSchemas.properties !== undefined) {
626
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
643
+ return createDetailsNode(
644
+ name,
645
+ mergedSchemaName,
646
+ mergedSchemas,
647
+ required,
648
+ schema.nullable
649
+ );
627
650
  }
628
651
 
629
652
  if (mergedSchemas.additionalProperties !== undefined) {
630
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
653
+ return createDetailsNode(
654
+ name,
655
+ mergedSchemaName,
656
+ mergedSchemas,
657
+ required,
658
+ schema.nullable
659
+ );
631
660
  }
632
661
 
633
662
  // array of objects
634
663
  if (mergedSchemas.items?.properties !== undefined) {
635
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
664
+ return createDetailsNode(
665
+ name,
666
+ mergedSchemaName,
667
+ mergedSchemas,
668
+ required,
669
+ schema.nullable
670
+ );
636
671
  }
637
672
 
638
673
  if (mergedSchemas.readOnly && mergedSchemas.readOnly === true) {
@@ -650,20 +685,44 @@ function createEdges({
650
685
  }
651
686
 
652
687
  if (schema.properties !== undefined) {
653
- return createDetailsNode(name, schemaName, schema, required);
688
+ return createDetailsNode(
689
+ name,
690
+ schemaName,
691
+ schema,
692
+ required,
693
+ schema.nullable
694
+ );
654
695
  }
655
696
 
656
697
  if (schema.additionalProperties !== undefined) {
657
- return createDetailsNode(name, schemaName, schema, required);
698
+ return createDetailsNode(
699
+ name,
700
+ schemaName,
701
+ schema,
702
+ required,
703
+ schema.nullable
704
+ );
658
705
  }
659
706
 
660
707
  // array of objects
661
708
  if (schema.items?.properties !== undefined) {
662
- return createDetailsNode(name, schemaName, schema, required);
709
+ return createDetailsNode(
710
+ name,
711
+ schemaName,
712
+ schema,
713
+ required,
714
+ schema.nullable
715
+ );
663
716
  }
664
717
 
665
718
  if (schema.items?.anyOf !== undefined || schema.items?.oneOf !== undefined) {
666
- return createDetailsNode(name, schemaName, schema, required);
719
+ return createDetailsNode(
720
+ name,
721
+ schemaName,
722
+ schema,
723
+ required,
724
+ schema.nullable
725
+ );
667
726
  }
668
727
 
669
728
  if (schema.readOnly && schema.readOnly === true) {
@@ -751,7 +810,7 @@ function createNodes(schema: SchemaObject): any {
751
810
 
752
811
  // Unknown node/schema type should return undefined
753
812
  // So far, haven't seen this hit in testing
754
- return undefined;
813
+ return "any";
755
814
  }
756
815
 
757
816
  interface Props {
@@ -840,7 +899,8 @@ export function createRequestSchema({ title, body, ...rest }: Props) {
840
899
  }
841
900
 
842
901
  const randomFirstKey = Object.keys(body.content)[0];
843
- const firstBody = body.content[randomFirstKey].schema;
902
+ const firstBody: any =
903
+ body.content[randomFirstKey].schema ?? body.content![randomFirstKey];
844
904
 
845
905
  if (firstBody === undefined) {
846
906
  return undefined;
@@ -442,7 +442,8 @@ function createDetailsNode(
442
442
  name: string,
443
443
  schemaName: string,
444
444
  schema: SchemaObject,
445
- required: string[] | boolean
445
+ required: string[] | boolean,
446
+ nullable: boolean | unknown
446
447
  ): any {
447
448
  return create("SchemaItem", {
448
449
  collapsible: true,
@@ -457,24 +458,33 @@ function createDetailsNode(
457
458
  style: { opacity: "0.6" },
458
459
  children: ` ${schemaName}`,
459
460
  }),
460
- guard(schema.nullable && schema.nullable === true, () => [
461
- create("strong", {
462
- style: {
463
- fontSize: "var(--ifm-code-font-size)",
464
- color: "var(--openapi-nullable)",
465
- },
466
- children: " nullable",
467
- }),
468
- ]),
469
- guard(schema.required && schema.required === true, () => [
470
- create("strong", {
471
- style: {
472
- fontSize: "var(--ifm-code-font-size)",
473
- color: "var(--openapi-required)",
474
- },
475
- children: " required",
476
- }),
477
- ]),
461
+ guard(
462
+ (schema.nullable && schema.nullable === true) ||
463
+ (nullable && nullable === true),
464
+ () => [
465
+ create("strong", {
466
+ style: {
467
+ fontSize: "var(--ifm-code-font-size)",
468
+ color: "var(--openapi-nullable)",
469
+ },
470
+ children: " nullable",
471
+ }),
472
+ ]
473
+ ),
474
+ guard(
475
+ Array.isArray(required)
476
+ ? required.includes(name)
477
+ : required === true,
478
+ () => [
479
+ create("strong", {
480
+ style: {
481
+ fontSize: "var(--ifm-code-font-size)",
482
+ color: "var(--openapi-required)",
483
+ },
484
+ children: " required",
485
+ }),
486
+ ]
487
+ ),
478
488
  ],
479
489
  }),
480
490
  create("div", {
@@ -605,7 +615,13 @@ function createEdges({
605
615
  }
606
616
 
607
617
  if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
608
- return createDetailsNode(name, schemaName, schema, required);
618
+ return createDetailsNode(
619
+ name,
620
+ schemaName,
621
+ schema,
622
+ required,
623
+ schema.nullable
624
+ );
609
625
  }
610
626
 
611
627
  if (schema.allOf !== undefined) {
@@ -620,20 +636,44 @@ function createEdges({
620
636
  mergedSchemas.oneOf !== undefined ||
621
637
  mergedSchemas.anyOf !== undefined
622
638
  ) {
623
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
639
+ return createDetailsNode(
640
+ name,
641
+ mergedSchemaName,
642
+ mergedSchemas,
643
+ required,
644
+ schema.nullable
645
+ );
624
646
  }
625
647
 
626
648
  if (mergedSchemas.properties !== undefined) {
627
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
649
+ return createDetailsNode(
650
+ name,
651
+ mergedSchemaName,
652
+ mergedSchemas,
653
+ required,
654
+ schema.nullable
655
+ );
628
656
  }
629
657
 
630
658
  if (mergedSchemas.additionalProperties !== undefined) {
631
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
659
+ return createDetailsNode(
660
+ name,
661
+ mergedSchemaName,
662
+ mergedSchemas,
663
+ required,
664
+ schema.nullable
665
+ );
632
666
  }
633
667
 
634
668
  // array of objects
635
669
  if (mergedSchemas.items?.properties !== undefined) {
636
- return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
670
+ return createDetailsNode(
671
+ name,
672
+ mergedSchemaName,
673
+ mergedSchemas,
674
+ required,
675
+ schema.nullable
676
+ );
637
677
  }
638
678
 
639
679
  if (mergedSchemas.writeOnly && mergedSchemas.writeOnly === true) {
@@ -651,20 +691,44 @@ function createEdges({
651
691
  }
652
692
 
653
693
  if (schema.properties !== undefined) {
654
- return createDetailsNode(name, schemaName, schema, required);
694
+ return createDetailsNode(
695
+ name,
696
+ schemaName,
697
+ schema,
698
+ required,
699
+ schema.nullable
700
+ );
655
701
  }
656
702
 
657
703
  if (schema.additionalProperties !== undefined) {
658
- return createDetailsNode(name, schemaName, schema, required);
704
+ return createDetailsNode(
705
+ name,
706
+ schemaName,
707
+ schema,
708
+ required,
709
+ schema.nullable
710
+ );
659
711
  }
660
712
 
661
713
  // array of objects
662
714
  if (schema.items?.properties !== undefined) {
663
- return createDetailsNode(name, schemaName, schema, required);
715
+ return createDetailsNode(
716
+ name,
717
+ schemaName,
718
+ schema,
719
+ required,
720
+ schema.nullable
721
+ );
664
722
  }
665
723
 
666
724
  if (schema.items?.anyOf !== undefined || schema.items?.oneOf !== undefined) {
667
- return createDetailsNode(name, schemaName, schema, required);
725
+ return createDetailsNode(
726
+ name,
727
+ schemaName,
728
+ schema,
729
+ required,
730
+ schema.nullable
731
+ );
668
732
  }
669
733
 
670
734
  if (schema.writeOnly && schema.writeOnly === true) {
@@ -697,7 +761,6 @@ function createNodes(schema: SchemaObject): any {
697
761
 
698
762
  if (schema.allOf !== undefined) {
699
763
  const { mergedSchemas } = mergeAllOf(schema.allOf);
700
-
701
764
  if (mergedSchemas.properties !== undefined) {
702
765
  nodes.push(createProperties(mergedSchemas));
703
766
  }
@@ -755,7 +818,7 @@ function createNodes(schema: SchemaObject): any {
755
818
 
756
819
  // Unknown node/schema type should return undefined
757
820
  // So far, haven't seen this hit in testing
758
- return undefined;
821
+ return "any";
759
822
  }
760
823
 
761
824
  interface Props {
@@ -789,7 +852,8 @@ export function createResponseSchema({ title, body, ...rest }: Props) {
789
852
  children: mimeTypes.map((mimeType: any) => {
790
853
  const responseExamples = body.content![mimeType].examples;
791
854
  const responseExample = body.content![mimeType].example;
792
- const firstBody = body.content![mimeType].schema;
855
+ const firstBody: any =
856
+ body.content![mimeType].schema ?? body.content![mimeType];
793
857
 
794
858
  if (
795
859
  firstBody === undefined &&
@@ -62,46 +62,45 @@ function createResponseHeaders(responseHeaders: any) {
62
62
  create("ul", {
63
63
  style: { marginLeft: "1rem" },
64
64
  children: [
65
- Object.entries(responseHeaders).map(([headerName, headerObj]) => {
66
- const {
67
- description,
68
- schema: { type },
69
- example,
70
- }: any = headerObj;
65
+ Object.entries(responseHeaders).map(
66
+ ([headerName, headerObj]: [any, any]) => {
67
+ const { description, example }: any = headerObj;
68
+ const type = headerObj.schema?.type ?? "any";
71
69
 
72
- return create("li", {
73
- className: "schemaItem",
74
- children: [
75
- createDetailsSummary({
76
- children: [
77
- create("strong", { children: headerName }),
78
- guard(type, () => [
79
- create("span", {
80
- style: { opacity: "0.6" },
81
- children: ` ${type}`,
82
- }),
83
- ]),
84
- ],
85
- }),
86
- create("div", {
87
- children: [
88
- guard(description, (description) =>
89
- create("div", {
90
- style: {
91
- marginTop: ".5rem",
92
- marginBottom: ".5rem",
93
- },
94
- children: [
95
- guard(example, () => `Example: ${example}`),
96
- createDescription(description),
97
- ],
98
- })
99
- ),
100
- ],
101
- }),
102
- ],
103
- });
104
- }),
70
+ return create("li", {
71
+ className: "schemaItem",
72
+ children: [
73
+ createDetailsSummary({
74
+ children: [
75
+ create("strong", { children: headerName }),
76
+ guard(type, () => [
77
+ create("span", {
78
+ style: { opacity: "0.6" },
79
+ children: ` ${type}`,
80
+ }),
81
+ ]),
82
+ ],
83
+ }),
84
+ create("div", {
85
+ children: [
86
+ guard(description, (description) =>
87
+ create("div", {
88
+ style: {
89
+ marginTop: ".5rem",
90
+ marginBottom: ".5rem",
91
+ },
92
+ children: [
93
+ guard(example, () => `Example: ${example}`),
94
+ createDescription(description),
95
+ ],
96
+ })
97
+ ),
98
+ ],
99
+ }),
100
+ ],
101
+ });
102
+ }
103
+ ),
105
104
  ],
106
105
  })
107
106
  );
@@ -88,7 +88,7 @@ export function createInfoPageMD({
88
88
  }: InfoPageMetadata) {
89
89
  return render([
90
90
  `import ApiLogo from "@theme/ApiLogo";\n`,
91
- `import Tabs from "@theme/Tabs";\n`,
91
+ `import SchemaTabs from "@theme/SchemaTabs";\n`,
92
92
  `import TabItem from "@theme/TabItem";\n`,
93
93
  `import Export from "@theme/ApiDemoPanel/Export";\n\n`,
94
94
 
@@ -31,7 +31,7 @@ const primitives: Primitives = {
31
31
  default: () => "string",
32
32
  email: () => "user@example.com",
33
33
  date: () => new Date().toISOString().substring(0, 10),
34
- "date-time": () => new Date().toISOString().substring(0, 10),
34
+ "date-time": () => new Date().toISOString(),
35
35
  uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
36
36
  hostname: () => "example.com",
37
37
  ipv4: () => "198.51.100.42",
@@ -31,7 +31,7 @@ const primitives: Primitives = {
31
31
  default: () => "string",
32
32
  email: () => "user@example.com",
33
33
  date: () => new Date().toISOString().substring(0, 10),
34
- "date-time": () => new Date().toISOString().substring(0, 10),
34
+ "date-time": () => new Date().toISOString(),
35
35
  uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
36
36
  hostname: () => "example.com",
37
37
  ipv4: () => "198.51.100.42",
@@ -88,7 +88,7 @@ function createItems(
88
88
  const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
89
89
  const infoId = kebabCase(infoIdSpaces);
90
90
 
91
- if (openapiData.info.description) {
91
+ if (openapiData.info.description || openapiData.info.title) {
92
92
  // Only create an info page if we have a description.
93
93
  const infoDescription = openapiData.info?.description;
94
94
  let splitDescription: any;
@@ -221,6 +221,9 @@ function createItems(
221
221
  .replace(/\s+$/, "")
222
222
  : "",
223
223
  ...(options?.proxy && { proxy: options.proxy }),
224
+ ...(options?.hideSendButton && {
225
+ hide_send_button: options.hideSendButton,
226
+ }),
224
227
  },
225
228
  api: {
226
229
  ...defaults,
@@ -338,6 +341,9 @@ function createItems(
338
341
  .replace(/\s+$/, "")
339
342
  : "",
340
343
  ...(options?.proxy && { proxy: options.proxy }),
344
+ ...(options?.hideSendButton && {
345
+ hide_send_button: options.hideSendButton,
346
+ }),
341
347
  },
342
348
  api: {
343
349
  ...defaults,
@@ -128,6 +128,21 @@ export async function loadAndResolveSpec(specUrlOrObject: object | string) {
128
128
  const {
129
129
  bundle: { parsed },
130
130
  } = await bundle(bundleOpts);
131
+
132
+ //Pre-processing before resolving JSON refs
133
+ if (parsed.components) {
134
+ for (let [component, type] of Object.entries(parsed.components) as any) {
135
+ if (component === "schemas") {
136
+ for (let [schemaKey, schemaValue] of Object.entries(type) as any) {
137
+ const title: string | undefined = schemaValue["title"];
138
+ if (!title) {
139
+ schemaValue.title = schemaKey;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+
131
146
  const resolved = await resolveJsonRefs(parsed);
132
147
 
133
148
  // Force serialization and replace circular $ref pointers
package/src/options.ts CHANGED
@@ -27,6 +27,7 @@ export const OptionsSchema = Joi.object({
27
27
  outputDir: Joi.string().required(),
28
28
  template: Joi.string(),
29
29
  downloadUrl: Joi.string(),
30
+ hideSendButton: Joi.boolean(),
30
31
  sidebarOptions: sidebarOptions,
31
32
  version: Joi.string().when("versions", {
32
33
  is: Joi.exist(),
@@ -41,7 +41,11 @@ function groupByTags(
41
41
  tags: TagObject[][],
42
42
  docPath: string
43
43
  ): ProcessedSidebar {
44
- const { outputDir, label } = options;
44
+ let { outputDir, label } = options;
45
+
46
+ // Remove trailing slash before proceeding
47
+ outputDir = outputDir.replace(/\/$/, "");
48
+
45
49
  const {
46
50
  sidebarCollapsed,
47
51
  sidebarCollapsible,
@@ -214,6 +218,7 @@ export default function generateSidebarSlice(
214
218
  docPath: string
215
219
  ) {
216
220
  let sidebarSlice: ProcessedSidebar = [];
221
+
217
222
  if (sidebarOptions.groupPathsBy === "tag") {
218
223
  sidebarSlice = groupByTags(
219
224
  api as ApiPageMetadata[],
package/src/types.ts CHANGED
@@ -33,6 +33,7 @@ export interface APIOptions {
33
33
  outputDir: string;
34
34
  template?: string;
35
35
  downloadUrl?: string;
36
+ hideSendButton?: boolean;
36
37
  sidebarOptions?: SidebarOptions;
37
38
  version?: string;
38
39
  label?: string;