docusaurus-plugin-openapi-docs 1.1.2 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +1 -1
  2. package/lib/markdown/createLogo.d.ts +2 -0
  3. package/lib/markdown/createLogo.js +19 -0
  4. package/lib/markdown/createRequestBodyDetails.d.ts +9 -2
  5. package/lib/markdown/createRequestBodyDetails.js +2 -2
  6. package/lib/markdown/createRequestSchema.d.ts +21 -0
  7. package/lib/markdown/createRequestSchema.js +680 -0
  8. package/lib/markdown/{createSchemaDetails.d.ts → createResponseSchema.d.ts} +2 -2
  9. package/lib/markdown/{createSchemaDetails.js → createResponseSchema.js} +289 -48
  10. package/lib/markdown/createStatusCodes.js +117 -4
  11. package/lib/markdown/index.d.ts +1 -1
  12. package/lib/markdown/index.js +12 -3
  13. package/lib/markdown/schema.js +50 -14
  14. package/lib/markdown/schema.test.js +18 -18
  15. package/lib/openapi/createExample.js +27 -14
  16. package/lib/openapi/openapi.d.ts +1 -1
  17. package/lib/openapi/openapi.js +30 -19
  18. package/lib/openapi/types.d.ts +8 -1
  19. package/lib/openapi/utils/loadAndResolveSpec.js +13 -0
  20. package/lib/sidebars/index.d.ts +1 -1
  21. package/lib/sidebars/index.js +14 -5
  22. package/lib/types.d.ts +1 -1
  23. package/package.json +8 -8
  24. package/src/markdown/createLogo.ts +21 -0
  25. package/src/markdown/createRequestBodyDetails.ts +11 -4
  26. package/src/markdown/createRequestSchema.ts +848 -0
  27. package/src/markdown/{createSchemaDetails.ts → createResponseSchema.ts} +350 -54
  28. package/src/markdown/createStatusCodes.ts +149 -9
  29. package/src/markdown/index.ts +34 -3
  30. package/src/markdown/schema.test.ts +18 -18
  31. package/src/markdown/schema.ts +60 -14
  32. package/src/openapi/createExample.ts +31 -14
  33. package/src/openapi/openapi.ts +21 -13
  34. package/src/openapi/types.ts +9 -1
  35. package/src/openapi/utils/loadAndResolveSpec.ts +13 -0
  36. package/src/sidebars/index.ts +17 -7
  37. package/src/types.ts +1 -1
@@ -7,13 +7,90 @@
7
7
 
8
8
  import { ApiItem } from "../types";
9
9
  import { createDescription } from "./createDescription";
10
- import { createSchemaDetails } from "./createSchemaDetails";
10
+ import { createDetails } from "./createDetails";
11
+ import { createDetailsSummary } from "./createDetailsSummary";
12
+ import { createResponseSchema } from "./createResponseSchema";
11
13
  import { create } from "./utils";
14
+ import { guard } from "./utils";
12
15
 
13
16
  interface Props {
14
17
  responses: ApiItem["responses"];
15
18
  }
16
19
 
20
+ function createResponseHeaders(responseHeaders: any) {
21
+ return guard(responseHeaders, () =>
22
+ create("ul", {
23
+ style: { marginLeft: "1rem" },
24
+ children: [
25
+ Object.entries(responseHeaders).map(([headerName, headerObj]) => {
26
+ const {
27
+ description,
28
+ schema: { type },
29
+ example,
30
+ }: any = headerObj;
31
+
32
+ return create("li", {
33
+ class: "schemaItem",
34
+ children: [
35
+ createDetailsSummary({
36
+ children: [
37
+ create("strong", { children: headerName }),
38
+ guard(type, () => [
39
+ create("span", {
40
+ style: { opacity: "0.6" },
41
+ children: ` ${type}`,
42
+ }),
43
+ ]),
44
+ ],
45
+ }),
46
+ create("div", {
47
+ children: [
48
+ guard(description, (description) =>
49
+ create("div", {
50
+ style: {
51
+ marginTop: ".5rem",
52
+ marginBottom: ".5rem",
53
+ },
54
+ children: [
55
+ guard(example, () => `Example: ${example}`),
56
+ createDescription(description),
57
+ ],
58
+ })
59
+ ),
60
+ ],
61
+ }),
62
+ ],
63
+ });
64
+ }),
65
+ ],
66
+ })
67
+ );
68
+ }
69
+
70
+ function createResponseExamples(responseExamples: any) {
71
+ return Object.entries(responseExamples).map(
72
+ ([exampleName, exampleValue]: any) => {
73
+ const camelToSpaceName = exampleName.replace(/([A-Z])/g, " $1");
74
+ let finalFormattedName =
75
+ camelToSpaceName.charAt(0).toUpperCase() + camelToSpaceName.slice(1);
76
+
77
+ return create("TabItem", {
78
+ label: `${finalFormattedName}`,
79
+ value: `${finalFormattedName}`,
80
+ children: [
81
+ create("ResponseSamples", {
82
+ responseExample: JSON.stringify(
83
+ exampleValue.value ?? exampleValue,
84
+ null,
85
+ 2
86
+ ),
87
+ }),
88
+ ],
89
+ });
90
+ }
91
+ );
92
+ }
93
+
17
94
  export function createStatusCodes({ responses }: Props) {
18
95
  if (responses === undefined) {
19
96
  return undefined;
@@ -28,6 +105,15 @@ export function createStatusCodes({ responses }: Props) {
28
105
  children: [
29
106
  create("ApiTabs", {
30
107
  children: codes.map((code) => {
108
+ const responseHeaders: any = responses[code].headers;
109
+ const responseContent: any = responses[code].content;
110
+ const responseContentKey: any =
111
+ responseContent && Object.keys(responseContent)[0];
112
+ const responseExamples: any =
113
+ responseContentKey &&
114
+ (responseContent[responseContentKey].examples ||
115
+ responseContent[responseContentKey].example);
116
+
31
117
  return create("TabItem", {
32
118
  label: code,
33
119
  value: code,
@@ -35,14 +121,68 @@ export function createStatusCodes({ responses }: Props) {
35
121
  create("div", {
36
122
  children: createDescription(responses[code].description),
37
123
  }),
38
- create("div", {
39
- children: createSchemaDetails({
40
- title: "Schema",
41
- body: {
42
- content: responses[code].content,
43
- },
44
- }),
45
- }),
124
+ guard(responseExamples, () =>
125
+ create("SchemaTabs", {
126
+ children: [
127
+ create("TabTtem", {
128
+ label: "Schema",
129
+ value: "Schema",
130
+ children: [
131
+ responseHeaders &&
132
+ createDetails({
133
+ "data-collaposed": false,
134
+ open: true,
135
+ style: { textAlign: "left", marginBottom: "1rem" },
136
+ children: [
137
+ createDetailsSummary({
138
+ children: [
139
+ create("strong", {
140
+ children: "Response Headers",
141
+ }),
142
+ ],
143
+ }),
144
+ createResponseHeaders(responseHeaders),
145
+ ],
146
+ }),
147
+ create("div", {
148
+ children: createResponseSchema({
149
+ title: "Schema",
150
+ body: {
151
+ content: responses[code].content,
152
+ },
153
+ }),
154
+ }),
155
+ ],
156
+ }),
157
+ createResponseExamples(responseExamples),
158
+ ],
159
+ })
160
+ ),
161
+ guard(responseHeaders && !responseExamples, () =>
162
+ createDetails({
163
+ "data-collaposed": false,
164
+ open: true,
165
+ style: { textAlign: "left" },
166
+ children: [
167
+ createDetailsSummary({
168
+ children: [
169
+ create("strong", { children: "Response Headers" }),
170
+ ],
171
+ }),
172
+ createResponseHeaders(responseHeaders),
173
+ ],
174
+ })
175
+ ),
176
+ guard(!responseExamples, () =>
177
+ create("div", {
178
+ children: createResponseSchema({
179
+ title: "Schema",
180
+ body: {
181
+ content: responses[code].content,
182
+ },
183
+ }),
184
+ })
185
+ ),
46
186
  ],
47
187
  });
48
188
  }),
@@ -10,6 +10,7 @@ import { escape } from "lodash";
10
10
  import {
11
11
  ContactObject,
12
12
  LicenseObject,
13
+ MediaTypeObject,
13
14
  SecuritySchemeObject,
14
15
  } from "../openapi/types";
15
16
  import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
@@ -18,6 +19,7 @@ import { createContactInfo } from "./createContactInfo";
18
19
  import { createDeprecationNotice } from "./createDeprecationNotice";
19
20
  import { createDescription } from "./createDescription";
20
21
  import { createLicense } from "./createLicense";
22
+ import { createLogo } from "./createLogo";
21
23
  import { createParamsDetails } from "./createParamsDetails";
22
24
  import { createRequestBodyDetails } from "./createRequestBodyDetails";
23
25
  import { createStatusCodes } from "./createStatusCodes";
@@ -25,6 +27,17 @@ import { createTermsOfService } from "./createTermsOfService";
25
27
  import { createVersionBadge } from "./createVersionBadge";
26
28
  import { render } from "./utils";
27
29
 
30
+ interface Props {
31
+ title: string;
32
+ body: {
33
+ content?: {
34
+ [key: string]: MediaTypeObject;
35
+ };
36
+ description?: string;
37
+ required?: boolean;
38
+ };
39
+ }
40
+
28
41
  export function createApiPageMD({
29
42
  title,
30
43
  api: {
@@ -37,10 +50,13 @@ export function createApiPageMD({
37
50
  },
38
51
  }: ApiPageMetadata) {
39
52
  return render([
53
+ `import ApiTabs from "@theme/ApiTabs";\n`,
54
+ `import MimeTabs from "@theme/MimeTabs";\n`,
40
55
  `import ParamsItem from "@theme/ParamsItem";\n`,
56
+ `import ResponseSamples from "@theme/ResponseSamples";\n`,
41
57
  `import SchemaItem from "@theme/SchemaItem"\n`,
42
- `import ApiTabs from "@theme/ApiTabs";\n`,
43
58
  `import SchemaTabs from "@theme/SchemaTabs";\n`,
59
+ `import DiscriminatorTabs from "@theme/DiscriminatorTabs";\n`,
44
60
  `import TabItem from "@theme/TabItem";\n\n`,
45
61
  `## ${escape(title)}\n\n`,
46
62
  createDeprecationNotice({ deprecated, description: deprecatedDescription }),
@@ -49,20 +65,35 @@ export function createApiPageMD({
49
65
  createParamsDetails({ parameters, type: "query" }),
50
66
  createParamsDetails({ parameters, type: "header" }),
51
67
  createParamsDetails({ parameters, type: "cookie" }),
52
- createRequestBodyDetails({ title: "Request Body", body: requestBody }),
68
+ createRequestBodyDetails({
69
+ title: "Request Body",
70
+ body: requestBody,
71
+ } as Props),
53
72
  createStatusCodes({ responses }),
54
73
  ]);
55
74
  }
56
75
 
57
76
  export function createInfoPageMD({
58
- info: { title, version, description, contact, license, termsOfService },
77
+ info: {
78
+ title,
79
+ version,
80
+ description,
81
+ contact,
82
+ license,
83
+ termsOfService,
84
+ logo,
85
+ darkLogo,
86
+ },
59
87
  securitySchemes,
60
88
  }: InfoPageMetadata) {
61
89
  return render([
90
+ `import ApiLogo from "@theme/ApiLogo";\n`,
62
91
  `import Tabs from "@theme/Tabs";\n`,
63
92
  `import TabItem from "@theme/TabItem";\n\n`,
93
+
64
94
  createVersionBadge(version),
65
95
  `# ${escape(title)}\n\n`,
96
+ createLogo(logo, darkLogo),
66
97
  createDescription(description),
67
98
  createAuthentication(securitySchemes as unknown as SecuritySchemeObject),
68
99
  createContactInfo(contact as ContactObject),
@@ -17,19 +17,19 @@ describe("getQualifierMessage", () => {
17
17
  // minLength + maxLength
18
18
  //
19
19
  it("should render minLength", () => {
20
- const expected = "**Possible values:** 1 ≤ length";
20
+ const expected = "**Possible values:** `non-empty`";
21
21
  const actual = getQualifierMessage({ minLength: 1 });
22
22
  expect(actual).toBe(expected);
23
23
  });
24
24
 
25
25
  it("should render maxLength", () => {
26
- const expected = "**Possible values:** length 40";
26
+ const expected = "**Possible values:** `<= 40 characters`";
27
27
  const actual = getQualifierMessage({ maxLength: 40 });
28
28
  expect(actual).toBe(expected);
29
29
  });
30
30
 
31
31
  it("should render minLength and maxLength", () => {
32
- const expected = "**Possible values:** 1 length 40";
32
+ const expected = "**Possible values:** `non-empty` and `<= 40 characters`";
33
33
  const actual = getQualifierMessage({ minLength: 1, maxLength: 40 });
34
34
  expect(actual).toBe(expected);
35
35
  });
@@ -46,7 +46,7 @@ describe("getQualifierMessage", () => {
46
46
 
47
47
  it("should render multiple string qualifiers", () => {
48
48
  const expected =
49
- "**Possible values:** 1 length 40, Value must match regular expression `^[a-zA-Z0-9_-]*$`";
49
+ "**Possible values:** `non-empty` and `<= 40 characters`, Value must match regular expression `^[a-zA-Z0-9_-]*$`";
50
50
  const actual = getQualifierMessage({
51
51
  minLength: 1,
52
52
  maxLength: 40,
@@ -68,49 +68,49 @@ describe("getQualifierMessage", () => {
68
68
  // minimum + maximum + exclusiveMinimum + exclusiveMaximum
69
69
  //
70
70
  it("should render minimum", () => {
71
- const expected = "**Possible values:** 1 ≤ value";
71
+ const expected = "**Possible values:** `>= 1`";
72
72
  const actual = getQualifierMessage({ minimum: 1 });
73
73
  expect(actual).toBe(expected);
74
74
  });
75
75
 
76
76
  it("should render maximum", () => {
77
- const expected = "**Possible values:** value 40";
77
+ const expected = "**Possible values:** `<= 40`";
78
78
  const actual = getQualifierMessage({ maximum: 40 });
79
79
  expect(actual).toBe(expected);
80
80
  });
81
81
 
82
82
  it("should render numeric exclusiveMinimum", () => {
83
- const expected = "**Possible values:** 1 < value";
83
+ const expected = "**Possible values:** `> 1`";
84
84
  const actual = getQualifierMessage({ exclusiveMinimum: 1 });
85
85
  expect(actual).toBe(expected);
86
86
  });
87
87
 
88
88
  it("should render numeric exclusiveMaximum", () => {
89
- const expected = "**Possible values:** value < 40";
89
+ const expected = "**Possible values:** `< 40`";
90
90
  const actual = getQualifierMessage({ exclusiveMaximum: 40 });
91
91
  expect(actual).toBe(expected);
92
92
  });
93
93
 
94
94
  it("should render boolean exclusiveMinimum", () => {
95
- const expected = "**Possible values:** 1 < value";
95
+ const expected = "**Possible values:** `> 1`";
96
96
  const actual = getQualifierMessage({ minimum: 1, exclusiveMinimum: true });
97
97
  expect(actual).toBe(expected);
98
98
  });
99
99
 
100
100
  it("should render boolean exclusiveMaximum", () => {
101
- const expected = "**Possible values:** value < 40";
101
+ const expected = "**Possible values:** `< 40`";
102
102
  const actual = getQualifierMessage({ maximum: 40, exclusiveMaximum: true });
103
103
  expect(actual).toBe(expected);
104
104
  });
105
105
 
106
106
  it("should render minimum when exclusiveMinimum is false", () => {
107
- const expected = "**Possible values:** 1 ≤ value";
107
+ const expected = "**Possible values:** `>= 1`";
108
108
  const actual = getQualifierMessage({ minimum: 1, exclusiveMinimum: false });
109
109
  expect(actual).toBe(expected);
110
110
  });
111
111
 
112
112
  it("should render maximum when exclusiveMaximum is false", () => {
113
- const expected = "**Possible values:** value 40";
113
+ const expected = "**Possible values:** `<= 40`";
114
114
  const actual = getQualifierMessage({
115
115
  maximum: 40,
116
116
  exclusiveMaximum: false,
@@ -119,13 +119,13 @@ describe("getQualifierMessage", () => {
119
119
  });
120
120
 
121
121
  it("should render minimum and maximum", () => {
122
- const expected = "**Possible values:** 1 value 40";
122
+ const expected = "**Possible values:** `>= 1` and `<= 40`";
123
123
  const actual = getQualifierMessage({ minimum: 1, maximum: 40 });
124
124
  expect(actual).toBe(expected);
125
125
  });
126
126
 
127
127
  it("should render boolean exclusiveMinimum and maximum", () => {
128
- const expected = "**Possible values:** 1 < value 40";
128
+ const expected = "**Possible values:** `> 1` and `<= 40`";
129
129
  const actual = getQualifierMessage({
130
130
  minimum: 1,
131
131
  maximum: 40,
@@ -135,7 +135,7 @@ describe("getQualifierMessage", () => {
135
135
  });
136
136
 
137
137
  it("should render minimum and boolean exclusiveMaximum", () => {
138
- const expected = "**Possible values:** 1 value < 40";
138
+ const expected = "**Possible values:** `>= 1` and `< 40`";
139
139
  const actual = getQualifierMessage({
140
140
  minimum: 1,
141
141
  maximum: 40,
@@ -145,7 +145,7 @@ describe("getQualifierMessage", () => {
145
145
  });
146
146
 
147
147
  it("should render numeric exclusiveMinimum and maximum", () => {
148
- const expected = "**Possible values:** 1 < value 40";
148
+ const expected = "**Possible values:** `> 1` and `<= 40`";
149
149
  const actual = getQualifierMessage({
150
150
  exclusiveMinimum: 1,
151
151
  maximum: 40,
@@ -154,7 +154,7 @@ describe("getQualifierMessage", () => {
154
154
  });
155
155
 
156
156
  it("should render minimum and numeric exclusiveMaximum", () => {
157
- const expected = "**Possible values:** 1 value < 40";
157
+ const expected = "**Possible values:** `>= 1` and `< 40`";
158
158
  const actual = getQualifierMessage({
159
159
  minimum: 1,
160
160
  exclusiveMaximum: 40,
@@ -163,7 +163,7 @@ describe("getQualifierMessage", () => {
163
163
  });
164
164
 
165
165
  it("should render numeric exclusiveMinimum and boolean exclusiveMaximum", () => {
166
- const expected = "**Possible values:** 1 < value < 40";
166
+ const expected = "**Possible values:** `> 1` and `< 40`";
167
167
  const actual = getQualifierMessage({
168
168
  exclusiveMinimum: 1,
169
169
  maximum: 40,
@@ -64,7 +64,11 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
64
64
  return undefined;
65
65
  }
66
66
 
67
- if (schema.items) {
67
+ if (
68
+ schema.items &&
69
+ schema.minItems === undefined &&
70
+ schema.maxItems === undefined
71
+ ) {
68
72
  return getQualifierMessage(schema.items);
69
73
  }
70
74
 
@@ -72,15 +76,38 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
72
76
 
73
77
  let qualifierGroups = [];
74
78
 
79
+ if (schema.items && schema.items.enum) {
80
+ if (schema.items.enum) {
81
+ qualifierGroups.push(
82
+ `[${schema.items.enum.map((e) => `\`${e}\``).join(", ")}]`
83
+ );
84
+ }
85
+ }
86
+
75
87
  if (schema.minLength || schema.maxLength) {
76
88
  let lengthQualifier = "";
77
- if (schema.minLength) {
78
- lengthQualifier += `${schema.minLength} ≤ `;
89
+ let minLength;
90
+ let maxLength;
91
+ if (schema.minLength && schema.minLength > 1) {
92
+ minLength = `\`>= ${schema.minLength} characters\``;
93
+ }
94
+ if (schema.minLength && schema.minLength === 1) {
95
+ minLength = `\`non-empty\``;
79
96
  }
80
- lengthQualifier += "length";
81
97
  if (schema.maxLength) {
82
- lengthQualifier += ` ${schema.maxLength}`;
98
+ maxLength = `\`<= ${schema.maxLength} characters\``;
99
+ }
100
+
101
+ if (minLength && !maxLength) {
102
+ lengthQualifier += minLength;
103
+ }
104
+ if (maxLength && !minLength) {
105
+ lengthQualifier += maxLength;
83
106
  }
107
+ if (minLength && maxLength) {
108
+ lengthQualifier += `${minLength} and ${maxLength}`;
109
+ }
110
+
84
111
  qualifierGroups.push(lengthQualifier);
85
112
  }
86
113
 
@@ -91,21 +118,33 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
91
118
  typeof schema.exclusiveMaximum === "number"
92
119
  ) {
93
120
  let minmaxQualifier = "";
121
+ let minimum;
122
+ let maximum;
94
123
  if (typeof schema.exclusiveMinimum === "number") {
95
- minmaxQualifier += `${schema.exclusiveMinimum} < `;
124
+ minimum = `\`> ${schema.exclusiveMinimum}\``;
96
125
  } else if (schema.minimum && !schema.exclusiveMinimum) {
97
- minmaxQualifier += `${schema.minimum} ≤ `;
126
+ minimum = `\`>= ${schema.minimum}\``;
98
127
  } else if (schema.minimum && schema.exclusiveMinimum === true) {
99
- minmaxQualifier += `${schema.minimum} < `;
128
+ minimum = `\`> ${schema.minimum}\``;
100
129
  }
101
- minmaxQualifier += "value";
102
130
  if (typeof schema.exclusiveMaximum === "number") {
103
- minmaxQualifier += ` < ${schema.exclusiveMaximum}`;
131
+ maximum = `\`< ${schema.exclusiveMaximum}\``;
104
132
  } else if (schema.maximum && !schema.exclusiveMaximum) {
105
- minmaxQualifier += ` ${schema.maximum}`;
133
+ maximum = `\`<= ${schema.maximum}\``;
106
134
  } else if (schema.maximum && schema.exclusiveMaximum === true) {
107
- minmaxQualifier += ` < ${schema.maximum}`;
135
+ maximum = `\`< ${schema.maximum}\``;
136
+ }
137
+
138
+ if (minimum && !maximum) {
139
+ minmaxQualifier += minimum;
140
+ }
141
+ if (maximum && !minimum) {
142
+ minmaxQualifier += maximum;
108
143
  }
144
+ if (minimum && maximum) {
145
+ minmaxQualifier += `${minimum} and ${maximum}`;
146
+ }
147
+
109
148
  qualifierGroups.push(minmaxQualifier);
110
149
  }
111
150
 
@@ -115,16 +154,23 @@ export function getQualifierMessage(schema?: SchemaObject): string | undefined {
115
154
  );
116
155
  }
117
156
 
157
+ // Check if discriminator mapping
158
+ const discriminator = schema as any;
159
+ if (discriminator.mapping) {
160
+ const values = Object.keys(discriminator.mapping);
161
+ qualifierGroups.push(`[${values.map((e) => `\`${e}\``).join(", ")}]`);
162
+ }
163
+
118
164
  if (schema.enum) {
119
165
  qualifierGroups.push(`[${schema.enum.map((e) => `\`${e}\``).join(", ")}]`);
120
166
  }
121
167
 
122
168
  if (schema.minItems) {
123
- qualifierGroups.push(`items >= ${schema.minItems}`);
169
+ qualifierGroups.push(`\`>= ${schema.minItems}\``);
124
170
  }
125
171
 
126
172
  if (schema.maxItems) {
127
- qualifierGroups.push(`items <= ${schema.maxItems}`);
173
+ qualifierGroups.push(`\`<= ${schema.maxItems}\``);
128
174
  }
129
175
 
130
176
  if (qualifierGroups.length === 0) {
@@ -7,6 +7,7 @@
7
7
 
8
8
  import chalk from "chalk";
9
9
 
10
+ import { mergeAllOf } from "../markdown/createRequestSchema";
10
11
  import { SchemaObject } from "./types";
11
12
 
12
13
  interface OASTypeToTypeMap {
@@ -29,6 +30,7 @@ const primitives: Primitives = {
29
30
  default: () => "string",
30
31
  email: () => "user@example.com",
31
32
  date: () => new Date().toISOString().substring(0, 10),
33
+ "date-time": () => new Date().toISOString().substring(0, 10),
32
34
  uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
33
35
  hostname: () => "example.com",
34
36
  ipv4: () => "198.51.100.42",
@@ -58,21 +60,16 @@ export const sampleFromSchema = (schema: SchemaObject = {}): any => {
58
60
  }
59
61
 
60
62
  if (allOf) {
61
- // TODO: We are just assuming it will always be an object for now
62
- let obj: SchemaObject = {
63
- type: "object",
64
- properties: {},
65
- required: [], // NOTE: We shouldn't need to worry about required
66
- };
67
- for (let item of allOf) {
68
- if (item.properties) {
69
- obj.properties = {
70
- ...obj.properties,
71
- ...item.properties,
72
- };
63
+ const { mergedSchemas }: { mergedSchemas: SchemaObject } =
64
+ mergeAllOf(allOf);
65
+ if (mergedSchemas.properties) {
66
+ for (const [key, value] of Object.entries(mergedSchemas.properties)) {
67
+ if (value.readOnly && value.readOnly === true) {
68
+ delete mergedSchemas.properties[key];
69
+ }
73
70
  }
74
71
  }
75
- return sampleFromSchema(obj);
72
+ return sampleFromSchema(mergedSchemas);
76
73
  }
77
74
 
78
75
  if (!type) {
@@ -88,6 +85,22 @@ export const sampleFromSchema = (schema: SchemaObject = {}): any => {
88
85
  if (type === "object") {
89
86
  let obj: any = {};
90
87
  for (let [name, prop] of Object.entries(properties ?? {})) {
88
+ if (prop.properties) {
89
+ for (const [key, value] of Object.entries(prop.properties)) {
90
+ if (value.readOnly && value.readOnly === true) {
91
+ delete prop.properties[key];
92
+ }
93
+ }
94
+ }
95
+
96
+ if (prop.items && prop.items.properties) {
97
+ for (const [key, value] of Object.entries(prop.items.properties)) {
98
+ if (value.readOnly && value.readOnly === true) {
99
+ delete prop.items.properties[key];
100
+ }
101
+ }
102
+ }
103
+
91
104
  if (prop.deprecated) {
92
105
  continue;
93
106
  }
@@ -115,6 +128,10 @@ export const sampleFromSchema = (schema: SchemaObject = {}): any => {
115
128
  return normalizeArray(schema.enum)[0];
116
129
  }
117
130
 
131
+ if (schema.readOnly && schema.readOnly === true) {
132
+ return undefined;
133
+ }
134
+
118
135
  return primitive(schema);
119
136
  } catch (err) {
120
137
  console.error(
@@ -131,7 +148,7 @@ function primitive(schema: SchemaObject = {}) {
131
148
  return;
132
149
  }
133
150
 
134
- let fn = primitives[type].default;
151
+ let fn = schema.default ? () => schema.default : primitives[type].default;
135
152
 
136
153
  if (format !== undefined) {
137
154
  fn = primitives[type][format] || fn;