docusaurus-plugin-openapi-docs 1.0.2 → 1.0.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 (42) hide show
  1. package/README.md +106 -17
  2. package/lib/index.d.ts +7 -1
  3. package/lib/index.js +228 -18
  4. package/lib/markdown/createAuthentication.d.ts +2 -0
  5. package/lib/markdown/createAuthentication.js +139 -0
  6. package/lib/markdown/createParamsDetails.js +2 -0
  7. package/lib/markdown/createSchemaDetails.js +2 -0
  8. package/lib/markdown/index.d.ts +3 -2
  9. package/lib/markdown/index.js +10 -2
  10. package/lib/openapi/createExample.js +59 -49
  11. package/lib/openapi/openapi.d.ts +3 -3
  12. package/lib/openapi/openapi.js +71 -41
  13. package/lib/openapi/openapi.test.js +0 -6
  14. package/lib/openapi/utils/loadAndBundleSpec.d.ts +3 -0
  15. package/lib/openapi/utils/loadAndBundleSpec.js +44 -0
  16. package/lib/openapi/utils/types.d.ts +306 -0
  17. package/lib/openapi/utils/types.js +8 -0
  18. package/lib/options.d.ts +0 -2
  19. package/lib/options.js +36 -7
  20. package/lib/sidebars/index.d.ts +1 -1
  21. package/lib/sidebars/index.js +33 -30
  22. package/lib/sidebars/utils.d.ts +2 -0
  23. package/lib/sidebars/utils.js +31 -0
  24. package/lib/types.d.ts +34 -11
  25. package/package.json +10 -8
  26. package/src/index.ts +291 -20
  27. package/src/markdown/createAuthentication.ts +160 -0
  28. package/src/markdown/createParamsDetails.ts +2 -0
  29. package/src/markdown/createSchemaDetails.ts +2 -0
  30. package/src/markdown/index.ts +15 -2
  31. package/src/openapi/createExample.ts +59 -50
  32. package/src/openapi/openapi.test.ts +0 -6
  33. package/src/openapi/openapi.ts +85 -39
  34. package/src/openapi/utils/loadAndBundleSpec.ts +62 -0
  35. package/src/openapi/utils/types.ts +303 -0
  36. package/src/options.ts +41 -8
  37. package/src/sidebars/index.ts +40 -30
  38. package/src/sidebars/utils.ts +29 -0
  39. package/src/types.ts +35 -9
  40. package/src/openapi/__fixtures__/examples/yogurtstore/_category_.json +0 -4
  41. package/src/openapi/__fixtures__/examples/yogurtstore/froyo.yaml +0 -13
  42. package/src/openapi/__fixtures__/examples/yogurtstore/nested/nested.yaml +0 -13
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createAuthentication = void 0;
10
+ const createDescription_1 = require("./createDescription");
11
+ const utils_1 = require("./utils");
12
+ function createAuthentication(securitySchemes) {
13
+ if (!securitySchemes || !Object.keys(securitySchemes).length)
14
+ return "";
15
+ const createAuthenticationTable = (securityScheme) => {
16
+ const { bearerFormat, flows, name, scheme, type } = securityScheme;
17
+ const createSecuritySchemeTypeRow = () => (0, utils_1.create)("tr", {
18
+ children: [
19
+ (0, utils_1.create)("th", { children: "Security Scheme Type:" }),
20
+ (0, utils_1.create)("td", { children: type }),
21
+ ],
22
+ });
23
+ const createOAuthFlowRows = () => {
24
+ const flowRows = Object.entries(flows).map(([flowType, flowObj]) => {
25
+ const { authorizationUrl, tokenUrl, refreshUrl, scopes } = flowObj;
26
+ return (0, utils_1.create)("tr", {
27
+ children: [
28
+ (0, utils_1.create)("th", { children: `${flowType} OAuth Flow:` }),
29
+ (0, utils_1.create)("td", {
30
+ children: [
31
+ (0, utils_1.guard)(tokenUrl, () => (0, utils_1.create)("p", { children: `Token URL: ${tokenUrl}` })),
32
+ (0, utils_1.guard)(authorizationUrl, () => (0, utils_1.create)("p", {
33
+ children: `Authorization URL: ${authorizationUrl}`,
34
+ })),
35
+ (0, utils_1.guard)(refreshUrl, () => (0, utils_1.create)("p", { children: `Refresh URL: ${refreshUrl}` })),
36
+ (0, utils_1.create)("span", { children: "Scopes:" }),
37
+ (0, utils_1.create)("ul", {
38
+ children: Object.entries(scopes).map(([scope, description]) => (0, utils_1.create)("li", { children: `${scope}: ${description}` })),
39
+ }),
40
+ ],
41
+ }),
42
+ ],
43
+ });
44
+ });
45
+ return flowRows.join("");
46
+ };
47
+ switch (type) {
48
+ case "apiKey":
49
+ return (0, utils_1.create)("div", {
50
+ children: [
51
+ (0, utils_1.create)("table", {
52
+ children: (0, utils_1.create)("tbody", {
53
+ children: [
54
+ createSecuritySchemeTypeRow(),
55
+ (0, utils_1.create)("tr", {
56
+ children: [
57
+ (0, utils_1.create)("th", { children: "Header parameter name:" }),
58
+ (0, utils_1.create)("td", { children: name }),
59
+ ],
60
+ }),
61
+ ],
62
+ }),
63
+ }),
64
+ ],
65
+ });
66
+ case "http":
67
+ return (0, utils_1.create)("div", {
68
+ children: [
69
+ (0, utils_1.create)("table", {
70
+ children: (0, utils_1.create)("tbody", {
71
+ children: [
72
+ createSecuritySchemeTypeRow(),
73
+ (0, utils_1.create)("tr", {
74
+ children: [
75
+ (0, utils_1.create)("th", { children: "HTTP Authorization Scheme:" }),
76
+ (0, utils_1.create)("td", { children: scheme }),
77
+ ],
78
+ }),
79
+ (0, utils_1.create)("tr", {
80
+ children: [
81
+ (0, utils_1.create)("th", { children: "Bearer format:" }),
82
+ (0, utils_1.create)("td", { children: bearerFormat }),
83
+ ],
84
+ }),
85
+ ],
86
+ }),
87
+ }),
88
+ ],
89
+ });
90
+ case "oauth2":
91
+ return (0, utils_1.create)("div", {
92
+ children: [
93
+ (0, utils_1.create)("table", {
94
+ children: (0, utils_1.create)("tbody", {
95
+ children: [
96
+ createSecuritySchemeTypeRow(),
97
+ createOAuthFlowRows(),
98
+ ],
99
+ }),
100
+ }),
101
+ ],
102
+ });
103
+ default:
104
+ return "";
105
+ }
106
+ };
107
+ const formatTabLabel = (str) => {
108
+ const formattedLabel = str
109
+ .replace(/(_|-)/g, " ")
110
+ .trim()
111
+ .replace(/\w\S*/g, (str) => str.charAt(0).toUpperCase() + str.substr(1))
112
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
113
+ .replace(/([A-Z])([A-Z][a-z])/g, "$1 $2");
114
+ const isOAuth = formattedLabel.toLowerCase().includes("oauth2");
115
+ const isApiKey = formattedLabel.toLowerCase().includes("api");
116
+ return isOAuth ? "OAuth 2.0" : isApiKey ? "API Key" : formattedLabel;
117
+ };
118
+ return (0, utils_1.create)("div", {
119
+ children: [
120
+ (0, utils_1.create)("h2", {
121
+ children: "Authentication",
122
+ id: "authentication",
123
+ style: { marginBottom: "1rem" },
124
+ }),
125
+ (0, utils_1.create)("Tabs", {
126
+ children: Object.entries(securitySchemes).map(([schemeType, schemeObj]) => (0, utils_1.create)("TabItem", {
127
+ label: formatTabLabel(schemeType),
128
+ value: `${schemeType}`,
129
+ children: [
130
+ (0, createDescription_1.createDescription)(schemeObj.description),
131
+ createAuthenticationTable(schemeObj),
132
+ ],
133
+ })),
134
+ }),
135
+ ],
136
+ style: { marginBottom: "2rem" },
137
+ });
138
+ }
139
+ exports.createAuthentication = createAuthentication;
@@ -19,6 +19,8 @@ function createParamsDetails({ parameters, type }) {
19
19
  return undefined;
20
20
  }
21
21
  return (0, createDetails_1.createDetails)({
22
+ "data-collapsed": false,
23
+ open: true,
22
24
  style: { marginBottom: "1rem" },
23
25
  children: [
24
26
  (0, createDetailsSummary_1.createDetailsSummary)({
@@ -206,6 +206,8 @@ function createSchemaDetails({ title, body, ...rest }) {
206
206
  }
207
207
  }
208
208
  return (0, createDetails_1.createDetails)({
209
+ "data-collapsed": false,
210
+ open: true,
209
211
  ...rest,
210
212
  children: [
211
213
  (0, createDetailsSummary_1.createDetailsSummary)({
@@ -1,3 +1,4 @@
1
- import { ApiPageMetadata, InfoPageMetadata } from "../types";
1
+ import { ApiPageMetadata, InfoPageMetadata, TagPageMetadata } from "../types";
2
2
  export declare function createApiPageMD({ title, api: { deprecated, "x-deprecated-description": deprecatedDescription, description, parameters, requestBody, responses, }, }: ApiPageMetadata): string;
3
- export declare function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, }: InfoPageMetadata): string;
3
+ export declare function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, securitySchemes, }: InfoPageMetadata): string;
4
+ export declare function createTagPageMD({ tag: { description } }: TagPageMetadata): string;
@@ -6,8 +6,9 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  * ========================================================================== */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.createInfoPageMD = exports.createApiPageMD = void 0;
9
+ exports.createTagPageMD = exports.createInfoPageMD = exports.createApiPageMD = void 0;
10
10
  const lodash_1 = require("lodash");
11
+ const createAuthentication_1 = require("./createAuthentication");
11
12
  const createContactInfo_1 = require("./createContactInfo");
12
13
  const createDeprecationNotice_1 = require("./createDeprecationNotice");
13
14
  const createDescription_1 = require("./createDescription");
@@ -36,14 +37,21 @@ function createApiPageMD({ title, api: { deprecated, "x-deprecated-description":
36
37
  ]);
37
38
  }
38
39
  exports.createApiPageMD = createApiPageMD;
39
- function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, }) {
40
+ function createInfoPageMD({ info: { title, version, description, contact, license, termsOfService }, securitySchemes, }) {
40
41
  return (0, utils_1.render)([
42
+ `import Tabs from "@theme/Tabs";\n`,
43
+ `import TabItem from "@theme/TabItem";\n\n`,
41
44
  (0, createVersionBadge_1.createVersionBadge)(version),
42
45
  `# ${(0, lodash_1.escape)(title)}\n\n`,
43
46
  (0, createDescription_1.createDescription)(description),
47
+ (0, createAuthentication_1.createAuthentication)(securitySchemes),
44
48
  (0, createContactInfo_1.createContactInfo)(contact),
45
49
  (0, createTermsOfService_1.createTermsOfService)(termsOfService),
46
50
  (0, createLicense_1.createLicense)(license),
47
51
  ]);
48
52
  }
49
53
  exports.createInfoPageMD = createInfoPageMD;
54
+ function createTagPageMD({ tag: { description } }) {
55
+ return (0, utils_1.render)([(0, createDescription_1.createDescription)(description)]);
56
+ }
57
+ exports.createTagPageMD = createTagPageMD;
@@ -5,8 +5,12 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  * ========================================================================== */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.sampleFromSchema = void 0;
13
+ const chalk_1 = __importDefault(require("chalk"));
10
14
  const primitives = {
11
15
  string: {
12
16
  default: () => "string",
@@ -31,64 +35,70 @@ const primitives = {
31
35
  array: {},
32
36
  };
33
37
  const sampleFromSchema = (schema = {}) => {
34
- let { type, example, allOf, properties, items } = schema;
35
- if (example !== undefined) {
36
- return example;
37
- }
38
- if (allOf) {
39
- // TODO: We are just assuming it will always be an object for now
40
- let obj = {
41
- type: "object",
42
- properties: {},
43
- required: [], // NOTE: We shouldn't need to worry about required
44
- };
45
- for (let item of allOf) {
46
- if (item.properties) {
47
- obj.properties = {
48
- ...obj.properties,
49
- ...item.properties,
50
- };
51
- }
52
- }
53
- return (0, exports.sampleFromSchema)(obj);
54
- }
55
- if (!type) {
56
- if (properties) {
57
- type = "object";
38
+ try {
39
+ let { type, example, allOf, properties, items } = schema;
40
+ if (example !== undefined) {
41
+ return example;
58
42
  }
59
- else if (items) {
60
- type = "array";
43
+ if (allOf) {
44
+ // TODO: We are just assuming it will always be an object for now
45
+ let obj = {
46
+ type: "object",
47
+ properties: {},
48
+ required: [], // NOTE: We shouldn't need to worry about required
49
+ };
50
+ for (let item of allOf) {
51
+ if (item.properties) {
52
+ obj.properties = {
53
+ ...obj.properties,
54
+ ...item.properties,
55
+ };
56
+ }
57
+ }
58
+ return (0, exports.sampleFromSchema)(obj);
61
59
  }
62
- else {
63
- return;
60
+ if (!type) {
61
+ if (properties) {
62
+ type = "object";
63
+ }
64
+ else if (items) {
65
+ type = "array";
66
+ }
67
+ else {
68
+ return;
69
+ }
64
70
  }
65
- }
66
- if (type === "object") {
67
- let obj = {};
68
- for (let [name, prop] of Object.entries(properties !== null && properties !== void 0 ? properties : {})) {
69
- if (prop.deprecated) {
70
- continue;
71
+ if (type === "object") {
72
+ let obj = {};
73
+ for (let [name, prop] of Object.entries(properties !== null && properties !== void 0 ? properties : {})) {
74
+ if (prop.deprecated) {
75
+ continue;
76
+ }
77
+ obj[name] = (0, exports.sampleFromSchema)(prop);
71
78
  }
72
- obj[name] = (0, exports.sampleFromSchema)(prop);
79
+ return obj;
73
80
  }
74
- return obj;
75
- }
76
- if (type === "array") {
77
- if (Array.isArray(items === null || items === void 0 ? void 0 : items.anyOf)) {
78
- return items === null || items === void 0 ? void 0 : items.anyOf.map((item) => (0, exports.sampleFromSchema)(item));
81
+ if (type === "array") {
82
+ if (Array.isArray(items === null || items === void 0 ? void 0 : items.anyOf)) {
83
+ return items === null || items === void 0 ? void 0 : items.anyOf.map((item) => (0, exports.sampleFromSchema)(item));
84
+ }
85
+ if (Array.isArray(items === null || items === void 0 ? void 0 : items.oneOf)) {
86
+ return items === null || items === void 0 ? void 0 : items.oneOf.map((item) => (0, exports.sampleFromSchema)(item));
87
+ }
88
+ return [(0, exports.sampleFromSchema)(items)];
79
89
  }
80
- if (Array.isArray(items === null || items === void 0 ? void 0 : items.oneOf)) {
81
- return items === null || items === void 0 ? void 0 : items.oneOf.map((item) => (0, exports.sampleFromSchema)(item));
90
+ if (schema.enum) {
91
+ if (schema.default) {
92
+ return schema.default;
93
+ }
94
+ return normalizeArray(schema.enum)[0];
82
95
  }
83
- return [(0, exports.sampleFromSchema)(items)];
96
+ return primitive(schema);
84
97
  }
85
- if (schema.enum) {
86
- if (schema.default) {
87
- return schema.default;
88
- }
89
- return normalizeArray(schema.enum)[0];
98
+ catch (err) {
99
+ console.error(chalk_1.default.yellow("WARNING: failed to create example from schema object:", err));
100
+ return;
90
101
  }
91
- return primitive(schema);
92
102
  };
93
103
  exports.sampleFromSchema = sampleFromSchema;
94
104
  function primitive(schema = {}) {
@@ -1,4 +1,4 @@
1
- import { ApiMetadata } from "../types";
1
+ import { ApiMetadata, SidebarOptions } from "../types";
2
2
  import { OpenApiObjectWithRef, TagObject } from "./types";
3
3
  interface OpenApiFiles {
4
4
  source: string;
@@ -6,7 +6,7 @@ interface OpenApiFiles {
6
6
  data: OpenApiObjectWithRef;
7
7
  }
8
8
  export declare function readOpenapiFiles(openapiPath: string, _options: {}): Promise<OpenApiFiles[]>;
9
- export declare function processOpenapiFiles(files: OpenApiFiles[]): Promise<[ApiMetadata[], TagObject[]]>;
10
- export declare function processOpenapiFile(openapiDataWithRefs: OpenApiObjectWithRef): Promise<[ApiMetadata[], TagObject[]]>;
9
+ export declare function processOpenapiFiles(files: OpenApiFiles[], sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[]]>;
10
+ export declare function processOpenapiFile(openapiDataWithRefs: OpenApiObjectWithRef, sidebarOptions: SidebarOptions): Promise<[ApiMetadata[], TagObject[]]>;
11
11
  export declare function getTagDisplayName(tagName: string, tags: TagObject[]): string;
12
12
  export {};
@@ -16,10 +16,11 @@ const openapi_to_postmanv2_1 = __importDefault(require("@paloaltonetworks/openap
16
16
  const postman_collection_1 = __importDefault(require("@paloaltonetworks/postman-collection"));
17
17
  const chalk_1 = __importDefault(require("chalk"));
18
18
  const fs_extra_1 = __importDefault(require("fs-extra"));
19
- const js_yaml_1 = __importDefault(require("js-yaml"));
20
19
  const json_refs_1 = __importDefault(require("json-refs"));
21
20
  const lodash_1 = require("lodash");
21
+ const index_1 = require("../index");
22
22
  const createExample_1 = require("./createExample");
23
+ const loadAndBundleSpec_1 = require("./utils/loadAndBundleSpec");
23
24
  /**
24
25
  * Finds any reference objects in the OpenAPI definition and resolves them to a finalized value.
25
26
  */
@@ -63,13 +64,39 @@ async function createPostmanCollection(openapiData) {
63
64
  }
64
65
  return await jsonToCollection(data);
65
66
  }
66
- function createItems(openapiData) {
67
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
67
+ function createItems(openapiData, sidebarOptions) {
68
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
68
69
  // TODO: Find a better way to handle this
69
70
  let items = [];
70
- // Only create an info page if we have a description.
71
+ const infoId = (0, lodash_1.kebabCase)(openapiData.info.title);
72
+ if ((sidebarOptions === null || sidebarOptions === void 0 ? void 0 : sidebarOptions.categoryLinkSource) === "tag") {
73
+ // Only create an tag pages if categoryLinkSource set to tag.
74
+ const tags = (_a = openapiData.tags) !== null && _a !== void 0 ? _a : [];
75
+ // eslint-disable-next-line array-callback-return
76
+ tags
77
+ .filter((tag) => { var _a; return !((_a = tag.description) === null || _a === void 0 ? void 0 : _a.includes("SchemaDefinition")); })
78
+ // eslint-disable-next-line array-callback-return
79
+ .map((tag) => {
80
+ var _a;
81
+ const description = getTagDisplayName(tag.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []);
82
+ const tagId = (0, lodash_1.kebabCase)(tag.name);
83
+ const tagPage = {
84
+ type: "tag",
85
+ id: tagId,
86
+ unversionedId: tagId,
87
+ title: description !== null && description !== void 0 ? description : "",
88
+ description: description !== null && description !== void 0 ? description : "",
89
+ slug: "/" + tagId,
90
+ frontMatter: {},
91
+ tag: {
92
+ ...tag,
93
+ },
94
+ };
95
+ items.push(tagPage);
96
+ });
97
+ }
71
98
  if (openapiData.info.description) {
72
- const infoId = (0, lodash_1.kebabCase)(openapiData.info.title);
99
+ // Only create an info page if we have a description.
73
100
  const infoPage = {
74
101
  type: "info",
75
102
  id: infoId,
@@ -78,10 +105,11 @@ function createItems(openapiData) {
78
105
  description: openapiData.info.description,
79
106
  slug: "/" + infoId,
80
107
  frontMatter: {},
108
+ securitySchemes: (_b = openapiData.components) === null || _b === void 0 ? void 0 : _b.securitySchemes,
81
109
  info: {
82
110
  ...openapiData.info,
83
- tags: (_a = openapiData.tags) === null || _a === void 0 ? void 0 : _a.map((tagName) => { var _a; return getTagDisplayName(tagName.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
84
- title: (_b = openapiData.info.title) !== null && _b !== void 0 ? _b : "Introduction",
111
+ tags: (_c = openapiData.tags) === null || _c === void 0 ? void 0 : _c.map((tagName) => { var _a; return getTagDisplayName(tagName.name, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
112
+ title: (_d = openapiData.info.title) !== null && _d !== void 0 ? _d : "Introduction",
85
113
  },
86
114
  };
87
115
  items.push(infoPage);
@@ -89,16 +117,16 @@ function createItems(openapiData) {
89
117
  for (let [path, pathObject] of Object.entries(openapiData.paths)) {
90
118
  const { $ref, description, parameters, servers, summary, ...rest } = pathObject;
91
119
  for (let [method, operationObject] of Object.entries({ ...rest })) {
92
- const title = (_d = (_c = operationObject.summary) !== null && _c !== void 0 ? _c : operationObject.operationId) !== null && _d !== void 0 ? _d : "Missing summary";
120
+ const title = (_f = (_e = operationObject.summary) !== null && _e !== void 0 ? _e : operationObject.operationId) !== null && _f !== void 0 ? _f : "Missing summary";
93
121
  if (operationObject.description === undefined) {
94
122
  operationObject.description =
95
- (_f = (_e = operationObject.summary) !== null && _e !== void 0 ? _e : operationObject.operationId) !== null && _f !== void 0 ? _f : "";
123
+ (_h = (_g = operationObject.summary) !== null && _g !== void 0 ? _g : operationObject.operationId) !== null && _h !== void 0 ? _h : "";
96
124
  }
97
125
  const baseId = (0, lodash_1.kebabCase)(title);
98
- const servers = (_h = (_g = operationObject.servers) !== null && _g !== void 0 ? _g : pathObject.servers) !== null && _h !== void 0 ? _h : openapiData.servers;
99
- const security = (_j = operationObject.security) !== null && _j !== void 0 ? _j : openapiData.security;
126
+ const servers = (_k = (_j = operationObject.servers) !== null && _j !== void 0 ? _j : pathObject.servers) !== null && _k !== void 0 ? _k : openapiData.servers;
127
+ const security = (_l = operationObject.security) !== null && _l !== void 0 ? _l : openapiData.security;
100
128
  // Add security schemes so we know how to handle security.
101
- const securitySchemes = (_k = openapiData.components) === null || _k === void 0 ? void 0 : _k.securitySchemes;
129
+ const securitySchemes = (_m = openapiData.components) === null || _m === void 0 ? void 0 : _m.securitySchemes;
102
130
  // Make sure schemes are lowercase. See: https://github.com/cloud-annotations/docusaurus-plugin-openapi/issues/79
103
131
  if (securitySchemes) {
104
132
  for (let securityScheme of Object.values(securitySchemes)) {
@@ -108,7 +136,7 @@ function createItems(openapiData) {
108
136
  }
109
137
  }
110
138
  let jsonRequestBodyExample;
111
- const body = (_m = (_l = operationObject.requestBody) === null || _l === void 0 ? void 0 : _l.content) === null || _m === void 0 ? void 0 : _m["application/json"];
139
+ const body = (_p = (_o = operationObject.requestBody) === null || _o === void 0 ? void 0 : _o.content) === null || _p === void 0 ? void 0 : _p["application/json"];
112
140
  if (body === null || body === void 0 ? void 0 : body.schema) {
113
141
  jsonRequestBodyExample = (0, createExample_1.sampleFromSchema)(body.schema);
114
142
  }
@@ -117,6 +145,7 @@ function createItems(openapiData) {
117
145
  const apiPage = {
118
146
  type: "api",
119
147
  id: baseId,
148
+ infoId: infoId !== null && infoId !== void 0 ? infoId : "",
120
149
  unversionedId: baseId,
121
150
  title: title,
122
151
  description: description !== null && description !== void 0 ? description : "",
@@ -124,7 +153,7 @@ function createItems(openapiData) {
124
153
  frontMatter: {},
125
154
  api: {
126
155
  ...defaults,
127
- tags: (_o = operationObject.tags) === null || _o === void 0 ? void 0 : _o.map((tagName) => { var _a; return getTagDisplayName(tagName, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
156
+ tags: (_q = operationObject.tags) === null || _q === void 0 ? void 0 : _q.map((tagName) => { var _a; return getTagDisplayName(tagName, (_a = openapiData.tags) !== null && _a !== void 0 ? _a : []); }),
128
157
  method,
129
158
  path,
130
159
  servers,
@@ -149,7 +178,7 @@ function bindCollectionToApiItems(items, postmanCollection) {
149
178
  .getPath({ unresolved: true }) // unresolved returns "/:variableName" instead of "/<type>"
150
179
  .replace(/:([a-z0-9-_]+)/gi, "{$1}"); // replace "/:variableName" with "/{variableName}"
151
180
  const apiItem = items.find((item) => {
152
- if (item.type === "info") {
181
+ if (item.type === "info" || item.type === "tag") {
153
182
  return false;
154
183
  }
155
184
  return item.api.path === path && item.api.method === method;
@@ -160,29 +189,30 @@ function bindCollectionToApiItems(items, postmanCollection) {
160
189
  });
161
190
  }
162
191
  async function readOpenapiFiles(openapiPath, _options) {
163
- const stat = await fs_extra_1.default.lstat(openapiPath);
164
- if (stat.isDirectory()) {
165
- console.warn(chalk_1.default.yellow("WARNING: Loading a directory of OpenAPI definitions is experimental and subject to unannounced breaking changes."));
166
- // TODO: Add config for inlcude/ignore
167
- const allFiles = await (0, utils_1.Globby)(["**/*.{json,yaml,yml}"], {
168
- cwd: openapiPath,
169
- ignore: utils_1.GlobExcludeDefault,
170
- });
171
- const sources = allFiles.filter((x) => !x.includes("_category_")); // todo: regex exclude?
172
- return Promise.all(sources.map(async (source) => {
173
- // TODO: make a function for this
174
- const fullPath = path_1.default.join(openapiPath, source);
175
- const openapiString = await fs_extra_1.default.readFile(fullPath, "utf-8");
176
- const data = js_yaml_1.default.load(openapiString);
177
- return {
178
- source: fullPath,
179
- sourceDirName: path_1.default.dirname(source),
180
- data,
181
- };
182
- }));
192
+ if (!(0, index_1.isURL)(openapiPath)) {
193
+ const stat = await fs_extra_1.default.lstat(openapiPath);
194
+ if (stat.isDirectory()) {
195
+ console.warn(chalk_1.default.yellow("WARNING: Loading a directory of OpenAPI definitions is experimental and subject to unannounced breaking changes."));
196
+ // TODO: Add config for inlcude/ignore
197
+ const allFiles = await (0, utils_1.Globby)(["**/*.{json,yaml,yml}"], {
198
+ cwd: openapiPath,
199
+ ignore: utils_1.GlobExcludeDefault,
200
+ deep: 1,
201
+ });
202
+ const sources = allFiles.filter((x) => !x.includes("_category_")); // todo: regex exclude?
203
+ return Promise.all(sources.map(async (source) => {
204
+ // TODO: make a function for this
205
+ const fullPath = path_1.default.join(openapiPath, source);
206
+ const data = (await (0, loadAndBundleSpec_1.loadAndBundleSpec)(fullPath));
207
+ return {
208
+ source: fullPath,
209
+ sourceDirName: path_1.default.dirname(source),
210
+ data,
211
+ };
212
+ }));
213
+ }
183
214
  }
184
- const openapiString = await fs_extra_1.default.readFile(openapiPath, "utf-8");
185
- const data = js_yaml_1.default.load(openapiString);
215
+ const data = (await (0, loadAndBundleSpec_1.loadAndBundleSpec)(openapiPath));
186
216
  return [
187
217
  {
188
218
  source: openapiPath,
@@ -192,9 +222,9 @@ async function readOpenapiFiles(openapiPath, _options) {
192
222
  ];
193
223
  }
194
224
  exports.readOpenapiFiles = readOpenapiFiles;
195
- async function processOpenapiFiles(files) {
225
+ async function processOpenapiFiles(files, sidebarOptions) {
196
226
  const promises = files.map(async (file) => {
197
- const processedFile = await processOpenapiFile(file.data);
227
+ const processedFile = await processOpenapiFile(file.data, sidebarOptions);
198
228
  const itemsObjectsArray = processedFile[0].map((item) => ({
199
229
  ...item,
200
230
  }));
@@ -213,10 +243,10 @@ async function processOpenapiFiles(files) {
213
243
  return [items, tags];
214
244
  }
215
245
  exports.processOpenapiFiles = processOpenapiFiles;
216
- async function processOpenapiFile(openapiDataWithRefs) {
246
+ async function processOpenapiFile(openapiDataWithRefs, sidebarOptions) {
217
247
  const openapiData = await resolveRefs(openapiDataWithRefs);
218
248
  const postmanCollection = await createPostmanCollection(openapiData);
219
- const items = createItems(openapiData);
249
+ const items = createItems(openapiData, sidebarOptions);
220
250
  bindCollectionToApiItems(items, postmanCollection);
221
251
  let tags = [];
222
252
  if (openapiData.tags !== undefined) {
@@ -22,12 +22,6 @@ describe("openapi", () => {
22
22
  const yaml = results.find((x) => x.source.endsWith("openapi.yaml"));
23
23
  expect(yaml).toBeTruthy();
24
24
  expect(yaml === null || yaml === void 0 ? void 0 : yaml.sourceDirName).toBe(".");
25
- const froyo = results.find((x) => x.source.endsWith("froyo.yaml"));
26
- expect(froyo).toBeTruthy();
27
- expect(froyo === null || froyo === void 0 ? void 0 : froyo.sourceDirName).toBe("yogurtstore");
28
- const nested = results.find((x) => x.source.endsWith("nested.yaml"));
29
- expect(nested).toBeTruthy();
30
- expect(nested === null || nested === void 0 ? void 0 : nested.sourceDirName).toBe("yogurtstore/nested");
31
25
  });
32
26
  });
33
27
  });
@@ -0,0 +1,3 @@
1
+ import { OpenAPISpec } from "./types";
2
+ export declare function loadAndBundleSpec(specUrlOrObject: object | string): Promise<OpenAPISpec>;
3
+ export declare function convertSwagger2OpenAPI(spec: any): Promise<OpenAPISpec>;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.convertSwagger2OpenAPI = exports.loadAndBundleSpec = void 0;
10
+ const bundle_1 = require("@redocly/openapi-core/lib/bundle");
11
+ const config_1 = require("@redocly/openapi-core/lib/config/config");
12
+ const swagger2openapi_1 = require("swagger2openapi");
13
+ async function loadAndBundleSpec(specUrlOrObject) {
14
+ const config = new config_1.Config({});
15
+ const bundleOpts = {
16
+ config,
17
+ base: process.cwd(),
18
+ };
19
+ if (typeof specUrlOrObject === "object" && specUrlOrObject !== null) {
20
+ bundleOpts["doc"] = {
21
+ source: { absoluteRef: "" },
22
+ parsed: specUrlOrObject,
23
+ };
24
+ }
25
+ else {
26
+ bundleOpts["ref"] = specUrlOrObject;
27
+ }
28
+ // Force dereference ?
29
+ // bundleOpts["dereference"] = true;
30
+ const { bundle: { parsed }, } = await (0, bundle_1.bundle)(bundleOpts);
31
+ return parsed.swagger !== undefined ? convertSwagger2OpenAPI(parsed) : parsed;
32
+ }
33
+ exports.loadAndBundleSpec = loadAndBundleSpec;
34
+ function convertSwagger2OpenAPI(spec) {
35
+ console.warn("[ReDoc Compatibility mode]: Converting OpenAPI 2.0 to OpenAPI 3.0");
36
+ return new Promise((resolve, reject) => (0, swagger2openapi_1.convertObj)(spec, { patch: true, warnOnly: true, text: "{}", anchors: true }, (err, res) => {
37
+ // TODO: log any warnings
38
+ if (err) {
39
+ return reject(err);
40
+ }
41
+ resolve(res && res.openapi);
42
+ }));
43
+ }
44
+ exports.convertSwagger2OpenAPI = convertSwagger2OpenAPI;