openapi-explorer 0.8.301 → 0.9.305
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.
- package/CHANGELOG.md +3 -0
- package/dist/openapi-explorer.min.js +5 -5
- package/dist/openapi-explorer.min.js.LICENSE.txt +2 -29
- package/dist/openapi-explorer.min.js.LICENSE.txt.gz +0 -0
- package/dist/openapi-explorer.min.js.gz +0 -0
- package/dist/openapi-explorer.min.js.map +1 -1
- package/dist/openapi-explorer.min.js.map.gz +0 -0
- package/dist/report.html +2 -2
- package/package.json +6 -6
- package/src/components/api-request.js +2 -2
- package/src/components/mime-types.js +67 -0
- package/src/openapi-explorer.js +0 -2
- package/src/templates/responsiveViewMainBodyTemplate.js +1 -4
- package/src/utils/spec-parser.js +10 -20
- package/src/utils/xml/xml.js +1 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-explorer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.305",
|
|
4
4
|
"description": "OpenAPI Explorer - API viewer with dynamically generated components, documentation, and interaction console",
|
|
5
5
|
"author": "Rhosys Developers <developers@rhosys.ch>",
|
|
6
6
|
"repository": {
|
|
@@ -39,22 +39,20 @@
|
|
|
39
39
|
],
|
|
40
40
|
"mode": "production",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"authress-login": "^1.
|
|
42
|
+
"authress-login": "^1.2.104",
|
|
43
43
|
"base64url": "^3.0.1",
|
|
44
44
|
"buffer": "^6.0.3",
|
|
45
45
|
"color": "^4.2.3",
|
|
46
46
|
"create-hash": "^1.2.0",
|
|
47
|
-
"js-yaml": "^4.0",
|
|
48
47
|
"lit-element": "2.4.0",
|
|
49
48
|
"lit-html": "^1.1.1",
|
|
50
49
|
"lodash.clonedeep": "^4.5.0",
|
|
51
50
|
"marked": "^4.0.16",
|
|
52
|
-
"mime-
|
|
51
|
+
"mime-db": "^1.52.0",
|
|
53
52
|
"openapi-data-validator": "^2.0.40",
|
|
54
|
-
"
|
|
53
|
+
"openapi-resolver": "^4.0.17",
|
|
55
54
|
"prismjs": "^1.23.0",
|
|
56
55
|
"regex-to-strings": "^2.0.3",
|
|
57
|
-
"swagger-client": "^3.13",
|
|
58
56
|
"xml-but-prettier": "^1.0.1"
|
|
59
57
|
},
|
|
60
58
|
"scripts": {
|
|
@@ -93,10 +91,12 @@
|
|
|
93
91
|
"fs-extra": "^8.1.0",
|
|
94
92
|
"glob": "^7.1.6",
|
|
95
93
|
"html-webpack-plugin": "^5.3.1",
|
|
94
|
+
"https-browserify": "^1.0.0",
|
|
96
95
|
"inspectpack": "^4.7.1",
|
|
97
96
|
"mocha": "^7.2.0",
|
|
98
97
|
"sinon": "^7.5.0",
|
|
99
98
|
"sinon-chai": "^3.3.0",
|
|
99
|
+
"stream-http": "^3.2.0",
|
|
100
100
|
"style-loader": "^2.0.0",
|
|
101
101
|
"terser-webpack-plugin": "^5.1.1",
|
|
102
102
|
"webpack": "^5.30.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LitElement, html } from 'lit-element';
|
|
2
2
|
import { marked } from 'marked';
|
|
3
3
|
import Prism from 'prismjs';
|
|
4
|
-
import
|
|
4
|
+
import mimeTypeResolver from './mime-types';
|
|
5
5
|
|
|
6
6
|
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
|
|
7
7
|
import formatXml from 'xml-but-prettier';
|
|
@@ -1103,7 +1103,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1103
1103
|
const contentDisposition = fetchResponse.headers.get('content-disposition');
|
|
1104
1104
|
const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
|
|
1105
1105
|
const filename = filenameRegex.exec(contentDisposition);
|
|
1106
|
-
this.respContentDisposition = filename && filename[1] && filename[1].replace(/['"]/g, '') || `download.${
|
|
1106
|
+
this.respContentDisposition = filename && filename[1] && filename[1].replace(/['"]/g, '') || `download.${mimeTypeResolver.extension(contentType) || 'file'}`;
|
|
1107
1107
|
respBlob = await fetchResponse.blob();
|
|
1108
1108
|
this.responseBlobUrl = URL.createObjectURL(respBlob);
|
|
1109
1109
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const db = require('mime-db');
|
|
2
|
+
|
|
3
|
+
const EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/;
|
|
4
|
+
/**
|
|
5
|
+
* Get the default extension for a MIME type.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} type
|
|
8
|
+
* @return {boolean|string}
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export default function extension(type) {
|
|
12
|
+
if (!type || typeof type !== 'string') {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// TODO: use media-typer
|
|
17
|
+
const match = EXTRACT_TYPE_REGEXP.exec(type);
|
|
18
|
+
|
|
19
|
+
// get extensions
|
|
20
|
+
const exts = match && exports.extensions[match[1].toLowerCase()];
|
|
21
|
+
|
|
22
|
+
if (!exts || !exts.length) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return exts[0];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const extensions = {};
|
|
30
|
+
const types = {};
|
|
31
|
+
populateMaps();
|
|
32
|
+
|
|
33
|
+
function populateMaps() {
|
|
34
|
+
// source preference (least -> most)
|
|
35
|
+
const preference = ['nginx', 'apache', undefined, 'iana'];
|
|
36
|
+
|
|
37
|
+
Object.keys(db).forEach(function forEachMimeType(type) {
|
|
38
|
+
const mime = db[type];
|
|
39
|
+
const exts = mime.extensions;
|
|
40
|
+
|
|
41
|
+
if (!exts || !exts.length) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// mime -> extensions
|
|
46
|
+
extensions[type] = exts;
|
|
47
|
+
|
|
48
|
+
// extension -> mime
|
|
49
|
+
for (let i = 0; i < exts.length; i++) {
|
|
50
|
+
const extensionToTest = exts[i];
|
|
51
|
+
|
|
52
|
+
if (types[extensionToTest]) {
|
|
53
|
+
const from = preference.indexOf(db[types[extensionToTest]].source);
|
|
54
|
+
const to = preference.indexOf(mime.source);
|
|
55
|
+
|
|
56
|
+
if (types[extensionToTest] !== 'application/octet-stream'
|
|
57
|
+
&& (from > to || (from === to && types[extensionToTest].substr(0, 12) === 'application/'))) {
|
|
58
|
+
// skip the remapping
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// set the extension -> mime
|
|
64
|
+
types[extensionToTest] = type;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
package/src/openapi-explorer.js
CHANGED
|
@@ -74,7 +74,6 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
74
74
|
serverUrl: { type: String, attribute: 'server-url' },
|
|
75
75
|
|
|
76
76
|
// Hide/Show Sections & Enable Disable actions
|
|
77
|
-
showSideNav: { type: String, attribute: 'show-side-nav' },
|
|
78
77
|
showInfo: { type: String, attribute: 'show-info' },
|
|
79
78
|
allowAuthentication: { type: String, attribute: 'show-authentication' },
|
|
80
79
|
allowTry: { type: String, attribute: 'enable-console' },
|
|
@@ -392,7 +391,6 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
392
391
|
if (!this.allowServerSelection || !'true, false,'.includes(`${this.allowServerSelection},`)) { this.allowServerSelection = 'true'; }
|
|
393
392
|
if (!this.allowAuthentication || !'true, false,'.includes(`${this.allowAuthentication},`)) { this.allowAuthentication = 'true'; }
|
|
394
393
|
|
|
395
|
-
if (!this.showSideNav || !'true false'.includes(this.showSideNav)) { this.showSideNav = 'true'; }
|
|
396
394
|
if (!this.showComponents || !'true false'.includes(this.showComponents)) { this.showComponents = 'false'; }
|
|
397
395
|
if (!this.fetchCredentials || !'omit, same-origin, include,'.includes(`${this.fetchCredentials},`)) { this.fetchCredentials = ''; }
|
|
398
396
|
|
|
@@ -33,10 +33,7 @@ export default function responsiveViewMainBodyTemplate() {
|
|
|
33
33
|
|
|
34
34
|
<div id='the-main-body' class="body">
|
|
35
35
|
<!-- Side Nav -->
|
|
36
|
-
${(
|
|
37
|
-
&& this.showSideNav === 'true'
|
|
38
|
-
&& this.resolvedSpec
|
|
39
|
-
) ? navbarTemplate.call(this) : ''
|
|
36
|
+
${(this.renderStyle === 'focused' && this.resolvedSpec) ? navbarTemplate.call(this) : ''
|
|
40
37
|
}
|
|
41
38
|
|
|
42
39
|
<!-- Main Content -->
|
package/src/utils/spec-parser.js
CHANGED
|
@@ -1,30 +1,20 @@
|
|
|
1
|
-
import
|
|
1
|
+
import OpenApiResolver from 'openapi-resolver/dist/openapi-resolver.browser';
|
|
2
2
|
import { marked } from 'marked';
|
|
3
|
-
import yaml from 'js-yaml';
|
|
4
3
|
import { invalidCharsRegEx } from './common-utils';
|
|
5
4
|
|
|
6
5
|
export default async function ProcessSpec(specUrlOrObject, serverUrl = '') {
|
|
7
6
|
const inputSpecIsAUrl = typeof specUrlOrObject === 'string' && specUrlOrObject.match(/^http/) || typeof specUrlOrObject === 'object' && typeof specUrlOrObject.href === 'string';
|
|
8
|
-
let specMeta;
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (inputSpecIsAUrl) {
|
|
19
|
-
specMeta = await SwaggerClient({ allowMetaPatches: false, url: specUrlOrObject.toString(), responseInterceptor });
|
|
20
|
-
} else if (typeof specUrlOrObject === 'string') {
|
|
21
|
-
specMeta = await SwaggerClient({ allowMetaPatches: false, spec: yaml.load(specUrlOrObject), responseInterceptor });
|
|
22
|
-
} else {
|
|
23
|
-
specMeta = await SwaggerClient({ allowMetaPatches: false, spec: specUrlOrObject, responseInterceptor });
|
|
8
|
+
let jsonParsedSpec;
|
|
9
|
+
try {
|
|
10
|
+
jsonParsedSpec = await OpenApiResolver(specUrlOrObject);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
// eslint-disable-next-line no-console
|
|
13
|
+
console.error('Error parsing specification', error);
|
|
14
|
+
throw Error('SpecificationNotFound');
|
|
24
15
|
}
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
if (specMeta.message === 'Not Found' || !jsonParsedSpec) {
|
|
17
|
+
if (!jsonParsedSpec) {
|
|
28
18
|
throw Error('SpecificationNotFound');
|
|
29
19
|
}
|
|
30
20
|
|
|
@@ -233,7 +223,7 @@ function groupByTags(openApiSpec) {
|
|
|
233
223
|
if (pathsAndWebhooks[pathOrHookName][methodName]) {
|
|
234
224
|
const pathOrHookObj = openApiSpec.paths[pathOrHookName][methodName];
|
|
235
225
|
// If path.methods are tagged, else generate it from path
|
|
236
|
-
const pathTags = pathOrHookObj.tags || [];
|
|
226
|
+
const pathTags = Array.isArray(pathOrHookObj.tags) ? pathOrHookObj.tags : pathOrHookObj.tags && [pathOrHookObj.tags] || [];
|
|
237
227
|
if (pathTags.length === 0) {
|
|
238
228
|
pathTags.push('General ⦂');
|
|
239
229
|
}
|
package/src/utils/xml/xml.js
CHANGED
|
@@ -18,7 +18,7 @@ function escapeForXML(string) {
|
|
|
18
18
|
|
|
19
19
|
const DEFAULT_INDENT = ' ';
|
|
20
20
|
|
|
21
|
-
function xml(input, rawOptions) {
|
|
21
|
+
export default function xml(input, rawOptions) {
|
|
22
22
|
let options = rawOptions;
|
|
23
23
|
if (typeof options !== 'object') {
|
|
24
24
|
options = {
|
|
@@ -80,32 +80,6 @@ function xml(input, rawOptions) {
|
|
|
80
80
|
return output;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
function element(/* input, …*/) {
|
|
84
|
-
const input = Array.prototype.slice.call(arguments);
|
|
85
|
-
const self = {
|
|
86
|
-
_elem: resolve(input)
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
self.push = function(pushInput) {
|
|
90
|
-
if (!this.append) {
|
|
91
|
-
throw new Error('not assigned to a parent!');
|
|
92
|
-
}
|
|
93
|
-
const that = this;
|
|
94
|
-
const indent = this._elem.indent;
|
|
95
|
-
format(this.append, resolve(
|
|
96
|
-
pushInput, indent, this._elem.icount + (indent ? 1 : 0)),
|
|
97
|
-
function() { that.append(true); });
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
self.close = function(closeInput) {
|
|
101
|
-
if (closeInput !== undefined) {
|
|
102
|
-
this.push(closeInput);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return self;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
83
|
function create_indent(character, count) {
|
|
110
84
|
return (new Array(count || 0).join(character || ''));
|
|
111
85
|
}
|
|
@@ -254,5 +228,3 @@ function attribute(key, value) {
|
|
|
254
228
|
return `${key}=` + `"${escapeForXML(value)}"`;
|
|
255
229
|
}
|
|
256
230
|
|
|
257
|
-
module.exports = xml;
|
|
258
|
-
module.exports.element = module.exports.Element = element;
|