rapidoc 9.3.6 → 9.3.8

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 (44) hide show
  1. package/.eslintrc +9 -1
  2. package/dist/index.html +1010 -6
  3. package/dist/index.html.gz +0 -0
  4. package/dist/rapidoc-min.js +444 -428
  5. package/dist/rapidoc-min.js.LICENSE.txt +1 -8
  6. package/dist/rapidoc-min.js.LICENSE.txt.gz +0 -0
  7. package/dist/rapidoc-min.js.gz +0 -0
  8. package/dist/rapidoc-min.js.map +1 -1
  9. package/dist/rapidoc-min.js.map.gz +0 -0
  10. package/dist/rapidoc.js +576 -373
  11. package/dist/report.html +2 -2
  12. package/index.html +1006 -209
  13. package/{index1.html → index_bak.html} +13 -6
  14. package/jsconfig.json +1 -1
  15. package/package.json +8 -8
  16. package/src/components/api-request.js +144 -100
  17. package/src/components/api-response.js +12 -13
  18. package/src/components/json-tree.js +1 -1
  19. package/src/components/schema-table.js +16 -6
  20. package/src/components/schema-tree.js +15 -10
  21. package/src/json-schema-viewer.js +7 -2
  22. package/src/rapidoc-mini.js +22 -4
  23. package/src/rapidoc.js +35 -19
  24. package/src/styles/border-styles.js +2 -2
  25. package/src/styles/endpoint-styles.js +13 -10
  26. package/src/styles/flex-styles.js +1 -1
  27. package/src/styles/font-styles.js +13 -13
  28. package/src/styles/input-styles.js +8 -3
  29. package/src/styles/nav-styles.js +1 -1
  30. package/src/styles/schema-styles.js +12 -9
  31. package/src/templates/advance-search-template.js +2 -1
  32. package/src/templates/callback-template.js +3 -1
  33. package/src/templates/code-samples-template.js +3 -3
  34. package/src/templates/endpoint-template.js +33 -28
  35. package/src/templates/expanded-endpoint-template.js +7 -3
  36. package/src/templates/json-schema-viewer-template.js +3 -3
  37. package/src/templates/logo-template.js +1 -1
  38. package/src/templates/main-body-template.js +6 -17
  39. package/src/templates/navbar-template.js +6 -6
  40. package/src/templates/security-scheme-template.js +14 -10
  41. package/src/utils/common-utils.js +5 -9
  42. package/src/utils/schema-utils.js +65 -16
  43. package/src/utils/spec-parser.js +77 -7
  44. package/src/utils/theme.js +4 -6
@@ -1,14 +1,14 @@
1
1
  import { css } from 'lit';
2
2
 
3
3
  export default css`
4
- .hover-bg:hover{
4
+ .hover-bg:hover {
5
5
  background: var(--bg3);
6
6
  }
7
7
  ::selection {
8
8
  background: var(--selection-bg);
9
9
  color: var(--selection-fg);
10
10
  }
11
- .regular-font{
11
+ .regular-font {
12
12
  font-family:var(--font-regular);
13
13
  }
14
14
  .mono-font {
@@ -18,7 +18,7 @@ export default css`
18
18
  font-size: calc(var(--font-size-small) + 18px);
19
19
  font-weight: normal
20
20
  }
21
- .sub-title{ font-size: 20px;}
21
+ .sub-title{ font-size: 20px; }
22
22
  .req-res-title {
23
23
  font-family: var(--font-regular);
24
24
  font-size: calc(var(--font-size-small) + 4px);
@@ -33,11 +33,11 @@ export default css`
33
33
  .regular-font-size { font-size: var(--font-size-regular); }
34
34
  .small-font-size { font-size: var(--font-size-small); }
35
35
  .upper { text-transform: uppercase; }
36
- .primary-text{ color: var(--primary-color); }
36
+ .primary-text { color: var(--primary-color); }
37
37
  .bold-text { font-weight:bold; }
38
38
  .gray-text { color: var(--light-fg); }
39
- .red-text {color: var(--red)}
40
- .blue-text {color: var(--blue)}
39
+ .red-text { color: var(--red) }
40
+ .blue-text { color: var(--blue) }
41
41
  .multiline {
42
42
  overflow: scroll;
43
43
  max-height: var(--resp-area-height, 400px);
@@ -53,14 +53,14 @@ export default css`
53
53
  color: var(--yellow);
54
54
  }
55
55
 
56
- h1{ font-family:var(--font-regular); font-size:28px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
57
- h2{ font-family:var(--font-regular); font-size:24px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
58
- h3{ font-family:var(--font-regular); font-size:18px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
59
- h4{ font-family:var(--font-regular); font-size:16px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
60
- h5{ font-family:var(--font-regular); font-size:14px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
61
- h6{ font-family:var(--font-regular); font-size:14px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
56
+ h1 { font-family:var(--font-regular); font-size:28px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
57
+ h2 { font-family:var(--font-regular); font-size:24px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
58
+ h3 { font-family:var(--font-regular); font-size:18px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
59
+ h4 { font-family:var(--font-regular); font-size:16px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
60
+ h5 { font-family:var(--font-regular); font-size:14px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
61
+ h6 { font-family:var(--font-regular); font-size:14px; padding-top: 10px; letter-spacing:normal; font-weight:normal; }
62
62
 
63
- h1,h2,h3,h4,h5,h5{
63
+ h1,h2,h3,h4,h5,h5 {
64
64
  margin-block-end: 0.2em;
65
65
  }
66
66
  p { margin-block-start: 0.5em; }
@@ -15,10 +15,10 @@ export default css`
15
15
  white-space: nowrap;
16
16
  border: 2px solid var(--primary-color);
17
17
  background-color:transparent;
18
- transition: background-color 0.2s;
19
18
  user-select: none;
20
19
  cursor: pointer;
21
20
  box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
21
+ transition-duration: 0.75s;
22
22
  }
23
23
  .m-btn.primary {
24
24
  background-color: var(--primary-color);
@@ -37,14 +37,19 @@ export default css`
37
37
  .m-btn.nav:hover {
38
38
  background-color: var(--nav-accent-color);
39
39
  }
40
- .m-btn:disabled{
40
+ .m-btn:disabled {
41
41
  background-color: var(--bg3);
42
42
  color: var(--fg3);
43
43
  border-color: var(--fg3);
44
44
  cursor: not-allowed;
45
45
  opacity: 0.4;
46
46
  }
47
- .toolbar-btn{
47
+ .m-btn:active {
48
+ filter: brightness(75%);
49
+ transform: scale(0.95);
50
+ transition:scale 0s;
51
+ }
52
+ .toolbar-btn {
48
53
  cursor: pointer;
49
54
  padding: 4px;
50
55
  margin:0 2px;
@@ -29,7 +29,7 @@ export default css`
29
29
  flex-wrap:nowrap;
30
30
  word-break:break-word;
31
31
  }
32
- ::slotted([slot=nav-logo]){
32
+ ::slotted([slot=nav-logo]) {
33
33
  padding:16px 16px 0 16px;
34
34
  }
35
35
  .nav-scroll {
@@ -3,6 +3,9 @@ import { css } from 'lit';
3
3
  export default css`
4
4
 
5
5
  *, *:before, *:after { box-sizing: border-box; }
6
+ :host {
7
+ container-type: inline-size;
8
+ }
6
9
 
7
10
  .tr {
8
11
  display: flex;
@@ -81,13 +84,13 @@ export default css`
81
84
  margin-left: 2px;
82
85
  }
83
86
 
84
- .stri, .string, .uri, .url, .byte, .bina, .date, .pass, .ipv4, .ipv4, .uuid, .emai, .host {color:var(--green);}
85
- .inte, .numb, .number, .int6, .int3, .floa, .doub, .deci .blue {color:var(--blue);}
86
- .null {color:var(--red);}
87
- .bool, .boolean{color:var(--orange)}
88
- .enum {color:var(--purple)}
89
- .cons {color:var(--purple)}
90
- .recu {color:var(--brown)}
87
+ .stri, .string, .uri, .url, .byte, .bina, .date, .pass, .ipv4, .ipv4, .uuid, .emai, .host { color:var(--green); }
88
+ .inte, .numb, .number, .int6, .int3, .floa, .doub, .deci .blue { color:var(--blue); }
89
+ .null { color:var(--red); }
90
+ .bool, .boolean { color:var(--orange) }
91
+ .enum { color:var(--purple) }
92
+ .cons { color:var(--purple) }
93
+ .recu { color:var(--brown) }
91
94
  .toolbar {
92
95
  display:flex;
93
96
  width:100%;
@@ -107,11 +110,11 @@ export default css`
107
110
  }
108
111
  .toolbar-item:first-of-type { margin:0 2px 0 0;}
109
112
 
110
- @media only screen and (min-width: 500px) {
113
+ @container (min-width: 500px) {
111
114
  .key-descr {
112
115
  display: block;
113
116
  }
114
- .expanded-descr .key-descr{
117
+ .expanded-descr .key-descr {
115
118
  display: block;
116
119
  }
117
120
  }
@@ -13,6 +13,7 @@ export default function searchByPropertiesModalTemplate() {
13
13
  >
14
14
  <span class="advanced-search-options">
15
15
  <input
16
+ id="input-advanced-search-dialog"
16
17
  style="width:100%; padding-right:20px;"
17
18
  type="text"
18
19
  part="textbox textbox-search-dialog"
@@ -52,7 +53,7 @@ export default function searchByPropertiesModalTemplate() {
52
53
  tabindex = '0'
53
54
  @click="${
54
55
  (e) => {
55
- this.matchPaths = ''; // clear quick filter if applied
56
+ this.searchVal = ''; // clear quick filter if applied
56
57
  this.showAdvancedSearchDialog = false; // Hide Search Dialog
57
58
  this.requestUpdate();
58
59
  this.scrollToEventTarget(e, true);
@@ -40,6 +40,7 @@ export default function callbackTemplate(callbacks) {
40
40
  schema-hide-write-only = "${this.schemaHideWriteOnly === 'never' ? 'false' : 'true'}"
41
41
  fetch-credentials = "${this.fetchCredentials}"
42
42
  exportparts = "wrap-request-btn:wrap-request-btn, btn:btn, btn-fill:btn-fill, btn-outline:btn-outline, btn-try:btn-try, btn-clear:btn-clear, btn-clear-resp:btn-clear-resp,
43
+ tab-panel:tab-panel, tab-btn:tab-btn, tab-btn-row:tab-btn-row, tab-coontent:tab-content,
43
44
  file-input:file-input, textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param,
44
45
  anchor:anchor, anchor-param-example:anchor-param-example, schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
45
46
  > </api-request>
@@ -58,7 +59,8 @@ export default function callbackTemplate(callbacks) {
58
59
  schema-hide-read-only = "${this.schemaHideReadOnly === 'never' ? 'false' : 'true'}"
59
60
  schema-hide-write-only = "false"
60
61
  exportparts = "btn:btn, btn-response-status:btn-response-status, btn-selected-response-status:btn-selected-response-status, btn-fill:btn-fill, btn-copy:btn-copy,
61
- schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
62
+ tab-panel:tab-panel, tab-btn:tab-btn, tab-btn-row:tab-btn-row, tab-coontent:tab-content,
63
+ schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
62
64
  > </api-response>
63
65
  </div>
64
66
  </div>
@@ -7,7 +7,7 @@ import { copyToClipboard } from '~/utils/common-utils';
7
7
  export default function codeSamplesTemplate(xCodeSamples) {
8
8
  return html`
9
9
  <section class="table-title" style="margin-top:24px;">CODE SAMPLES</div>
10
- <div class="tab-panel col"
10
+ <div part="tab-panel" class="tab-panel col"
11
11
  @click="${
12
12
  (e) => {
13
13
  if (!e.target.classList.contains('tab-btn')) { return; }
@@ -19,8 +19,8 @@ export default function codeSamplesTemplate(xCodeSamples) {
19
19
  tabContents.forEach((tabBodyEl) => { tabBodyEl.style.display = (tabBodyEl.dataset.tab === clickedTab ? 'block' : 'none'); });
20
20
  }
21
21
  }">
22
- <div class="tab-buttons row" style="width:100; overflow">
23
- ${xCodeSamples.map((v, i) => html`<button class="tab-btn ${i === 0 ? 'active' : ''}" data-tab = '${v.lang}${i}'> ${v.label || v.lang} </button>`)}
22
+ <div part="tab-btn-row" class="tab-buttons row" style="width:100; overflow">
23
+ ${xCodeSamples.map((v, i) => html`<button part="tab-btn" class="tab-btn ${i === 0 ? 'active' : ''}" data-tab = '${v.lang}${i}'> ${v.label || v.lang} </button>`)}
24
24
  </div>
25
25
  ${xCodeSamples.map((v, i) => html`
26
26
  <div class="tab-content m-markdown" style= "display:${i === 0 ? 'block' : 'none'}" data-tab = '${v.lang}${i}'>
@@ -6,7 +6,7 @@ import '~/components/api-response';
6
6
  import codeSamplesTemplate from '~/templates/code-samples-template';
7
7
  import callbackTemplate from '~/templates/callback-template';
8
8
  import { pathSecurityTemplate } from '~/templates/security-scheme-template';
9
- import { pathIsInSearch, rapidocApiKey } from '~/utils/common-utils';
9
+ import { getMatchedPaths, rapidocApiKey } from '~/utils/common-utils';
10
10
 
11
11
  function toggleExpand(path) {
12
12
  if (path.expanded) {
@@ -91,7 +91,7 @@ function endpointBodyTemplate(path) {
91
91
  <div part="section-endpoint-body-${path.expanded ? 'expanded' : 'collapsed'}" class='endpoint-body ${path.method} ${path.deprecated ? 'deprecated' : ''}'>
92
92
  <div class="summary">
93
93
  ${path.summary
94
- ? html`<div class="title" part="section-endpoint-body-title">${path.summary}<div>`
94
+ ? html`<div class="title" part="section-endpoint-body-title">${path.summary}</div>`
95
95
  : path.shortSummary !== path.description
96
96
  ? html`<div class="title" part="section-endpoint-body-title">${path.shortSummary}</div>`
97
97
  : ''
@@ -100,7 +100,9 @@ function endpointBodyTemplate(path) {
100
100
  ? html`
101
101
  <div style="display:flex; flex-wrap:wrap;font-size: var(--font-size-small);">
102
102
  ${path.xBadges.map((v) => (
103
- html`<span part="endpoint-badge" style="margin:1px; margin-right:5px; padding:1px 8px; font-weight:bold; border-radius:12px; background-color: var(--light-${v.color}, var(--input-bg)); color:var(--${v.color}); border:1px solid var(--${v.color})">${v.label}</span>`
103
+ v.color === 'none'
104
+ ? ''
105
+ : html`<span part="endpoint-badge" style="margin:1px; margin-right:5px; padding:1px 8px; font-weight:bold; border-radius:12px; background-color: var(--light-${v.color}, var(--input-bg)); color:var(--${v.color}); border:1px solid var(--${v.color})">${v.label}</span>`
104
106
  ))
105
107
  }
106
108
  </div>
@@ -138,7 +140,7 @@ function endpointBodyTemplate(path) {
138
140
  .request_body = "${path.requestBody}"
139
141
  .api_keys = "${nonEmptyApiKeys}"
140
142
  .servers = "${path.servers}"
141
- server-url = "${path.servers && path.servers.length > 0 ? path.servers[0].url : this.selectedServer.computedUrl}"
143
+ server-url = "${path.servers && path.servers.length > 0 ? path.servers[0].url : this.selectedServer?.computedUrl}"
142
144
  active-schema-tab = "${this.defaultSchemaTab}"
143
145
  fill-request-fields-with-example = "${this.fillRequestFieldsWithExample}"
144
146
  allow-try = "${this.allowTry}"
@@ -153,6 +155,7 @@ function endpointBodyTemplate(path) {
153
155
  schema-hide-write-only = "${this.schemaHideWriteOnly === 'never' ? 'false' : path.isWebhook ? 'true' : 'false'}"
154
156
  fetch-credentials = "${this.fetchCredentials}"
155
157
  exportparts = "wrap-request-btn:wrap-request-btn, btn:btn, btn-fill:btn-fill, btn-outline:btn-outline, btn-try:btn-try, btn-clear:btn-clear, btn-clear-resp:btn-clear-resp,
158
+ tab-panel:tab-panel, tab-btn:tab-btn, tab-btn-row:tab-btn-row, tab-coontent:tab-content,
156
159
  file-input:file-input, textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param,
157
160
  anchor:anchor, anchor-param-example:anchor-param-example, schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
158
161
  > </api-request>
@@ -175,18 +178,20 @@ function endpointBodyTemplate(path) {
175
178
  schema-hide-write-only = "${this.schemaHideWriteOnly === 'never' ? 'false' : path.isWebhook ? 'false' : 'true'}"
176
179
  selected-status = "${Object.keys(path.responses || {})[0] || ''}"
177
180
  exportparts = "btn:btn, btn-fill:btn-fill, btn-outline:btn-outline, btn-try:btn-try, file-input:file-input,
178
- textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param, anchor:anchor, anchor-param-example:anchor-param-example, btn-clear-resp:btn-clear-resp,
179
- schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
181
+ textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param, anchor:anchor, anchor-param-example:anchor-param-example, btn-clear-resp:btn-clear-resp,
182
+ tab-panel:tab-panel, tab-btn:tab-btn, tab-btn-row:tab-btn-row, tab-coontent:tab-content,
183
+ schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
180
184
  > </api-response>
181
185
  </div>
182
186
  </div>`;
183
187
  }
184
188
 
185
- export default function endpointTemplate(showExpandCollapse = true, showTags = true, pathsExpanded = false) {
189
+ export default function endpointTemplate(isMini = false, pathsExpanded = false) {
186
190
  if (!this.resolvedSpec) { return ''; }
187
191
  return html`
188
- ${showExpandCollapse
189
- ? html`
192
+ ${isMini
193
+ ? ''
194
+ : html`
190
195
  <div style="display:flex; justify-content:flex-end;">
191
196
  <span @click="${(e) => onExpandCollapseAll(e, 'expand-all')}" style="color:var(--primary-color); cursor:pointer;">
192
197
  Expand all
@@ -197,11 +202,25 @@ export default function endpointTemplate(showExpandCollapse = true, showTags = t
197
202
  </span>
198
203
  &nbsp; sections
199
204
  </div>`
200
- : ''
201
205
  }
202
206
  ${this.resolvedSpec.tags.map((tag) => html`
203
- ${showTags
204
- ? html`
207
+ ${isMini
208
+ ? html`
209
+ <div class='section-tag-body'>
210
+ ${tag.paths.filter((path) => {
211
+ if (this.searchVal) {
212
+ return getMatchedPaths(this.searchVal, path, tag.name);
213
+ }
214
+ return true;
215
+ }).map((path) => html`
216
+ <section id='${path.elementId}' class='m-endpoint regular-font ${path.method} ${pathsExpanded || path.expanded ? 'expanded' : 'collapsed'}'>
217
+ ${endpointHeadTemplate.call(this, path, pathsExpanded)}
218
+ ${pathsExpanded || path.expanded ? endpointBodyTemplate.call(this, path) : ''}
219
+ </section>`)
220
+ }
221
+ </div>
222
+ `
223
+ : html`
205
224
  <div class='regular-font section-gap section-tag ${tag.expanded ? 'expanded' : 'collapsed'}'>
206
225
  <div class='section-tag-header' @click="${() => { tag.expanded = !tag.expanded; this.requestUpdate(); }}">
207
226
  <div id='${tag.elementId}' class="sub-title tag" style="color:var(--primary-color)">${tag.displayName || tag.name}</div>
@@ -212,8 +231,8 @@ export default function endpointTemplate(showExpandCollapse = true, showTags = t
212
231
  ${unsafeHTML(marked(tag.description || ''))}
213
232
  </div>
214
233
  ${tag.paths.filter((v) => {
215
- if (this.matchPaths) {
216
- return pathIsInSearch(this.matchPaths, v, this.matchType);
234
+ if (this.searchVal) {
235
+ return getMatchedPaths(this.searchVal, v, tag.name);
217
236
  }
218
237
  return true;
219
238
  }).map((path) => html`
@@ -223,20 +242,6 @@ export default function endpointTemplate(showExpandCollapse = true, showTags = t
223
242
  </section>`)
224
243
  }
225
244
  </div>
226
- </div>`
227
- : html`
228
- <div class='section-tag-body'>
229
- ${tag.paths.filter((v) => {
230
- if (this.matchPaths) {
231
- return pathIsInSearch(this.matchPaths, v, this.matchType);
232
- }
233
- return true;
234
- }).map((path) => html`
235
- <section id='${path.elementId}' class='m-endpoint regular-font ${path.method} ${pathsExpanded || path.expanded ? 'expanded' : 'collapsed'}'>
236
- ${endpointHeadTemplate.call(this, path, pathsExpanded)}
237
- ${pathsExpanded || path.expanded ? endpointBodyTemplate.call(this, path) : ''}
238
- </section>`)
239
- }
240
245
  </div>
241
246
  `
242
247
  }
@@ -80,7 +80,9 @@ export function expandedEndpointBodyTemplate(path, tagName = '', tagDescription
80
80
  ? html`
81
81
  <div style="display:flex; flex-wrap:wrap; margin-bottom: -24px; font-size: var(--font-size-small);">
82
82
  ${path.xBadges.map((v) => (
83
- html`<span style="margin:1px; margin-right:5px; padding:1px 8px; font-weight:bold; border-radius:12px; background-color: var(--light-${v.color}, var(--input-bg)); color:var(--${v.color}); border:1px solid var(--${v.color})">${v.label}</span>`
83
+ v.color === 'none'
84
+ ? ''
85
+ : html`<span style="margin:1px; margin-right:5px; padding:1px 8px; font-weight:bold; border-radius:12px; background-color: var(--light-${v.color}, var(--input-bg)); color:var(--${v.color}); border:1px solid var(--${v.color})">${v.label}</span>`
84
86
  ))
85
87
  }
86
88
  </div>
@@ -126,7 +128,7 @@ export function expandedEndpointBodyTemplate(path, tagName = '', tagDescription
126
128
  .request_body = "${path.requestBody}"
127
129
  .api_keys = "${nonEmptyApiKeys}"
128
130
  .servers = "${path.servers}"
129
- server-url = "${path.servers?.[0]?.url || this.selectedServer.computedUrl}"
131
+ server-url = "${path.servers?.[0]?.url || this.selectedServer?.computedUrl}"
130
132
  fill-request-fields-with-example = "${this.fillRequestFieldsWithExample}"
131
133
  allow-try = "${this.allowTry}"
132
134
  show-curl-before-try = "${this.showCurlBeforeTry}"
@@ -141,6 +143,7 @@ export function expandedEndpointBodyTemplate(path, tagName = '', tagDescription
141
143
  schema-hide-write-only = "${this.schemaHideWriteOnly === 'never' ? 'false' : path.isWebhook ? 'true' : 'false'}"
142
144
  fetch-credentials = "${this.fetchCredentials}"
143
145
  exportparts = "wrap-request-btn:wrap-request-btn, btn:btn, btn-fill:btn-fill, btn-outline:btn-outline, btn-try:btn-try, btn-clear:btn-clear, btn-clear-resp:btn-clear-resp,
146
+ tab-panel:tab-panel, tab-btn:tab-btn, tab-btn-row:tab-btn-row, tab-coontent:tab-content,
144
147
  file-input:file-input, textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param,
145
148
  anchor:anchor, anchor-param-example:anchor-param-example, schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
146
149
  > </api-request>
@@ -162,7 +165,8 @@ export function expandedEndpointBodyTemplate(path, tagName = '', tagDescription
162
165
  schema-hide-write-only = "${this.schemaHideWriteOnly === 'never' ? 'false' : path.isWebhook ? 'false' : 'true'}"
163
166
  selected-status = "${Object.keys(path.responses || {})[0] || ''}"
164
167
  exportparts = "btn:btn, btn-response-status:btn-response-status, btn-selected-response-status:btn-selected-response-status, btn-fill:btn-fill, btn-copy:btn-copy,
165
- schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
168
+ tab-panel:tab-panel, tab-btn:tab-btn, tab-btn-row:tab-btn-row, tab-coontent:tab-content,
169
+ schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
166
170
  > </api-response>
167
171
  </div>
168
172
  </div>
@@ -5,7 +5,7 @@ import { marked } from 'marked';
5
5
  // Templates
6
6
  import overviewTemplate from '~/templates/overview-template';
7
7
  import headerTemplate from '~/templates/header-template';
8
- import { schemaInObjectNotation, generateExample } from '~/utils/schema-utils';
8
+ import { schemaInObjectNotation, generateExample, standardizeExample } from '~/utils/schema-utils';
9
9
  import '~/components/json-tree';
10
10
  import '~/components/schema-tree';
11
11
  import SetTheme from '~/utils/theme';
@@ -49,7 +49,7 @@ function jsonSchemaBodyTemplate() {
49
49
  ${this.showInfo === 'true' ? overviewTemplate.call(this) : ''}
50
50
  <div style="font-size:var(--font-size-regular);">
51
51
  ${this.resolvedSpec.schemaAndExamples.map((jSchemaBody) => {
52
- const examplesObj = generateExample(jSchemaBody.schema, 'json', jSchemaBody.examples, jSchemaBody.example, true, false, 'json', true);
52
+ const examplesObj = generateExample(jSchemaBody.schema, 'json', standardizeExample(jSchemaBody.examples), standardizeExample(jSchemaBody.example), true, false, 'json', true);
53
53
  jSchemaBody.selectedExample = examplesObj[0]?.exampleId;
54
54
  return html`
55
55
  <section id='${jSchemaBody.elementId}' class='json-schema-and-example regular-font' style="display:flex; flex-direction: column; border:1px solid var(--border-color); margin-bottom:32px; border-top: 5px solid var(--border-color)">
@@ -99,7 +99,7 @@ function jsonSchemaBodyTemplate() {
99
99
 
100
100
  // Json Schema Root Template
101
101
  export default function jsonSchemaViewerTemplate(isMini = false) {
102
- // export default function jsonSchemaViewerTemplate(isMini = false, showExpandCollapse = true, showTags = true, pathsExpanded = false) {
102
+ // export default function jsonSchemaViewerTemplate(isMini = false, pathsExpanded = false) {
103
103
  if (!this.resolvedSpec) {
104
104
  return '';
105
105
  }
@@ -4,7 +4,7 @@ import { html } from 'lit';
4
4
  export default function logoTemplate(style) {
5
5
  return html`
6
6
  <div style=${style}>
7
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="1 0 511 512">
7
+ <svg viewBox="1 0 511 512">
8
8
  <path d="M351 411a202 202 0 01-350 0 203 203 0 01333-24 203 203 0 0117 24zm0 0" fill="#adc165"/>
9
9
  <path d="M334 387a202 202 0 01-216-69 202 202 0 01216 69zm78 32H85a8 8 0 01-8-8 8 8 0 018-8h327a8 8 0 017 8 8 8 0 01-7 8zm0 0" fill="#99aa52"/>
10
10
  <path d="M374 338l-5 30a202 202 0 01-248-248 203 203 0 01253 218zm0 0" fill="#ffc73b"/>
@@ -13,7 +13,7 @@ import advancedSearchTemplate from '~/templates/advance-search-template';
13
13
  import SetTheme from '~/utils/theme';
14
14
  import { isValidHexColor } from '~/utils/color-utils';
15
15
 
16
- export default function mainBodyTemplate(isMini = false, showExpandCollapse = true, showTags = true, pathsExpanded = false) {
16
+ export default function mainBodyTemplate(isMini = false, pathsExpanded = false) {
17
17
  if (!this.resolvedSpec) {
18
18
  return '';
19
19
  }
@@ -34,25 +34,14 @@ export default function mainBodyTemplate(isMini = false, showExpandCollapse = tr
34
34
  };
35
35
  /* eslint-disable indent */
36
36
  if (this.resolvedSpec.specLoadError) {
37
- if (isMini) {
38
- return html`
39
- ${this.theme === 'dark' ? SetTheme.call(this, 'dark', newTheme) : SetTheme.call(this, 'light', newTheme)}
40
- <div style='display:flex; align-items:center; border:1px dashed var(--border-color); height:42px; padding:5px; font-size:var(--font-size-small); color:var(--red); font-family:var(--font-mono)'> ${this.resolvedSpec.info.description} </div>
41
- `;
42
- }
43
37
  return html`
44
38
  ${this.theme === 'dark' ? SetTheme.call(this, 'dark', newTheme) : SetTheme.call(this, 'light', newTheme)}
45
- <!-- Header -->
46
- ${headerTemplate.call(this)}
47
- <main class='main-content regular-font' part='section-main-content'>
48
- <slot></slot>
49
- <div style='margin:24px; text-align: center;'>
50
- <h1 style='color: var(--red)'> ${this.resolvedSpec.info.title} </h1>
51
- <div style='font-family:var(--font-mono)'> ${this.resolvedSpec.info.description} </div>
52
- </div>
53
- </main>
39
+ <div id="spec-not-found" style='display:flex; align-items:center; justify-content: center; border:1px dashed var(--border-color); height:42px; padding:5px; font-size:var(--font-size-small); color:var(--red); font-family:var(--font-mono)'>
40
+ ${this.resolvedSpec.info.description}
41
+ </div>
54
42
  `;
55
43
  }
44
+
56
45
  if (this.resolvedSpec.isSpecLoading) {
57
46
  return html`
58
47
  ${this.theme === 'dark' ? SetTheme.call(this, 'dark', newTheme) : SetTheme.call(this, 'light', newTheme)}
@@ -104,7 +93,7 @@ export default function mainBodyTemplate(isMini = false, showExpandCollapse = tr
104
93
  </div>
105
94
  ${this.renderStyle === 'read'
106
95
  ? expandedEndpointTemplate.call(this)
107
- : endpointTemplate.call(this, showExpandCollapse, showTags, pathsExpanded)
96
+ : endpointTemplate.call(this, isMini, pathsExpanded)
108
97
  }
109
98
  `
110
99
  }
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit';
2
2
  import { marked } from 'marked';
3
- import { pathIsInSearch } from '~/utils/common-utils';
3
+ import { getMatchedPaths } from '~/utils/common-utils';
4
4
 
5
5
  export function expandCollapseNavBarTag(navLinkEl, action = 'toggle') {
6
6
  const tagAndPathEl = navLinkEl?.closest('.nav-bar-tag-and-paths');
@@ -82,7 +82,7 @@ export default function navbarTemplate() {
82
82
  >
83
83
  <div style='margin: 6px 5px 0 -24px; font-size:var(--font-size-regular); cursor:pointer;'>&#x21a9;</div>
84
84
  </div>
85
- ${this.matchPaths
85
+ ${this.searchVal
86
86
  ? html`
87
87
  <button @click = '${this.onClearSearch}' class='m-btn thin-border' style='margin-left:5px; color:var(--nav-text-color); width:75px; padding:6px 8px;' part='btn btn-outline btn-clear-filter'>
88
88
  CLEAR
@@ -91,7 +91,7 @@ export default function navbarTemplate() {
91
91
  }
92
92
  `
93
93
  }
94
- ${this.allowAdvancedSearch === 'false' || this.matchPaths
94
+ ${this.allowAdvancedSearch === 'false' || this.searchVal
95
95
  ? ''
96
96
  : html`
97
97
  <button class='m-btn primary' part='btn btn-fill btn-search' style='margin-left:5px; padding:6px 8px; width:75px' @click='${this.onShowSearchModalClicked}'>
@@ -166,7 +166,7 @@ export default function navbarTemplate() {
166
166
 
167
167
  <!-- TAGS AND PATHS-->
168
168
  ${this.resolvedSpec.tags
169
- .filter((tag) => tag.paths.filter((path) => pathIsInSearch(this.matchPaths, path, this.matchType)).length)
169
+ .filter((tag) => tag.paths.filter((path) => getMatchedPaths(this.searchVal, path, tag.name)).length)
170
170
  .map((tag) => html`
171
171
  <div class='nav-bar-tag-and-paths ${(this.renderStyle === 'read' ? 'expanded' : (tag.expanded ? 'expanded' : 'collapsed'))}' >
172
172
  ${tag.name === 'General ⦂'
@@ -208,8 +208,8 @@ export default function navbarTemplate() {
208
208
  <div class='nav-bar-paths-under-tag' style='max-height:${(tag.expanded || this.renderStyle === 'read') ? ((tag.paths?.length || 1) * 50) : 0}px;'>
209
209
  <!-- Paths in each tag (endpoints) -->
210
210
  ${tag.paths.filter((v) => {
211
- if (this.matchPaths) {
212
- return pathIsInSearch(this.matchPaths, v, this.matchType);
211
+ if (this.searchVal) {
212
+ return getMatchedPaths(this.searchVal, v, tag.name);
213
213
  }
214
214
  return true;
215
215
  }).map((p) => html`
@@ -134,7 +134,7 @@ async function fetchAccessToken(tokenUrl, clientId, clientSecret, redirectUrl, g
134
134
  }
135
135
  return false;
136
136
  }
137
- } catch (err) {
137
+ } catch {
138
138
  if (respDisplayEl) {
139
139
  respDisplayEl.innerHTML = '<span style="color:var(--red)">Failed to get access token</span>';
140
140
  }
@@ -261,7 +261,7 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
261
261
  const pkceOnly = authFlow['x-pkce-only'] || false;
262
262
  const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0);
263
263
  // Calculcate base URL
264
- const url = new URL(this.selectedServer.computedUrl);
264
+ const url = new URL(this.selectedServer?.computedUrl);
265
265
  const baseUrl = url.origin;
266
266
 
267
267
  if (refreshUrl && !isUrlAbsolute(refreshUrl)) {
@@ -322,8 +322,8 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
322
322
  ${flowName === 'password'
323
323
  ? html`
324
324
  <div style="margin:5px 0">
325
- <input type="text" value = "" placeholder="username" spellcheck="false" class="oauth2 ${flowName} ${securitySchemeId} api-key-user" part="textbox textbox-username">
326
- <input type="password" value = "" placeholder="password" spellcheck="false" class="oauth2 ${flowName} ${securitySchemeId} api-key-password" style = "margin:0 5px;" part="textbox textbox-password">
325
+ <input type="text" value = "" placeholder="username" spellcheck="false" class="oauth2 ${flowName} ${securitySchemeId} api-key-user" part="textbox textbox-username" id="input-${securitySchemeId}-${flowName}-api-key-user">
326
+ <input type="password" value = "" placeholder="password" spellcheck="false" class="oauth2 ${flowName} ${securitySchemeId} api-key-password" style = "margin:0 5px;" part="textbox textbox-password" id="input-${securitySchemeId}-${flowName}-api-key-password">
327
327
  </div>`
328
328
  : ''
329
329
  }
@@ -343,6 +343,7 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
343
343
  ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'password'
344
344
  ? html`
345
345
  <input
346
+ id="${securitySchemeId}-${flowName}-oauth-client-secret"
346
347
  type="password" part="textbox textbox-auth-client-secret"
347
348
  value = "${clientSecret || ''}" placeholder="client-secret" spellcheck="false"
348
349
  class="oauth2 ${flowName} ${securitySchemeId}
@@ -407,7 +408,9 @@ export default function securitySchemeTemplate() {
407
408
  ${this.resolvedSpec.securitySchemes && this.resolvedSpec.securitySchemes.length > 0
408
409
  ? html`
409
410
  <table role="presentation" id="auth-table" class='m-table padded-12' style="width:100%;">
410
- ${this.resolvedSpec.securitySchemes.map((v) => html`
411
+ ${this.resolvedSpec.securitySchemes
412
+ .filter((v) => v.type)
413
+ .map((v) => html`
411
414
  <tr id="security-scheme-${v.securitySchemeId}" class="${v.type.toLowerCase()}">
412
415
  <td style="max-width:500px; overflow-wrap: break-word;">
413
416
  <div style="line-height:28px; margin-bottom:5px;">
@@ -428,7 +431,7 @@ export default function securitySchemeTemplate() {
428
431
  : ''
429
432
  }
430
433
 
431
- ${(v.type.toLowerCase() === 'apikey') || (v.type.toLowerCase() === 'http' && v.scheme.toLowerCase() === 'bearer')
434
+ ${(v.type.toLowerCase() === 'apikey') || (v.type.toLowerCase() === 'http' && v.scheme?.toLowerCase() === 'bearer')
432
435
  ? html`
433
436
  <div style="margin-bottom:5px">
434
437
  ${v.type.toLowerCase() === 'apikey'
@@ -439,7 +442,7 @@ export default function securitySchemeTemplate() {
439
442
  <div style="max-height:28px;">
440
443
  ${v.in !== 'cookie'
441
444
  ? html`
442
- <input type = "text" value = "${v.value}" class="${v.type} ${v.securitySchemeId} api-key-input" placeholder = "api-token" spellcheck = "false">
445
+ <input type = "text" value = "${v.value}" class="${v.type} ${v.securitySchemeId} api-key-input" placeholder = "api-token" spellcheck = "false" id = "${v.type}-${v.securitySchemeId}-api-key-input">
443
446
  <button class="m-btn thin-border" style = "margin-left:5px;"
444
447
  part = "btn btn-outline"
445
448
  @click="${(e) => { onApiKeyChange.call(this, v.securitySchemeId, e); }}">
@@ -450,14 +453,14 @@ export default function securitySchemeTemplate() {
450
453
  </div>`
451
454
  : ''
452
455
  }
453
- ${v.type.toLowerCase() === 'http' && v.scheme.toLowerCase() === 'basic'
456
+ ${v.type.toLowerCase() === 'http' && v.scheme?.toLowerCase() === 'basic'
454
457
  ? html`
455
458
  <div style="margin-bottom:5px">
456
459
  Send <code>Authorization</code> in <code>header</code> containing the word <code>Basic</code> followed by a space and a base64 encoded string of <code>username:password</code>.
457
460
  </div>
458
461
  <div>
459
- <input type="text" value = "${v.user}" placeholder="username" spellcheck="false" class="${v.type} ${v.securitySchemeId} api-key-user" style="width:100px">
460
- <input type="password" value = "${v.password}" placeholder="password" spellcheck="false" class="${v.type} ${v.securitySchemeId} api-key-password" style = "width:100px; margin:0 5px;">
462
+ <input type="text" value = "${v.user}" placeholder="username" spellcheck="false" class="${v.type} ${v.securitySchemeId} api-key-user" style="width:100px" id = "input-${v.type}-${v.securitySchemeId}-api-key-user">
463
+ <input type="password" value = "${v.password}" placeholder="password" spellcheck="false" class="${v.type} ${v.securitySchemeId} api-key-password" style = "width:100px; margin:0 5px;" id = "input-${v.type}-${v.securitySchemeId}-api-key-password">
461
464
  <button class="m-btn thin-border"
462
465
  @click="${(e) => { onApiKeyChange.call(this, v.securitySchemeId, e); }}"
463
466
  part = "btn btn-outline"
@@ -600,6 +603,7 @@ export function pathSecurityTemplate(pathSecurity) {
600
603
  `)
601
604
  }
602
605
  </div>
606
+ </div>
603
607
  `;
604
608
  }
605
609
  return '';
@@ -49,17 +49,13 @@ export async function wait(ms) {
49
49
  });
50
50
  }
51
51
 
52
- export function componentIsInSearch(searchVal, component) {
52
+ export function getMatchedComponents(searchVal, component) {
53
53
  return component.name.toLowerCase().includes(searchVal.toLowerCase());
54
54
  }
55
55
 
56
- export function pathIsInSearch(searchVal, path, matchType = 'includes') {
57
- if (matchType === 'includes') {
58
- const stringToSearch = `${path.method} ${path.path} ${path.summary || ''} ${path.description || ''} ${path.operationId || ''}`.toLowerCase();
59
- return stringToSearch.includes(searchVal.toLowerCase());
60
- }
61
- const regex = new RegExp(searchVal, 'i');
62
- return regex.test(`${path.method} ${path.path}`);
56
+ export function getMatchedPaths(searchVal, path, tagName = '') {
57
+ const stringToSearch = `${path.method} ${path.path} ${path.summary || ''} ${path.description || ''} ${path.operationId || ''} ${tagName}`.toLowerCase();
58
+ return stringToSearch.includes(searchVal.toLowerCase());
63
59
  }
64
60
 
65
61
  export function schemaKeys(schemaProps, result = new Set()) {
@@ -90,7 +86,7 @@ export function advancedSearch(searchVal, allSpecTags, searchOptions = []) {
90
86
  stringToSearch = path.path;
91
87
  }
92
88
  if (searchOptions.includes('search-api-descr')) {
93
- stringToSearch = `${stringToSearch} ${path.summary || path.description || ''}`;
89
+ stringToSearch = `${stringToSearch} ${(path.summary || '') + (path.description || '')}`;
94
90
  }
95
91
  if (searchOptions.includes('search-api-params')) {
96
92
  stringToSearch = `${stringToSearch} ${path.parameters?.map((v) => v.name).join(' ') || ''}`;