openapi-explorer 0.8.294 → 0.8.297
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 +1 -0
- package/dist/openapi-explorer.min.js +3 -3
- package/dist/openapi-explorer.min.js.LICENSE.txt +1 -1
- package/dist/openapi-explorer.min.js.LICENSE.txt.gz +0 -0
- package/dist/openapi-explorer.min.js.gz +0 -0
- package/dist/report.html +2 -2
- package/package.json +1 -1
- package/src/openapi-explorer.js +43 -64
- package/src/styles/nav-styles.js +1 -2
- package/src/templates/endpoint-template.js +1 -1
- package/src/templates/focused-endpoint-template.js +0 -4
- package/src/templates/responsiveViewMainBodyTemplate.js +1 -6
- package/src/utils/spec-parser.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-explorer",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.297",
|
|
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": {
|
package/src/openapi-explorer.js
CHANGED
|
@@ -515,7 +515,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
515
515
|
return;
|
|
516
516
|
}
|
|
517
517
|
if (!this.serverUrl) {
|
|
518
|
-
this.serverUrl = spec.servers[0].url;
|
|
518
|
+
this.serverUrl = spec.servers[0].computedUrl || spec.servers[0].url;
|
|
519
519
|
}
|
|
520
520
|
this.afterSpecParsedAndValidated(spec);
|
|
521
521
|
} catch (err) {
|
|
@@ -558,62 +558,45 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
558
558
|
this.resolvedSpec = spec;
|
|
559
559
|
this.selectedServer = this.resolvedSpec.servers.find((s) => s.url === this.serverUrl || !this.serverUrl);
|
|
560
560
|
this.dispatchEvent(new CustomEvent('spec-loaded', { detail: spec }));
|
|
561
|
+
// Wait for 10 milliseconds to account for any changes to the spec via spec-loaded
|
|
562
|
+
await sleep(10);
|
|
561
563
|
this.requestUpdate();
|
|
562
564
|
|
|
563
565
|
// Initiate IntersectionObserver and put it at the end of event loop, to allow loading all the child elements (must for larger specs)
|
|
564
566
|
this.intersectionObserver.disconnect();
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
this.
|
|
567
|
+
|
|
568
|
+
if (this.renderStyle === 'focused') {
|
|
569
|
+
const defaultElementId = this.showInfo ? 'overview' : this.resolvedSpec.tags && this.resolvedSpec.tags[0] && this.resolvedSpec.tags[0].paths[0];
|
|
570
|
+
this.scrollTo(this.explorerLocation || defaultElementId);
|
|
568
571
|
}
|
|
569
572
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
if (locationHash) {
|
|
573
|
-
if (this.renderStyle === 'view') {
|
|
574
|
-
this.expandAndGotoOperation(locationHash, true, true);
|
|
575
|
-
} else if (this.renderStyle === 'focused') {
|
|
576
|
-
this.scrollTo(locationHash);
|
|
577
|
-
}
|
|
578
|
-
} else if (this.renderStyle === 'focused') {
|
|
579
|
-
const defaultElementId = this.showInfo ? 'overview' : this.resolvedSpec.tags[0] && this.resolvedSpec.tags[0].paths[0];
|
|
580
|
-
this.scrollTo(defaultElementId);
|
|
573
|
+
if (this.renderStyle === 'view' && this.explorerLocation) {
|
|
574
|
+
this.expandAndGotoOperation(this.explorerLocation);
|
|
581
575
|
}
|
|
582
576
|
}
|
|
583
577
|
|
|
584
|
-
expandAndGotoOperation(elementId
|
|
578
|
+
expandAndGotoOperation(elementId) {
|
|
585
579
|
// Expand full operation and tag
|
|
586
|
-
let isExpandingNeeded =
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
if (path.expanded && tag.expanded) {
|
|
596
|
-
isExpandingNeeded = false;
|
|
597
|
-
} else {
|
|
598
|
-
path.expanded = true;
|
|
599
|
-
tag.expanded = true;
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
580
|
+
let isExpandingNeeded = false;
|
|
581
|
+
|
|
582
|
+
const tag = this.resolvedSpec.tags.find(t => t.paths && t.paths.find(p => p.elementId === elementId));
|
|
583
|
+
const path = tag && tag.paths && tag.paths.find((p) => p.elementId === elementId);
|
|
584
|
+
if (path && (!path.expanded || !tag.expanded)) {
|
|
585
|
+
isExpandingNeeded = true;
|
|
586
|
+
path.expanded = true;
|
|
587
|
+
tag.expanded = true;
|
|
588
|
+
this.requestUpdate();
|
|
603
589
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
590
|
+
|
|
591
|
+
// requestUpdate() and delay required, else we cant find element because it won't exist immediately
|
|
592
|
+
const tmpElementId = elementId.indexOf('#') === -1 ? elementId : elementId.substring(1);
|
|
593
|
+
window.setTimeout(() => {
|
|
594
|
+
const gotoEl = this.shadowRoot.getElementById(tmpElementId);
|
|
595
|
+
if (gotoEl) {
|
|
596
|
+
gotoEl.scrollIntoView({ behavior: 'auto', block: 'start' });
|
|
597
|
+
replaceState(tmpElementId);
|
|
608
598
|
}
|
|
609
|
-
|
|
610
|
-
const gotoEl = this.shadowRoot.getElementById(tmpElementId);
|
|
611
|
-
if (gotoEl) {
|
|
612
|
-
gotoEl.scrollIntoView({ behavior: 'auto', block: 'start' });
|
|
613
|
-
replaceState(tmpElementId);
|
|
614
|
-
}
|
|
615
|
-
}, isExpandingNeeded ? 150 : 0);
|
|
616
|
-
}
|
|
599
|
+
}, isExpandingNeeded ? 150 : 0);
|
|
617
600
|
}
|
|
618
601
|
|
|
619
602
|
isValidTopId(id) {
|
|
@@ -696,28 +679,26 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
696
679
|
repeatedElementIndex = assignedNodes && [].findIndex.call(assignedNodes, (slot) => slot === event.target);
|
|
697
680
|
}
|
|
698
681
|
this.isIntersectionObserverActive = false;
|
|
699
|
-
this.scrollTo(navEl.dataset.contentId,
|
|
682
|
+
this.scrollTo(navEl.dataset.contentId, scrollNavItemToView, repeatedElementIndex);
|
|
700
683
|
setTimeout(() => {
|
|
701
684
|
this.isIntersectionObserverActive = true;
|
|
702
685
|
}, 300);
|
|
703
686
|
}
|
|
704
687
|
|
|
705
688
|
// Public Method (scrolls to a given path and highlights the left-nav selection)
|
|
706
|
-
async scrollTo(elementId,
|
|
689
|
+
async scrollTo(elementId, scrollNavItemToView = true, repeatedElementIndex) {
|
|
707
690
|
if (!this.resolvedSpec) {
|
|
708
691
|
return;
|
|
709
692
|
}
|
|
710
693
|
|
|
711
694
|
if (this.renderStyle === 'view') {
|
|
712
|
-
this.expandAndGotoOperation(elementId
|
|
695
|
+
this.expandAndGotoOperation(elementId);
|
|
713
696
|
return;
|
|
714
697
|
}
|
|
715
698
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
await sleep(0);
|
|
720
|
-
}
|
|
699
|
+
// explorerLocation will get validated in the focused-endpoint-template
|
|
700
|
+
this.explorerLocation = elementId;
|
|
701
|
+
await sleep(0);
|
|
721
702
|
|
|
722
703
|
const contentEl = this.shadowRoot.getElementById(elementId);
|
|
723
704
|
if (!contentEl) {
|
|
@@ -725,22 +706,20 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
725
706
|
}
|
|
726
707
|
|
|
727
708
|
// For focused APIs, always scroll to the top of the component
|
|
728
|
-
if (
|
|
709
|
+
if (!elementId.match('cmp--')) {
|
|
729
710
|
this.shadowRoot.getElementById('operations-root').scrollIntoView({ behavior: 'auto', block: 'start' });
|
|
730
711
|
} else {
|
|
731
712
|
contentEl.scrollIntoView({ behavior: 'auto', block: 'start' });
|
|
732
713
|
}
|
|
733
714
|
|
|
734
715
|
// for focused style it is important to reset request-body-selection and response selection which maintains the state for in case of multiple req-body or multiple response mime-type
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
responseEl.resetSelection();
|
|
743
|
-
}
|
|
716
|
+
const requestEl = this.shadowRoot.querySelector('api-request');
|
|
717
|
+
if (requestEl) {
|
|
718
|
+
requestEl.resetRequestBodySelection();
|
|
719
|
+
}
|
|
720
|
+
const responseEl = this.shadowRoot.querySelector('api-response');
|
|
721
|
+
if (responseEl) {
|
|
722
|
+
responseEl.resetSelection();
|
|
744
723
|
}
|
|
745
724
|
|
|
746
725
|
// Update Location Hash
|
|
@@ -772,7 +751,7 @@ export default class OpenApiExplorer extends LitElement {
|
|
|
772
751
|
node.classList.remove('active');
|
|
773
752
|
});
|
|
774
753
|
newNavEl.classList.add('active'); // must add the class after scrolling
|
|
775
|
-
|
|
754
|
+
this.requestUpdate();
|
|
776
755
|
}
|
|
777
756
|
|
|
778
757
|
// Event handler for Advanced Search text-inputs and checkboxes
|
package/src/styles/nav-styles.js
CHANGED
|
@@ -6,7 +6,6 @@ import componentsTemplate from './components-template';
|
|
|
6
6
|
import overviewTemplate from './overview-template';
|
|
7
7
|
import serverTemplate from './server-template';
|
|
8
8
|
import securitySchemeTemplate from './security-scheme-template';
|
|
9
|
-
import { expandCollapseNavBarTag } from './navbar-template';
|
|
10
9
|
|
|
11
10
|
function wrapFocusedTemplate(templateToWrap) {
|
|
12
11
|
return html`
|
|
@@ -71,9 +70,6 @@ export default function focusedEndpointTemplate() {
|
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
if (selectedPathObj) {
|
|
74
|
-
// In focused mode we must expand the nav-bar tag element if it is collapsed
|
|
75
|
-
const newNavEl = this.shadowRoot.getElementById(`link-${focusElId}`);
|
|
76
|
-
expandCollapseNavBarTag(newNavEl, 'expand');
|
|
77
73
|
focusedTemplate = wrapFocusedTemplate.call(this, expandedEndpointBodyTemplate.call(this, selectedPathObj, selectedTagObj.name));
|
|
78
74
|
} else {
|
|
79
75
|
// if explorerLocation is not found then show the default content (overview or first-path)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { html } from 'lit-element';
|
|
2
2
|
|
|
3
3
|
// Templates
|
|
4
|
-
import expandedEndpointTemplate from './expanded-endpoint-template';
|
|
5
4
|
import focusedEndpointTemplate from './focused-endpoint-template';
|
|
6
5
|
import overviewTemplate from './overview-template';
|
|
7
6
|
import endpointTemplate from './endpoint-template';
|
|
@@ -61,11 +60,7 @@ export default function responsiveViewMainBodyTemplate() {
|
|
|
61
60
|
class='observe-me ${this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}'>
|
|
62
61
|
<slot name="custom-section"></slot>
|
|
63
62
|
</section>
|
|
64
|
-
${this
|
|
65
|
-
? expandedEndpointTemplate.call(this)
|
|
66
|
-
: endpointTemplate.call(this)
|
|
67
|
-
}
|
|
68
|
-
`
|
|
63
|
+
${endpointTemplate.call(this)}`
|
|
69
64
|
}
|
|
70
65
|
</div>
|
|
71
66
|
`
|
package/src/utils/spec-parser.js
CHANGED
|
@@ -4,7 +4,7 @@ import yaml from 'js-yaml';
|
|
|
4
4
|
import { invalidCharsRegEx } from './common-utils';
|
|
5
5
|
|
|
6
6
|
export default async function ProcessSpec(specUrlOrObject, serverUrl = '') {
|
|
7
|
-
const inputSpecIsAUrl = typeof specUrlOrObject === 'string' && specUrlOrObject.match(/^http/);
|
|
7
|
+
const inputSpecIsAUrl = typeof specUrlOrObject === 'string' && specUrlOrObject.match(/^http/) || typeof specUrlOrObject === 'object' && typeof specUrlOrObject.href === 'string';
|
|
8
8
|
let specMeta;
|
|
9
9
|
|
|
10
10
|
// Dynamically resolve non yaml or json files and insert their descriptions where necessary
|
|
@@ -16,7 +16,7 @@ export default async function ProcessSpec(specUrlOrObject, serverUrl = '') {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
if (inputSpecIsAUrl) {
|
|
19
|
-
specMeta = await SwaggerClient({ allowMetaPatches: false, url: specUrlOrObject, responseInterceptor });
|
|
19
|
+
specMeta = await SwaggerClient({ allowMetaPatches: false, url: specUrlOrObject.toString(), responseInterceptor });
|
|
20
20
|
} else if (typeof specUrlOrObject === 'string') {
|
|
21
21
|
specMeta = await SwaggerClient({ allowMetaPatches: false, spec: yaml.load(specUrlOrObject), responseInterceptor });
|
|
22
22
|
} else {
|