docusaurus-plugin-openapi-docs 1.0.5 → 1.1.1

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 (56) hide show
  1. package/README.md +6 -7
  2. package/lib/index.js +3 -3
  3. package/lib/markdown/createSchemaDetails.js +325 -132
  4. package/lib/markdown/index.js +1 -0
  5. package/lib/markdown/schema.js +25 -9
  6. package/lib/markdown/utils.d.ts +1 -1
  7. package/lib/markdown/utils.js +4 -1
  8. package/lib/openapi/openapi.d.ts +5 -5
  9. package/lib/openapi/openapi.js +27 -23
  10. package/lib/openapi/openapi.test.js +1 -1
  11. package/lib/openapi/types.d.ts +2 -1
  12. package/lib/openapi/utils/loadAndResolveSpec.d.ts +2 -0
  13. package/lib/openapi/utils/loadAndResolveSpec.js +112 -0
  14. package/lib/openapi/utils/services/OpenAPIParser.d.ts +52 -0
  15. package/lib/openapi/utils/services/OpenAPIParser.js +342 -0
  16. package/lib/openapi/utils/services/RedocNormalizedOptions.d.ts +100 -0
  17. package/lib/openapi/utils/services/RedocNormalizedOptions.js +170 -0
  18. package/lib/openapi/utils/types/index.d.ts +2 -0
  19. package/lib/openapi/utils/types/index.js +23 -0
  20. package/lib/openapi/utils/types/open-api.d.ts +305 -0
  21. package/lib/openapi/utils/types/open-api.js +8 -0
  22. package/lib/openapi/utils/utils/JsonPointer.d.ts +51 -0
  23. package/lib/openapi/utils/utils/JsonPointer.js +95 -0
  24. package/lib/openapi/utils/utils/helpers.d.ts +43 -0
  25. package/lib/openapi/utils/utils/helpers.js +230 -0
  26. package/lib/openapi/utils/utils/index.d.ts +3 -0
  27. package/lib/openapi/utils/utils/index.js +25 -0
  28. package/lib/openapi/utils/utils/openapi.d.ts +40 -0
  29. package/lib/openapi/utils/utils/openapi.js +605 -0
  30. package/lib/options.js +1 -1
  31. package/lib/sidebars/index.js +9 -5
  32. package/lib/types.d.ts +1 -1
  33. package/package.json +16 -11
  34. package/src/index.ts +3 -3
  35. package/src/markdown/createSchemaDetails.ts +405 -159
  36. package/src/markdown/index.ts +1 -0
  37. package/src/markdown/schema.ts +28 -8
  38. package/src/markdown/utils.ts +5 -2
  39. package/src/openapi/openapi.test.ts +1 -1
  40. package/src/openapi/openapi.ts +39 -29
  41. package/src/openapi/types.ts +2 -1
  42. package/src/openapi/utils/loadAndResolveSpec.ts +123 -0
  43. package/src/openapi/utils/services/OpenAPIParser.ts +433 -0
  44. package/src/openapi/utils/services/RedocNormalizedOptions.ts +330 -0
  45. package/src/openapi/utils/types/index.ts +10 -0
  46. package/src/openapi/utils/types/open-api.ts +303 -0
  47. package/src/openapi/utils/utils/JsonPointer.ts +99 -0
  48. package/src/openapi/utils/utils/helpers.ts +239 -0
  49. package/src/openapi/utils/utils/index.ts +11 -0
  50. package/src/openapi/utils/utils/openapi.ts +771 -0
  51. package/src/options.ts +1 -1
  52. package/src/sidebars/index.ts +11 -6
  53. package/src/types.ts +1 -1
  54. package/lib/openapi/utils/loadAndBundleSpec.d.ts +0 -3
  55. package/lib/openapi/utils/loadAndBundleSpec.js +0 -44
  56. package/src/openapi/utils/loadAndBundleSpec.ts +0 -62
package/README.md CHANGED
@@ -81,7 +81,7 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
81
81
  'docusaurus-plugin-openapi-docs',
82
82
  {
83
83
  id: "apiDocs",
84
- docPluginId: "classic",
84
+ docsPluginId: "classic",
85
85
  config: {
86
86
  petstore: { // Note: petstore key is treated as the <id> and can be used to specify an API doc instance when using CLI commands
87
87
  specPath: "examples/petstore.yaml", // Path to designated spec file
@@ -108,10 +108,10 @@ Here is an example of properly configuring your `docusaurus.config.js` file for
108
108
 
109
109
  The `docusaurus-plugin-openapi-docs` plugin can be configured with the following options:
110
110
 
111
- | Name | Type | Default | Description |
112
- | ------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
113
- | `id` | `string` | `null` | A unique document id. |
114
- | `docPluginId` | `string` | `null` | The ID associated with the `plugin-content-docs` or `preset` instance used to render the OpenAPI docs (e.g. "your-plugin-id", "classic", "default"). |
111
+ | Name | Type | Default | Description |
112
+ | -------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
113
+ | `id` | `string` | `null` | A unique document id. |
114
+ | `docsPluginId` | `string` | `null` | The ID associated with the `plugin-content-docs` or `preset` instance used to render the OpenAPI docs (e.g. "your-plugin-id", "classic", "default"). |
115
115
 
116
116
  ### config
117
117
 
@@ -121,7 +121,6 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
121
121
  | ---------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
122
122
  | `specPath` | `string` | `null` | Designated URL or path to the source of an OpenAPI specification file or directory of multiple OpenAPI specification files. |
123
123
  | `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
124
- | `ouputDir` | `string` | `null` | Desired output path for generated MDX files. |
125
124
  | `template` | `string` | `null` | _Optional:_ Customize MDX content with a desired template. |
126
125
  | `sidebarOptions` | `object` | `null` | _Optional:_ Set of options for sidebar configuration. See below for a list of supported options. |
127
126
  | `version` | `string` | `null` | _Optional:_ Version assigned to single or micro-spec API specified in `specPath`. |
@@ -247,7 +246,7 @@ yarn docusaurus gen-api-docs:version petstore:all
247
246
  Run the following to bootstrap a Docsaurus v2 site (classic theme) with `docusaurus-openapi-docs`:
248
247
 
249
248
  ```bash
250
- npx create-docusaurus@2.0.0-beta.21 my-website --package-manager yarn
249
+ npx create-docusaurus@2.0.0-rc.1 my-website --package-manager yarn
251
250
  ```
252
251
 
253
252
  > When prompted to select a template choose `Git repository`.
package/lib/index.js CHANGED
@@ -54,13 +54,13 @@ function getDocsData(dataArray, filter) {
54
54
  }
55
55
  exports.getDocsData = getDocsData;
56
56
  function pluginOpenAPIDocs(context, options) {
57
- const { config, docPluginId } = options;
57
+ const { config, docsPluginId } = options;
58
58
  const { siteDir, siteConfig } = context;
59
59
  // Get routeBasePath and path from plugin-content-docs or preset
60
60
  const presets = siteConfig.presets;
61
61
  const plugins = siteConfig.plugins;
62
62
  const presetsPlugins = presets.concat(plugins);
63
- const docData = getDocsData(presetsPlugins, docPluginId);
63
+ const docData = getDocsData(presetsPlugins, docsPluginId);
64
64
  const docRouteBasePath = docData ? docData.routeBasePath : undefined;
65
65
  const docPath = docData ? (docData.path ? docData.path : "docs") : undefined;
66
66
  async function generateApiDocs(options) {
@@ -69,7 +69,7 @@ function pluginOpenAPIDocs(context, options) {
69
69
  ? specPath
70
70
  : path_1.default.resolve(siteDir, specPath);
71
71
  try {
72
- const openapiFiles = await (0, openapi_1.readOpenapiFiles)(contentPath, {});
72
+ const openapiFiles = await (0, openapi_1.readOpenapiFiles)(contentPath, options);
73
73
  const [loadedApi, tags] = await (0, openapi_1.processOpenapiFiles)(openapiFiles, sidebarOptions);
74
74
  if (!fs_1.default.existsSync(outputDir)) {
75
75
  try {
@@ -12,11 +12,12 @@ const createDetails_1 = require("./createDetails");
12
12
  const createDetailsSummary_1 = require("./createDetailsSummary");
13
13
  const schema_1 = require("./schema");
14
14
  const utils_1 = require("./utils");
15
- const mergeAllOf = require("json-schema-merge-allof");
16
- function resolveAllOf(allOf) {
17
- // Use external library to resolve and merge nested allOf schemas
18
- let properties = {};
19
- const mergedSchemas = mergeAllOf(allOf, {
15
+ const jsonSchemaMergeAllOf = require("json-schema-merge-allof");
16
+ /**
17
+ * Returns a merged representation of allOf array of schemas.
18
+ */
19
+ function mergeAllOf(allOf) {
20
+ const mergedSchemas = jsonSchemaMergeAllOf(allOf, {
20
21
  resolvers: {
21
22
  readOnly: function () {
22
23
  return true;
@@ -26,9 +27,6 @@ function resolveAllOf(allOf) {
26
27
  },
27
28
  },
28
29
  });
29
- if (mergedSchemas.properties) {
30
- properties = mergedSchemas.properties;
31
- }
32
30
  const required = allOf.reduce((acc, cur) => {
33
31
  if (Array.isArray(cur.required)) {
34
32
  const next = [...acc, ...cur.required];
@@ -36,153 +34,344 @@ function resolveAllOf(allOf) {
36
34
  }
37
35
  return acc;
38
36
  }, []);
39
- return { properties, required };
37
+ return { mergedSchemas, required };
40
38
  }
41
- function createRow({ name, schema, required }) {
42
- const schemaName = (0, schema_1.getSchemaName)(schema, true);
43
- if (schemaName && (schemaName === "object" || schemaName === "object[]")) {
44
- return (0, utils_1.create)("SchemaItem", {
45
- collapsible: true,
46
- className: "schemaItem",
47
- children: [
48
- (0, createDetails_1.createDetails)({
49
- children: [
50
- (0, createDetailsSummary_1.createDetailsSummary)({
51
- children: [
52
- (0, utils_1.create)("strong", { children: name }),
53
- (0, utils_1.create)("span", {
54
- style: { opacity: "0.6" },
55
- children: ` ${schemaName}`,
56
- }),
57
- (0, utils_1.guard)(required, () => [
58
- (0, utils_1.create)("strong", {
59
- style: {
60
- fontSize: "var(--ifm-code-font-size)",
61
- color: "var(--openapi-required)",
62
- },
63
- children: " required",
64
- }),
65
- ]),
66
- ],
67
- }),
68
- (0, utils_1.create)("div", {
69
- style: { marginLeft: "1rem" },
70
- children: [
71
- (0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema), (message) => (0, utils_1.create)("div", {
72
- style: { marginTop: ".5rem", marginBottom: ".5rem" },
73
- children: (0, createDescription_1.createDescription)(message),
74
- })),
75
- (0, utils_1.guard)(schema.description, (description) => (0, utils_1.create)("div", {
76
- style: { marginTop: ".5rem", marginBottom: ".5rem" },
77
- children: (0, createDescription_1.createDescription)(description),
78
- })),
79
- createRows({ schema: schema }),
80
- ],
39
+ /**
40
+ * For handling nested anyOf/oneOf.
41
+ */
42
+ function createAnyOneOf(schema) {
43
+ const type = schema.oneOf ? "oneOf" : "anyOf";
44
+ return (0, utils_1.create)("li", {
45
+ children: [
46
+ (0, utils_1.create)("div", {
47
+ children: [
48
+ (0, utils_1.create)("span", {
49
+ className: "badge badge--info",
50
+ children: type,
51
+ }),
52
+ (0, utils_1.create)("SchemaTabs", {
53
+ children: schema[type].map((anyOneSchema, index) => {
54
+ const label = anyOneSchema.title
55
+ ? anyOneSchema.title
56
+ : `MOD${index + 1}`;
57
+ const anyOneChildren = [];
58
+ if (anyOneSchema.properties !== undefined) {
59
+ anyOneChildren.push(createProperties(anyOneSchema));
60
+ }
61
+ if (anyOneSchema.allOf !== undefined) {
62
+ anyOneChildren.push(createNodes(anyOneSchema));
63
+ }
64
+ if (anyOneSchema.items !== undefined) {
65
+ anyOneChildren.push(createItems(anyOneSchema));
66
+ }
67
+ if (anyOneSchema.type === "string" ||
68
+ anyOneSchema.type === "number" ||
69
+ anyOneSchema.type === "integer" ||
70
+ anyOneSchema.type === "boolean") {
71
+ anyOneChildren.push(createNodes(anyOneSchema));
72
+ }
73
+ if (anyOneChildren.length) {
74
+ return (0, utils_1.create)("TabItem", {
75
+ label: label,
76
+ value: `${index}-item-properties`,
77
+ children: anyOneChildren,
78
+ });
79
+ }
80
+ return undefined;
81
81
  }),
82
+ }),
83
+ ],
84
+ }),
85
+ ],
86
+ });
87
+ }
88
+ function createProperties(schema) {
89
+ return Object.entries(schema.properties).map(([key, val]) => createEdges({
90
+ name: key,
91
+ schema: val,
92
+ required: Array.isArray(schema.required)
93
+ ? schema.required.includes(key)
94
+ : false,
95
+ }));
96
+ }
97
+ function createAdditionalProperties(schema) {
98
+ // TODO?:
99
+ // {
100
+ // description: 'Integration configuration. See \n' +
101
+ // '[Integration Configurations](https://prisma.pan.dev/api/cloud/api-integration-config/).\n',
102
+ // example: { webhookUrl: 'https://hooks.slack.com/abcdef' },
103
+ // externalDocs: { url: 'https://prisma.pan.dev/api/cloud/api-integration-config' },
104
+ // type: 'object'
105
+ // }
106
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
107
+ // TODO?:
108
+ // {
109
+ // items: {
110
+ // properties: {
111
+ // aliasField: [Object],
112
+ // displayName: [Object],
113
+ // fieldName: [Object],
114
+ // maxLength: [Object],
115
+ // options: [Object],
116
+ // redlockMapping: [Object],
117
+ // required: [Object],
118
+ // type: [Object],
119
+ // typeaheadUri: [Object],
120
+ // value: [Object]
121
+ // },
122
+ // type: 'object'
123
+ // },
124
+ // type: 'array'
125
+ // }
126
+ if (((_a = schema.additionalProperties) === null || _a === void 0 ? void 0 : _a.type) === "string" ||
127
+ ((_b = schema.additionalProperties) === null || _b === void 0 ? void 0 : _b.type) === "object" ||
128
+ ((_c = schema.additionalProperties) === null || _c === void 0 ? void 0 : _c.type) === "boolean" ||
129
+ ((_d = schema.additionalProperties) === null || _d === void 0 ? void 0 : _d.type) === "integer" ||
130
+ ((_e = schema.additionalProperties) === null || _e === void 0 ? void 0 : _e.type) === "number") {
131
+ const type = (_f = schema.additionalProperties) === null || _f === void 0 ? void 0 : _f.type;
132
+ const additionalProperties = (_g = schema.additionalProperties) === null || _g === void 0 ? void 0 : _g.additionalProperties;
133
+ if (additionalProperties !== undefined) {
134
+ const type = (_j = (_h = schema.additionalProperties) === null || _h === void 0 ? void 0 : _h.additionalProperties) === null || _j === void 0 ? void 0 : _j.type;
135
+ const format = (_l = (_k = schema.additionalProperties) === null || _k === void 0 ? void 0 : _k.additionalProperties) === null || _l === void 0 ? void 0 : _l.format;
136
+ return (0, utils_1.create)("li", {
137
+ children: (0, utils_1.create)("div", {
138
+ children: [
139
+ (0, utils_1.create)("code", { children: `property name*` }),
140
+ (0, utils_1.guard)(type, (type) => (0, utils_1.create)("span", {
141
+ style: { opacity: "0.6" },
142
+ children: ` ${type}`,
143
+ })),
144
+ (0, utils_1.guard)(format, (format) => (0, utils_1.create)("span", {
145
+ style: { opacity: "0.6" },
146
+ children: ` (${format})`,
147
+ })),
148
+ (0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema.additionalProperties), (message) => (0, utils_1.create)("div", {
149
+ style: { marginTop: "var(--ifm-table-cell-padding)" },
150
+ children: (0, createDescription_1.createDescription)(message),
151
+ })),
82
152
  ],
83
153
  }),
84
- ],
154
+ });
155
+ }
156
+ return (0, utils_1.create)("li", {
157
+ children: (0, utils_1.create)("div", {
158
+ children: [
159
+ (0, utils_1.create)("code", { children: `property name*` }),
160
+ (0, utils_1.guard)(type, (type) => (0, utils_1.create)("span", {
161
+ style: { opacity: "0.6" },
162
+ children: ` ${type}`,
163
+ })),
164
+ (0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema.additionalProperties), (message) => (0, utils_1.create)("div", {
165
+ style: { marginTop: "var(--ifm-table-cell-padding)" },
166
+ children: (0, createDescription_1.createDescription)(message),
167
+ })),
168
+ ],
169
+ }),
85
170
  });
86
171
  }
172
+ return Object.entries(schema.additionalProperties).map(([key, val]) => createEdges({
173
+ name: key,
174
+ schema: val,
175
+ required: Array.isArray(schema.required)
176
+ ? schema.required.includes(key)
177
+ : false,
178
+ }));
179
+ }
180
+ // TODO: figure out how to handle array of objects
181
+ function createItems(schema) {
182
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
183
+ if (((_a = schema.items) === null || _a === void 0 ? void 0 : _a.properties) !== undefined) {
184
+ return createProperties(schema.items);
185
+ }
186
+ if (((_b = schema.items) === null || _b === void 0 ? void 0 : _b.additionalProperties) !== undefined) {
187
+ return createAdditionalProperties(schema.items);
188
+ }
189
+ if (((_c = schema.items) === null || _c === void 0 ? void 0 : _c.oneOf) !== undefined || ((_d = schema.items) === null || _d === void 0 ? void 0 : _d.anyOf) !== undefined) {
190
+ return createAnyOneOf(schema.items);
191
+ }
192
+ if (((_e = schema.items) === null || _e === void 0 ? void 0 : _e.allOf) !== undefined) {
193
+ const { mergedSchemas } = mergeAllOf((_f = schema.items) === null || _f === void 0 ? void 0 : _f.allOf);
194
+ // Handles combo anyOf/oneOf + properties
195
+ if ((mergedSchemas.oneOf !== undefined ||
196
+ mergedSchemas.anyOf !== undefined) &&
197
+ mergedSchemas.properties) {
198
+ return (0, utils_1.create)("div", {
199
+ children: [
200
+ createAnyOneOf(mergedSchemas),
201
+ createProperties(mergedSchemas),
202
+ ],
203
+ });
204
+ }
205
+ // Handles only anyOf/oneOf
206
+ if (mergedSchemas.oneOf !== undefined ||
207
+ mergedSchemas.anyOf !== undefined) {
208
+ return (0, utils_1.create)("div", {
209
+ children: [
210
+ createAnyOneOf(mergedSchemas),
211
+ createProperties(mergedSchemas),
212
+ ],
213
+ });
214
+ }
215
+ }
216
+ if (((_g = schema.items) === null || _g === void 0 ? void 0 : _g.type) === "string" ||
217
+ ((_h = schema.items) === null || _h === void 0 ? void 0 : _h.type) === "number" ||
218
+ ((_j = schema.items) === null || _j === void 0 ? void 0 : _j.type) === "integer" ||
219
+ ((_k = schema.items) === null || _k === void 0 ? void 0 : _k.type) === "boolean") {
220
+ return createNodes(schema.items);
221
+ }
222
+ // TODO: clean this up or eliminate it?
223
+ return Object.entries(schema.items).map(([key, val]) => createEdges({
224
+ name: key,
225
+ schema: val,
226
+ required: Array.isArray(schema.required)
227
+ ? schema.required.includes(key)
228
+ : false,
229
+ }));
230
+ }
231
+ function createDetailsNode(name, schemaName, schema, required) {
232
+ return (0, utils_1.create)("SchemaItem", {
233
+ collapsible: true,
234
+ className: "schemaItem",
235
+ children: [
236
+ (0, createDetails_1.createDetails)({
237
+ children: [
238
+ (0, createDetailsSummary_1.createDetailsSummary)({
239
+ children: [
240
+ (0, utils_1.create)("strong", { children: name }),
241
+ (0, utils_1.create)("span", {
242
+ style: { opacity: "0.6" },
243
+ children: ` ${schemaName}`,
244
+ }),
245
+ (0, utils_1.guard)(required, () => [
246
+ (0, utils_1.create)("strong", {
247
+ style: {
248
+ fontSize: "var(--ifm-code-font-size)",
249
+ color: "var(--openapi-required)",
250
+ },
251
+ children: " required",
252
+ }),
253
+ ]),
254
+ ],
255
+ }),
256
+ (0, utils_1.create)("div", {
257
+ style: { marginLeft: "1rem" },
258
+ children: [
259
+ (0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema), (message) => (0, utils_1.create)("div", {
260
+ style: { marginTop: ".5rem", marginBottom: ".5rem" },
261
+ children: (0, createDescription_1.createDescription)(message),
262
+ })),
263
+ (0, utils_1.guard)(schema.description, (description) => (0, utils_1.create)("div", {
264
+ style: { marginTop: ".5rem", marginBottom: ".5rem" },
265
+ children: (0, createDescription_1.createDescription)(description),
266
+ })),
267
+ createNodes(schema),
268
+ ],
269
+ }),
270
+ ],
271
+ }),
272
+ ],
273
+ });
274
+ }
275
+ /**
276
+ * Creates the edges or "leaves" of a schema tree. Edges can branch into sub-nodes with createDetails().
277
+ */
278
+ function createEdges({ name, schema, required }) {
279
+ var _a;
280
+ const schemaName = (0, schema_1.getSchemaName)(schema);
281
+ if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
282
+ return createDetailsNode(name, schemaName, schema, required);
283
+ }
284
+ if (schema.allOf !== undefined) {
285
+ const { mergedSchemas, required, } = mergeAllOf(schema.allOf);
286
+ const mergedSchemaName = (0, schema_1.getSchemaName)(mergedSchemas);
287
+ if (mergedSchemas.oneOf !== undefined ||
288
+ mergedSchemas.anyOf !== undefined) {
289
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
290
+ }
291
+ if (mergedSchemas.properties !== undefined) {
292
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
293
+ }
294
+ if (mergedSchemas.additionalProperties !== undefined) {
295
+ return createDetailsNode(name, mergedSchemaName, mergedSchemas, required);
296
+ }
297
+ return (0, utils_1.create)("SchemaItem", {
298
+ collapsible: false,
299
+ name,
300
+ required,
301
+ schemaDescription: mergedSchemas.description,
302
+ schemaName: schemaName,
303
+ qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
304
+ });
305
+ }
306
+ if (schema.properties !== undefined) {
307
+ return createDetailsNode(name, schemaName, schema, required);
308
+ }
309
+ if (schema.additionalProperties !== undefined) {
310
+ return createDetailsNode(name, schemaName, schema, required);
311
+ }
312
+ // array of objects
313
+ if (((_a = schema.items) === null || _a === void 0 ? void 0 : _a.properties) !== undefined) {
314
+ return createDetailsNode(name, schemaName, schema, required);
315
+ }
316
+ // primitives and array of non-objects
87
317
  return (0, utils_1.create)("SchemaItem", {
88
318
  collapsible: false,
89
319
  name,
90
320
  required,
91
321
  schemaDescription: schema.description,
92
- schemaName: (0, schema_1.getSchemaName)(schema, true),
322
+ schemaName: schemaName,
93
323
  qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
94
324
  });
95
325
  }
96
- function createRows({ schema }) {
97
- // object
98
- if (schema.properties !== undefined) {
99
- return (0, utils_1.create)("ul", {
100
- children: Object.entries(schema.properties).map(([key, val]) => createRow({
101
- name: key,
102
- schema: val,
103
- required: Array.isArray(schema.required)
104
- ? schema.required.includes(key)
105
- : false,
106
- })),
107
- });
326
+ /**
327
+ * Creates a hierarchical level of a schema tree. Nodes produce edges that can branch into sub-nodes with edges, recursively.
328
+ */
329
+ function createNodes(schema) {
330
+ if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
331
+ return createAnyOneOf(schema);
108
332
  }
109
- // TODO: This can be a bit complicated types can be missmatched and there can be nested allOfs which need to be resolved before merging properties
110
333
  if (schema.allOf !== undefined) {
111
- const { properties, required } = resolveAllOf(schema.allOf);
112
- return (0, utils_1.create)("div", {
113
- children: [
114
- (0, utils_1.create)("span", {
115
- className: "badge badge--info",
116
- style: { marginBottom: "1rem" },
117
- children: "allOf",
118
- }),
119
- (0, utils_1.create)("ul", {
120
- className: "allOf",
121
- children: Object.entries(properties).map(([key, val]) => createRow({
122
- name: key,
123
- schema: val,
124
- required: Array.isArray(required)
125
- ? required.includes(key)
126
- : false,
127
- })),
128
- }),
129
- ],
130
- });
334
+ const { mergedSchemas } = mergeAllOf(schema.allOf);
335
+ // allOf seems to always result in properties
336
+ if (mergedSchemas.properties !== undefined) {
337
+ return createProperties(mergedSchemas);
338
+ }
339
+ }
340
+ if (schema.properties !== undefined) {
341
+ return createProperties(schema);
342
+ }
343
+ if (schema.additionalProperties !== undefined) {
344
+ return createAdditionalProperties(schema);
131
345
  }
132
- // array
346
+ // TODO: figure out how to handle array of objects
133
347
  if (schema.items !== undefined) {
134
- return createRows({ schema: schema.items });
348
+ return createItems(schema);
135
349
  }
136
350
  // primitive
137
- return undefined;
138
- }
139
- function createRowsRoot({ schema }) {
140
- // object
141
- if (schema.properties !== undefined) {
142
- return Object.entries(schema.properties).map(([key, val]) => createRow({
143
- name: key,
144
- schema: val,
145
- required: Array.isArray(schema.required)
146
- ? schema.required.includes(key)
147
- : false,
148
- }));
149
- }
150
- // TODO: This can be a bit complicated types can be missmatched and there can be nested allOfs which need to be resolved before merging properties
151
- if (schema.allOf !== undefined) {
152
- const { properties, required } = resolveAllOf(schema.allOf);
153
- return Object.entries(properties).map(([key, val]) => createRow({
154
- name: key,
155
- schema: val,
156
- required: Array.isArray(required) ? required.includes(key) : false,
157
- }));
158
- }
159
- // array
160
- if (schema.items !== undefined) {
351
+ if (schema.type !== undefined) {
161
352
  return (0, utils_1.create)("li", {
162
353
  children: (0, utils_1.create)("div", {
163
- children: [createRows({ schema: schema.items })],
354
+ children: [
355
+ (0, utils_1.create)("strong", { children: schema.type }),
356
+ (0, utils_1.guard)(schema.format, (format) => (0, utils_1.create)("span", {
357
+ style: { opacity: "0.6" },
358
+ children: ` ${format}`,
359
+ })),
360
+ (0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema), (message) => (0, utils_1.create)("div", {
361
+ style: { marginTop: "var(--ifm-table-cell-padding)" },
362
+ children: (0, createDescription_1.createDescription)(message),
363
+ })),
364
+ (0, utils_1.guard)(schema.description, (description) => (0, utils_1.create)("div", {
365
+ style: { marginTop: "var(--ifm-table-cell-padding)" },
366
+ children: (0, createDescription_1.createDescription)(description),
367
+ })),
368
+ ],
164
369
  }),
165
370
  });
166
371
  }
167
- // primitive
168
- return (0, utils_1.create)("li", {
169
- children: (0, utils_1.create)("div", {
170
- children: [
171
- (0, utils_1.create)("span", {
172
- style: { opacity: "0.6" },
173
- children: ` ${schema.type}`,
174
- }),
175
- (0, utils_1.guard)((0, schema_1.getQualifierMessage)(schema), (message) => (0, utils_1.create)("div", {
176
- style: { marginTop: "var(--ifm-table-cell-padding)" },
177
- children: (0, createDescription_1.createDescription)(message),
178
- })),
179
- (0, utils_1.guard)(schema.description, (description) => (0, utils_1.create)("div", {
180
- style: { marginTop: "var(--ifm-table-cell-padding)" },
181
- children: (0, createDescription_1.createDescription)(description),
182
- })),
183
- ],
184
- }),
185
- });
372
+ // Unknown node/schema type should return undefined
373
+ // So far, haven't seen this hit in testing
374
+ return undefined;
186
375
  }
187
376
  function createSchemaDetails({ title, body, ...rest }) {
188
377
  if (body === undefined ||
@@ -191,7 +380,6 @@ function createSchemaDetails({ title, body, ...rest }) {
191
380
  Object.keys(body.content).length === 0) {
192
381
  return undefined;
193
382
  }
194
- // TODO:
195
383
  // NOTE: We just pick a random content-type.
196
384
  // How common is it to have multiple?
197
385
  const randomFirstKey = Object.keys(body.content)[0];
@@ -205,6 +393,7 @@ function createSchemaDetails({ title, body, ...rest }) {
205
393
  return undefined;
206
394
  }
207
395
  }
396
+ // Root-level schema dropdown
208
397
  return (0, createDetails_1.createDetails)({
209
398
  "data-collapsed": false,
210
399
  open: true,
@@ -214,6 +403,10 @@ function createSchemaDetails({ title, body, ...rest }) {
214
403
  style: { textAlign: "left" },
215
404
  children: [
216
405
  (0, utils_1.create)("strong", { children: `${title}` }),
406
+ (0, utils_1.guard)(firstBody.type === "array", (format) => (0, utils_1.create)("span", {
407
+ style: { opacity: "0.6" },
408
+ children: ` array`,
409
+ })),
217
410
  (0, utils_1.guard)(body.required, () => [
218
411
  (0, utils_1.create)("strong", {
219
412
  style: {
@@ -238,7 +431,7 @@ function createSchemaDetails({ title, body, ...rest }) {
238
431
  }),
239
432
  (0, utils_1.create)("ul", {
240
433
  style: { marginLeft: "1rem" },
241
- children: createRowsRoot({ schema: firstBody }),
434
+ children: createNodes(firstBody),
242
435
  }),
243
436
  ],
244
437
  });
@@ -24,6 +24,7 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
24
24
  `import ParamsItem from "@theme/ParamsItem";\n`,
25
25
  `import SchemaItem from "@theme/SchemaItem"\n`,
26
26
  `import ApiTabs from "@theme/ApiTabs";\n`,
27
+ `import SchemaTabs from "@theme/SchemaTabs";\n`,
27
28
  `import TabItem from "@theme/TabItem";\n\n`,
28
29
  `## ${(0, lodash_1.escape)(title)}\n\n`,
29
30
  (0, createDeprecationNotice_1.createDeprecationNotice)({ deprecated, description: deprecatedDescription }),