docusaurus-plugin-openapi-docs 3.0.0-beta.8 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +86 -61
  2. package/lib/index.d.ts +1 -1
  3. package/lib/index.js +24 -24
  4. package/lib/markdown/createRequestSchema.js +0 -6
  5. package/lib/markdown/createResponseSchema.js +0 -5
  6. package/lib/markdown/createSchema.d.ts +1 -1
  7. package/lib/markdown/createSchema.js +69 -63
  8. package/lib/markdown/createSchema.test.js +77 -0
  9. package/lib/markdown/createStatusCodes.js +1 -1
  10. package/lib/markdown/createVersionBadge.js +1 -1
  11. package/lib/markdown/utils.js +1 -1
  12. package/lib/openapi/openapi.js +38 -33
  13. package/lib/openapi/openapi.test.js +2 -0
  14. package/lib/openapi/types.d.ts +2 -1
  15. package/lib/options.js +3 -0
  16. package/lib/sidebars/index.js +30 -11
  17. package/lib/types.d.ts +4 -1
  18. package/package.json +4 -4
  19. package/src/index.ts +35 -31
  20. package/src/markdown/__snapshots__/createSchema.test.ts.snap +221 -0
  21. package/src/markdown/createRequestSchema.ts +0 -6
  22. package/src/markdown/createResponseSchema.ts +0 -6
  23. package/src/markdown/createSchema.test.ts +88 -0
  24. package/src/markdown/createSchema.ts +83 -81
  25. package/src/markdown/createStatusCodes.ts +1 -1
  26. package/src/markdown/createVersionBadge.ts +8 -4
  27. package/src/markdown/utils.ts +1 -1
  28. package/src/openapi/__fixtures__/examples/openapi.yaml +7 -0
  29. package/src/openapi/openapi.test.ts +4 -0
  30. package/src/openapi/openapi.ts +43 -33
  31. package/src/openapi/types.ts +2 -1
  32. package/src/openapi-to-postmanv2.d.ts +1 -1
  33. package/src/options.ts +3 -0
  34. package/src/postman-collection.d.ts +1 -1
  35. package/src/sidebars/index.ts +55 -27
  36. package/src/types.ts +4 -1
@@ -11,6 +11,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.createNodes = exports.mergeAllOf = void 0;
13
13
  const clsx_1 = __importDefault(require("clsx"));
14
+ const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
14
15
  const createArrayBracket_1 = require("./createArrayBracket");
15
16
  const createDescription_1 = require("./createDescription");
16
17
  const createDetails_1 = require("./createDetails");
@@ -40,14 +41,14 @@ function mergeAllOf(allOf) {
40
41
  },
41
42
  ignoreAdditionalProperties: true,
42
43
  });
43
- const required = allOf.reduce((acc, cur) => {
44
+ const mergedRequired = allOf.reduce((acc, cur) => {
44
45
  if (Array.isArray(cur.required)) {
45
46
  const next = [...acc, ...cur.required];
46
47
  return next;
47
48
  }
48
49
  return acc;
49
50
  }, []);
50
- return { mergedSchemas, required };
51
+ return { mergedSchemas, mergedRequired };
51
52
  }
52
53
  exports.mergeAllOf = mergeAllOf;
53
54
  /**
@@ -116,6 +117,16 @@ function createAnyOneOf(schema) {
116
117
  */
117
118
  function createProperties(schema) {
118
119
  const discriminator = schema.discriminator;
120
+ if (Object.keys(schema.properties).length === 0) {
121
+ return (0, utils_1.create)("SchemaItem", {
122
+ collapsible: false,
123
+ name: "",
124
+ required: false,
125
+ schemaName: "object",
126
+ qualifierMessage: undefined,
127
+ schema: {},
128
+ });
129
+ }
119
130
  return Object.entries(schema.properties).map(([key, val]) => {
120
131
  return createEdges({
121
132
  name: key,
@@ -131,70 +142,52 @@ function createProperties(schema) {
131
142
  * For handling additionalProperties.
132
143
  */
133
144
  function createAdditionalProperties(schema) {
134
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
145
+ var _a;
135
146
  const additionalProperties = schema.additionalProperties;
136
- const type = additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.type;
147
+ if (!additionalProperties)
148
+ return [];
137
149
  // Handle free-form objects
138
- if (String(additionalProperties) === "true" && schema.type === "object") {
150
+ if (additionalProperties === true || (0, isEmpty_1.default)(additionalProperties)) {
139
151
  return (0, utils_1.create)("SchemaItem", {
140
152
  name: "property name*",
141
153
  required: false,
142
154
  schemaName: "any",
143
- qualifierMessage: (0, schema_1.getQualifierMessage)(schema.additionalProperties),
155
+ qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
144
156
  schema: schema,
145
157
  collapsible: false,
146
158
  discriminator: false,
147
159
  });
148
160
  }
149
- if ((type === "object" || type === "array") &&
150
- ((additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.properties) ||
151
- (additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.items) ||
152
- (additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.allOf) ||
153
- (additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.additionalProperties) ||
154
- (additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.oneOf) ||
155
- (additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.anyOf))) {
161
+ // objects, arrays, complex schemas
162
+ if (additionalProperties.properties ||
163
+ additionalProperties.items ||
164
+ additionalProperties.allOf ||
165
+ additionalProperties.additionalProperties ||
166
+ additionalProperties.oneOf ||
167
+ additionalProperties.anyOf) {
156
168
  const title = additionalProperties.title;
157
169
  const schemaName = (0, schema_1.getSchemaName)(additionalProperties);
158
170
  const required = (_a = schema.required) !== null && _a !== void 0 ? _a : false;
159
171
  return createDetailsNode("property name*", title !== null && title !== void 0 ? title : schemaName, additionalProperties, required, schema.nullable);
160
172
  }
161
- if (((_b = schema.additionalProperties) === null || _b === void 0 ? void 0 : _b.type) === "string" ||
162
- ((_c = schema.additionalProperties) === null || _c === void 0 ? void 0 : _c.type) === "object" ||
163
- ((_d = schema.additionalProperties) === null || _d === void 0 ? void 0 : _d.type) === "boolean" ||
164
- ((_e = schema.additionalProperties) === null || _e === void 0 ? void 0 : _e.type) === "integer" ||
165
- ((_f = schema.additionalProperties) === null || _f === void 0 ? void 0 : _f.type) === "number") {
166
- const additionalProperties = (_g = schema.additionalProperties) === null || _g === void 0 ? void 0 : _g.additionalProperties;
167
- if (additionalProperties !== undefined) {
168
- const type = (_j = (_h = schema.additionalProperties) === null || _h === void 0 ? void 0 : _h.additionalProperties) === null || _j === void 0 ? void 0 : _j.type;
169
- const schemaName = (0, schema_1.getSchemaName)((_k = schema.additionalProperties) === null || _k === void 0 ? void 0 : _k.additionalProperties);
170
- return (0, utils_1.create)("SchemaItem", {
171
- name: "property name*",
172
- required: false,
173
- schemaName: schemaName !== null && schemaName !== void 0 ? schemaName : type,
174
- qualifierMessage: (_l = schema.additionalProperties) !== null && _l !== void 0 ? _l : (0, schema_1.getQualifierMessage)(schema.additionalProperties),
175
- schema: schema,
176
- collapsible: false,
177
- discriminator: false,
178
- });
179
- }
180
- const schemaName = (0, schema_1.getSchemaName)(schema.additionalProperties);
173
+ // primitive types
174
+ if (additionalProperties.type === "string" ||
175
+ additionalProperties.type === "boolean" ||
176
+ additionalProperties.type === "integer" ||
177
+ additionalProperties.type === "number") {
178
+ const schemaName = (0, schema_1.getSchemaName)(additionalProperties);
181
179
  return (0, utils_1.create)("SchemaItem", {
182
180
  name: "property name*",
183
181
  required: false,
184
182
  schemaName: schemaName,
185
183
  qualifierMessage: (0, schema_1.getQualifierMessage)(schema),
186
- schema: schema.additionalProperties,
184
+ schema: additionalProperties,
187
185
  collapsible: false,
188
186
  discriminator: false,
189
187
  });
190
188
  }
191
- return Object.entries(schema.additionalProperties).map(([key, val]) => createEdges({
192
- name: key,
193
- schema: val,
194
- required: Array.isArray(schema.required)
195
- ? schema.required.includes(key)
196
- : false,
197
- }));
189
+ // unknown
190
+ return [];
198
191
  }
199
192
  /**
200
193
  * For handling items.
@@ -483,6 +476,16 @@ function createPropertyDiscriminator(name, schemaName, schema, discriminator, re
483
476
  */
484
477
  function createEdges({ name, schema, required, discriminator, }) {
485
478
  var _a, _b, _c, _d;
479
+ if (SCHEMA_TYPE === "request") {
480
+ if (schema.readOnly && schema.readOnly === true) {
481
+ return undefined;
482
+ }
483
+ }
484
+ if (SCHEMA_TYPE === "response") {
485
+ if (schema.writeOnly && schema.writeOnly === true) {
486
+ return undefined;
487
+ }
488
+ }
486
489
  const schemaName = (0, schema_1.getSchemaName)(schema);
487
490
  if (discriminator !== undefined && discriminator.propertyName === name) {
488
491
  return createPropertyDiscriminator(name, "string", schema, discriminator, required);
@@ -491,7 +494,17 @@ function createEdges({ name, schema, required, discriminator, }) {
491
494
  return createAnyOneOfProperty(name, schemaName, schema, required, schema.nullable);
492
495
  }
493
496
  if (schema.allOf !== undefined) {
494
- const { mergedSchemas, required, } = mergeAllOf(schema.allOf);
497
+ const { mergedSchemas } = mergeAllOf(schema.allOf);
498
+ if (SCHEMA_TYPE === "request") {
499
+ if (mergedSchemas.readOnly && mergedSchemas.readOnly === true) {
500
+ return undefined;
501
+ }
502
+ }
503
+ if (SCHEMA_TYPE === "response") {
504
+ if (mergedSchemas.writeOnly && mergedSchemas.writeOnly === true) {
505
+ return undefined;
506
+ }
507
+ }
495
508
  const mergedSchemaName = (0, schema_1.getSchemaName)(mergedSchemas);
496
509
  if (mergedSchemas.oneOf !== undefined ||
497
510
  mergedSchemas.anyOf !== undefined) {
@@ -507,16 +520,6 @@ function createEdges({ name, schema, required, discriminator, }) {
507
520
  if (((_a = mergedSchemas.items) === null || _a === void 0 ? void 0 : _a.properties) !== undefined) {
508
521
  return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
509
522
  }
510
- if (SCHEMA_TYPE === "request") {
511
- if (mergedSchemas.readOnly && mergedSchemas.readOnly === true) {
512
- return undefined;
513
- }
514
- }
515
- if (SCHEMA_TYPE === "response") {
516
- if (mergedSchemas.writeOnly && mergedSchemas.writeOnly === true) {
517
- return undefined;
518
- }
519
- }
520
523
  return (0, utils_1.create)("SchemaItem", {
521
524
  collapsible: false,
522
525
  name,
@@ -539,16 +542,6 @@ function createEdges({ name, schema, required, discriminator, }) {
539
542
  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) {
540
543
  return createDetailsNode(name, schemaName, schema, required, schema.nullable);
541
544
  }
542
- if (SCHEMA_TYPE === "request") {
543
- if (schema.readOnly && schema.readOnly === true) {
544
- return undefined;
545
- }
546
- }
547
- if (SCHEMA_TYPE === "response") {
548
- if (schema.writeOnly && schema.writeOnly === true) {
549
- return undefined;
550
- }
551
- }
552
545
  // primitives and array of non-objects
553
546
  return (0, utils_1.create)("SchemaItem", {
554
547
  collapsible: false,
@@ -564,6 +557,16 @@ function createEdges({ name, schema, required, discriminator, }) {
564
557
  */
565
558
  function createNodes(schema, schemaType) {
566
559
  SCHEMA_TYPE = schemaType;
560
+ if (SCHEMA_TYPE === "request") {
561
+ if (schema.readOnly && schema.readOnly === true) {
562
+ return undefined;
563
+ }
564
+ }
565
+ if (SCHEMA_TYPE === "response") {
566
+ if (schema.writeOnly && schema.writeOnly === true) {
567
+ return undefined;
568
+ }
569
+ }
567
570
  const nodes = [];
568
571
  // if (schema.discriminator !== undefined) {
569
572
  // return createDiscriminator(schema);
@@ -573,7 +576,10 @@ function createNodes(schema, schemaType) {
573
576
  }
574
577
  if (schema.allOf !== undefined) {
575
578
  const { mergedSchemas } = mergeAllOf(schema.allOf);
576
- // allOf seems to always result in properties
579
+ if (mergedSchemas.oneOf !== undefined ||
580
+ mergedSchemas.anyOf !== undefined) {
581
+ nodes.push(createAnyOneOf(mergedSchemas));
582
+ }
577
583
  if (mergedSchemas.properties !== undefined) {
578
584
  nodes.push(createProperties(mergedSchemas));
579
585
  }
@@ -34,6 +34,7 @@ const createSchema_1 = require("./createSchema");
34
34
  describe("createNodes", () => {
35
35
  it("should create readable MODs for oneOf primitive properties", async () => {
36
36
  const schema = {
37
+ "x-tags": ["clown"],
37
38
  type: "object",
38
39
  properties: {
39
40
  oneOfProperty: {
@@ -70,4 +71,80 @@ describe("createNodes", () => {
70
71
  };
71
72
  expect(await Promise.all((0, createSchema_1.createNodes)(schema, "request").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
72
73
  });
74
+ describe("additionalProperties", () => {
75
+ it.each([
76
+ [
77
+ {
78
+ allOf: [
79
+ {
80
+ oneOf: [
81
+ {
82
+ type: "object",
83
+ properties: {
84
+ type: {
85
+ type: "string",
86
+ enum: ["nose"],
87
+ },
88
+ },
89
+ required: ["type"],
90
+ },
91
+ {
92
+ type: "object",
93
+ properties: {
94
+ type: {
95
+ type: "string",
96
+ enum: ["mouth"],
97
+ },
98
+ },
99
+ required: ["type"],
100
+ },
101
+ {
102
+ type: "object",
103
+ properties: {
104
+ type: {
105
+ type: "string",
106
+ enum: ["eyes"],
107
+ },
108
+ default: {
109
+ type: "string",
110
+ },
111
+ },
112
+ required: ["type"],
113
+ },
114
+ ],
115
+ },
116
+ {
117
+ type: "object",
118
+ properties: {
119
+ description: {
120
+ type: "string",
121
+ description: "Description of the body part.",
122
+ },
123
+ },
124
+ required: ["description"],
125
+ },
126
+ ],
127
+ },
128
+ ],
129
+ [
130
+ {
131
+ type: "array",
132
+ items: { type: "object", properties: { a: "string", b: "number" } },
133
+ },
134
+ ],
135
+ [{ type: "string" }],
136
+ [{ type: "number" }],
137
+ [{ type: "integer" }],
138
+ [{ type: "boolean" }],
139
+ [false],
140
+ [true],
141
+ [{}],
142
+ ])("should handle additionalProperties: %p", async (additionalProperties) => {
143
+ const schema = {
144
+ type: "object",
145
+ additionalProperties,
146
+ };
147
+ expect(await Promise.all((0, createSchema_1.createNodes)(schema, "request").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
148
+ });
149
+ });
73
150
  });
@@ -275,7 +275,7 @@ function createStatusCodes({ label, id, responses }) {
275
275
  responseHeaders &&
276
276
  (0, createDetails_1.createDetails)({
277
277
  className: "openapi-markdown__details",
278
- "data-collaposed": true,
278
+ "data-collapsed": true,
279
279
  open: false,
280
280
  style: { textAlign: "left", marginBottom: "1rem" },
281
281
  children: [
@@ -13,7 +13,7 @@ function createVersionBadge(version) {
13
13
  (0, utils_1.create)("span", {
14
14
  className: "theme-doc-version-badge badge badge--secondary",
15
15
  children: `Version: ${escape(version)}`,
16
- }),
16
+ }, { inline: true }),
17
17
  `\n\n`,
18
18
  ]);
19
19
  }
@@ -45,7 +45,7 @@ exports.render = render;
45
45
  exports.lessThan = /<=?(?!(=|button|\s?\/button|code|\s?\/code|details|\s?\/details|summary|\s?\/summary|hr|\s?\/hr|br|\s?\/br|span|\s?\/span|strong|\s?\/strong|small|\s?\/small|table|\s?\/table|thead|\s?\/thead|tbody|\s?\/tbody|td|\s?\/td|tr|\s?\/tr|th|\s?\/th|h1|\s?\/h1|h2|\s?\/h2|h3|\s?\/h3|h4|\s?\/h4|h5|\s?\/h5|h6|\s?\/h6|title|\s?\/title|p|\s?\/p|em|\s?\/em|b|\s?\/b|i|\s?\/i|u|\s?\/u|strike|\s?\/strike|bold|\s?\/bold|a|\s?\/a|table|\s?\/table|li|\s?\/li|ol|\s?\/ol|ul|\s?\/ul|img|\s?\/img|svg|\s?\/svg|div|\s?\/div|center|\s?\/center))/gu;
46
46
  exports.greaterThan = /(?<!(button|code|details|summary|hr|br|span|strong|small|table|thead|tbody|td|tr|th|h1|h2|h3|h4|h5|h6|title|p|em|b|i|u|strike|bold|a|li|ol|ul|img|svg|div|center|\/|\s|"|'))>/gu;
47
47
  exports.codeFence = /`{1,3}[\s\S]*?`{1,3}/g;
48
- exports.curlyBrackets = /([{|}])/g;
48
+ exports.curlyBrackets = /([{}])/g;
49
49
  exports.codeBlock = /(^```.*[\s\S]*?```$|`[^`].+?`)/gm;
50
50
  function clean(value) {
51
51
  if (!value) {
@@ -12,14 +12,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.getTagDisplayName = exports.processOpenapiFile = exports.processOpenapiFiles = exports.readOpenapiFiles = void 0;
13
13
  const path_1 = __importDefault(require("path"));
14
14
  const utils_1 = require("@docusaurus/utils");
15
- const openapi_to_postmanv2_1 = __importDefault(require("@paloaltonetworks/openapi-to-postmanv2"));
16
- const postman_collection_1 = __importDefault(require("@paloaltonetworks/postman-collection"));
17
15
  const chalk_1 = __importDefault(require("chalk"));
18
16
  const fs_extra_1 = __importDefault(require("fs-extra"));
19
17
  const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
20
18
  const kebabCase_1 = __importDefault(require("lodash/kebabCase"));
21
19
  const unionBy_1 = __importDefault(require("lodash/unionBy"));
22
20
  const uniq_1 = __importDefault(require("lodash/uniq"));
21
+ const openapi_to_postmanv2_1 = __importDefault(require("openapi-to-postmanv2"));
22
+ const postman_collection_1 = __importDefault(require("postman-collection"));
23
23
  const createRequestExample_1 = require("./createRequestExample");
24
24
  const loadAndResolveSpec_1 = require("./utils/loadAndResolveSpec");
25
25
  const index_1 = require("../index");
@@ -61,7 +61,7 @@ async function createPostmanCollection(openapiData) {
61
61
  return await jsonToCollection(data);
62
62
  }
63
63
  function createItems(openapiData, options, sidebarOptions) {
64
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
64
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
65
65
  // TODO: Find a better way to handle this
66
66
  let items = [];
67
67
  const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
@@ -324,42 +324,47 @@ function createItems(openapiData, options, sidebarOptions) {
324
324
  items.push(apiPage);
325
325
  }
326
326
  }
327
- if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true) {
327
+ if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true ||
328
+ Object.entries((_1 = (_0 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _0 === void 0 ? void 0 : _0.schemas) !== null && _1 !== void 0 ? _1 : {})
329
+ .flatMap(([_, s]) => s["x-tags"])
330
+ .filter((item) => !!item).length > 0) {
328
331
  // Gather schemas
329
- for (let [schema, schemaObject] of Object.entries((_1 = (_0 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _0 === void 0 ? void 0 : _0.schemas) !== null && _1 !== void 0 ? _1 : {})) {
330
- const baseIdSpaces = (_3 = (_2 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _2 === void 0 ? void 0 : _2.replace(" ", "-").toLowerCase()) !== null && _3 !== void 0 ? _3 : "";
331
- const baseId = (0, kebabCase_1.default)(baseIdSpaces);
332
- const schemaDescription = schemaObject.description;
333
- let splitDescription;
334
- if (schemaDescription) {
335
- splitDescription = schemaDescription.match(/[^\r\n]+/g);
336
- }
337
- const schemaPage = {
338
- type: "schema",
339
- id: baseId,
340
- infoId: infoId !== null && infoId !== void 0 ? infoId : "",
341
- unversionedId: baseId,
342
- title: schemaObject.title
343
- ? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
344
- : schema,
345
- description: schemaObject.description
346
- ? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
347
- : "",
348
- frontMatter: {
349
- description: splitDescription
350
- ? splitDescription[0]
351
- .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
352
- .replace(/\s+$/, "")
332
+ for (let [schema, schemaObject] of Object.entries((_3 = (_2 = openapiData === null || openapiData === void 0 ? void 0 : openapiData.components) === null || _2 === void 0 ? void 0 : _2.schemas) !== null && _3 !== void 0 ? _3 : {})) {
333
+ if ((options === null || options === void 0 ? void 0 : options.showSchemas) === true || schemaObject["x-tags"]) {
334
+ const baseIdSpaces = (_5 = (_4 = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.title) === null || _4 === void 0 ? void 0 : _4.replace(" ", "-").toLowerCase()) !== null && _5 !== void 0 ? _5 : "";
335
+ const baseId = (0, kebabCase_1.default)(baseIdSpaces);
336
+ const schemaDescription = schemaObject.description;
337
+ let splitDescription;
338
+ if (schemaDescription) {
339
+ splitDescription = schemaDescription.match(/[^\r\n]+/g);
340
+ }
341
+ const schemaPage = {
342
+ type: "schema",
343
+ id: baseId,
344
+ infoId: infoId !== null && infoId !== void 0 ? infoId : "",
345
+ unversionedId: baseId,
346
+ title: schemaObject.title
347
+ ? schemaObject.title.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
348
+ : schema,
349
+ description: schemaObject.description
350
+ ? schemaObject.description.replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
353
351
  : "",
354
- },
355
- schema: schemaObject,
356
- };
357
- items.push(schemaPage);
352
+ frontMatter: {
353
+ description: splitDescription
354
+ ? splitDescription[0]
355
+ .replace(/((?:^|[^\\])(?:\\{2})*)"/g, "$1'")
356
+ .replace(/\s+$/, "")
357
+ : "",
358
+ },
359
+ schema: schemaObject,
360
+ };
361
+ items.push(schemaPage);
362
+ }
358
363
  }
359
364
  }
360
365
  if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
361
366
  // Get global tags
362
- const tags = (_4 = openapiData.tags) !== null && _4 !== void 0 ? _4 : [];
367
+ const tags = (_6 = openapiData.tags) !== null && _6 !== void 0 ? _6 : [];
363
368
  // Get operation tags
364
369
  const apiItems = items.filter((item) => {
365
370
  return item.type === "api";
@@ -17,6 +17,7 @@ const _1 = require(".");
17
17
  describe("openapi", () => {
18
18
  describe("readOpenapiFiles", () => {
19
19
  it("readOpenapiFiles", async () => {
20
+ var _a, _b;
20
21
  const results = await (0, _1.readOpenapiFiles)((0, utils_1.posixPath)(path_1.default.join(__dirname, "__fixtures__/examples")));
21
22
  const categoryMeta = results.find((x) => x.source.endsWith("_category_.json"));
22
23
  expect(categoryMeta).toBeFalsy();
@@ -26,6 +27,7 @@ describe("openapi", () => {
26
27
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.sourceDirName).toBe(".");
27
28
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.data.tags).toBeDefined();
28
29
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.data["x-tagGroups"]).toBeDefined();
30
+ expect((_b = (_a = yaml === null || yaml === void 0 ? void 0 : yaml.data.components) === null || _a === void 0 ? void 0 : _a.schemas) === null || _b === void 0 ? void 0 : _b.HelloString["x-tags"]).toBeDefined();
29
31
  });
30
32
  });
31
33
  });
@@ -269,7 +269,7 @@ export type SchemaObject = Omit<JSONSchema, "type" | "allOf" | "oneOf" | "anyOf"
269
269
  not?: SchemaObject;
270
270
  items?: SchemaObject;
271
271
  properties?: Map<SchemaObject>;
272
- additionalProperties?: Map<SchemaObject>;
272
+ additionalProperties?: boolean | SchemaObject;
273
273
  nullable?: boolean;
274
274
  discriminator?: DiscriminatorObject;
275
275
  readOnly?: boolean;
@@ -278,6 +278,7 @@ export type SchemaObject = Omit<JSONSchema, "type" | "allOf" | "oneOf" | "anyOf"
278
278
  externalDocs?: ExternalDocumentationObject;
279
279
  example?: any;
280
280
  deprecated?: boolean;
281
+ "x-tags"?: string[];
281
282
  };
282
283
  export type SchemaObjectWithRef = Omit<JSONSchema, "type" | "allOf" | "oneOf" | "anyOf" | "not" | "items" | "properties" | "additionalProperties"> & {
283
284
  type?: "string" | "number" | "integer" | "boolean" | "object" | "array";
package/lib/options.js CHANGED
@@ -22,6 +22,7 @@ const markdownGenerators = utils_validation_1.Joi.object({
22
22
  });
23
23
  exports.OptionsSchema = utils_validation_1.Joi.object({
24
24
  id: utils_validation_1.Joi.string().required(),
25
+ docsPlugin: utils_validation_1.Joi.string(),
25
26
  docsPluginId: utils_validation_1.Joi.string().required(),
26
27
  config: utils_validation_1.Joi.object()
27
28
  .pattern(/^/, utils_validation_1.Joi.object({
@@ -35,6 +36,7 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
35
36
  sidebarOptions: sidebarOptions,
36
37
  markdownGenerators: markdownGenerators,
37
38
  showSchemas: utils_validation_1.Joi.boolean(),
39
+ disableCompression: utils_validation_1.Joi.boolean(),
38
40
  version: utils_validation_1.Joi.string().when("versions", {
39
41
  is: utils_validation_1.Joi.exist(),
40
42
  then: utils_validation_1.Joi.required(),
@@ -52,6 +54,7 @@ exports.OptionsSchema = utils_validation_1.Joi.object({
52
54
  outputDir: utils_validation_1.Joi.string().required(),
53
55
  label: utils_validation_1.Joi.string().required(),
54
56
  baseUrl: utils_validation_1.Joi.string().required(),
57
+ downloadUrl: utils_validation_1.Joi.string(),
55
58
  })),
56
59
  }))
57
60
  .required(),
@@ -24,7 +24,7 @@ function isSchemaItem(item) {
24
24
  return item.type === "schema";
25
25
  }
26
26
  function groupByTags(items, sidebarOptions, options, tags, docPath) {
27
- let { outputDir, label } = options;
27
+ let { outputDir, label, showSchemas } = options;
28
28
  // Remove trailing slash before proceeding
29
29
  outputDir = outputDir.replace(/\/$/, "");
30
30
  const { sidebarCollapsed, sidebarCollapsible, customProps, categoryLinkSource, } = sidebarOptions;
@@ -43,16 +43,21 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
43
43
  const operationTags = (0, uniq_1.default)(apiItems
44
44
  .flatMap((item) => item.api.tags)
45
45
  .filter((item) => !!item));
46
- // Combine globally defined tags with operation tags
47
- // Only include global tag if referenced in operation tags
46
+ const schemaTags = (0, uniq_1.default)(schemaItems
47
+ .flatMap((item) => item.schema["x-tags"])
48
+ .filter((item) => !!item));
49
+ // Combine globally defined tags with operation and schema tags
50
+ // Only include global tag if referenced in operation/schema tags
48
51
  let apiTags = [];
49
52
  tags.flat().forEach((tag) => {
50
53
  // Should we also check x-displayName?
51
- if (operationTags.includes(tag.name)) {
54
+ if (operationTags.includes(tag.name) || schemaTags.includes(tag.name)) {
52
55
  apiTags.push(tag.name);
53
56
  }
54
57
  });
55
- apiTags = (0, uniq_1.default)(apiTags.concat(operationTags));
58
+ if (sidebarOptions.groupPathsBy !== "tagGroup") {
59
+ apiTags = (0, uniq_1.default)(apiTags.concat(operationTags, schemaTags));
60
+ }
56
61
  const basePath = docPath
57
62
  ? outputDir.split(docPath)[1].replace(/^\/+/g, "")
58
63
  : outputDir.slice(outputDir.indexOf("/", 1)).replace(/^\/+/g, "");
@@ -68,7 +73,7 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
68
73
  }, item.api.method)
69
74
  : (0, clsx_1.default)({
70
75
  "menu__list-item--deprecated": item.schema.deprecated,
71
- });
76
+ }, "schema");
72
77
  return {
73
78
  type: "doc",
74
79
  id: basePath === "" || undefined ? `${id}` : `${basePath}/${id}`,
@@ -126,15 +131,15 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
126
131
  : (0, utils_1.posixPath)(path_1.default.join("/category", basePath, (0, lodash_1.kebabCase)(tag))),
127
132
  };
128
133
  }
134
+ const taggedApiItems = apiItems.filter((item) => { var _a; return !!((_a = item.api.tags) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
135
+ const taggedSchemaItems = schemaItems.filter((item) => { var _a; return !!((_a = item.schema["x-tags"]) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
129
136
  return {
130
137
  type: "category",
131
138
  label: (_a = tagObject === null || tagObject === void 0 ? void 0 : tagObject["x-displayName"]) !== null && _a !== void 0 ? _a : tag,
132
139
  link: linkConfig,
133
140
  collapsible: sidebarCollapsible,
134
141
  collapsed: sidebarCollapsed,
135
- items: apiItems
136
- .filter((item) => { var _a; return !!((_a = item.api.tags) === null || _a === void 0 ? void 0 : _a.includes(tag)); })
137
- .map(createDocItem),
142
+ items: [...taggedSchemaItems, ...taggedApiItems].map(createDocItem),
138
143
  };
139
144
  })
140
145
  .filter((item) => item.items.length > 0); // Filter out any categories with no items.
@@ -157,14 +162,16 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
157
162
  ];
158
163
  }
159
164
  let schemas = [];
160
- if (schemaItems.length > 0) {
165
+ if (showSchemas && schemaItems.length > 0) {
161
166
  schemas = [
162
167
  {
163
168
  type: "category",
164
169
  label: "Schemas",
165
170
  collapsible: sidebarCollapsible,
166
171
  collapsed: sidebarCollapsed,
167
- items: schemaItems.map(createDocItem),
172
+ items: schemaItems
173
+ .filter(({ schema }) => !schema["x-tags"])
174
+ .map(createDocItem),
168
175
  },
169
176
  ];
170
177
  }
@@ -178,7 +185,9 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
178
185
  function generateSidebarSlice(sidebarOptions, options, api, tags, docPath, tagGroups) {
179
186
  let sidebarSlice = [];
180
187
  if (sidebarOptions.groupPathsBy === "tagGroup") {
188
+ let schemasGroup = [];
181
189
  tagGroups === null || tagGroups === void 0 ? void 0 : tagGroups.forEach((tagGroup) => {
190
+ var _a;
182
191
  //filter tags only included in group
183
192
  const filteredTags = [];
184
193
  tags[0].forEach((tag) => {
@@ -193,8 +202,18 @@ function generateSidebarSlice(sidebarOptions, options, api, tags, docPath, tagGr
193
202
  collapsed: true,
194
203
  items: groupByTags(api, sidebarOptions, options, [filteredTags], docPath),
195
204
  };
205
+ if (options.showSchemas) {
206
+ // For the first tagGroup, save the generated "Schemas" category for later.
207
+ if (schemasGroup.length === 0) {
208
+ schemasGroup = (_a = groupCategory.items) === null || _a === void 0 ? void 0 : _a.filter((item) => item.type === "category" && item.label === "Schemas");
209
+ }
210
+ // Remove the "Schemas" category from every `groupCategory`.
211
+ groupCategory.items = groupCategory.items.filter((item) => "label" in item ? item.label !== "Schemas" : true);
212
+ }
196
213
  sidebarSlice.push(groupCategory);
197
214
  });
215
+ // Add `schemasGroup` to the end of the sidebar.
216
+ sidebarSlice.push(...schemasGroup);
198
217
  }
199
218
  else if (sidebarOptions.groupPathsBy === "tag") {
200
219
  sidebarSlice = groupByTags(api, sidebarOptions, options, tags, docPath);
package/lib/types.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type Request from "@paloaltonetworks/postman-collection";
1
+ import type Request from "postman-collection";
2
2
  import { InfoObject, OperationObject, SchemaObject, SecuritySchemeObject, TagObject } from "./openapi/types";
3
3
  export type { PropSidebarItemCategory, SidebarItemLink, PropSidebar, PropSidebarItem, } from "@docusaurus/plugin-content-docs-types";
4
4
  export interface PluginOptions {
5
5
  id?: string;
6
+ docsPlugin?: string;
6
7
  docsPluginId: string;
7
8
  config: {
8
9
  [key: string]: APIOptions;
@@ -25,6 +26,7 @@ export interface APIOptions {
25
26
  proxy?: string;
26
27
  markdownGenerators?: MarkdownGenerator;
27
28
  showSchemas?: boolean;
29
+ disableCompression?: boolean;
28
30
  }
29
31
  export interface MarkdownGenerator {
30
32
  createApiPageMD?: (pageData: ApiPageMetadata) => string;
@@ -46,6 +48,7 @@ export interface APIVersionOptions {
46
48
  outputDir: string;
47
49
  label: string;
48
50
  baseUrl: string;
51
+ downloadUrl?: string;
49
52
  }
50
53
  export interface LoadedContent {
51
54
  loadedApi: ApiMetadata[];