openapi-explorer 2.1.647 → 2.1.650

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.
@@ -496,7 +496,9 @@ export default class ApiRequest extends LitElement {
496
496
  const requestBodyContainerEl = requestPanelEl.querySelector('.request-body-container');
497
497
  let pathUrl = `${this.serverUrl.replace(/\/$/, '')}${this.path.replaceAll(' ', '')}`; // Generate URL using Path Params
498
498
 
499
+ const pathParameterMap = {};
499
500
  pathParamEls.map(el => {
501
+ pathParameterMap[el.dataset.pname] = el.value;
500
502
  pathUrl = pathUrl.replace(`{${el.dataset.pname}}`, encodeURIComponent(el.value) || '-');
501
503
  }); // Handle relative serverUrls
502
504
 
@@ -511,15 +513,18 @@ export default class ApiRequest extends LitElement {
511
513
  headers: new Headers()
512
514
  }; // Query Params
513
515
 
516
+ const queryParameterMap = {};
514
517
  queryParamEls.forEach(el => {
515
518
  if (!el.dataset.array || el.dataset.array === 'false') {
516
519
  if (el.value !== '') {
520
+ queryParameterMap[el.dataset.pname] = el.value;
517
521
  fetchUrl.searchParams.append(el.dataset.pname, el.value);
518
522
  }
519
523
  } else {
520
524
  const paramSerializeStyle = el.dataset.paramSerializeStyle;
521
525
  const paramSerializeExplode = el.dataset.paramSerializeExplode;
522
526
  const values = Array.isArray(el.value) ? el.value.filter(v => v !== '') : [];
527
+ queryParameterMap[el.dataset.pname] = values;
523
528
 
524
529
  if (values.length > 0) {
525
530
  if (paramSerializeStyle === 'spaceDelimited') {
@@ -727,6 +732,8 @@ export default class ApiRequest extends LitElement {
727
732
  return {
728
733
  fetchOptions,
729
734
  fetchUrl,
735
+ path: pathParameterMap,
736
+ query: queryParameterMap,
730
737
  curlParts: {
731
738
  data: curlData,
732
739
  form: curlForm
@@ -752,7 +759,9 @@ export default class ApiRequest extends LitElement {
752
759
  const tryBtnEl = this.querySelectorAll('.btn-execute')[0];
753
760
  const {
754
761
  fetchOptions,
755
- fetchUrl
762
+ fetchUrl,
763
+ path,
764
+ query
756
765
  } = this.recomputeFetchOptions();
757
766
  this.responseIsBlob = false;
758
767
  this.respContentDisposition = '';
@@ -766,6 +775,8 @@ export default class ApiRequest extends LitElement {
766
775
  const fetchRequest = {
767
776
  explorerLocation: this.elementId,
768
777
  url: fetchUrl.toString(),
778
+ path,
779
+ query,
769
780
  options: fetchOptions,
770
781
  ...fetchOptions
771
782
  };
@@ -1,4 +1,4 @@
1
1
  import { css } from 'lit';
2
2
  /* eslint-disable max-len */
3
3
 
4
- export default css`.m-btn{border-radius:var(--border-radius);font-weight:600;display:inline-block;padding:6px 16px;font-size:var(--font-size-small);outline:0;line-height:1;text-align:center;white-space:nowrap;border:2px solid var(--primary-color);background-color:transparent;transition:background-color .2s;user-select:none;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.m-btn.primary{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.outline-primary{color:var(--primary-color);background-color:var(--bg);border:1px solid var(--bg)}.m-btn.outline-primary:hover{border:1px solid var(--bg)}.m-btn.thin-border{border-width:1px}.m-btn.large{padding:8px 14px}.m-btn.small{padding:5px 12px}.m-btn.tiny{padding:5px 6px}.m-btn.circle{border-radius:50%}.m-btn:hover{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.nav{border:2px solid var(--secondary-color)}.m-btn.nav:hover{background-color:var(--secondary-color)}.m-btn:disabled{background-color:var(--bg3);color:var(--fg3);border-color:var(--fg3);cursor:progress;opacity:.4}button,input,select,textarea{color:var(--fg);outline:0;background-color:var(--input-bg);border:1px solid var(--border-color);border-radius:var(--border-radius)}button{font-family:var(--font-regular)}input[type=file],input[type=password],input[type=text],select,textarea{font-family:var(--font-regular);font-weight:400;font-size:var(--font-size-small);transition:border .2s;padding:6px 5px}select{font-family:var(--font-regular);padding-right:30px;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%3E%3Cpath%20d%3D%22M10.3%203.3L6%207.6%201.7%203.3A1%201%200%2000.3%204.7l5%205a1%201%200%20001.4%200l5-5a1%201%200%2010-1.4-1.4z%22%20fill%3D%22%23777777%22%2F%3E%3C%2Fsvg%3E");background-position:calc(100% - 5px) center;background-repeat:no-repeat;background-size:10px;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}select:hover{border-color:var(--primary-color)}input[type=password]::placeholder,input[type=text]::placeholder,textarea::placeholder{color:var(--placeholder-color);opacity:1}input[type=password]:active,input[type=password]:focus,input[type=text]:active,input[type=text]:focus,select:focus,textarea:active,textarea:focus{border:1px solid var(--primary-color)}input[type=file]{font-family:var(--font-regular);padding:2px;cursor:pointer;border:1px solid var(--primary-color);min-height:calc(var(--font-size-small) + 18px)}input[type=file]::-webkit-file-upload-button{font-family:var(--font-regular);font-size:var(--font-size-small);outline:0;cursor:pointer;padding:3px 8px;border:1px solid var(--primary-color);background-color:var(--primary-color);color:var(--primary-btn-text-color);border-radius:var(--border-radius);-webkit-appearance:none}pre,textarea{scrollbar-width:thin;scrollbar-color:var(--border-color) var(--input-bg)}pre::-webkit-scrollbar,textarea::-webkit-scrollbar{width:8px;height:8px}pre::-webkit-scrollbar-track,textarea::-webkit-scrollbar-track{background:var(--input-bg)}pre::-webkit-scrollbar-thumb,textarea::-webkit-scrollbar-thumb{border-radius:2px;background-color:var(--border-color)}.link{font-size:var(--font-size-small);text-decoration:underline;color:var(--blue);font-family:var(--font-mono);margin-bottom:2px}input[type=checkbox]:focus{outline:0}input[type=checkbox]{appearance:none;display:inline-block;background-color:var(--light-bg);border-radius:9px;cursor:pointer;height:18px;position:relative;transition:border .15s,padding .25s;min-width:36px;width:36px;vertical-align:top}input[type=checkbox]:after{position:absolute;background-color:var(--bg);border-radius:8px;content:'';top:0;left:0;right:16px;display:block;height:16px;transition:left .25s .1s,right .15s .175s}input[type=checkbox]:checked{box-shadow:inset 0 0 0 13px var(--primary-color);border-color:var(--primary-color)}input[type=checkbox]:checked:after{border:1px solid var(--primary-color);left:16px;right:1px;transition:border .25s,left .15s .25s,right .25s .175s}input.oauth-client-id{flex-grow:1;max-width:300px}input.oauth-client-secret{flex-grow:1;max-width:300px}`;
4
+ export default css`.m-btn{border-radius:var(--border-radius);font-weight:600;display:inline-block;padding:6px 16px;font-size:var(--font-size-small);outline:0;line-height:1;text-align:center;white-space:nowrap;border:2px solid var(--primary-color);background-color:transparent;transition:background-color .2s;user-select:none;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.m-btn.primary{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.outline-primary{color:var(--primary-color);background-color:var(--bg);border:1px solid var(--bg)}.m-btn.outline-primary:hover{border:1px solid var(--bg)}.m-btn.thin-border{border-width:1px}.m-btn.large{padding:8px 14px}.m-btn.small{padding:5px 12px}.m-btn.tiny{padding:5px 6px}.m-btn.circle{border-radius:50%}.m-btn:hover{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.nav{border:2px solid var(--secondary-color)}.m-btn.nav:hover{background-color:var(--secondary-color)}.m-btn:disabled{background-color:var(--bg3);color:var(--fg3);border-color:var(--fg3);cursor:progress;opacity:.4}button,input,select,textarea{color:var(--fg);outline:0;background-color:var(--input-bg);border:1px solid var(--border-color);border-radius:var(--border-radius)}button{font-family:var(--font-regular)}input[type=file],input[type=password],input[type=text],select,textarea{font-family:var(--font-regular);font-weight:400;font-size:var(--font-size-small);transition:border .2s;padding:6px 5px}select{font-family:var(--font-regular);padding-right:30px;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%3E%3Cpath%20d%3D%22M10.3%203.3L6%207.6%201.7%203.3A1%201%200%2000.3%204.7l5%205a1%201%200%20001.4%200l5-5a1%201%200%2010-1.4-1.4z%22%20fill%3D%22%23777777%22%2F%3E%3C%2Fsvg%3E");background-position:calc(100% - 5px) center;background-repeat:no-repeat;background-size:10px;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}select:hover{border-color:var(--primary-color)}input[type=password]::placeholder,input[type=text]::placeholder,textarea::placeholder{color:var(--placeholder-color);opacity:1}input[type=password]:active,input[type=password]:focus,input[type=text]:active,input[type=text]:focus,select:focus,textarea:active,textarea:focus{border:1px solid var(--primary-color)}input[type=file]{font-family:var(--font-regular);padding:2px;cursor:pointer;border:1px solid var(--primary-color);min-height:calc(var(--font-size-small) + 18px)}input[type=file]::-webkit-file-upload-button{font-family:var(--font-regular);font-size:var(--font-size-small);outline:0;cursor:pointer;padding:3px 8px;border:1px solid var(--primary-color);background-color:var(--primary-color);color:var(--primary-btn-text-color);border-radius:var(--border-radius);-webkit-appearance:none}pre,textarea{scrollbar-width:thin;scrollbar-color:var(--border-color) var(--input-bg)}pre::-webkit-scrollbar,textarea::-webkit-scrollbar{width:8px;height:8px}pre::-webkit-scrollbar-track,textarea::-webkit-scrollbar-track{background:var(--input-bg)}pre::-webkit-scrollbar-thumb,textarea::-webkit-scrollbar-thumb{border-radius:2px;background-color:var(--border-color)}.link{font-size:var(--font-size-small);text-decoration:underline;color:var(--blue);font-family:var(--font-mono);margin-bottom:2px}input[type=checkbox]:focus{outline:0}input[type=checkbox]{appearance:none;display:inline-block;background-color:var(--light-bg);border-radius:9px;cursor:pointer;height:18px;position:relative;transition:border .15s,padding .25s;min-width:36px;width:36px;vertical-align:top}input[type=checkbox]:after{position:absolute;background-color:var(--bg);border-radius:8px;content:'';top:0;left:0;right:16px;display:block;height:16px;transition:left .25s .1s,right .15s .175s}input[type=checkbox]:checked{box-shadow:inset 0 0 0 13px var(--primary-color);border-color:var(--primary-color)}input[type=checkbox]:checked:after{border:1px solid var(--primary-color);left:16px;right:1px;transition:border .25s,left .15s .25s,right .25s .175s}.oauth-client-input{display:flex;align-items:center;flex-grow:1;width:300px;max-width:300px;margin-top:1rem}input.oauth-client-secret{flex-grow:1;max-width:300px}`;
@@ -204,9 +204,9 @@ export async function checkForAuthToken(redirectToApiLocation) {
204
204
 
205
205
  async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) {
206
206
  const authFlowDivEl = e.target.closest('.oauth-flow');
207
- const clientId = authFlowDivEl.querySelector('.oauth-client-id') ? authFlowDivEl.querySelector('.oauth-client-id').value.trim() : '';
208
- const clientSecret = authFlowDivEl.querySelector('.oauth-client-secret') ? authFlowDivEl.querySelector('.oauth-client-secret').value.trim() : '';
209
- const sendClientSecretIn = authFlowDivEl.querySelector('.oauth-send-client-secret-in') ? authFlowDivEl.querySelector('.oauth-send-client-secret-in').value.trim() : 'header';
207
+ const clientId = authFlowDivEl.querySelector('#oauth-client-id') ? authFlowDivEl.querySelector('#oauth-client-id').value.trim() : '';
208
+ const clientSecret = authFlowDivEl.querySelector('#oauth-client-secret') ? authFlowDivEl.querySelector('#oauth-client-secret').value.trim() : '';
209
+ const sendClientSecretIn = authFlowDivEl.querySelector('#oauth-send-client-secret-in') ? authFlowDivEl.querySelector('#oauth-send-client-secret-in').value.trim() : 'header';
210
210
  const checkedScopeEls = [...authFlowDivEl.querySelectorAll('input[type="checkbox"]:checked')];
211
211
  const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId);
212
212
  let grantType = '';
@@ -294,9 +294,45 @@ function oAuthFlowTemplate(flowName, securityObj, authFlow) {
294
294
  flowNameDisplay = flowName;
295
295
  }
296
296
 
297
- return html` <div class="oauth-flow" style="padding:10px 0;margin-bottom:10px"> <div class="tiny-title upper" style="margin-bottom:5px">${flowNameDisplay}</div> ${authorizationUrl ? html`<div><span style="width:75px;display:inline-block">Auth URL</span> <span class="mono-font"> ${authorizationUrl} </span></div>` : ''} ${tokenUrl ? html`<div><span style="width:75px;display:inline-block">Token URL</span> <span class="mono-font">${tokenUrl}</span></div>` : ''} ${refreshUrl ? html`<div><span style="width:75px;display:inline-block">Refresh URL</span> <span class="mono-font">${refreshUrl}</span></div>` : ''} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? html` ${authFlow.scopes ? html` <span> Scopes </span> <div class="oauth-scopes" part="section-auth-scopes" style="width:100%;display:flex;flex-direction:column;flex-wrap:wrap;margin:0 0 .125rem 0"> ${Object.entries(authFlow.scopes).map((scopeAndDescr, index) => html` <div class="m-checkbox" style="display:inline-flex;align-items:center"> <input type="checkbox" checked="checked" part="checkbox checkbox-auth-scope" id="${flowName}${index}" value="${scopeAndDescr[0]}"> <label for="${flowName}${index}" style="margin-left:5px"> <span class="mono-font">${scopeAndDescr[0]}</span> ${scopeAndDescr[0] !== scopeAndDescr[1] ? ` - ${scopeAndDescr[1] || ''}` : ''} </label> </div> `)} </div> ` : ''} <div style="display:flex"> <input type="text" part="textbox textbox-auth-client-id" value="${securityObj.clientId || ''}" placeholder="Client ID" spellcheck="false" class="oauth-client-id"> ${flowName === 'clientCredentials' ? html` <input type="password" part="textbox textbox-auth-client-secret" value="" placeholder="Client Secret" spellcheck="false" class="oauth-client-secret" style="margin:0 5px"> <select aria-label="oauth client secret location" style="margin-right:5px" class="oauth-send-client-secret-in"> <option value="header" selected="selected"> Authorization Header </option> <option value="request-body"> Request Body </option> </select>` : html`<div style="width:5px"></div>`} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? html` <button class="m-btn thin-border" part="btn btn-outline" @click="${e => {
297
+ return html` <div class="oauth-flow" style="padding:10px 0;margin-bottom:10px"> <div class="tiny-title upper" style="margin-bottom:5px">${flowNameDisplay}</div> ${authorizationUrl ? html`<div><span style="width:75px;display:inline-block">Auth URL</span> <span class="mono-font"> ${authorizationUrl} </span></div>` : ''} ${tokenUrl ? html`<div><span style="width:75px;display:inline-block">Token URL</span> <span class="mono-font">${tokenUrl}</span></div>` : ''} ${refreshUrl ? html`<div><span style="width:75px;display:inline-block">Refresh URL</span> <span class="mono-font">${refreshUrl}</span></div>` : ''} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? html` ${authFlow.scopes ? html` <span> Scopes </span> <div class="oauth-scopes" part="section-auth-scopes" style="width:100%;display:flex;flex-direction:column;flex-wrap:wrap;margin:0 0 .125rem 0"> ${Object.entries(authFlow.scopes).map((scopeAndDescr, index) => html` <div class="m-checkbox" style="display:inline-flex;align-items:center"> <input type="checkbox" checked="checked" part="checkbox checkbox-auth-scope" id="${flowName}${index}" value="${scopeAndDescr[0]}"> <label for="${flowName}${index}" style="margin-left:5px"> <span class="mono-font">${scopeAndDescr[0]}</span> ${scopeAndDescr[0] !== scopeAndDescr[1] ? ` - ${scopeAndDescr[1] || ''}` : ''} </label> </div> `)} </div> ` : ''} <div style="display:flex"> <div> <input id="oauth-client-id" type="text" part="textbox textbox-auth-client-id" value="${securityObj.clientId || ''}" placeholder="Client ID" spellcheck="false" class="oauth-client-input"> ${flowName === 'clientCredentials' ? html` <input id="oauth-client-secret" type="password" part="textbox textbox-auth-client-secret" value="" placeholder="Client Secret" spellcheck="false" class="oauth-client-input"> <select id="oauth-send-client-secret-in" aria-label="oauth client secret location" style="margin-right:5px" class="oauth-client-input"> <option value="header" selected="selected"> Authorization Header </option> <option value="request-body"> Request Body </option> </select> ` : html`<div style="width:5px"></div>`} </div> ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? html` <div class="oauth-client-input" style="margin-left:1rem"> <button class="m-btn thin-border" part="btn btn-outline" @click="${e => {
298
298
  onInvokeOAuthFlow.call(this, apiKeyId, flowName, authorizationUrl, tokenUrl, e);
299
- }}">GET TOKEN</button>` : ''} </div> <div class="oauth-resp-display red-text small-font-size"></div> ` : ''} </div> `;
299
+ }}">GET TOKEN</button> </div>` : ''} </div> <div class="oauth-resp-display red-text small-font-size"></div> ` : ''} </div> `;
300
+ }
301
+
302
+ function renderSecurityScheme(v) {
303
+ if (!v.type) {
304
+ return '';
305
+ }
306
+
307
+ if (v.type.toLowerCase() === 'apikey' || v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'bearer') {
308
+ var _v$bearerFormat, _v$bearerFormat2;
309
+
310
+ return html` <div style="padding-top:1rem"> ${v.type.toLowerCase() === 'apikey' ? html`Send <code>${v.name || 'API key'}</code> in <code>${v.in || 'the request'}</code> with the given value:` : html`Send <code>Authorization</code> in <code>header</code> containing the word <code>Bearer</code> followed by a space and then the ${(_v$bearerFormat = v.bearerFormat) !== null && _v$bearerFormat !== void 0 ? _v$bearerFormat : 'Token String'}.`} </div> <form style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> ${v.in === 'cookie' ? html` <div style="display:block"> <input type="text" value="${getCookieValue(v.apiKeyId)}" disabled="disabled" class="api-key-input" placeholder="IygRVGf54B59e0GAkKmigGfuiVlp/uhFfk2ifA+jMMJzau2F1jPldc09gPTfnMw13BFBxqUZIFDm55DPfwkb0A==" spellcheck="false" style="resize:horizontal;width:100%"> <br> <small> <strong>Cookies</strong>&nbsp;are set and configured by the remote service, therefore it is not possible to configure them from the browser. </small> </div>` : !v.finalKeyValue ? html` <input type="text" value="${v.value}" placeholder="${(_v$bearerFormat2 = v.bearerFormat) !== null && _v$bearerFormat2 !== void 0 ? _v$bearerFormat2 : 'api-token'}" spellcheck="false" class="api-key-input fs-exclude" data-hj-suppress data-sl="mask"> <button type="submit" class="m-btn thin-border" style="margin-left:5px" part="btn btn-outline" @click="${e => {
311
+ onApiKeyChange.call(this, v.apiKeyId, e);
312
+ }}"> ${getI18nText('authentication.set')} </button>` : html`<span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
313
+ v.finalKeyValue = '';
314
+ this.requestUpdate();
315
+ }}">REMOVE</button>`} </form>`;
316
+ }
317
+
318
+ if (v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic') {
319
+ if (v.finalKeyValue) {
320
+ return html` <div style="padding-top:1rem">${getI18nText('authentication.http-basic-desc')}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
321
+ v.finalKeyValue = '';
322
+ this.requestUpdate();
323
+ }}">REMOVE</button> </div>`;
324
+ }
325
+
326
+ return html` <div style="padding-top:1rem">${getI18nText('authentication.http-basic-desc')}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <form style="display:flex"> <input type="text" value="${v.user}" placeholder="${getI18nText('authentication.username')}" spellcheck="false" class="api-key-user" style="width:100px"> <input class="api-key-password fs-exclude" data-hj-suppress data-sl="mask" type="password" value="${v.password}" placeholder="${getI18nText('authentication.password')}" spellcheck="false" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => {
327
+ onApiKeyChange.call(this, v.apiKeyId, e);
328
+ }}" part="btn btn-outline"> ${v.finalKeyValue ? 'UPDATE' : getI18nText('authentication.set')} </button> </form> </div>`;
329
+ }
330
+
331
+ if (v.type.toLowerCase() === 'oauth2' && Object.keys(v.flows).length) {
332
+ return html`${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))}`;
333
+ }
334
+
335
+ return '';
300
336
  }
301
337
 
302
338
  export default function securitySchemeTemplate() {
@@ -307,20 +343,9 @@ export default function securitySchemeTemplate() {
307
343
  }
308
344
 
309
345
  const providedApiKeys = schemes.filter(v => v.finalKeyValue);
310
- return html` <section id="auth" part="section-auth" class="observe-me ${this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}"> <slot name="authentication"> <div class="section-padding"> <slot name="authentication-header"> <div class="sub-title regular-font">${getI18nText('headers.authentication')}</div> </slot> <div class="small-font-size" style="display:flex;align-items:center;min-height:30px"> ${providedApiKeys.length > 0 ? html` <div class="blue-text"> ${providedApiKeys.length} API key applied </div> <div style="flex:1"></div> <button class="m-btn thin-border" part="btn btn-outline" @click="${() => {
346
+ return html` <section id="auth" part="section-auth" class="observe-me ${this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}"> <slot name="authentication"> <div class="section-padding"> <slot name="authentication-header"> <div class="sub-title regular-font">${getI18nText('headers.authentication')}</div> </slot> <div class="small-font-size" style="display:flex;align-items:center;min-height:40px"> ${providedApiKeys.length > 0 ? html` <div class="blue-text"> ${providedApiKeys.length} API key applied </div> <div style="flex:1"></div> <button class="m-btn thin-border" part="btn btn-outline" @click="${() => {
311
347
  onClearAllApiKeys.call(this);
312
- }}">CLEAR ALL API KEYS</button>` : html`<div class="red-text">${getI18nText('authentication.no-api-key-applied')}</div>`} </div> ${schemes.length > 0 ? html` <table role="presentation" class="m-table" style="width:100%"> ${schemes.map(v => {
313
- var _v$bearerFormat, _v$bearerFormat2;
314
-
315
- return html` <tr> <td colspan="1" style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px"> <span style="font-weight:700">${v.typeDisplay}</span> ${v.finalKeyValue ? html` <span class="blue-text"> ${v.finalKeyValue ? 'Key Applied' : ''} </span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
316
- v.finalKeyValue = '';
317
- this.requestUpdate();
318
- }}">REMOVE</button> ` : ''} </div> ${v.description ? html` <div class="m-markdown"> ${unsafeHTML(marked(v.description || ''))} </div>` : ''} </td> <td colspan="3"> ${v.type && (v.type.toLowerCase() === 'apikey' || v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'bearer') ? html` ${v.type.toLowerCase() === 'apikey' ? html`Send <code>${v.name}</code> in <code>${v.in}</code> with the given value:` : html`Send <code>Authorization</code> in <code>header</code> containing the word <code>Bearer</code> followed by a space and then the ${(_v$bearerFormat = v.bearerFormat) !== null && _v$bearerFormat !== void 0 ? _v$bearerFormat : 'Token String'}.`} <form style="display:flex"> ${v.in === 'cookie' ? html` <div style="display:block"> <input type="text" value="${getCookieValue(v.apiKeyId)}" disabled="disabled" class="api-key-input" placeholder="IygRVGf54B59e0GAkKmigGfuiVlp/uhFfk2ifA+jMMJzau2F1jPldc09gPTfnMw13BFBxqUZIFDm55DPfwkb0A==" spellcheck="false" style="resize:horizontal;width:100%"> <br> <small> <strong>Cookies</strong>&nbsp;are set and configured by the remote service, therefore it is not possible to configure them from the browser. </small> </div>` : html` <input type="text" value="${v.value}" placeholder="${(_v$bearerFormat2 = v.bearerFormat) !== null && _v$bearerFormat2 !== void 0 ? _v$bearerFormat2 : 'api-token'}" spellcheck="false" class="api-key-input fs-exclude" data-hj-suppress data-sl="mask"> <button type="submit" class="m-btn thin-border" style="margin-left:5px" part="btn btn-outline" @click="${e => {
319
- onApiKeyChange.call(this, v.apiKeyId, e);
320
- }}"> ${v.finalKeyValue ? 'UPDATE' : 'SET'} </button>`} </form>` : ''} ${v.type && v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic' ? html` ${getI18nText('authentication.http-basic-desc')} <form style="display:flex"> <input type="text" value="${v.user}" placeholder="${getI18nText('authentication.username')}" spellcheck="false" class="api-key-user" style="width:100px"> <input class="api-key-password fs-exclude" data-hj-suppress data-sl="mask" type="password" value="${v.password}" placeholder="${getI18nText('authentication.password')}" spellcheck="false" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => {
321
- onApiKeyChange.call(this, v.apiKeyId, e);
322
- }}" part="btn btn-outline"> ${v.finalKeyValue ? 'UPDATE' : getI18nText('authentication.set')} </button> </form>` : ''} </td> </tr> ${v.type.toLowerCase() === 'oauth2' ? html` <tr> <td colspan="2" style="border:none;padding-left:48px"> ${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))} </td> </tr> ` : ''} `;
323
- })} </table>` : ''} <slot name="authentication-footer"></slot> </div> </slot> </section> `;
348
+ }}">CLEAR ALL API KEYS</button>` : html`<div class="red-text">${getI18nText('authentication.no-api-key-applied')}</div>`} </div> ${schemes.length > 0 ? html` <table role="presentation" class="m-table" style="width:100%"> ${schemes.map(v => html` <tr> <td colspan="1" style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px;display:flex;flex-direction:column;justify-content:center;align-items:center"> <div style="display:flex;justify-content:center"> <span style="font-weight:700">${getTypeDisplayHeader(v)}</span> </div> </div> ${v.description ? html` <div class="m-markdown"> ${unsafeHTML(marked(v.description || ''))} </div>` : ''} </td> <td colspan="3">${renderSecurityScheme.call(this, v)}</td> </tr>`)} </table>` : ''} <slot name="authentication-footer"></slot> </div> </slot> </section> `;
324
349
  }
325
350
 
326
351
  function getOauthScopeTemplate(rawScopes) {
@@ -333,6 +358,22 @@ function getOauthScopeTemplate(rawScopes) {
333
358
  return html` <div> <b>Required scopes:</b> <br> <div style="margin-left:8px"> ${scopes.map(scope => html`<span>${scope}</span>&nbsp;`)} </div> </div>`;
334
359
  }
335
360
 
361
+ function getTypeDisplayHeader(securityScheme) {
362
+ if (securityScheme.type === 'apiKey') {
363
+ return `API Key (${securityScheme.name})`;
364
+ }
365
+
366
+ if (securityScheme.type === 'oauth2') {
367
+ return 'OAuth2.0';
368
+ }
369
+
370
+ if (securityScheme.type === 'http') {
371
+ return securityScheme.scheme === 'basic' ? getI18nText('authentication.http-basic') : 'HTTP Bearer';
372
+ }
373
+
374
+ return securityScheme.type;
375
+ }
376
+
336
377
  export function pathSecurityTemplate(pathSecurity) {
337
378
  if (this.resolvedSpec.securitySchemes && pathSecurity) {
338
379
  const orSecurityKeys1 = [];
@@ -343,7 +384,7 @@ export function pathSecurityTemplate(pathSecurity) {
343
384
  const s = this.resolvedSpec.securitySchemes.find(ss => ss.apiKeyId === pathSecurityKey);
344
385
 
345
386
  if (s) {
346
- andKeyTypes.push(s.typeDisplay);
387
+ andKeyTypes.push(getTypeDisplayHeader(s));
347
388
  andSecurityKeys1.push({ ...s,
348
389
  scopes: pSecurity[pathSecurityKey]
349
390
  });
@@ -51,20 +51,8 @@ export default async function ProcessSpec(specUrlOrObject, serverUrl = '') {
51
51
 
52
52
  securitySchemes.push(securityObj);
53
53
  });
54
- } // Updated Security Type Display Text based on Type
55
-
56
-
57
- securitySchemes.forEach(v => {
58
- if (v.type === 'http') {
59
- v.typeDisplay = v.scheme === 'basic' ? getI18nText('authentication.http-basic') : 'HTTP Bearer';
60
- } else if (v.type === 'apiKey') {
61
- v.typeDisplay = `API Key (${v.name})`;
62
- } else if (v.type === 'oauth2') {
63
- v.typeDisplay = 'OAuth2.0';
64
- } else {
65
- v.typeDisplay = v.type;
66
- }
67
- }); // Servers
54
+ } // Servers
55
+
68
56
 
69
57
  let servers = [];
70
58
 
@@ -516,7 +516,9 @@ class ApiRequest extends _lit.LitElement {
516
516
  const requestBodyContainerEl = requestPanelEl.querySelector('.request-body-container');
517
517
  let pathUrl = `${this.serverUrl.replace(/\/$/, '')}${this.path.replaceAll(' ', '')}`; // Generate URL using Path Params
518
518
 
519
+ const pathParameterMap = {};
519
520
  pathParamEls.map(el => {
521
+ pathParameterMap[el.dataset.pname] = el.value;
520
522
  pathUrl = pathUrl.replace(`{${el.dataset.pname}}`, encodeURIComponent(el.value) || '-');
521
523
  }); // Handle relative serverUrls
522
524
 
@@ -531,15 +533,18 @@ class ApiRequest extends _lit.LitElement {
531
533
  headers: new Headers()
532
534
  }; // Query Params
533
535
 
536
+ const queryParameterMap = {};
534
537
  queryParamEls.forEach(el => {
535
538
  if (!el.dataset.array || el.dataset.array === 'false') {
536
539
  if (el.value !== '') {
540
+ queryParameterMap[el.dataset.pname] = el.value;
537
541
  fetchUrl.searchParams.append(el.dataset.pname, el.value);
538
542
  }
539
543
  } else {
540
544
  const paramSerializeStyle = el.dataset.paramSerializeStyle;
541
545
  const paramSerializeExplode = el.dataset.paramSerializeExplode;
542
546
  const values = Array.isArray(el.value) ? el.value.filter(v => v !== '') : [];
547
+ queryParameterMap[el.dataset.pname] = values;
543
548
 
544
549
  if (values.length > 0) {
545
550
  if (paramSerializeStyle === 'spaceDelimited') {
@@ -747,6 +752,8 @@ class ApiRequest extends _lit.LitElement {
747
752
  return {
748
753
  fetchOptions,
749
754
  fetchUrl,
755
+ path: pathParameterMap,
756
+ query: queryParameterMap,
750
757
  curlParts: {
751
758
  data: curlData,
752
759
  form: curlForm
@@ -772,7 +779,9 @@ class ApiRequest extends _lit.LitElement {
772
779
  const tryBtnEl = this.querySelectorAll('.btn-execute')[0];
773
780
  const {
774
781
  fetchOptions,
775
- fetchUrl
782
+ fetchUrl,
783
+ path,
784
+ query
776
785
  } = this.recomputeFetchOptions();
777
786
  this.responseIsBlob = false;
778
787
  this.respContentDisposition = '';
@@ -786,6 +795,8 @@ class ApiRequest extends _lit.LitElement {
786
795
  const fetchRequest = {
787
796
  explorerLocation: this.elementId,
788
797
  url: fetchUrl.toString(),
798
+ path,
799
+ query,
789
800
  options: fetchOptions,
790
801
  ...fetchOptions
791
802
  };
@@ -6,6 +6,6 @@ exports.default = void 0;
6
6
  var _lit = require("lit");
7
7
 
8
8
  /* eslint-disable max-len */
9
- var _default = (0, _lit.css)`.m-btn{border-radius:var(--border-radius);font-weight:600;display:inline-block;padding:6px 16px;font-size:var(--font-size-small);outline:0;line-height:1;text-align:center;white-space:nowrap;border:2px solid var(--primary-color);background-color:transparent;transition:background-color .2s;user-select:none;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.m-btn.primary{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.outline-primary{color:var(--primary-color);background-color:var(--bg);border:1px solid var(--bg)}.m-btn.outline-primary:hover{border:1px solid var(--bg)}.m-btn.thin-border{border-width:1px}.m-btn.large{padding:8px 14px}.m-btn.small{padding:5px 12px}.m-btn.tiny{padding:5px 6px}.m-btn.circle{border-radius:50%}.m-btn:hover{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.nav{border:2px solid var(--secondary-color)}.m-btn.nav:hover{background-color:var(--secondary-color)}.m-btn:disabled{background-color:var(--bg3);color:var(--fg3);border-color:var(--fg3);cursor:progress;opacity:.4}button,input,select,textarea{color:var(--fg);outline:0;background-color:var(--input-bg);border:1px solid var(--border-color);border-radius:var(--border-radius)}button{font-family:var(--font-regular)}input[type=file],input[type=password],input[type=text],select,textarea{font-family:var(--font-regular);font-weight:400;font-size:var(--font-size-small);transition:border .2s;padding:6px 5px}select{font-family:var(--font-regular);padding-right:30px;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%3E%3Cpath%20d%3D%22M10.3%203.3L6%207.6%201.7%203.3A1%201%200%2000.3%204.7l5%205a1%201%200%20001.4%200l5-5a1%201%200%2010-1.4-1.4z%22%20fill%3D%22%23777777%22%2F%3E%3C%2Fsvg%3E");background-position:calc(100% - 5px) center;background-repeat:no-repeat;background-size:10px;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}select:hover{border-color:var(--primary-color)}input[type=password]::placeholder,input[type=text]::placeholder,textarea::placeholder{color:var(--placeholder-color);opacity:1}input[type=password]:active,input[type=password]:focus,input[type=text]:active,input[type=text]:focus,select:focus,textarea:active,textarea:focus{border:1px solid var(--primary-color)}input[type=file]{font-family:var(--font-regular);padding:2px;cursor:pointer;border:1px solid var(--primary-color);min-height:calc(var(--font-size-small) + 18px)}input[type=file]::-webkit-file-upload-button{font-family:var(--font-regular);font-size:var(--font-size-small);outline:0;cursor:pointer;padding:3px 8px;border:1px solid var(--primary-color);background-color:var(--primary-color);color:var(--primary-btn-text-color);border-radius:var(--border-radius);-webkit-appearance:none}pre,textarea{scrollbar-width:thin;scrollbar-color:var(--border-color) var(--input-bg)}pre::-webkit-scrollbar,textarea::-webkit-scrollbar{width:8px;height:8px}pre::-webkit-scrollbar-track,textarea::-webkit-scrollbar-track{background:var(--input-bg)}pre::-webkit-scrollbar-thumb,textarea::-webkit-scrollbar-thumb{border-radius:2px;background-color:var(--border-color)}.link{font-size:var(--font-size-small);text-decoration:underline;color:var(--blue);font-family:var(--font-mono);margin-bottom:2px}input[type=checkbox]:focus{outline:0}input[type=checkbox]{appearance:none;display:inline-block;background-color:var(--light-bg);border-radius:9px;cursor:pointer;height:18px;position:relative;transition:border .15s,padding .25s;min-width:36px;width:36px;vertical-align:top}input[type=checkbox]:after{position:absolute;background-color:var(--bg);border-radius:8px;content:'';top:0;left:0;right:16px;display:block;height:16px;transition:left .25s .1s,right .15s .175s}input[type=checkbox]:checked{box-shadow:inset 0 0 0 13px var(--primary-color);border-color:var(--primary-color)}input[type=checkbox]:checked:after{border:1px solid var(--primary-color);left:16px;right:1px;transition:border .25s,left .15s .25s,right .25s .175s}input.oauth-client-id{flex-grow:1;max-width:300px}input.oauth-client-secret{flex-grow:1;max-width:300px}`;
9
+ var _default = (0, _lit.css)`.m-btn{border-radius:var(--border-radius);font-weight:600;display:inline-block;padding:6px 16px;font-size:var(--font-size-small);outline:0;line-height:1;text-align:center;white-space:nowrap;border:2px solid var(--primary-color);background-color:transparent;transition:background-color .2s;user-select:none;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.m-btn.primary{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.outline-primary{color:var(--primary-color);background-color:var(--bg);border:1px solid var(--bg)}.m-btn.outline-primary:hover{border:1px solid var(--bg)}.m-btn.thin-border{border-width:1px}.m-btn.large{padding:8px 14px}.m-btn.small{padding:5px 12px}.m-btn.tiny{padding:5px 6px}.m-btn.circle{border-radius:50%}.m-btn:hover{background-color:var(--primary-color);color:var(--primary-btn-text-color)}.m-btn.nav{border:2px solid var(--secondary-color)}.m-btn.nav:hover{background-color:var(--secondary-color)}.m-btn:disabled{background-color:var(--bg3);color:var(--fg3);border-color:var(--fg3);cursor:progress;opacity:.4}button,input,select,textarea{color:var(--fg);outline:0;background-color:var(--input-bg);border:1px solid var(--border-color);border-radius:var(--border-radius)}button{font-family:var(--font-regular)}input[type=file],input[type=password],input[type=text],select,textarea{font-family:var(--font-regular);font-weight:400;font-size:var(--font-size-small);transition:border .2s;padding:6px 5px}select{font-family:var(--font-regular);padding-right:30px;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%3E%3Cpath%20d%3D%22M10.3%203.3L6%207.6%201.7%203.3A1%201%200%2000.3%204.7l5%205a1%201%200%20001.4%200l5-5a1%201%200%2010-1.4-1.4z%22%20fill%3D%22%23777777%22%2F%3E%3C%2Fsvg%3E");background-position:calc(100% - 5px) center;background-repeat:no-repeat;background-size:10px;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}select:hover{border-color:var(--primary-color)}input[type=password]::placeholder,input[type=text]::placeholder,textarea::placeholder{color:var(--placeholder-color);opacity:1}input[type=password]:active,input[type=password]:focus,input[type=text]:active,input[type=text]:focus,select:focus,textarea:active,textarea:focus{border:1px solid var(--primary-color)}input[type=file]{font-family:var(--font-regular);padding:2px;cursor:pointer;border:1px solid var(--primary-color);min-height:calc(var(--font-size-small) + 18px)}input[type=file]::-webkit-file-upload-button{font-family:var(--font-regular);font-size:var(--font-size-small);outline:0;cursor:pointer;padding:3px 8px;border:1px solid var(--primary-color);background-color:var(--primary-color);color:var(--primary-btn-text-color);border-radius:var(--border-radius);-webkit-appearance:none}pre,textarea{scrollbar-width:thin;scrollbar-color:var(--border-color) var(--input-bg)}pre::-webkit-scrollbar,textarea::-webkit-scrollbar{width:8px;height:8px}pre::-webkit-scrollbar-track,textarea::-webkit-scrollbar-track{background:var(--input-bg)}pre::-webkit-scrollbar-thumb,textarea::-webkit-scrollbar-thumb{border-radius:2px;background-color:var(--border-color)}.link{font-size:var(--font-size-small);text-decoration:underline;color:var(--blue);font-family:var(--font-mono);margin-bottom:2px}input[type=checkbox]:focus{outline:0}input[type=checkbox]{appearance:none;display:inline-block;background-color:var(--light-bg);border-radius:9px;cursor:pointer;height:18px;position:relative;transition:border .15s,padding .25s;min-width:36px;width:36px;vertical-align:top}input[type=checkbox]:after{position:absolute;background-color:var(--bg);border-radius:8px;content:'';top:0;left:0;right:16px;display:block;height:16px;transition:left .25s .1s,right .15s .175s}input[type=checkbox]:checked{box-shadow:inset 0 0 0 13px var(--primary-color);border-color:var(--primary-color)}input[type=checkbox]:checked:after{border:1px solid var(--primary-color);left:16px;right:1px;transition:border .25s,left .15s .25s,right .25s .175s}.oauth-client-input{display:flex;align-items:center;flex-grow:1;width:300px;max-width:300px;margin-top:1rem}input.oauth-client-secret{flex-grow:1;max-width:300px}`;
10
10
 
11
11
  exports.default = _default;
@@ -217,9 +217,9 @@ async function checkForAuthToken(redirectToApiLocation) {
217
217
 
218
218
  async function onInvokeOAuthFlow(apiKeyId, flowType, authUrl, tokenUrl, e) {
219
219
  const authFlowDivEl = e.target.closest('.oauth-flow');
220
- const clientId = authFlowDivEl.querySelector('.oauth-client-id') ? authFlowDivEl.querySelector('.oauth-client-id').value.trim() : '';
221
- const clientSecret = authFlowDivEl.querySelector('.oauth-client-secret') ? authFlowDivEl.querySelector('.oauth-client-secret').value.trim() : '';
222
- const sendClientSecretIn = authFlowDivEl.querySelector('.oauth-send-client-secret-in') ? authFlowDivEl.querySelector('.oauth-send-client-secret-in').value.trim() : 'header';
220
+ const clientId = authFlowDivEl.querySelector('#oauth-client-id') ? authFlowDivEl.querySelector('#oauth-client-id').value.trim() : '';
221
+ const clientSecret = authFlowDivEl.querySelector('#oauth-client-secret') ? authFlowDivEl.querySelector('#oauth-client-secret').value.trim() : '';
222
+ const sendClientSecretIn = authFlowDivEl.querySelector('#oauth-send-client-secret-in') ? authFlowDivEl.querySelector('#oauth-send-client-secret-in').value.trim() : 'header';
223
223
  const checkedScopeEls = [...authFlowDivEl.querySelectorAll('input[type="checkbox"]:checked')];
224
224
  const securityObj = this.resolvedSpec.securitySchemes.find(v => v.apiKeyId === apiKeyId);
225
225
  let grantType = '';
@@ -307,9 +307,45 @@ function oAuthFlowTemplate(flowName, securityObj, authFlow) {
307
307
  flowNameDisplay = flowName;
308
308
  }
309
309
 
310
- return (0, _lit.html)` <div class="oauth-flow" style="padding:10px 0;margin-bottom:10px"> <div class="tiny-title upper" style="margin-bottom:5px">${flowNameDisplay}</div> ${authorizationUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Auth URL</span> <span class="mono-font"> ${authorizationUrl} </span></div>` : ''} ${tokenUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Token URL</span> <span class="mono-font">${tokenUrl}</span></div>` : ''} ${refreshUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Refresh URL</span> <span class="mono-font">${refreshUrl}</span></div>` : ''} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? (0, _lit.html)` ${authFlow.scopes ? (0, _lit.html)` <span> Scopes </span> <div class="oauth-scopes" part="section-auth-scopes" style="width:100%;display:flex;flex-direction:column;flex-wrap:wrap;margin:0 0 .125rem 0"> ${Object.entries(authFlow.scopes).map((scopeAndDescr, index) => (0, _lit.html)` <div class="m-checkbox" style="display:inline-flex;align-items:center"> <input type="checkbox" checked="checked" part="checkbox checkbox-auth-scope" id="${flowName}${index}" value="${scopeAndDescr[0]}"> <label for="${flowName}${index}" style="margin-left:5px"> <span class="mono-font">${scopeAndDescr[0]}</span> ${scopeAndDescr[0] !== scopeAndDescr[1] ? ` - ${scopeAndDescr[1] || ''}` : ''} </label> </div> `)} </div> ` : ''} <div style="display:flex"> <input type="text" part="textbox textbox-auth-client-id" value="${securityObj.clientId || ''}" placeholder="Client ID" spellcheck="false" class="oauth-client-id"> ${flowName === 'clientCredentials' ? (0, _lit.html)` <input type="password" part="textbox textbox-auth-client-secret" value="" placeholder="Client Secret" spellcheck="false" class="oauth-client-secret" style="margin:0 5px"> <select aria-label="oauth client secret location" style="margin-right:5px" class="oauth-send-client-secret-in"> <option value="header" selected="selected"> Authorization Header </option> <option value="request-body"> Request Body </option> </select>` : (0, _lit.html)`<div style="width:5px"></div>`} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? (0, _lit.html)` <button class="m-btn thin-border" part="btn btn-outline" @click="${e => {
310
+ return (0, _lit.html)` <div class="oauth-flow" style="padding:10px 0;margin-bottom:10px"> <div class="tiny-title upper" style="margin-bottom:5px">${flowNameDisplay}</div> ${authorizationUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Auth URL</span> <span class="mono-font"> ${authorizationUrl} </span></div>` : ''} ${tokenUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Token URL</span> <span class="mono-font">${tokenUrl}</span></div>` : ''} ${refreshUrl ? (0, _lit.html)`<div><span style="width:75px;display:inline-block">Refresh URL</span> <span class="mono-font">${refreshUrl}</span></div>` : ''} ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? (0, _lit.html)` ${authFlow.scopes ? (0, _lit.html)` <span> Scopes </span> <div class="oauth-scopes" part="section-auth-scopes" style="width:100%;display:flex;flex-direction:column;flex-wrap:wrap;margin:0 0 .125rem 0"> ${Object.entries(authFlow.scopes).map((scopeAndDescr, index) => (0, _lit.html)` <div class="m-checkbox" style="display:inline-flex;align-items:center"> <input type="checkbox" checked="checked" part="checkbox checkbox-auth-scope" id="${flowName}${index}" value="${scopeAndDescr[0]}"> <label for="${flowName}${index}" style="margin-left:5px"> <span class="mono-font">${scopeAndDescr[0]}</span> ${scopeAndDescr[0] !== scopeAndDescr[1] ? ` - ${scopeAndDescr[1] || ''}` : ''} </label> </div> `)} </div> ` : ''} <div style="display:flex"> <div> <input id="oauth-client-id" type="text" part="textbox textbox-auth-client-id" value="${securityObj.clientId || ''}" placeholder="Client ID" spellcheck="false" class="oauth-client-input"> ${flowName === 'clientCredentials' ? (0, _lit.html)` <input id="oauth-client-secret" type="password" part="textbox textbox-auth-client-secret" value="" placeholder="Client Secret" spellcheck="false" class="oauth-client-input"> <select id="oauth-send-client-secret-in" aria-label="oauth client secret location" style="margin-right:5px" class="oauth-client-input"> <option value="header" selected="selected"> Authorization Header </option> <option value="request-body"> Request Body </option> </select> ` : (0, _lit.html)`<div style="width:5px"></div>`} </div> ${flowName === 'authorizationCode' || flowName === 'clientCredentials' || flowName === 'implicit' ? (0, _lit.html)` <div class="oauth-client-input" style="margin-left:1rem"> <button class="m-btn thin-border" part="btn btn-outline" @click="${e => {
311
311
  onInvokeOAuthFlow.call(this, apiKeyId, flowName, authorizationUrl, tokenUrl, e);
312
- }}">GET TOKEN</button>` : ''} </div> <div class="oauth-resp-display red-text small-font-size"></div> ` : ''} </div> `;
312
+ }}">GET TOKEN</button> </div>` : ''} </div> <div class="oauth-resp-display red-text small-font-size"></div> ` : ''} </div> `;
313
+ }
314
+
315
+ function renderSecurityScheme(v) {
316
+ if (!v.type) {
317
+ return '';
318
+ }
319
+
320
+ if (v.type.toLowerCase() === 'apikey' || v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'bearer') {
321
+ var _v$bearerFormat, _v$bearerFormat2;
322
+
323
+ return (0, _lit.html)` <div style="padding-top:1rem"> ${v.type.toLowerCase() === 'apikey' ? (0, _lit.html)`Send <code>${v.name || 'API key'}</code> in <code>${v.in || 'the request'}</code> with the given value:` : (0, _lit.html)`Send <code>Authorization</code> in <code>header</code> containing the word <code>Bearer</code> followed by a space and then the ${(_v$bearerFormat = v.bearerFormat) !== null && _v$bearerFormat !== void 0 ? _v$bearerFormat : 'Token String'}.`} </div> <form style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> ${v.in === 'cookie' ? (0, _lit.html)` <div style="display:block"> <input type="text" value="${getCookieValue(v.apiKeyId)}" disabled="disabled" class="api-key-input" placeholder="IygRVGf54B59e0GAkKmigGfuiVlp/uhFfk2ifA+jMMJzau2F1jPldc09gPTfnMw13BFBxqUZIFDm55DPfwkb0A==" spellcheck="false" style="resize:horizontal;width:100%"> <br> <small> <strong>Cookies</strong>&nbsp;are set and configured by the remote service, therefore it is not possible to configure them from the browser. </small> </div>` : !v.finalKeyValue ? (0, _lit.html)` <input type="text" value="${v.value}" placeholder="${(_v$bearerFormat2 = v.bearerFormat) !== null && _v$bearerFormat2 !== void 0 ? _v$bearerFormat2 : 'api-token'}" spellcheck="false" class="api-key-input fs-exclude" data-hj-suppress data-sl="mask"> <button type="submit" class="m-btn thin-border" style="margin-left:5px" part="btn btn-outline" @click="${e => {
324
+ onApiKeyChange.call(this, v.apiKeyId, e);
325
+ }}"> ${(0, _index.getI18nText)('authentication.set')} </button>` : (0, _lit.html)`<span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
326
+ v.finalKeyValue = '';
327
+ this.requestUpdate();
328
+ }}">REMOVE</button>`} </form>`;
329
+ }
330
+
331
+ if (v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic') {
332
+ if (v.finalKeyValue) {
333
+ return (0, _lit.html)` <div style="padding-top:1rem">${(0, _index.getI18nText)('authentication.http-basic-desc')}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <span class="blue-text" style="margin-right:1rem">Key Applied</span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
334
+ v.finalKeyValue = '';
335
+ this.requestUpdate();
336
+ }}">REMOVE</button> </div>`;
337
+ }
338
+
339
+ return (0, _lit.html)` <div style="padding-top:1rem">${(0, _index.getI18nText)('authentication.http-basic-desc')}</div> <div style="height:50px;margin-top:1rem;padding:10px 0;margin-bottom:10px"> <form style="display:flex"> <input type="text" value="${v.user}" placeholder="${(0, _index.getI18nText)('authentication.username')}" spellcheck="false" class="api-key-user" style="width:100px"> <input class="api-key-password fs-exclude" data-hj-suppress data-sl="mask" type="password" value="${v.password}" placeholder="${(0, _index.getI18nText)('authentication.password')}" spellcheck="false" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => {
340
+ onApiKeyChange.call(this, v.apiKeyId, e);
341
+ }}" part="btn btn-outline"> ${v.finalKeyValue ? 'UPDATE' : (0, _index.getI18nText)('authentication.set')} </button> </form> </div>`;
342
+ }
343
+
344
+ if (v.type.toLowerCase() === 'oauth2' && Object.keys(v.flows).length) {
345
+ return (0, _lit.html)`${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))}`;
346
+ }
347
+
348
+ return '';
313
349
  }
314
350
 
315
351
  function securitySchemeTemplate() {
@@ -320,20 +356,9 @@ function securitySchemeTemplate() {
320
356
  }
321
357
 
322
358
  const providedApiKeys = schemes.filter(v => v.finalKeyValue);
323
- return (0, _lit.html)` <section id="auth" part="section-auth" class="observe-me ${this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}"> <slot name="authentication"> <div class="section-padding"> <slot name="authentication-header"> <div class="sub-title regular-font">${(0, _index.getI18nText)('headers.authentication')}</div> </slot> <div class="small-font-size" style="display:flex;align-items:center;min-height:30px"> ${providedApiKeys.length > 0 ? (0, _lit.html)` <div class="blue-text"> ${providedApiKeys.length} API key applied </div> <div style="flex:1"></div> <button class="m-btn thin-border" part="btn btn-outline" @click="${() => {
359
+ return (0, _lit.html)` <section id="auth" part="section-auth" class="observe-me ${this.renderStyle === 'focused' ? 'section-gap--focused-mode' : 'section-gap'}"> <slot name="authentication"> <div class="section-padding"> <slot name="authentication-header"> <div class="sub-title regular-font">${(0, _index.getI18nText)('headers.authentication')}</div> </slot> <div class="small-font-size" style="display:flex;align-items:center;min-height:40px"> ${providedApiKeys.length > 0 ? (0, _lit.html)` <div class="blue-text"> ${providedApiKeys.length} API key applied </div> <div style="flex:1"></div> <button class="m-btn thin-border" part="btn btn-outline" @click="${() => {
324
360
  onClearAllApiKeys.call(this);
325
- }}">CLEAR ALL API KEYS</button>` : (0, _lit.html)`<div class="red-text">${(0, _index.getI18nText)('authentication.no-api-key-applied')}</div>`} </div> ${schemes.length > 0 ? (0, _lit.html)` <table role="presentation" class="m-table" style="width:100%"> ${schemes.map(v => {
326
- var _v$bearerFormat, _v$bearerFormat2;
327
-
328
- return (0, _lit.html)` <tr> <td colspan="1" style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px"> <span style="font-weight:700">${v.typeDisplay}</span> ${v.finalKeyValue ? (0, _lit.html)` <span class="blue-text"> ${v.finalKeyValue ? 'Key Applied' : ''} </span> <button class="m-btn thin-border small" part="btn btn-outline" @click="${() => {
329
- v.finalKeyValue = '';
330
- this.requestUpdate();
331
- }}">REMOVE</button> ` : ''} </div> ${v.description ? (0, _lit.html)` <div class="m-markdown"> ${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(v.description || ''))} </div>` : ''} </td> <td colspan="3"> ${v.type && (v.type.toLowerCase() === 'apikey' || v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'bearer') ? (0, _lit.html)` ${v.type.toLowerCase() === 'apikey' ? (0, _lit.html)`Send <code>${v.name}</code> in <code>${v.in}</code> with the given value:` : (0, _lit.html)`Send <code>Authorization</code> in <code>header</code> containing the word <code>Bearer</code> followed by a space and then the ${(_v$bearerFormat = v.bearerFormat) !== null && _v$bearerFormat !== void 0 ? _v$bearerFormat : 'Token String'}.`} <form style="display:flex"> ${v.in === 'cookie' ? (0, _lit.html)` <div style="display:block"> <input type="text" value="${getCookieValue(v.apiKeyId)}" disabled="disabled" class="api-key-input" placeholder="IygRVGf54B59e0GAkKmigGfuiVlp/uhFfk2ifA+jMMJzau2F1jPldc09gPTfnMw13BFBxqUZIFDm55DPfwkb0A==" spellcheck="false" style="resize:horizontal;width:100%"> <br> <small> <strong>Cookies</strong>&nbsp;are set and configured by the remote service, therefore it is not possible to configure them from the browser. </small> </div>` : (0, _lit.html)` <input type="text" value="${v.value}" placeholder="${(_v$bearerFormat2 = v.bearerFormat) !== null && _v$bearerFormat2 !== void 0 ? _v$bearerFormat2 : 'api-token'}" spellcheck="false" class="api-key-input fs-exclude" data-hj-suppress data-sl="mask"> <button type="submit" class="m-btn thin-border" style="margin-left:5px" part="btn btn-outline" @click="${e => {
332
- onApiKeyChange.call(this, v.apiKeyId, e);
333
- }}"> ${v.finalKeyValue ? 'UPDATE' : 'SET'} </button>`} </form>` : ''} ${v.type && v.type.toLowerCase() === 'http' && v.scheme && v.scheme.toLowerCase() === 'basic' ? (0, _lit.html)` ${(0, _index.getI18nText)('authentication.http-basic-desc')} <form style="display:flex"> <input type="text" value="${v.user}" placeholder="${(0, _index.getI18nText)('authentication.username')}" spellcheck="false" class="api-key-user" style="width:100px"> <input class="api-key-password fs-exclude" data-hj-suppress data-sl="mask" type="password" value="${v.password}" placeholder="${(0, _index.getI18nText)('authentication.password')}" spellcheck="false" style="width:100px;margin:0 5px"> <button type="submit" class="m-btn thin-border" @click="${e => {
334
- onApiKeyChange.call(this, v.apiKeyId, e);
335
- }}" part="btn btn-outline"> ${v.finalKeyValue ? 'UPDATE' : (0, _index.getI18nText)('authentication.set')} </button> </form>` : ''} </td> </tr> ${v.type.toLowerCase() === 'oauth2' ? (0, _lit.html)` <tr> <td colspan="2" style="border:none;padding-left:48px"> ${Object.keys(v.flows).map(f => oAuthFlowTemplate.call(this, f, v, v.flows[f]))} </td> </tr> ` : ''} `;
336
- })} </table>` : ''} <slot name="authentication-footer"></slot> </div> </slot> </section> `;
361
+ }}">CLEAR ALL API KEYS</button>` : (0, _lit.html)`<div class="red-text">${(0, _index.getI18nText)('authentication.no-api-key-applied')}</div>`} </div> ${schemes.length > 0 ? (0, _lit.html)` <table role="presentation" class="m-table" style="width:100%"> ${schemes.map(v => (0, _lit.html)` <tr> <td colspan="1" style="max-width:500px;overflow-wrap:break-word"> <div style="min-height:24px;display:flex;flex-direction:column;justify-content:center;align-items:center"> <div style="display:flex;justify-content:center"> <span style="font-weight:700">${getTypeDisplayHeader(v)}</span> </div> </div> ${v.description ? (0, _lit.html)` <div class="m-markdown"> ${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(v.description || ''))} </div>` : ''} </td> <td colspan="3">${renderSecurityScheme.call(this, v)}</td> </tr>`)} </table>` : ''} <slot name="authentication-footer"></slot> </div> </slot> </section> `;
337
362
  }
338
363
 
339
364
  function getOauthScopeTemplate(rawScopes) {
@@ -346,6 +371,22 @@ function getOauthScopeTemplate(rawScopes) {
346
371
  return (0, _lit.html)` <div> <b>Required scopes:</b> <br> <div style="margin-left:8px"> ${scopes.map(scope => (0, _lit.html)`<span>${scope}</span>&nbsp;`)} </div> </div>`;
347
372
  }
348
373
 
374
+ function getTypeDisplayHeader(securityScheme) {
375
+ if (securityScheme.type === 'apiKey') {
376
+ return `API Key (${securityScheme.name})`;
377
+ }
378
+
379
+ if (securityScheme.type === 'oauth2') {
380
+ return 'OAuth2.0';
381
+ }
382
+
383
+ if (securityScheme.type === 'http') {
384
+ return securityScheme.scheme === 'basic' ? (0, _index.getI18nText)('authentication.http-basic') : 'HTTP Bearer';
385
+ }
386
+
387
+ return securityScheme.type;
388
+ }
389
+
349
390
  function pathSecurityTemplate(pathSecurity) {
350
391
  if (this.resolvedSpec.securitySchemes && pathSecurity) {
351
392
  const orSecurityKeys1 = [];
@@ -356,7 +397,7 @@ function pathSecurityTemplate(pathSecurity) {
356
397
  const s = this.resolvedSpec.securitySchemes.find(ss => ss.apiKeyId === pathSecurityKey);
357
398
 
358
399
  if (s) {
359
- andKeyTypes.push(s.typeDisplay);
400
+ andKeyTypes.push(getTypeDisplayHeader(s));
360
401
  andSecurityKeys1.push({ ...s,
361
402
  scopes: pSecurity[pathSecurityKey]
362
403
  });
@@ -63,20 +63,8 @@ async function ProcessSpec(specUrlOrObject, serverUrl = '') {
63
63
 
64
64
  securitySchemes.push(securityObj);
65
65
  });
66
- } // Updated Security Type Display Text based on Type
67
-
68
-
69
- securitySchemes.forEach(v => {
70
- if (v.type === 'http') {
71
- v.typeDisplay = v.scheme === 'basic' ? (0, _index.getI18nText)('authentication.http-basic') : 'HTTP Bearer';
72
- } else if (v.type === 'apiKey') {
73
- v.typeDisplay = `API Key (${v.name})`;
74
- } else if (v.type === 'oauth2') {
75
- v.typeDisplay = 'OAuth2.0';
76
- } else {
77
- v.typeDisplay = v.type;
78
- }
79
- }); // Servers
66
+ } // Servers
67
+
80
68
 
81
69
  let servers = [];
82
70
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-explorer",
3
- "version": "2.1.647",
3
+ "version": "2.1.650",
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",