docusaurus-plugin-openapi-docs 1.5.1 → 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.
@@ -6,6 +6,7 @@
6
6
  * ========================================================================== */
7
7
 
8
8
  import chalk from "chalk";
9
+ import merge from "lodash/merge";
9
10
 
10
11
  import { mergeAllOf } from "../markdown/createRequestSchema";
11
12
  import { SchemaObject } from "./types";
@@ -30,7 +31,7 @@ const primitives: Primitives = {
30
31
  default: () => "string",
31
32
  email: () => "user@example.com",
32
33
  date: () => new Date().toISOString().substring(0, 10),
33
- "date-time": () => new Date().toISOString().substring(0, 10),
34
+ "date-time": () => new Date().toISOString(),
34
35
  uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
35
36
  hostname: () => "example.com",
36
37
  ipv4: () => "198.51.100.42",
@@ -77,18 +78,30 @@ function sampleRequestFromProp(name: string, prop: any, obj: any): any {
77
78
 
78
79
  export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
79
80
  try {
80
- let { type, example, allOf, properties, items, oneOf, anyOf } = schema;
81
+ // deep copy schema before processing
82
+ let schemaCopy = JSON.parse(JSON.stringify(schema));
83
+ let { type, example, allOf, properties, items, oneOf, anyOf } = schemaCopy;
81
84
 
82
85
  if (example !== undefined) {
83
86
  return example;
84
87
  }
85
88
 
86
89
  if (oneOf) {
90
+ if (properties) {
91
+ const combinedSchemas = merge(schemaCopy, oneOf[0]);
92
+ delete combinedSchemas.oneOf;
93
+ return sampleRequestFromSchema(combinedSchemas);
94
+ }
87
95
  // Just go with first schema
88
96
  return sampleRequestFromSchema(oneOf[0]);
89
97
  }
90
98
 
91
99
  if (anyOf) {
100
+ if (properties) {
101
+ const combinedSchemas = merge(schemaCopy, anyOf[0]);
102
+ delete combinedSchemas.anyOf;
103
+ return sampleRequestFromSchema(combinedSchemas);
104
+ }
92
105
  // Just go with first schema
93
106
  return sampleRequestFromSchema(anyOf[0]);
94
107
  }
@@ -103,6 +116,11 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
103
116
  }
104
117
  }
105
118
  }
119
+ if (properties) {
120
+ const combinedSchemas = merge(schemaCopy, mergedSchemas);
121
+ delete combinedSchemas.allOf;
122
+ return sampleRequestFromSchema(combinedSchemas);
123
+ }
106
124
  return sampleRequestFromSchema(mergedSchemas);
107
125
  }
108
126
 
@@ -118,9 +136,9 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
118
136
 
119
137
  if (type === "object") {
120
138
  let obj: any = {};
121
- for (let [name, prop] of Object.entries(properties ?? {})) {
139
+ for (let [name, prop] of Object.entries(properties ?? {}) as any) {
122
140
  if (prop.properties) {
123
- for (const [key, value] of Object.entries(prop.properties)) {
141
+ for (const [key, value] of Object.entries(prop.properties) as any) {
124
142
  if (
125
143
  (value.readOnly && value.readOnly === true) ||
126
144
  value.deprecated
@@ -131,7 +149,9 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
131
149
  }
132
150
 
133
151
  if (prop.items && prop.items.properties) {
134
- for (const [key, value] of Object.entries(prop.items.properties)) {
152
+ for (const [key, value] of Object.entries(
153
+ prop.items.properties
154
+ ) as any) {
135
155
  if (
136
156
  (value.readOnly && value.readOnly === true) ||
137
157
  value.deprecated
@@ -157,28 +177,31 @@ export const sampleRequestFromSchema = (schema: SchemaObject = {}): any => {
157
177
 
158
178
  if (type === "array") {
159
179
  if (Array.isArray(items?.anyOf)) {
160
- return items?.anyOf.map((item) => sampleRequestFromSchema(item));
180
+ return items?.anyOf.map((item: any) => sampleRequestFromSchema(item));
161
181
  }
162
182
 
163
183
  if (Array.isArray(items?.oneOf)) {
164
- return items?.oneOf.map((item) => sampleRequestFromSchema(item));
184
+ return items?.oneOf.map((item: any) => sampleRequestFromSchema(item));
165
185
  }
166
186
 
167
187
  return [sampleRequestFromSchema(items)];
168
188
  }
169
189
 
170
- if (schema.enum) {
171
- if (schema.default) {
172
- return schema.default;
190
+ if (schemaCopy.enum) {
191
+ if (schemaCopy.default) {
192
+ return schemaCopy.default;
173
193
  }
174
- return normalizeArray(schema.enum)[0];
194
+ return normalizeArray(schemaCopy.enum)[0];
175
195
  }
176
196
 
177
- if ((schema.readOnly && schema.readOnly === true) || schema.deprecated) {
197
+ if (
198
+ (schema.readOnly && schema.readOnly === true) ||
199
+ schemaCopy.deprecated
200
+ ) {
178
201
  return undefined;
179
202
  }
180
203
 
181
- return primitive(schema);
204
+ return primitive(schemaCopy);
182
205
  } catch (err) {
183
206
  console.error(
184
207
  chalk.yellow("WARNING: failed to create example from schema object:", err)
@@ -6,6 +6,7 @@
6
6
  * ========================================================================== */
7
7
 
8
8
  import chalk from "chalk";
9
+ import merge from "lodash/merge";
9
10
 
10
11
  import { mergeAllOf } from "../markdown/createResponseSchema";
11
12
  import { SchemaObject } from "./types";
@@ -30,7 +31,7 @@ const primitives: Primitives = {
30
31
  default: () => "string",
31
32
  email: () => "user@example.com",
32
33
  date: () => new Date().toISOString().substring(0, 10),
33
- "date-time": () => new Date().toISOString().substring(0, 10),
34
+ "date-time": () => new Date().toISOString(),
34
35
  uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
35
36
  hostname: () => "example.com",
36
37
  ipv4: () => "198.51.100.42",
@@ -77,7 +78,9 @@ function sampleResponseFromProp(name: string, prop: any, obj: any): any {
77
78
 
78
79
  export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
79
80
  try {
80
- let { type, example, allOf, oneOf, anyOf, properties, items } = schema;
81
+ // deep copy schema before processing
82
+ let schemaCopy = JSON.parse(JSON.stringify(schema));
83
+ let { type, example, allOf, properties, items, oneOf, anyOf } = schemaCopy;
81
84
 
82
85
  if (example !== undefined) {
83
86
  return example;
@@ -96,15 +99,30 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
96
99
  }
97
100
  }
98
101
  }
102
+ if (properties) {
103
+ const combinedSchemas = merge(schemaCopy, mergedSchemas);
104
+ delete combinedSchemas.allOf;
105
+ return sampleResponseFromSchema(combinedSchemas);
106
+ }
99
107
  return sampleResponseFromSchema(mergedSchemas);
100
108
  }
101
109
 
102
110
  if (oneOf) {
111
+ if (properties) {
112
+ const combinedSchemas = merge(schemaCopy, oneOf[0]);
113
+ delete combinedSchemas.oneOf;
114
+ return sampleResponseFromSchema(combinedSchemas);
115
+ }
103
116
  // Just go with first schema
104
117
  return sampleResponseFromSchema(oneOf[0]);
105
118
  }
106
119
 
107
120
  if (anyOf) {
121
+ if (properties) {
122
+ const combinedSchemas = merge(schemaCopy, anyOf[0]);
123
+ delete combinedSchemas.anyOf;
124
+ return sampleResponseFromSchema(combinedSchemas);
125
+ }
108
126
  // Just go with first schema
109
127
  return sampleResponseFromSchema(anyOf[0]);
110
128
  }
@@ -121,9 +139,9 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
121
139
 
122
140
  if (type === "object") {
123
141
  let obj: any = {};
124
- for (let [name, prop] of Object.entries(properties ?? {})) {
142
+ for (let [name, prop] of Object.entries(properties ?? {}) as any) {
125
143
  if (prop.properties) {
126
- for (const [key, value] of Object.entries(prop.properties)) {
144
+ for (const [key, value] of Object.entries(prop.properties) as any) {
127
145
  if (
128
146
  (value.writeOnly && value.writeOnly === true) ||
129
147
  value.deprecated
@@ -134,7 +152,9 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
134
152
  }
135
153
 
136
154
  if (prop.items && prop.items.properties) {
137
- for (const [key, value] of Object.entries(prop.items.properties)) {
155
+ for (const [key, value] of Object.entries(
156
+ prop.items.properties
157
+ ) as any) {
138
158
  if (
139
159
  (value.writeOnly && value.writeOnly === true) ||
140
160
  value.deprecated
@@ -160,28 +180,31 @@ export const sampleResponseFromSchema = (schema: SchemaObject = {}): any => {
160
180
 
161
181
  if (type === "array") {
162
182
  if (Array.isArray(items?.anyOf)) {
163
- return items?.anyOf.map((item) => sampleResponseFromSchema(item));
183
+ return items?.anyOf.map((item: any) => sampleResponseFromSchema(item));
164
184
  }
165
185
 
166
186
  if (Array.isArray(items?.oneOf)) {
167
- return items?.oneOf.map((item) => sampleResponseFromSchema(item));
187
+ return items?.oneOf.map((item: any) => sampleResponseFromSchema(item));
168
188
  }
169
189
 
170
190
  return [sampleResponseFromSchema(items)];
171
191
  }
172
192
 
173
- if (schema.enum) {
174
- if (schema.default) {
175
- return schema.default;
193
+ if (schemaCopy.enum) {
194
+ if (schemaCopy.default) {
195
+ return schemaCopy.default;
176
196
  }
177
- return normalizeArray(schema.enum)[0];
197
+ return normalizeArray(schemaCopy.enum)[0];
178
198
  }
179
199
 
180
- if ((schema.writeOnly && schema.writeOnly === true) || schema.deprecated) {
200
+ if (
201
+ (schemaCopy.writeOnly && schemaCopy.writeOnly === true) ||
202
+ schemaCopy.deprecated
203
+ ) {
181
204
  return undefined;
182
205
  }
183
206
 
184
- return primitive(schema);
207
+ return primitive(schemaCopy);
185
208
  } catch (err) {
186
209
  console.error(
187
210
  chalk.yellow("WARNING: failed to create example from schema object:", err)
@@ -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;