openapi-explorer 2.4.812 → 2.4.834
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/dist/browser/openapi-explorer.min.js +2 -2
- package/dist/es/components/api-request.js +1 -1
- package/dist/es/components/api-response.js +1 -1
- package/dist/es/components/syntax-highlighter.js +8 -5
- package/dist/es/templates/code-samples-template.js +1 -1
- package/dist/es/utils/common-utils.js +5 -10
- package/dist/es/utils/schema-utils.js +6 -3
- package/dist/lib/components/api-request.js +1 -1
- package/dist/lib/components/api-response.js +1 -1
- package/dist/lib/components/syntax-highlighter.js +8 -5
- package/dist/lib/templates/code-samples-template.js +1 -1
- package/dist/lib/utils/common-utils.js +5 -10
- package/dist/lib/utils/schema-utils.js +6 -3
- package/package.json +1 -1
|
@@ -455,7 +455,7 @@ export default class ApiRequest extends LitElement {
|
|
|
455
455
|
return;
|
|
456
456
|
}
|
|
457
457
|
this.activeResponseTab = e.target.dataset.tab;
|
|
458
|
-
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${getI18nText('operations.request')}</button> ${!hasResponse ? '' : html` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${getI18nText('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${getI18nText('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? html` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? html`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? html`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : html` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}"> </div> </div>`;
|
|
458
|
+
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${getI18nText('operations.request')}</button> ${!hasResponse ? '' : html` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${getI18nText('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${getI18nText('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? html` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? html`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? html`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : html` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}" .label="${getI18nText('operations.response')}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}" .label="${getI18nText('operations.response-headers')}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}" .label="${getI18nText('operations.request')}"> </div> </div>`;
|
|
459
459
|
}
|
|
460
460
|
apiCallTemplate() {
|
|
461
461
|
return html` <div style="display:flex;align-items:flex-end;margin:16px 0;font-size:var(--font-size-small)"> ${this.parameters.length > 0 || this.request_body ? html` <button class="m-btn thin-border" part="btn btn-outline" style="margin-right:5px" @click="${this.onClearRequestData}"> ${getI18nText('operations.clear')} </button>` : ''} <button class="m-btn primary btn-execute thin-border" part="btn btn-fill btn-try" @click="${this.onTryClick}">${getI18nText('operations.execute')}</button> </div> ${this.apiResponseTabTemplate()} `;
|
|
@@ -160,7 +160,7 @@ export default class ApiResponse extends LitElement {
|
|
|
160
160
|
if (!mimeRespDetails) {
|
|
161
161
|
return html` <pre style="color:var(--red)" class="example-panel border-top"> No example provided </pre> `;
|
|
162
162
|
}
|
|
163
|
-
return html` ${mimeRespDetails.examples.length === 1 ? html` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}">` : html` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => html`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => html` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}"> </div> `)} </span> `} `;
|
|
163
|
+
return html` ${mimeRespDetails.examples.length === 1 ? html` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}" .label="${getI18nText('operations.response')}">` : html` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => html`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => html` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? html`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? html`<div class="m-markdown-small" style="padding:4px 0"> ${unsafeHTML(toMarkdown(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}" .label="${getI18nText('operations.response')}"> </div> `)} </span> `} `;
|
|
164
164
|
}
|
|
165
165
|
mimeSchemaTemplate(mimeRespDetails) {
|
|
166
166
|
if (!mimeRespDetails) {
|
|
@@ -42,6 +42,9 @@ class SyntaxHighlighter extends LitElement {
|
|
|
42
42
|
content: {
|
|
43
43
|
type: Object
|
|
44
44
|
},
|
|
45
|
+
label: {
|
|
46
|
+
type: String
|
|
47
|
+
},
|
|
45
48
|
language: {
|
|
46
49
|
type: String,
|
|
47
50
|
attribute: 'language'
|
|
@@ -53,7 +56,7 @@ class SyntaxHighlighter extends LitElement {
|
|
|
53
56
|
};
|
|
54
57
|
}
|
|
55
58
|
static finalizeStyles() {
|
|
56
|
-
return [PrismStyles, FontStyle, InputStyle, css`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}`];
|
|
59
|
+
return [PrismStyles, FontStyle, InputStyle, css`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}.toolbar-copy-btn~.sr-only{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;width:1px;overflow:hidden;position:absolute;white-space:nowrap}`];
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
/**
|
|
@@ -73,7 +76,7 @@ class SyntaxHighlighter extends LitElement {
|
|
|
73
76
|
return null;
|
|
74
77
|
}
|
|
75
78
|
render() {
|
|
76
|
-
return this.renderCopyWrapper(this.renderHighlight());
|
|
79
|
+
return this.renderCopyWrapper(this.renderHighlight(), this.label.toLowerCase());
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
/**
|
|
@@ -89,7 +92,7 @@ class SyntaxHighlighter extends LitElement {
|
|
|
89
92
|
}
|
|
90
93
|
const stringContent = ((_this$content = this.content) === null || _this$content === void 0 ? void 0 : _this$content.toString()) || '';
|
|
91
94
|
const increasedSpaceContent = lang !== 'python' && lang !== 'yaml' && lang !== 'toml' ? stringContent.split('\n').map(line => line.replace(/^\s{2}/g, ' ')).join('\n') : stringContent;
|
|
92
|
-
return grammar ? html`<pre><code>${unsafeHTML(Prism.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : html`<pre>${increasedSpaceContent}</pre>`;
|
|
95
|
+
return grammar ? html`<pre tabindex="0" role="region" aria-label="${this.label}"><code>${unsafeHTML(Prism.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : html`<pre tabindex="0" role="region" aria-label="${this.label}">${increasedSpaceContent}</pre>`;
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
/**
|
|
@@ -97,8 +100,8 @@ class SyntaxHighlighter extends LitElement {
|
|
|
97
100
|
* @param {*} content Content
|
|
98
101
|
* @returns Content
|
|
99
102
|
*/
|
|
100
|
-
renderCopyWrapper(content) {
|
|
101
|
-
return html`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" part="btn btn-fill btn-copy">${getI18nText('operations.copy')}</button> ${content} </div>`;
|
|
103
|
+
renderCopyWrapper(content, label) {
|
|
104
|
+
return html`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" aria-label="${getI18nText('operations.copy')} ${label}" part="btn btn-fill btn-copy">${getI18nText('operations.copy')}</button> ${content} <div class="sr-only" aria-live="polite" role="status"></div> </div>`;
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
/**
|
|
@@ -22,7 +22,7 @@ export default function codeSamplesTemplate(xCodeSamples) {
|
|
|
22
22
|
}).filter(l => typeof l !== 'undefined'));
|
|
23
23
|
const sanitizedSource = v.source.split('\n').map(s => s.substring(0, paddingToRemove).match(/^\s+$/) ? s.substring(paddingToRemove) : s);
|
|
24
24
|
const fullSource = sanitizedSource.join('\n');
|
|
25
|
-
return html` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}"> </div>`;
|
|
25
|
+
return html` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}" .label="${getI18nText('parameters.samples')}"> </div>`;
|
|
26
26
|
})} </div></section>`;
|
|
27
27
|
}
|
|
28
28
|
/* eslint-enable indent */
|
|
@@ -17,7 +17,8 @@ export const invalidCharsRegEx = new RegExp(/[\s#:?&={}-]+/, 'g'); // used for g
|
|
|
17
17
|
export function sleep(ms) {
|
|
18
18
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
19
19
|
}
|
|
20
|
-
export function copyToClipboard(copyData, eventTarget) {
|
|
20
|
+
export async function copyToClipboard(copyData, eventTarget) {
|
|
21
|
+
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
21
22
|
// In lots of places we have more than a couple of spaces for <pre> display purposes, we remove those extra spaces here.
|
|
22
23
|
let data = copyData === null || copyData === void 0 ? void 0 : copyData.trim().replace(/\s{8}/g, ' ');
|
|
23
24
|
try {
|
|
@@ -29,25 +30,19 @@ export function copyToClipboard(copyData, eventTarget) {
|
|
|
29
30
|
} catch (error) {
|
|
30
31
|
// Ignore non JSON text;
|
|
31
32
|
}
|
|
32
|
-
const textArea = document.createElement('textarea');
|
|
33
|
-
textArea.value = data;
|
|
34
|
-
textArea.style.position = 'fixed'; // avoid scrolling to bottom
|
|
35
|
-
document.body.appendChild(textArea);
|
|
36
|
-
textArea.focus();
|
|
37
|
-
textArea.select();
|
|
38
33
|
try {
|
|
39
|
-
|
|
40
|
-
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
34
|
+
await window.navigator.clipboard.writeText(data);
|
|
41
35
|
if (btnEl) {
|
|
42
36
|
btnEl.innerText = getI18nText('operations.copied');
|
|
37
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = getI18nText('operations.copied');
|
|
43
38
|
setTimeout(() => {
|
|
44
39
|
btnEl.innerText = getI18nText('operations.copy');
|
|
40
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = '';
|
|
45
41
|
}, 5000);
|
|
46
42
|
}
|
|
47
43
|
} catch (err) {
|
|
48
44
|
console.error('Unable to copy', err); // eslint-disable-line no-console
|
|
49
45
|
}
|
|
50
|
-
document.body.removeChild(textArea);
|
|
51
46
|
}
|
|
52
47
|
export function getBaseUrlFromUrl(url) {
|
|
53
48
|
const pathArray = url.split('/');
|
|
@@ -360,7 +360,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '
|
|
|
360
360
|
// If allOf is an array of multiple elements, then all the keys makes a single object
|
|
361
361
|
const objWithAllProps = {};
|
|
362
362
|
allOf.map((v, i) => {
|
|
363
|
-
if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf) {
|
|
363
|
+
if (v.type === 'object' || v.properties || v.patternProperties || v.allOf || v.anyOf || v.oneOf) {
|
|
364
364
|
const propSuffix = (v.anyOf || v.oneOf) && i > 0 ? i : '';
|
|
365
365
|
const partialObj = schemaInObjectNotation(v, options, level + 1, propSuffix);
|
|
366
366
|
Object.assign(objWithAllProps, partialObj);
|
|
@@ -386,7 +386,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '
|
|
|
386
386
|
let writeOnly = true;
|
|
387
387
|
let readOnly = true;
|
|
388
388
|
(anyOf || oneOf || []).forEach((v, index) => {
|
|
389
|
-
if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf || v.type === 'array' || v.items) {
|
|
389
|
+
if (v.type === 'object' || v.properties || v.patternProperties || v.allOf || v.anyOf || v.oneOf || v.type === 'array' || v.items) {
|
|
390
390
|
const partialObj = schemaInObjectNotation(v, options);
|
|
391
391
|
if (partialObj) {
|
|
392
392
|
var _partialObj$Flags, _partialObj$Flags2;
|
|
@@ -493,6 +493,9 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '
|
|
|
493
493
|
objTypeOption[key] = schemaInObjectNotation(schemaProperties[key], options, level + 1);
|
|
494
494
|
}
|
|
495
495
|
}
|
|
496
|
+
for (const key in schemaPatternProperties) {
|
|
497
|
+
objTypeOption[`<pattern: ${key}>`] = schemaInObjectNotation(schemaPatternProperties[key], options, level + 1);
|
|
498
|
+
}
|
|
496
499
|
if (schema.additionalProperties) {
|
|
497
500
|
objTypeOption['<any-key>'] = schemaInObjectNotation(schema.additionalProperties, options);
|
|
498
501
|
}
|
|
@@ -522,7 +525,7 @@ export function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '
|
|
|
522
525
|
}
|
|
523
526
|
return obj;
|
|
524
527
|
}
|
|
525
|
-
if (propertyType === 'object' || schemaProperties || schema.circularReference) {
|
|
528
|
+
if (propertyType === 'object' || schemaProperties || schemaPatternProperties || schema.circularReference) {
|
|
526
529
|
const obj = {
|
|
527
530
|
'::type': ''
|
|
528
531
|
};
|
|
@@ -460,7 +460,7 @@ class ApiRequest extends _lit.LitElement {
|
|
|
460
460
|
return;
|
|
461
461
|
}
|
|
462
462
|
this.activeResponseTab = e.target.dataset.tab;
|
|
463
|
-
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${(0, _index.getI18nText)('operations.request')}</button> ${!hasResponse ? '' : (0, _lit.html)` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${(0, _index.getI18nText)('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${(0, _index.getI18nText)('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? (0, _lit.html)` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? (0, _lit.html)`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? (0, _lit.html)`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : (0, _lit.html)` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}"> </div> </div>`;
|
|
463
|
+
}}"> <br> <div style="width:100%"> <button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab="curl">${(0, _index.getI18nText)('operations.request')}</button> ${!hasResponse ? '' : (0, _lit.html)` <button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab="response">${(0, _index.getI18nText)('operations.response')}</button> <button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab="headers">${(0, _index.getI18nText)('operations.response-headers')}</button>`} </div> </div> ${this.responseIsBlob ? (0, _lit.html)` <div class="tab-content col" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> ${this.responseBlobType === 'image' ? (0, _lit.html)`<img style="max-height:var(--resp-area-height,300px);object-fit:contain" class="mar-top-8" src="${this.responseBlobUrl}">` : ''} <div style="display:flex;justify-content:center"> <div> <button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.downloadResponseBlob}" part="btn btn-outline">DOWNLOAD</button> ${this.responseBlobType === 'view' || this.responseBlobType === 'image' ? (0, _lit.html)`<button class="m-btn thin-border mar-top-8" style="width:135px" @click="${this.viewResponseBlob}" part="btn btn-outline">VIEW (NEW TAB)</button>` : ''} </div> </div> </div>` : (0, _lit.html)` <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'response' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" mime-type="${this.responseContentType}" .content="${this.responseText}" .label="${(0, _index.getI18nText)('operations.response')}"> </div>`} <div class="tab-content col m-markdown" style="flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="http" .content="${this.responseHeaders}" .label="${(0, _index.getI18nText)('operations.response-headers')}"> </div> <div class="tab-content m-markdown col" style="flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'}"> <syntax-highlighter style="min-height:60px" language="shell" .content="${curlSyntax.trim()}" .label="${(0, _index.getI18nText)('operations.request')}"> </div> </div>`;
|
|
464
464
|
}
|
|
465
465
|
apiCallTemplate() {
|
|
466
466
|
return (0, _lit.html)` <div style="display:flex;align-items:flex-end;margin:16px 0;font-size:var(--font-size-small)"> ${this.parameters.length > 0 || this.request_body ? (0, _lit.html)` <button class="m-btn thin-border" part="btn btn-outline" style="margin-right:5px" @click="${this.onClearRequestData}"> ${(0, _index.getI18nText)('operations.clear')} </button>` : ''} <button class="m-btn primary btn-execute thin-border" part="btn btn-fill btn-try" @click="${this.onTryClick}">${(0, _index.getI18nText)('operations.execute')}</button> </div> ${this.apiResponseTabTemplate()} `;
|
|
@@ -165,7 +165,7 @@ class ApiResponse extends _lit.LitElement {
|
|
|
165
165
|
if (!mimeRespDetails) {
|
|
166
166
|
return (0, _lit.html)` <pre style="color:var(--red)" class="example-panel border-top"> No example provided </pre> `;
|
|
167
167
|
}
|
|
168
|
-
return (0, _lit.html)` ${mimeRespDetails.examples.length === 1 ? (0, _lit.html)` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}">` : (0, _lit.html)` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => (0, _lit.html)`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => (0, _lit.html)` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}"> </div> `)} </span> `} `;
|
|
168
|
+
return (0, _lit.html)` ${mimeRespDetails.examples.length === 1 ? (0, _lit.html)` ${mimeRespDetails.examples[0].exampleSummary && mimeRespDetails.examples[0].exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${mimeRespDetails.examples[0].exampleSummary} </div>` : ''} ${mimeRespDetails.examples[0].exampleDescription ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(mimeRespDetails.examples[0].exampleDescription || ''))} </div>` : ''} <syntax-highlighter class="example-panel generic-tree pad-top-8" mime-type="${mimeRespDetails.examples[0].exampleType}" .content="${mimeRespDetails.examples[0].exampleValue}" .label="${(0, _index.getI18nText)('operations.response')}">` : (0, _lit.html)` <span class="example-panel generic-tree ${this.renderStyle === 'read' ? 'border pad-8-16' : 'border-top pad-top-8'}"> <select aria-label="response body example" @change="${e => this.onSelectExample(e)}"> ${mimeRespDetails.examples.map(v => (0, _lit.html)`<option value="${v.exampleId}" ?selected="${v.exampleId === mimeRespDetails.selectedExample}"> ${!v.exampleSummary || v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary} </option>`)} </select> ${mimeRespDetails.examples.map(v => (0, _lit.html)` <div class="example" data-example="${v.exampleId}" style="display:${v.exampleId === mimeRespDetails.selectedExample ? 'block' : 'none'}"> ${v.exampleSummary && v.exampleSummary.length > 80 ? (0, _lit.html)`<div style="padding:4px 0"> ${v.exampleSummary} </div>` : ''} ${v.exampleDescription && v.exampleDescription !== v.exampleSummary ? (0, _lit.html)`<div class="m-markdown-small" style="padding:4px 0"> ${(0, _unsafeHtml.unsafeHTML)((0, _commonUtils.toMarkdown)(v.exampleDescription || ''))} </div>` : ''} <syntax-highlighter mime-type="${v.exampleType}" .content="${v.exampleValue}" .label="${(0, _index.getI18nText)('operations.response')}"> </div> `)} </span> `} `;
|
|
169
169
|
}
|
|
170
170
|
mimeSchemaTemplate(mimeRespDetails) {
|
|
171
171
|
if (!mimeRespDetails) {
|
|
@@ -44,6 +44,9 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
44
44
|
content: {
|
|
45
45
|
type: Object
|
|
46
46
|
},
|
|
47
|
+
label: {
|
|
48
|
+
type: String
|
|
49
|
+
},
|
|
47
50
|
language: {
|
|
48
51
|
type: String,
|
|
49
52
|
attribute: 'language'
|
|
@@ -55,7 +58,7 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
55
58
|
};
|
|
56
59
|
}
|
|
57
60
|
static finalizeStyles() {
|
|
58
|
-
return [_prismStyles.default, _fontStyles.default, _inputStyles.default, (0, _lit.css)`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}`];
|
|
61
|
+
return [_prismStyles.default, _fontStyles.default, _inputStyles.default, (0, _lit.css)`:host{font-weight:400}div{position:relative;display:flex;flex-direction:column}.toolbar-copy-btn{position:absolute;top:0;right:0;margin-right:8px}.toolbar-copy-btn+pre{white-space:pre;max-height:400px;overflow:auto;display:flex;padding-right:70px}.toolbar-copy-btn~.sr-only{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;width:1px;overflow:hidden;position:absolute;white-space:nowrap}`];
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
/**
|
|
@@ -75,7 +78,7 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
75
78
|
return null;
|
|
76
79
|
}
|
|
77
80
|
render() {
|
|
78
|
-
return this.renderCopyWrapper(this.renderHighlight());
|
|
81
|
+
return this.renderCopyWrapper(this.renderHighlight(), this.label.toLowerCase());
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
/**
|
|
@@ -91,7 +94,7 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
91
94
|
}
|
|
92
95
|
const stringContent = ((_this$content = this.content) === null || _this$content === void 0 ? void 0 : _this$content.toString()) || '';
|
|
93
96
|
const increasedSpaceContent = lang !== 'python' && lang !== 'yaml' && lang !== 'toml' ? stringContent.split('\n').map(line => line.replace(/^\s{2}/g, ' ')).join('\n') : stringContent;
|
|
94
|
-
return grammar ? (0, _lit.html)`<pre><code>${(0, _unsafeHtml.unsafeHTML)(_prismjs.default.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : (0, _lit.html)`<pre>${increasedSpaceContent}</pre>`;
|
|
97
|
+
return grammar ? (0, _lit.html)`<pre tabindex="0" role="region" aria-label="${this.label}"><code>${(0, _unsafeHtml.unsafeHTML)(_prismjs.default.highlight(increasedSpaceContent, grammar, lang))}</code></pre>` : (0, _lit.html)`<pre tabindex="0" role="region" aria-label="${this.label}">${increasedSpaceContent}</pre>`;
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
/**
|
|
@@ -99,8 +102,8 @@ class SyntaxHighlighter extends _lit.LitElement {
|
|
|
99
102
|
* @param {*} content Content
|
|
100
103
|
* @returns Content
|
|
101
104
|
*/
|
|
102
|
-
renderCopyWrapper(content) {
|
|
103
|
-
return (0, _lit.html)`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" part="btn btn-fill btn-copy">${(0, _index.getI18nText)('operations.copy')}</button> ${content} </div>`;
|
|
105
|
+
renderCopyWrapper(content, label) {
|
|
106
|
+
return (0, _lit.html)`<div class="fs-exclude ph-no-capture" data-hj-suppress data-sl="mask" style="min-height:2rem"> <button class="m-btn outline-primary toolbar-copy-btn" @click="${this.copyToClipboard}" aria-label="${(0, _index.getI18nText)('operations.copy')} ${label}" part="btn btn-fill btn-copy">${(0, _index.getI18nText)('operations.copy')}</button> ${content} <div class="sr-only" aria-live="polite" role="status"></div> </div>`;
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
/**
|
|
@@ -25,7 +25,7 @@ function codeSamplesTemplate(xCodeSamples) {
|
|
|
25
25
|
}).filter(l => typeof l !== 'undefined'));
|
|
26
26
|
const sanitizedSource = v.source.split('\n').map(s => s.substring(0, paddingToRemove).match(/^\s+$/) ? s.substring(paddingToRemove) : s);
|
|
27
27
|
const fullSource = sanitizedSource.join('\n');
|
|
28
|
-
return (0, _lit.html)` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}"> </div>`;
|
|
28
|
+
return (0, _lit.html)` <div class="tab-content m-markdown code-sample-wrapper" style="display:${i === 0 ? 'block' : 'none'}" data-tab="${v.lang}${i}"> <syntax-highlighter language="${v.lang}" .content="${fullSource}" .label="${(0, _index.getI18nText)('parameters.samples')}"> </div>`;
|
|
29
29
|
})} </div></section>`;
|
|
30
30
|
}
|
|
31
31
|
/* eslint-enable indent */
|
|
@@ -32,7 +32,8 @@ const invalidCharsRegEx = exports.invalidCharsRegEx = new RegExp(/[\s#:?&={}-]+/
|
|
|
32
32
|
function sleep(ms) {
|
|
33
33
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
34
34
|
}
|
|
35
|
-
function copyToClipboard(copyData, eventTarget) {
|
|
35
|
+
async function copyToClipboard(copyData, eventTarget) {
|
|
36
|
+
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
36
37
|
// In lots of places we have more than a couple of spaces for <pre> display purposes, we remove those extra spaces here.
|
|
37
38
|
let data = copyData === null || copyData === void 0 ? void 0 : copyData.trim().replace(/\s{8}/g, ' ');
|
|
38
39
|
try {
|
|
@@ -44,25 +45,19 @@ function copyToClipboard(copyData, eventTarget) {
|
|
|
44
45
|
} catch (error) {
|
|
45
46
|
// Ignore non JSON text;
|
|
46
47
|
}
|
|
47
|
-
const textArea = document.createElement('textarea');
|
|
48
|
-
textArea.value = data;
|
|
49
|
-
textArea.style.position = 'fixed'; // avoid scrolling to bottom
|
|
50
|
-
document.body.appendChild(textArea);
|
|
51
|
-
textArea.focus();
|
|
52
|
-
textArea.select();
|
|
53
48
|
try {
|
|
54
|
-
|
|
55
|
-
const btnEl = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.target;
|
|
49
|
+
await window.navigator.clipboard.writeText(data);
|
|
56
50
|
if (btnEl) {
|
|
57
51
|
btnEl.innerText = (0, _index.getI18nText)('operations.copied');
|
|
52
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = (0, _index.getI18nText)('operations.copied');
|
|
58
53
|
setTimeout(() => {
|
|
59
54
|
btnEl.innerText = (0, _index.getI18nText)('operations.copy');
|
|
55
|
+
btnEl.parentElement.querySelector('.sr-only').innerText = '';
|
|
60
56
|
}, 5000);
|
|
61
57
|
}
|
|
62
58
|
} catch (err) {
|
|
63
59
|
console.error('Unable to copy', err); // eslint-disable-line no-console
|
|
64
60
|
}
|
|
65
|
-
document.body.removeChild(textArea);
|
|
66
61
|
}
|
|
67
62
|
function getBaseUrlFromUrl(url) {
|
|
68
63
|
const pathArray = url.split('/');
|
|
@@ -369,7 +369,7 @@ function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '') {
|
|
|
369
369
|
// If allOf is an array of multiple elements, then all the keys makes a single object
|
|
370
370
|
const objWithAllProps = {};
|
|
371
371
|
allOf.map((v, i) => {
|
|
372
|
-
if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf) {
|
|
372
|
+
if (v.type === 'object' || v.properties || v.patternProperties || v.allOf || v.anyOf || v.oneOf) {
|
|
373
373
|
const propSuffix = (v.anyOf || v.oneOf) && i > 0 ? i : '';
|
|
374
374
|
const partialObj = schemaInObjectNotation(v, options, level + 1, propSuffix);
|
|
375
375
|
Object.assign(objWithAllProps, partialObj);
|
|
@@ -395,7 +395,7 @@ function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '') {
|
|
|
395
395
|
let writeOnly = true;
|
|
396
396
|
let readOnly = true;
|
|
397
397
|
(anyOf || oneOf || []).forEach((v, index) => {
|
|
398
|
-
if (v.type === 'object' || v.properties || v.allOf || v.anyOf || v.oneOf || v.type === 'array' || v.items) {
|
|
398
|
+
if (v.type === 'object' || v.properties || v.patternProperties || v.allOf || v.anyOf || v.oneOf || v.type === 'array' || v.items) {
|
|
399
399
|
const partialObj = schemaInObjectNotation(v, options);
|
|
400
400
|
if (partialObj) {
|
|
401
401
|
var _partialObj$Flags, _partialObj$Flags2;
|
|
@@ -502,6 +502,9 @@ function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '') {
|
|
|
502
502
|
objTypeOption[key] = schemaInObjectNotation(schemaProperties[key], options, level + 1);
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
|
+
for (const key in schemaPatternProperties) {
|
|
506
|
+
objTypeOption[`<pattern: ${key}>`] = schemaInObjectNotation(schemaPatternProperties[key], options, level + 1);
|
|
507
|
+
}
|
|
505
508
|
if (schema.additionalProperties) {
|
|
506
509
|
objTypeOption['<any-key>'] = schemaInObjectNotation(schema.additionalProperties, options);
|
|
507
510
|
}
|
|
@@ -531,7 +534,7 @@ function schemaInObjectNotation(rawSchema, options, level = 0, suffix = '') {
|
|
|
531
534
|
}
|
|
532
535
|
return obj;
|
|
533
536
|
}
|
|
534
|
-
if (propertyType === 'object' || schemaProperties || schema.circularReference) {
|
|
537
|
+
if (propertyType === 'object' || schemaProperties || schemaPatternProperties || schema.circularReference) {
|
|
535
538
|
const obj = {
|
|
536
539
|
'::type': ''
|
|
537
540
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-explorer",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.834",
|
|
4
4
|
"description": "OpenAPI Explorer - API viewer with dynamically generated components, documentation, and interaction console",
|
|
5
5
|
"author": "Authress Developers <developers@authress.io>",
|
|
6
6
|
"type": "module",
|