openapi-explorer 1.0.564 → 1.0.567

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.
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-explorer.min.js","mappings":";;AA8BA;AC4iBA;AA5BA;AAmDA","sources":["webpack://openapi-explorer/./src/templates/code-samples-template.js","webpack://openapi-explorer/./src/components/api-request.js"],"sourcesContent":["import { html } from 'lit';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport Prism from 'prismjs';\nimport { copyToClipboard } from '../utils/common-utils';\nimport { getI18nText } from '../languages';\n\n/* eslint-disable indent */\nexport default function codeSamplesTemplate(xCodeSamples) {\n return html`\n <section class=\"table-title top-gap\"> CODE SAMPLES </div>\n <div class=\"tab-panel col\"\n @click=\"${\n (e) => {\n if (!e.target.classList.contains('tab-btn')) { return; }\n const clickedTab = e.target.dataset.tab;\n\n const tabButtons = [...e.currentTarget.querySelectorAll('.tab-btn')];\n const tabContents = [...e.currentTarget.querySelectorAll('.tab-content')];\n tabButtons.forEach((tabBtnEl) => tabBtnEl.classList[tabBtnEl.dataset.tab === clickedTab ? 'add' : 'remove']('active'));\n tabContents.forEach((tabBodyEl) => { tabBodyEl.style.display = (tabBodyEl.dataset.tab === clickedTab ? 'block' : 'none'); });\n }\n }\">\n <div class=\"tab-buttons row\" style=\"width:100; overflow\">\n ${xCodeSamples.map((v, i) => html`<button class=\"tab-btn ${i === 0 ? 'active' : ''}\" data-tab = '${v.lang}${i}'> ${v.label || v.lang} </button>`)}\n </div>\n ${xCodeSamples.map((v, i) => {\n const paddingToRemove = Math.min(...v.source.split('\\n').slice(1).map(l => l.match(/^(\\s+).*$/)?.[1].length).filter(l => typeof l !== 'undefined'));\n const sanitizedSource = v.source.split('\\n').map(s => s.substring(0, paddingToRemove).match(/^\\s+$/) ? s.substring(paddingToRemove) : s);\n const fullSource = sanitizedSource.join('\\n');\n return html`\n <div class=\"tab-content m-markdown code-sample-wrapper\" style= \"display:${i === 0 ? 'block' : 'none'}\" data-tab = '${v.lang}${i}'>\n <button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(v.source, e); }}'>${getI18nText('operations.copy')}</button>\n <pre><code>${Prism.languages[v.lang?.toLowerCase()] ? unsafeHTML(Prism.highlight(fullSource, Prism.languages[v.lang?.toLowerCase()], v.lang?.toLowerCase())) : fullSource}\n </code></pre>\n </div>`;\n })\n }\n </section>`;\n}\n/* eslint-enable indent */\n","import { LitElement, html } from 'lit';\nimport { marked } from 'marked';\nimport Prism from 'prismjs';\nimport mimeTypeResolver from './mime-types';\n\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport formatXml from 'xml-but-prettier';\n\nimport { copyToClipboard } from '../utils/common-utils';\nimport { getI18nText } from '../languages';\nimport { schemaInObjectNotation, getTypeInfo, generateExample } from '../utils/schema-utils';\nimport './json-tree';\nimport './schema-tree';\nimport getRequestFormTable from './request-form-table';\nimport './tag-input';\n\nconst textFileRegex = RegExp('^font/|tar$|zip$|7z$|rtf$|msword$|excel$|/pdf$|/octet-stream$|^application/vnd.');\nconst mediaFileRegex = RegExp('^audio/|^image/|^video/');\n\nexport default class ApiRequest extends LitElement {\n createRenderRoot() { return this; }\n\n constructor() {\n super();\n this.responseMessage = '';\n this.responseStatus = '';\n this.responseHeaders = '';\n this.responseText = '';\n this.responseUrl = '';\n this.responseElapsedMs = 0;\n this.curlSyntax = '';\n this.activeResponseTab = 'response'; // allowed values: response, headers, curl\n this.selectedRequestBodyType = '';\n this.selectedRequestBodyExample = '';\n }\n\n static get properties() {\n return {\n serverUrl: { type: String, attribute: 'server-url' },\n servers: { type: Array },\n method: { type: String },\n path: { type: String },\n elementId: { type: String, attribute: 'element-id' },\n parameters: { type: Array },\n request_body: { type: Object },\n api_keys: { type: Array },\n parser: { type: Object },\n accept: { type: String },\n callback: { type: String },\n responseMessage: { type: String, attribute: false },\n responseText: { type: String, attribute: false },\n responseHeaders: { type: String, attribute: false },\n responseStatus: { type: String, attribute: false },\n responseUrl: { type: String, attribute: false },\n responseElapsedMs: { type: Number, attribute: false },\n fillRequestWithDefault: { type: String, attribute: 'fill-defaults' },\n includeNulls: { type: Boolean, attribute: 'display-nulls', converter(value) { return value === 'true'; } },\n allowTry: { type: String, attribute: 'enable-console' },\n renderStyle: { type: String, attribute: 'render-style' },\n schemaStyle: { type: String, attribute: 'schema-style' },\n activeSchemaTab: { type: String, attribute: 'active-schema-tab' },\n schemaExpandLevel: { type: Number, attribute: 'schema-expand-level' },\n schemaHideReadOnly: { type: String, attribute: 'schema-hide-read-only' },\n fetchCredentials: { type: String, attribute: 'fetch-credentials' },\n\n // properties for internal tracking\n activeResponseTab: { type: String }, // internal tracking of response-tab not exposed as a attribute\n selectedRequestBodyType: { type: String, attribute: 'selected-request-body-type' }, // internal tracking of selected request-body type\n selectedRequestBodyExample: { type: String, attribute: 'selected-request-body-example' }, // internal tracking of selected request-body example\n };\n }\n\n render() {\n return html`\n <div class=\"api-request col regular-font request-panel ${(this.renderStyle === 'focused' || this.callback === 'true') ? 'focused-mode' : 'view-mode'}\">\n <div class=\" ${this.callback === 'true' ? 'tiny-title' : 'req-res-title'} \"> \n ${this.callback === 'true' ? 'CALLBACK REQUEST' : getI18nText('operations.request')}\n </div>\n <div>\n ${this.inputParametersTemplate('path')}\n ${this.inputParametersTemplate('query')}\n ${this.requestBodyTemplate()}\n ${this.inputParametersTemplate('header')}\n ${this.inputParametersTemplate('cookie')}\n ${this.allowTry === 'false' ? '' : html`${this.apiCallTemplate()}`}\n </div> \n </div>\n `;\n }\n\n updated(changedProperties) {\n if (changedProperties.has('elementId')) {\n this.selectedRequestBodyType = '';\n this.selectedRequestBodyExample = '';\n }\n\n // In focused mode after rendering the request component, update the text-areas(which contains examples) using the original values from hidden textareas.\n // This is done coz, user may update the dom by editing the textarea's and once the DOM is updated externally change detection wont happen, therefore update the values manually\n if (this.renderStyle !== 'focused') {\n return;\n }\n\n // dont update example as only tabs is switched\n if (changedProperties.size === 1 && changedProperties.has('activeSchemaTab')) {\n return;\n }\n\n const exampleTextAreaEls = [...this.querySelectorAll('textarea[data-ptype=\"form-data\"]')];\n exampleTextAreaEls.forEach((el) => {\n const origExampleEl = this.querySelector(`textarea[data-pname='hidden-${el.dataset.pname}']`);\n if (origExampleEl) {\n el.value = origExampleEl.value;\n }\n });\n }\n\n /* eslint-disable indent */\n inputParametersTemplate(paramLocation) {\n const filteredParams = this.parameters ? this.parameters.filter((param) => param.in === paramLocation) : [];\n if (filteredParams.length === 0) {\n return '';\n }\n\n const title = {\n path: 'PATH PARAMETERS',\n query: 'QUERY-STRING PARAMETERS',\n header: 'REQUEST HEADERS',\n cookie: 'COOKIES'\n }[paramLocation];\n\n const tableRows = [];\n for (const param of filteredParams) {\n if (!param.schema) {\n continue;\n }\n const paramSchema = getTypeInfo(param.schema, { includeNulls: this.includeNulls });\n if (!paramSchema) {\n continue;\n }\n const defaultVal = Array.isArray(paramSchema.default) ? paramSchema.default : `${paramSchema.default}`;\n let paramStyle = 'form';\n let paramExplode = true;\n if (paramLocation === 'query') {\n if (param.style && 'form spaceDelimited pipeDelimited'.includes(param.style)) {\n paramStyle = param.style;\n }\n if (typeof param.explode === 'boolean') {\n paramExplode = param.explode;\n }\n }\n\n tableRows.push(html`\n <tr> \n <td colspan=\"1\" style=\"width:160px; min-width:50px; vertical-align: top\">\n <div class=\"param-name ${paramSchema.deprecated ? 'deprecated' : ''}\" style=\"margin-top: 1rem;\">\n ${param.name}${!paramSchema.deprecated && param.required ? html`<span style='color:var(--red);'>*</span>` : ''}\n </div>\n <div class=\"param-type\" style=\"margin-bottom: 1rem;\">\n ${paramSchema.type === 'array'\n ? `${paramSchema.arrayType}`\n : `${paramSchema.format ? paramSchema.format : paramSchema.type}`\n }${!paramSchema.deprecated && param.required ? html`<span style='opacity: 0;'>*</span>` : ''}\n </div>\n </td> \n <td colspan=\"2\" style=\"min-width:160px; vertical-align: top\">\n ${this.allowTry === 'true'\n ? paramSchema.type === 'array' && html`\n <tag-input class=\"request-param\" \n style = \"width:100%; margin-top: 1rem; margin-bottom: 1rem;\" \n data-ptype = \"${paramLocation}\"\n data-pname = \"${param.name}\"\n data-default = \"${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}\"\n data-param-serialize-style = \"${paramStyle}\"\n data-param-serialize-explode = \"${paramExplode}\"\n data-array = \"true\"\n placeholder=\"${paramSchema.example || (Array.isArray(defaultVal) ? defaultVal[0] : defaultVal) || 'add-multiple ↩'}\"\n .value = \"${Array.isArray(defaultVal) ? defaultVal : defaultVal.split(',')}\"></tag-input>`\n || paramSchema.type === 'object' && html`\n <textarea \n class = \"textarea small request-param\"\n part = \"textarea small textarea-param\"\n rows = 3\n data-ptype = \"${paramLocation}\"\n data-pname = \"${param.name}\"\n data-default = \"${defaultVal}\"\n data-param-serialize-style = \"${paramStyle}\"\n data-param-serialize-explode = \"${paramExplode}\"\n spellcheck = \"false\"\n placeholder=\"${paramSchema.example || defaultVal || ''}\"\n style = \"width:100%; margin-top: 1rem; margin-bottom: 1rem;\"\n .value=\"${this.fillRequestWithDefault === 'true' ? defaultVal : ''}\"></textarea>`\n || html`\n <input type=\"${paramSchema.format === 'password' ? 'password' : 'text'}\" spellcheck=\"false\" style=\"width:100%; margin-top: 1rem; margin-bottom: 1rem;\"\n placeholder=\"${paramSchema.example || defaultVal || ''}\"\n class=\"request-param\"\n part=\"textbox textbox-param\"\n data-ptype=\"${paramLocation}\"\n data-pname=\"${param.name}\" \n data-default=\"${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}\"\n data-array=\"false\"\n @keyup=\"${this.requestParamFunction}\"\n .value=\"${this.fillRequestWithDefault === 'true' ? defaultVal : ''}\"\n />`\n : ''}\n\n <div style=\"min-width:50px; margin-bottom: 1rem;\">\n ${this.exampleListTemplate.call(this, param, paramSchema.type)}\n </div>\n </td>\n ${this.renderStyle === 'focused'\n ? html`\n <td colspan=\"2\">\n ${param.description\n ? html`\n <div class=\"param-description\">\n ${unsafeHTML(marked(param.description))}\n </div>`\n : ''\n }\n ${paramSchema.default || paramSchema.s || paramSchema.allowedValues || paramSchema.pattern\n ? html`\n <div class=\"param-constraint\">\n ${paramSchema.constraints.length ? html`<span style=\"font-weight:bold\">Constraints: </span>${paramSchema.constraints.join(', ')}<br>` : ''}\n ${paramSchema.pattern ? html`\n <div class=\"tooltip tooltip-replace\" style=\"cursor: pointer; max-width: 100%; display: flex;\">\n <div style=\"white-space:nowrap; font-weight:bold; margin-right: 2px;\">Pattern: </div>\n <div style=\"white-space:nowrap; text-overflow:ellipsis; max-width:100%; overflow:hidden;\">${paramSchema.pattern}</div>\n <br>\n <div class=\"tooltip-text\" style=\"position: absolute; display:block;\">${paramSchema.pattern}</div>\n </div>\n ` : ''}\n ${paramSchema.allowedValues && paramSchema.allowedValues.split('┃').map((v, i) => html`\n ${i > 0 ? '|' : html`<span style=\"font-weight:bold\">Allowed: </span>`}\n ${html`\n <a part=\"anchor anchor-param-constraint\" class = \"${this.allowTry === 'true' ? '' : 'inactive-link'}\"\n data-type=\"${paramSchema.type === 'array' ? 'array' : 'string'}\"\n data-enum=\"${v.trim()}\"\n @click=\"${(e) => {\n const inputEl = e.target.closest('table').querySelector(`[data-pname=\"${param.name}\"]`);\n if (inputEl) {\n inputEl.value = e.target.dataset.type === 'array' ? [e.target.dataset.enum] : e.target.dataset.enum;\n }\n }}\"\n >\n ${v} \n </a>`\n }`)}\n </div>`\n : ''\n }\n </td> \n </tr>`\n : ''\n }\n `);\n }\n\n return html`\n <div class=\"table-title top-gap\">${title}${paramLocation === 'path' ? html`<span style='color:var(--red);'>*</span>` : ''}</div>\n <div style=\"display:block; overflow-x:auto; max-width:100%;\">\n <table role=\"presentation\" class=\"m-table\" style=\"width:100%; word-break:break-word;\">\n ${tableRows}\n </table>\n </div>`;\n }\n\n renderExample(example, paramType, paramName) {\n return html`\n <a\n part=\"anchor anchor-param-example\"\n class=\"${this.allowTry === 'true' ? '' : 'inactive-link'}\"\n data-example-type=\"${paramType === 'array' ? paramType : 'string'}\"\n data-example=\"${Array.isArray(example.exampleValue) ? example.exampleValue?.join('~|~') : example.exampleValue}\"\n @click=\"${(e) => {\n const inputEl = e.target.closest('table').querySelector(`[data-pname=\"${paramName}\"]`);\n if (inputEl) {\n inputEl.value = paramType === 'array' ? (e.target.dataset.example.split('~|~') || []) : e.target.dataset.example;\n }\n }}\">${Array.isArray(example.exampleValue) ? example.exampleValue?.join(', ') : example.exampleValue}\n </a>\n `;\n }\n\n renderShortFormatExamples(examples, paramType, paramName) {\n return html`${examples.map((example, i) => html`\n ${i === 0 ? '' : '┃'}\n ${this.renderExample(example, paramType, paramName)}`)}`;\n }\n\n renderLongFormatExamples(exampleList, paramType, paramName) {\n return html`\n <ul style=\"margin-block-start: 0.25em;\">\n ${exampleList.map(example =>\n html`\n <li>\n ${this.renderExample(example, paramType, paramName)}\n ${example.exampleSummary?.length > 0 ? html`<span>&lpar;${example.exampleSummary}&rpar;</span>` : ''}\n ${example.exampleDescription?.length > 0 ? html`<p>${unsafeHTML(marked(example.exampleDescription))}</p>` : ''}\n </li>`\n )}\n </ul>`;\n }\n\n /* eslint-disable indent */\n\n exampleListTemplate(param, paramType) {\n const paramName = param.name;\n const paramSchema = getTypeInfo(param.schema, { includeNulls: this.includeNulls });\n\n const examples = generateExample(\n param.examples || param.example && { Example: { value: param.example } } || paramSchema.examples || paramSchema.example && { Example: { value: paramSchema.example } },\n null, param.schema, null, false, true, 'json', false);\n\n const someExampleWithSummaryOrDescription = examples.some((x) => x.exampleSummary?.length > 0 || x.exampleDescription?.length > 0);\n if (examples.length === 1) {\n return html` ${examples.length > 0\n ? html`<span style=\"font-weight:bold\">Example: </span>\n ${\n someExampleWithSummaryOrDescription\n ? this.renderLongFormatExamples(examples, paramType, paramName)\n : this.renderShortFormatExamples(examples, paramType, paramName)\n }`\n : ''}`;\n }\n\n return html` ${examples.length > 1\n ? html`<span style=\"font-weight:bold\">Examples: </span>\n ${\n someExampleWithSummaryOrDescription\n ? this.renderLongFormatExamples(examples, paramType, paramName)\n : this.renderShortFormatExamples(examples, paramType, paramName)\n }`\n : ''}`;\n }\n\n resetRequestBodySelection() {\n this.selectedRequestBodyType = '';\n this.selectedRequestBodyExample = '';\n this.clearResponseData();\n }\n\n // Request-Body Event Handlers\n onSelectExample(e) {\n this.selectedRequestBodyExample = e.target.value;\n const exampleDropdownEl = e.target;\n window.setTimeout((selectEl) => {\n const exampleTextareaEl = selectEl.closest('.example-panel').querySelector('.request-body-param');\n const userInputExampleTextareaEl = selectEl.closest('.example-panel').querySelector('.request-body-param-user-input');\n userInputExampleTextareaEl.value = exampleTextareaEl.value;\n }, 0, exampleDropdownEl);\n }\n\n onMimeTypeChange(e) {\n this.selectedRequestBodyType = e.target.value;\n const mimeDropdownEl = e.target;\n this.selectedRequestBodyExample = '';\n window.setTimeout((selectEl) => {\n const exampleTextareaEl = selectEl.closest('.request-body-container').querySelector('.request-body-param');\n if (exampleTextareaEl) {\n const userInputExampleTextareaEl = selectEl.closest('.request-body-container').querySelector('.request-body-param-user-input');\n userInputExampleTextareaEl.value = exampleTextareaEl.value;\n }\n }, 0, mimeDropdownEl);\n }\n\n requestBodyTemplate() {\n if (!this.request_body) {\n return '';\n }\n if (Object.keys(this.request_body).length === 0) {\n return '';\n }\n\n if (this.method === 'get' || this.method === 'head') {\n return '';\n }\n\n // Variable to store partial HTMLs\n let reqBodyTypeSelectorHtml = '';\n let reqBodyFileInputHtml = '';\n let reqBodySchemaHtml = '';\n let reqBodyDefaultHtml = '';\n let bodyTabNameUseBody = true;\n\n const requestBodyTypes = [];\n const content = this.request_body.content;\n for (const mimeType in content) {\n requestBodyTypes.push({\n mimeType,\n schema: content[mimeType].schema,\n example: content[mimeType].example,\n examples: content[mimeType].examples,\n });\n }\n\n if (!content[this.selectedRequestBodyType]) {\n this.selectedRequestBodyType = requestBodyTypes[0]?.mimeType;\n }\n\n // MIME Type selector\n reqBodyTypeSelectorHtml = requestBodyTypes.length === 1\n ? ''\n : html`\n <select aria-label=\"mime type\" style=\"min-width:100px; max-width:100%; margin-bottom:-1px;\" @change = '${(e) => this.onMimeTypeChange(e)}'>\n ${requestBodyTypes.map((reqBody) => html`\n <option value = '${reqBody.mimeType}' ?selected = '${reqBody.mimeType === this.selectedRequestBodyType}'>\n ${reqBody.mimeType}\n </option> `)\n }\n </select>\n `;\n\n // For Loop - Main\n const reqBody = requestBodyTypes.find(req => req.mimeType === this.selectedRequestBodyType);\n // Generate Example\n if (this.selectedRequestBodyType.includes('json') || this.selectedRequestBodyType.includes('xml') || this.selectedRequestBodyType.includes('text')) {\n const reqBodyExamples = generateExample(\n reqBody.examples ? reqBody.examples : '',\n reqBody.example ? reqBody.example : '',\n reqBody.schema,\n reqBody.mimeType,\n false,\n true,\n 'text',\n true\n );\n\n if (!this.selectedRequestBodyExample) {\n this.selectedRequestBodyExample = (reqBodyExamples.length > 0 ? reqBodyExamples[0].exampleId : '');\n }\n const displayedBodyExample = reqBodyExamples.find(v => v.exampleId === this.selectedRequestBodyExample) || reqBodyExamples[0];\n reqBodyDefaultHtml = html`\n <div class = 'example-panel border-top pad-top-8'>\n ${reqBodyExamples.length === 1\n ? ''\n : html`\n <select aria-label='request body example' style=\"min-width:100px; max-width:100%; margin-bottom:-1px;\" @change='${(e) => this.onSelectExample(e)}'>\n ${reqBodyExamples.map((v) => html`<option value=\"${v.exampleId}\" ?selected=${v.exampleId === this.selectedRequestBodyExample}> \n ${v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary ? v.exampleSummary : v.exampleId} \n </option>`)}\n </select>`\n }\n ${displayedBodyExample ? html`\n <div class=\"example\" data-default = '${displayedBodyExample.exampleId}'>\n ${displayedBodyExample.exampleSummary && displayedBodyExample.exampleSummary.length > 80 ? html`<div style=\"padding: 4px 0\"> ${displayedBodyExample.exampleSummary} </div>` : ''}\n ${displayedBodyExample.exampleDescription ? html`<div class=\"m-markdown-small\" style=\"padding: 4px 0\"> ${unsafeHTML(marked(displayedBodyExample.exampleDescription || ''))} </div>` : ''}\n <!-- this textarea is for user to edit the example -->\n <slot name=\"${this.elementId}--request-body\">\n <textarea \n class = \"textarea request-body-param-user-input\"\n part = \"textarea textarea-param\"\n spellcheck = \"false\"\n data-ptype = \"${reqBody.mimeType}\" \n data-default = \"${displayedBodyExample.exampleFormat === 'text' ? displayedBodyExample.exampleValue : JSON.stringify(displayedBodyExample.exampleValue, null, 8)}\"\n data-default-format = \"${displayedBodyExample.exampleFormat}\"\n style=\"width:100%; resize:vertical;\"\n .value=\"${this.fillRequestWithDefault === 'true' ? (displayedBodyExample.exampleFormat === 'text' ? displayedBodyExample.exampleValue : JSON.stringify(displayedBodyExample.exampleValue, null, 8)) : ''}\"\n ></textarea>\n </slot>\n\n <!-- This textarea(hidden) is to store the original example value, this will remain unchanged when users switches from one example to another, its is used to populate the editable textarea -->\n <textarea \n class = \"textarea is-hidden request-body-param ${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)}\" \n spellcheck = \"false\"\n data-ptype = \"${reqBody.mimeType}\" \n style=\"width:100%; resize:vertical; display:none\"\n .value=\"${(displayedBodyExample.exampleFormat === 'text' ? displayedBodyExample.exampleValue : JSON.stringify(displayedBodyExample.exampleValue, null, 8))}\"\n ></textarea>\n </div>`\n : ''}\n\n </div>\n `;\n } else if (this.selectedRequestBodyType.includes('form-urlencoded') || this.selectedRequestBodyType.includes('form-data')) {\n bodyTabNameUseBody = false;\n const schemaAsObj = schemaInObjectNotation(reqBody.schema, { includeNulls: this.includeNulls });\n reqBodyDefaultHtml = getRequestFormTable.call(this, schemaAsObj, this.selectedRequestBodyType);\n } else if (mediaFileRegex.test(this.selectedRequestBodyType) || textFileRegex.test(this.selectedRequestBodyType)) {\n reqBodyFileInputHtml = html`\n <div class = \"small-font-size bold-text row\">\n <input type=\"file\" part=\"file-input\" style=\"max-width:100%\" class=\"request-body-param-file\" data-ptype=\"${reqBody.mimeType}\" spellcheck=\"false\" />\n </div> \n `;\n }\n\n // Generate Schema\n if (reqBody.mimeType.includes('json') || reqBody.mimeType.includes('xml') || reqBody.mimeType.includes('text') || reqBody.mimeType.includes('form-')) {\n const schemaAsObj = schemaInObjectNotation(reqBody.schema, { includeNulls: this.includeNulls });\n if (this.schemaStyle === 'table') {\n reqBodySchemaHtml = html`\n ${reqBodySchemaHtml}\n <schema-table\n class = '${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)} pad-top-8'\n style = 'display: ${this.selectedRequestBodyType === reqBody.mimeType ? 'block' : 'none'};'\n .data = '${schemaAsObj}'\n schema-expand-level = \"${this.schemaExpandLevel}\"\n schema-hide-read-only = \"${this.schemaHideReadOnly.includes(this.method)}\"\n schema-hide-write-only = false\n > </schema-table>\n `;\n } else {\n reqBodySchemaHtml = html`\n ${reqBodySchemaHtml}\n <schema-tree\n class = '${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)} pad-top-8'\n style = 'display: ${this.selectedRequestBodyType === reqBody.mimeType ? 'block' : 'none'};'\n .data = '${schemaAsObj}'\n schema-expand-level = \"${this.schemaExpandLevel}\"\n schema-hide-read-only = \"${this.schemaHideReadOnly.includes(this.method)}\"\n schema-hide-write-only = false\n > </schema-tree>\n `;\n }\n }\n\n return html`\n <div class='request-body-container' data-selected-request-body-type=\"${this.selectedRequestBodyType}\">\n <div class=\"table-title top-gap row\">\n REQUEST BODY ${this.request_body.required ? html`<span class=\"mono-font\" style='color:var(--red)'>*</span>` : ''} \n <span style = \"font-weight:normal; margin-left:5px\"> ${this.selectedRequestBodyType}</span>\n <span style=\"flex:1\"></span>\n ${reqBodyTypeSelectorHtml}\n </div>\n ${this.request_body.description ? html`<div class=\"m-markdown\" style=\"margin-bottom:12px\">${unsafeHTML(marked(this.request_body.description))}</div>` : ''}\n \n ${reqBodySchemaHtml || reqBodyDefaultHtml\n ? html`\n <div class=\"tab-panel col\" style=\"border-width:0 0 1px 0;\">\n <div class=\"tab-buttons row\" @click=\"${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}\">\n <button class=\"tab-btn ${this.activeSchemaTab === 'model' ? 'active' : ''}\" data-tab=\"model\" >${getI18nText('operations.model')}</button>\n <button class=\"tab-btn ${this.activeSchemaTab !== 'model' ? 'active' : ''}\" data-tab=\"body\">${bodyTabNameUseBody ? getI18nText('operations.body') : getI18nText('operations.form')}</button>\n </div>\n ${html`<div class=\"tab-content col\" style=\"display: ${this.activeSchemaTab === 'model' ? 'block' : 'none'}\"> ${reqBodySchemaHtml}</div>`}\n ${html`<div class=\"tab-content col\" style=\"display: ${this.activeSchemaTab === 'model' ? 'none' : 'block'}\"> ${reqBodyDefaultHtml}</div>`}\n </div>`\n : html`${reqBodyFileInputHtml}`\n }\n </div> \n `;\n }\n\n // formDataTemplate(schema, mimeType, exampleValue = '') {\n // return html`\n // <textarea\n // class = \"textarea dynamic-form-param ${mimeType}\"\n // part = \"textarea textarea-param\"\n // spellcheck = \"false\"\n // data-pname=\"dynamic-form\"\n // data-ptype=\"${mimeType}\"\n // style=\"width:100%\"\n // >${exampleValue}</textarea>\n // ${schema.description ? html`<span class=\"m-markdown-small\">${unsafeHTML(marked(schema.description))}</span>` : ''}\n // `;\n // }\n\n apiResponseTabTemplate() {\n const responseFormat = this.responseHeaders.includes('json') ? 'json' : (this.responseHeaders.includes('html') || this.responseHeaders.includes('xml')) ? 'html' : '';\n return html`\n <div class=\"row\" style=\"font-size:var(--font-size-small); margin:5px 0\">\n ${this.responseMessage\n ? html`<div class=\"response-message ${this.responseStatus}\">Response Status: ${this.responseMessage}\n ${this.responseElapsedMs ? html`<span><br>Execution Time: ${this.responseElapsedMs}ms</span>` : ''}\n </div>` : ''\n }\n <div style=\"flex:1\"></div>\n <button class=\"m-btn\" part=\"btn btn-outline\" @click=\"${this.clearResponseData}\">CLEAR RESPONSE</button>\n </div>\n <div class=\"tab-panel col\" style=\"border-width:0 0 1px 0;\">\n <div id=\"tab_buttons\" class=\"tab-buttons row\" @click=\"${(e) => {\n if (e.target.classList.contains('tab-btn') === false) { return; }\n this.activeResponseTab = e.target.dataset.tab;\n }}\">\n <button class=\"tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}\" data-tab = 'response'>${getI18nText('operations.response')}</button>\n <button class=\"tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}\" data-tab = 'headers'>${getI18nText('operations.response-headers')}</button>\n <button class=\"tab-btn ${this.activeResponseTab === 'curl' ? 'active' : ''}\" data-tab = 'curl'>CURL</button>\n </div>\n ${this.responseIsBlob\n ? html`\n <div class=\"tab-content col\" style=\"flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};\">\n <button class=\"m-btn thin-border mar-top-8\" style=\"width:135px\" @click=\"${this.downloadResponseBlob}\" part=\"btn btn-outline\">DOWNLOAD</button>\n ${this.responseBlobType === 'view'\n ? html`<button class=\"m-btn thin-border mar-top-8\" style=\"width:135px\" @click=\"${this.viewResponseBlob}\" part=\"btn btn-outline\">VIEW (NEW TAB)</button>`\n : ''\n }\n </div>`\n : html`\n <div class=\"tab-content col m-markdown\" style=\"flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};\" >\n ${this.responseText\n ? html`<button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(this.responseText, e); }}' part=\"btn btn-fill\">${getI18nText('operations.copy')}</button>`\n : ''\n }\n <pre style=\"min-height: 60px\" @copy='${() => { copyToClipboard(window.getSelection().toString()); }}'>${responseFormat\n ? html`<code>${unsafeHTML(Prism.highlight(this.responseText, Prism.languages[responseFormat], responseFormat))}</code>`\n : `${this.responseText}`\n }\n </pre>\n </div>`\n }\n <div class=\"tab-content col m-markdown\" style=\"flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'};\" >\n <button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(this.responseHeaders, e); }}' part=\"btn btn-fill\">${getI18nText('operations.copy')}</button>\n <pre><code>${unsafeHTML(Prism.highlight(this.responseHeaders, Prism.languages.css, 'css'))}</code></pre>\n </div>\n <div class=\"tab-content col m-markdown\" style=\"flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'};\">\n <button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(this.curlSyntax, e); }}' part=\"btn btn-fill\">${getI18nText('operations.copy')}</button>\n <pre class=\"fs-exclude\" data-hj-suppress data-sl=\"mask\">\n <code>${unsafeHTML(Prism.highlight(this.curlSyntax.trim(), Prism.languages.shell, 'shell'))}</code>\n </pre>\n </div>\n </div>`;\n }\n\n apiCallTemplate() {\n return html`\n <div style=\"display:flex; align-items:flex-end; margin:16px 0; font-size:var(--font-size-small);\">\n ${\n this.parameters.length > 0 || this.request_body\n ? html`\n <button class=\"m-btn thin-border\" part=\"btn btn-outline\" style=\"margin-right:5px;\" @click=\"${this.onClearRequestData}\">\n ${getI18nText('operations.clear')}\n </button>`\n : ''\n }\n <button class=\"m-btn primary btn-execute thin-border\" part=\"btn btn-fill btn-try\" @click=\"${this.onTryClick}\">${getI18nText('operations.execute')}</button>\n </div>\n ${this.responseMessage === '' ? '' : this.apiResponseTabTemplate()}\n `;\n }\n /* eslint-enable indent */\n\n onClearRequestData(e) {\n const requestPanelEl = e.target.closest('.request-panel');\n const requestPanelInputEls = [...requestPanelEl.querySelectorAll('input, tag-input, textarea:not(.is-hidden)')];\n requestPanelInputEls.forEach((el) => { el.value = ''; });\n\n const event = { bubbles: true, composed: true, detail: { explorerLocation: this.elementId, operation: { method: this.method, path: this.path }, type: 'RequestCleared' } };\n this.dispatchEvent(new CustomEvent('event', event));\n }\n\n async onTryClick() {\n const tryBtnEl = this.querySelectorAll('.btn-execute')[0];\n let curlData = '';\n let curlForm = '';\n const closestRespContainer = this.closest('.expanded-req-resp-container, .req-resp-container');\n const respEl = closestRespContainer && closestRespContainer.getElementsByTagName('api-response')[0];\n const acceptHeader = respEl?.selectedMimeType;\n const requestPanelEl = this.closest('.request-panel');\n const pathParamEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='path']\")];\n const queryParamEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='query']\")];\n const queryParamObjTypeEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='query-object']\")];\n const headerParamEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='header']\")];\n const requestBodyContainerEl = requestPanelEl.querySelector('.request-body-container');\n\n let pathUrl = `${this.serverUrl.replace(/\\/$/, '')}${this.path.replaceAll(' ', '')}`;\n\n // Generate URL using Path Params\n pathParamEls.map((el) => {\n pathUrl = pathUrl.replace(`{${el.dataset.pname}}`, encodeURIComponent(el.value) || '-');\n });\n\n // Handle relative serverUrls\n if (!pathUrl.startsWith('http')) {\n const newUrl = new URL(pathUrl, window.location.href);\n pathUrl = newUrl.toString();\n }\n\n const fetchUrl = new URL(pathUrl);\n\n const fetchOptions = {\n method: this.method.toUpperCase(),\n headers: new Headers()\n };\n\n // Query Params\n if (queryParamEls.length > 0) {\n queryParamEls.forEach((el) => {\n if (el.dataset.array === 'false') {\n if (el.value !== '') {\n fetchUrl.searchParams.append(el.dataset.pname, el.value);\n }\n } else {\n const paramSerializeStyle = el.dataset.paramSerializeStyle;\n const paramSerializeExplode = el.dataset.paramSerializeExplode;\n let vals = ((el.value && Array.isArray(el.value)) ? el.value : []);\n vals = Array.isArray(vals) ? vals.filter((v) => v !== '') : [];\n if (vals.length > 0) {\n if (paramSerializeStyle === 'spaceDelimited') {\n fetchUrl.searchParams.append(el.dataset.pname, vals.join(' ').replace(/^\\s|\\s$/g, ''));\n } else if (paramSerializeStyle === 'pipeDelimited') {\n fetchUrl.searchParams.append(el.dataset.pname, vals.join('|').replace(/^\\||\\|$/g, ''));\n } else {\n if (paramSerializeExplode === 'true') { // eslint-disable-line no-lonely-if\n vals.forEach((v) => { fetchUrl.searchParams.append(el.dataset.pname, v); });\n } else {\n fetchUrl.searchParams.append(el.dataset.pname, vals.join(',').replace(/^,|,$/g, ''));\n }\n }\n }\n }\n });\n }\n\n // Query Params (Dynamic - create from JSON)\n if (queryParamObjTypeEls.length > 0) {\n queryParamObjTypeEls.map((el) => {\n try {\n let queryParamObj = {};\n const paramSerializeStyle = el.dataset.paramSerializeStyle;\n const paramSerializeExplode = el.dataset.paramSerializeExplode;\n queryParamObj = Object.assign(queryParamObj, JSON.parse(el.value.replace(/\\s+/g, ' ')));\n for (const key in queryParamObj) {\n if (typeof queryParamObj[key] === 'object') {\n if (Array.isArray(queryParamObj[key])) {\n if (paramSerializeStyle === 'spaceDelimited') {\n fetchUrl.searchParams.append(key, queryParamObj[key].join(' '));\n } else if (paramSerializeStyle === 'pipeDelimited') {\n fetchUrl.searchParams.append(key, queryParamObj[key].join('|'));\n } else {\n if (paramSerializeExplode === 'true') { // eslint-disable-line no-lonely-if\n queryParamObj[key].forEach((v) => {\n fetchUrl.searchParams.append(key, v);\n });\n } else {\n fetchUrl.searchParams.append(key, queryParamObj[key]);\n }\n }\n }\n } else {\n fetchUrl.searchParams.append(key, queryParamObj[key]);\n }\n }\n } catch (err) {\n console.log('OpenAPI Explorer: unable to parse %s into object', el.value); // eslint-disable-line no-console\n }\n });\n }\n\n // Add Authentication api keys if provided\n this.api_keys.filter((v) => v.finalKeyValue).forEach((v) => {\n if (v.in === 'query') {\n fetchUrl.searchParams.append(v.name, v.finalKeyValue);\n return;\n }\n\n // Otherwise put it in the header\n fetchOptions.headers.append(v.name, v.finalKeyValue);\n });\n\n if (acceptHeader) {\n // Uses the acceptHeader from Response panel\n fetchOptions.headers.append('Accept', acceptHeader);\n } else if (this.accept) {\n fetchOptions.headers.append('Accept', this.accept);\n }\n\n // Add Header Params\n headerParamEls.map((el) => {\n if (el.value) {\n fetchOptions.headers.append(el.dataset.pname, el.value);\n }\n });\n\n // Request Body Params\n if (requestBodyContainerEl) {\n const requestBodyType = requestBodyContainerEl.dataset.selectedRequestBodyType;\n if (requestBodyType.includes('form-urlencoded')) {\n // url-encoded Form Params (dynamic) - Parse JSON and generate Params\n const formUrlDynamicTextAreaEl = requestPanelEl.querySelector(\"[data-ptype='dynamic-form']\");\n if (formUrlDynamicTextAreaEl) {\n const val = formUrlDynamicTextAreaEl.value;\n const formUrlDynParams = new URLSearchParams();\n let proceed = true;\n let tmpObj;\n if (val) {\n try {\n tmpObj = JSON.parse(val);\n } catch (err) {\n proceed = false;\n console.warn('OpenAPI Explorer: Invalid JSON provided', err); // eslint-disable-line no-console\n }\n } else {\n proceed = false;\n }\n if (proceed) {\n for (const prop in tmpObj) {\n formUrlDynParams.append(prop, JSON.stringify(tmpObj[prop]));\n }\n fetchOptions.body = formUrlDynParams;\n curlData = ` \\\\\\n -d ${formUrlDynParams.toString()}`;\n }\n } else {\n // url-encoded Form Params (regular)\n const formUrlEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='form-urlencode']\")];\n const formUrlParams = new URLSearchParams();\n formUrlEls\n .filter((v) => (v.type !== 'file'))\n .forEach((el) => {\n if (el.dataset.array === 'false') {\n if (el.value) {\n formUrlParams.append(el.dataset.pname, el.value);\n }\n } else {\n const vals = (el.value && Array.isArray(el.value)) ? el.value.join(',') : '';\n formUrlParams.append(el.dataset.pname, vals);\n }\n });\n fetchOptions.body = formUrlParams;\n curlData = ` \\\\\\n -d ${formUrlParams.toString()}`;\n }\n } else if (requestBodyType.includes('form-data')) {\n const formDataParams = new FormData();\n const formDataEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='form-data']\")];\n formDataEls.forEach((el) => {\n if (el.dataset.array === 'false') {\n if (el.type === 'file' && el.files[0]) {\n formDataParams.append(el.dataset.pname, el.files[0], el.files[0].name);\n curlForm += ` \\\\\\n -F \"${el.dataset.pname}=@${el.files[0].name}\"`;\n } else if (el.value) {\n formDataParams.append(el.dataset.pname, el.value);\n curlForm += ` \\\\\\n -F \"${el.dataset.pname}=${el.value}\"`;\n }\n } else if (el.value && Array.isArray(el.value)) {\n el.value.forEach((v) => {\n curlForm += ` \\\\\\n -F \"${el.dataset.pname}[]=${v}\"`;\n });\n formDataParams.append(el.dataset.pname, el.value.join(','));\n }\n });\n fetchOptions.body = formDataParams;\n } else if (mediaFileRegex.test(requestBodyType) || textFileRegex.test(requestBodyType)) {\n const bodyParamFileEl = requestPanelEl.querySelector('.request-body-param-file');\n if (bodyParamFileEl && bodyParamFileEl.files[0]) {\n fetchOptions.body = bodyParamFileEl.files[0];\n curlData = ` \\\\\\n --data-binary @${bodyParamFileEl.files[0].name}`;\n }\n } else if (requestBodyType.includes('json') || requestBodyType.includes('xml') || requestBodyType.includes('text')) {\n const exampleTextAreaEl = requestPanelEl.querySelector('.request-body-param-user-input');\n if (exampleTextAreaEl && exampleTextAreaEl.value) {\n fetchOptions.body = exampleTextAreaEl.value;\n if (requestBodyType.includes('json')) {\n try {\n curlData = ` \\\\\\n -d '${JSON.stringify(JSON.parse(exampleTextAreaEl.value))}'`;\n } catch (err) { /* Ignore unparseable JSON */ }\n }\n\n if (!curlData) {\n // Save single quotes wrapped => 'text' => `\"'\"text\"'\"`\n curlData = ` \\\\\\n -d '${exampleTextAreaEl.value.replace(/'/g, '\\'\"\\'\"\\'')}'`;\n }\n }\n }\n // Common for all request-body\n if (!requestBodyType.includes('form-data')) {\n // For multipart/form-data don't set the content-type to allow creation of browser generated part boundaries\n fetchOptions.headers.append('Content-Type', requestBodyType);\n }\n }\n\n this.responseIsBlob = false;\n this.respContentDisposition = '';\n if (this.responseBlobUrl) {\n URL.revokeObjectURL(this.responseBlobUrl);\n this.responseBlobUrl = '';\n }\n\n if (this.fetchCredentials) {\n fetchOptions.credentials = this.fetchCredentials;\n }\n\n // Options is legacy usage, documentation has been updated to reference properties of the fetch option directly, but older usages may still be using options\n const fetchRequest = { explorerLocation: this.elementId, url: fetchUrl.toString(), options: fetchOptions, ...fetchOptions };\n const event = {\n bubbles: true,\n composed: true,\n detail: {\n request: fetchRequest,\n },\n };\n this.dispatchEvent(new CustomEvent('before-try', event));\n this.dispatchEvent(new CustomEvent('request', event));\n const newFetchOptions = {\n method: fetchRequest.method || fetchOptions.method,\n headers: fetchRequest.headers || fetchOptions.headers,\n credentials: fetchRequest.credentials || fetchOptions.credentials,\n body: fetchRequest.body || fetchOptions.body\n };\n const fetchRequestObject = new Request(fetchRequest.url, newFetchOptions);\n\n const curl = `curl -X ${this.method.toUpperCase()} \"${fetchUrl.toString()}\"`;\n const curlHeaders = [...newFetchOptions.headers.entries()].reduce((acc, [key, value]) => `${acc} \\\\\\n -H \"${key}: ${value}\"`, '');\n this.curlSyntax = `${curl}${curlHeaders}${curlData}${curlForm}`;\n\n let fetchResponse;\n try {\n let respBlob;\n let respJson;\n let respText;\n tryBtnEl.disabled = true;\n const fetchStart = new Date();\n\n this.responseStatus = '';\n this.responseMessage = '';\n this.responseUrl = '';\n this.responseHeaders = '';\n this.responseText = '⌛';\n\n this.requestUpdate();\n const awaiter = new Promise(resolve => setTimeout(resolve, 200));\n fetchResponse = await fetch(fetchRequestObject);\n this.responseElapsedMs = new Date() - fetchStart;\n await awaiter;\n\n tryBtnEl.disabled = false;\n this.responseStatus = fetchResponse.ok ? 'success' : 'error';\n this.responseMessage = fetchResponse.statusText ? `${fetchResponse.statusText} (${fetchResponse.status})` : fetchResponse.status;\n this.responseUrl = fetchResponse.url;\n this.responseHeaders = '';\n const headers = {};\n fetchResponse.headers.forEach((hdrVal, hdr) => {\n this.responseHeaders = `${this.responseHeaders}${hdr.trim()}: ${hdrVal}\\n`;\n headers[hdr.trim()] = hdrVal && hdrVal.trim();\n });\n const contentType = fetchResponse.headers.get('content-type');\n const respEmpty = (await fetchResponse.clone().text()).length === 0;\n if (respEmpty) {\n this.responseText = '';\n } else if (contentType) {\n if (contentType.includes('json')) {\n if ((/charset=[^\"']+/).test(contentType)) {\n const encoding = contentType.split('charset=')[1];\n const buffer = await fetchResponse.arrayBuffer();\n try {\n respText = new TextDecoder(encoding).decode(buffer);\n } catch (_) {\n respText = new TextDecoder('utf-8').decode(buffer);\n }\n try {\n this.responseText = JSON.stringify(JSON.parse(respText), null, 8);\n } catch (_) {\n this.responseText = respText;\n }\n } else {\n respJson = await fetchResponse.json();\n this.responseText = JSON.stringify(respJson, null, 8);\n }\n } else if (textFileRegex.test(contentType)) {\n this.responseIsBlob = true;\n this.responseBlobType = 'download';\n } else if (mediaFileRegex.test(contentType)) {\n this.responseIsBlob = true;\n this.responseBlobType = 'view';\n } else {\n respText = await fetchResponse.text();\n if (contentType.includes('xml')) {\n this.responseText = formatXml(respText, { textNodesOnSameLine: true, indentor: ' ' });\n } else {\n this.responseText = respText;\n }\n }\n if (this.responseIsBlob) {\n const contentDisposition = fetchResponse.headers.get('content-disposition');\n const filenameRegex = /filename[^;=\\n]*=((['\"]).*?\\2|[^;\\n]*)/;\n const filename = filenameRegex.exec(contentDisposition);\n this.respContentDisposition = filename && filename[1] && filename[1].replace(/['\"]/g, '') || `download.${mimeTypeResolver.extension(contentType) || 'file'}`;\n respBlob = await fetchResponse.blob();\n this.responseBlobUrl = URL.createObjectURL(respBlob);\n }\n } else {\n respText = await fetchResponse.text();\n this.responseText = respText;\n }\n const responseEvent = {\n bubbles: true,\n composed: true,\n detail: {\n explorerLocation: this.elementId,\n request: fetchRequest,\n response: {\n headers,\n body: respJson || respText || respBlob || fetchResponse.body,\n status: fetchResponse.status,\n },\n },\n };\n this.dispatchEvent(new CustomEvent('after-try', responseEvent));\n this.dispatchEvent(new CustomEvent('response', responseEvent));\n } catch (error) {\n tryBtnEl.disabled = false;\n this.responseMessage = `${error.message} (Check the browser network tab for more information.)`;\n this.responseStatus = 'error';\n const responseEvent = {\n bubbles: true,\n composed: true,\n detail: {\n explorerLocation: this.elementId,\n error,\n request: fetchRequest,\n },\n };\n document.dispatchEvent(new CustomEvent('after-try', responseEvent));\n document.dispatchEvent(new CustomEvent('response', responseEvent));\n }\n }\n\n onAddRemoveFileInput(e, pname, ptype) {\n if (e.target.tagName.toLowerCase() !== 'button') {\n return;\n }\n\n if (e.target.classList.contains('file-input-remove-btn')) {\n // Remove File Input Set\n const el = e.target.closest('.input-set');\n el.remove();\n return;\n }\n const el = e.target.closest('.file-input-container');\n\n // Add File Input Set\n\n // Container\n const newInputContainerEl = document.createElement('div');\n newInputContainerEl.setAttribute('class', 'input-set row');\n\n // File Input\n const newInputEl = document.createElement('input');\n newInputEl.type = 'file';\n newInputEl.setAttribute('class', 'file-input');\n newInputEl.setAttribute('data-pname', pname);\n newInputEl.setAttribute('data-ptype', ptype.includes('form-urlencode') ? 'form-urlencode' : 'form-data');\n newInputEl.setAttribute('data-array', 'false');\n newInputEl.setAttribute('data-file-array', 'true');\n\n // Remover Button\n const newRemoveBtnEl = document.createElement('button');\n newRemoveBtnEl.setAttribute('class', 'file-input-remove-btn');\n newRemoveBtnEl.innerHTML = '&#x2715;';\n\n newInputContainerEl.appendChild(newInputEl);\n newInputContainerEl.appendChild(newRemoveBtnEl);\n el.insertBefore(newInputContainerEl, e.target);\n // el.appendChild(newInputContainerEl);\n }\n\n downloadResponseBlob() {\n if (this.responseBlobUrl) {\n const a = document.createElement('a');\n document.body.appendChild(a);\n a.style = 'display: none';\n a.href = this.responseBlobUrl;\n a.download = this.respContentDisposition;\n a.click();\n a.remove();\n }\n }\n\n viewResponseBlob() {\n if (this.responseBlobUrl) {\n const a = document.createElement('a');\n document.body.appendChild(a);\n a.style = 'display: none';\n a.href = this.responseBlobUrl;\n a.target = '_blank';\n a.click();\n a.remove();\n }\n }\n\n clearResponseData() {\n this.responseUrl = '';\n this.responseHeaders = '';\n this.responseText = '';\n this.responseStatus = '';\n this.responseMessage = '';\n this.responseElapsedMs = 0;\n this.responseIsBlob = false;\n this.responseBlobType = '';\n this.respContentDisposition = '';\n if (this.responseBlobUrl) {\n URL.revokeObjectURL(this.responseBlobUrl);\n this.responseBlobUrl = '';\n }\n }\n\n requestParamFunction(event) {\n if (event.key === 'Enter') {\n this.onTryClick();\n event.preventDefault();\n }\n }\n\n disconnectedCallback() {\n // Cleanup ObjectURL forthe blob data if this component created one\n if (this.responseBlobUrl) {\n URL.revokeObjectURL(this.responseBlobUrl);\n this.responseBlobUrl = '';\n }\n super.disconnectedCallback();\n }\n}\n\n// Register the element with the browser\nif (!customElements.get('openapi-explorer')) {\n customElements.define('api-request', ApiRequest);\n}\n"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"openapi-explorer.min.js","mappings":";;AA8BA;AC4iBA;AA5BA;AAmDA","sources":["webpack://openapi-explorer/./src/templates/code-samples-template.js","webpack://openapi-explorer/./src/components/api-request.js"],"sourcesContent":["import { html } from 'lit';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport Prism from 'prismjs';\nimport { copyToClipboard } from '../utils/common-utils';\nimport { getI18nText } from '../languages';\n\n/* eslint-disable indent */\nexport default function codeSamplesTemplate(xCodeSamples) {\n return html`\n <section class=\"table-title top-gap\"> CODE SAMPLES </div>\n <div class=\"tab-panel col\"\n @click=\"${\n (e) => {\n if (!e.target.classList.contains('tab-btn')) { return; }\n const clickedTab = e.target.dataset.tab;\n\n const tabButtons = [...e.currentTarget.querySelectorAll('.tab-btn')];\n const tabContents = [...e.currentTarget.querySelectorAll('.tab-content')];\n tabButtons.forEach((tabBtnEl) => tabBtnEl.classList[tabBtnEl.dataset.tab === clickedTab ? 'add' : 'remove']('active'));\n tabContents.forEach((tabBodyEl) => { tabBodyEl.style.display = (tabBodyEl.dataset.tab === clickedTab ? 'block' : 'none'); });\n }\n }\">\n <div class=\"tab-buttons row\" style=\"width:100; overflow\">\n ${xCodeSamples.map((v, i) => html`<button class=\"tab-btn ${i === 0 ? 'active' : ''}\" data-tab = '${v.lang}${i}'> ${v.label || v.lang} </button>`)}\n </div>\n ${xCodeSamples.map((v, i) => {\n const paddingToRemove = Math.min(...v.source.split('\\n').slice(1).map(l => l.match(/^(\\s+).*$/)?.[1].length).filter(l => typeof l !== 'undefined'));\n const sanitizedSource = v.source.split('\\n').map(s => s.substring(0, paddingToRemove).match(/^\\s+$/) ? s.substring(paddingToRemove) : s);\n const fullSource = sanitizedSource.join('\\n');\n return html`\n <div class=\"tab-content m-markdown code-sample-wrapper\" style= \"display:${i === 0 ? 'block' : 'none'}\" data-tab = '${v.lang}${i}'>\n <button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(v.source, e); }}'>${getI18nText('operations.copy')}</button>\n <pre><code>${Prism.languages[v.lang?.toLowerCase()] ? unsafeHTML(Prism.highlight(fullSource, Prism.languages[v.lang?.toLowerCase()], v.lang?.toLowerCase())) : fullSource}\n </code></pre>\n </div>`;\n })\n }\n </section>`;\n}\n/* eslint-enable indent */\n","import { LitElement, html } from 'lit';\nimport { marked } from 'marked';\nimport Prism from 'prismjs';\nimport mimeTypeResolver from './mime-types';\n\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport formatXml from 'xml-but-prettier';\n\nimport { copyToClipboard } from '../utils/common-utils';\nimport { getI18nText } from '../languages';\nimport { schemaInObjectNotation, getTypeInfo, generateExample } from '../utils/schema-utils';\nimport './json-tree';\nimport './schema-tree';\nimport getRequestFormTable from './request-form-table';\nimport './tag-input';\n\nconst textFileRegex = RegExp('^font/|tar$|zip$|7z$|rtf$|msword$|excel$|/pdf$|/octet-stream$|^application/vnd.');\nconst mediaFileRegex = RegExp('^audio/|^image/|^video/');\n\nexport default class ApiRequest extends LitElement {\n createRenderRoot() { return this; }\n\n constructor() {\n super();\n this.responseMessage = '';\n this.responseStatus = '';\n this.responseHeaders = '';\n this.responseText = '';\n this.responseUrl = '';\n this.responseElapsedMs = 0;\n this.curlSyntax = '';\n this.activeResponseTab = 'response'; // allowed values: response, headers, curl\n this.selectedRequestBodyType = '';\n this.selectedRequestBodyExample = '';\n }\n\n static get properties() {\n return {\n serverUrl: { type: String, attribute: 'server-url' },\n servers: { type: Array },\n method: { type: String },\n path: { type: String },\n elementId: { type: String, attribute: 'element-id' },\n parameters: { type: Array },\n request_body: { type: Object },\n api_keys: { type: Array },\n parser: { type: Object },\n accept: { type: String },\n callback: { type: String },\n responseMessage: { type: String, attribute: false },\n responseText: { type: String, attribute: false },\n responseHeaders: { type: String, attribute: false },\n responseStatus: { type: String, attribute: false },\n responseUrl: { type: String, attribute: false },\n responseElapsedMs: { type: Number, attribute: false },\n fillRequestWithDefault: { type: String, attribute: 'fill-defaults' },\n includeNulls: { type: Boolean, attribute: 'display-nulls', converter(value) { return value === 'true'; } },\n allowTry: { type: String, attribute: 'enable-console' },\n renderStyle: { type: String, attribute: 'render-style' },\n schemaStyle: { type: String, attribute: 'schema-style' },\n activeSchemaTab: { type: String, attribute: 'active-schema-tab' },\n schemaExpandLevel: { type: Number, attribute: 'schema-expand-level' },\n schemaHideReadOnly: { type: String, attribute: 'schema-hide-read-only' },\n fetchCredentials: { type: String, attribute: 'fetch-credentials' },\n\n // properties for internal tracking\n activeResponseTab: { type: String }, // internal tracking of response-tab not exposed as a attribute\n selectedRequestBodyType: { type: String, attribute: 'selected-request-body-type' }, // internal tracking of selected request-body type\n selectedRequestBodyExample: { type: String, attribute: 'selected-request-body-example' }, // internal tracking of selected request-body example\n };\n }\n\n render() {\n return html`\n <div class=\"api-request col regular-font request-panel ${(this.renderStyle === 'focused' || this.callback === 'true') ? 'focused-mode' : 'view-mode'}\">\n <div class=\" ${this.callback === 'true' ? 'tiny-title' : 'req-res-title'} \"> \n ${this.callback === 'true' ? 'CALLBACK REQUEST' : getI18nText('operations.request')}\n </div>\n <div>\n ${this.inputParametersTemplate('path')}\n ${this.inputParametersTemplate('query')}\n ${this.requestBodyTemplate()}\n ${this.inputParametersTemplate('header')}\n ${this.inputParametersTemplate('cookie')}\n ${this.allowTry === 'false' ? '' : html`${this.apiCallTemplate()}`}\n </div> \n </div>\n `;\n }\n\n updated(changedProperties) {\n if (changedProperties.has('elementId')) {\n this.selectedRequestBodyType = '';\n this.selectedRequestBodyExample = '';\n }\n\n // In focused mode after rendering the request component, update the text-areas(which contains examples) using the original values from hidden textareas.\n // This is done coz, user may update the dom by editing the textarea's and once the DOM is updated externally change detection wont happen, therefore update the values manually\n if (this.renderStyle !== 'focused') {\n return;\n }\n\n // dont update example as only tabs is switched\n if (changedProperties.size === 1 && changedProperties.has('activeSchemaTab')) {\n return;\n }\n\n const exampleTextAreaEls = [...this.querySelectorAll('textarea[data-ptype=\"form-data\"]')];\n exampleTextAreaEls.forEach((el) => {\n const origExampleEl = this.querySelector(`textarea[data-pname='hidden-${el.dataset.pname}']`);\n if (origExampleEl) {\n el.value = origExampleEl.value;\n }\n });\n }\n\n /* eslint-disable indent */\n inputParametersTemplate(paramLocation) {\n const filteredParams = this.parameters ? this.parameters.filter((param) => param.in === paramLocation) : [];\n if (filteredParams.length === 0) {\n return '';\n }\n\n const title = {\n path: 'PATH PARAMETERS',\n query: 'QUERY-STRING PARAMETERS',\n header: 'REQUEST HEADERS',\n cookie: 'COOKIES'\n }[paramLocation];\n\n const tableRows = [];\n for (const param of filteredParams) {\n if (!param.schema) {\n continue;\n }\n const paramSchema = getTypeInfo(param.schema, { includeNulls: this.includeNulls });\n if (!paramSchema) {\n continue;\n }\n const defaultVal = Array.isArray(paramSchema.default) ? paramSchema.default : `${paramSchema.default}`;\n let paramStyle = 'form';\n let paramExplode = true;\n if (paramLocation === 'query') {\n if (param.style && 'form spaceDelimited pipeDelimited'.includes(param.style)) {\n paramStyle = param.style;\n }\n if (typeof param.explode === 'boolean') {\n paramExplode = param.explode;\n }\n }\n\n tableRows.push(html`\n <tr> \n <td colspan=\"1\" style=\"width:160px; min-width:50px; vertical-align: top\">\n <div class=\"param-name ${paramSchema.deprecated ? 'deprecated' : ''}\" style=\"margin-top: 1rem;\">\n ${param.name}${!paramSchema.deprecated && param.required ? html`<span style='color:var(--red);'>*</span>` : ''}\n </div>\n <div class=\"param-type\" style=\"margin-bottom: 1rem;\">\n ${paramSchema.type === 'array'\n ? `${paramSchema.arrayType}`\n : `${paramSchema.format ? paramSchema.format : paramSchema.type}`\n }${!paramSchema.deprecated && param.required ? html`<span style='opacity: 0;'>*</span>` : ''}\n </div>\n </td> \n <td colspan=\"2\" style=\"min-width:160px; vertical-align: top\">\n ${this.allowTry === 'true'\n ? paramSchema.type === 'array' && html`\n <tag-input class=\"request-param\" \n style = \"width:100%; margin-top: 1rem; margin-bottom: 1rem;\" \n data-ptype = \"${paramLocation}\"\n data-pname = \"${param.name}\"\n data-default = \"${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}\"\n data-param-serialize-style = \"${paramStyle}\"\n data-param-serialize-explode = \"${paramExplode}\"\n data-array = \"true\"\n placeholder=\"${paramSchema.example || (Array.isArray(defaultVal) ? defaultVal[0] : defaultVal) || 'add-multiple ↩'}\"\n .value = \"${Array.isArray(defaultVal) ? defaultVal : defaultVal.split(',')}\"></tag-input>`\n || paramSchema.type === 'object' && html`\n <textarea \n class = \"textarea small request-param\"\n part = \"textarea small textarea-param\"\n rows = 3\n data-ptype = \"${paramLocation}\"\n data-pname = \"${param.name}\"\n data-default = \"${defaultVal}\"\n data-param-serialize-style = \"${paramStyle}\"\n data-param-serialize-explode = \"${paramExplode}\"\n spellcheck = \"false\"\n placeholder=\"${paramSchema.example || defaultVal || ''}\"\n style = \"width:100%; margin-top: 1rem; margin-bottom: 1rem;\"\n .value=\"${this.fillRequestWithDefault === 'true' ? defaultVal : ''}\"></textarea>`\n || html`\n <input type=\"${paramSchema.format === 'password' ? 'password' : 'text'}\" spellcheck=\"false\" style=\"width:100%; margin-top: 1rem; margin-bottom: 1rem;\"\n placeholder=\"${paramSchema.example || defaultVal || ''}\"\n class=\"request-param\"\n part=\"textbox textbox-param\"\n data-ptype=\"${paramLocation}\"\n data-pname=\"${param.name}\" \n data-default=\"${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}\"\n data-array=\"false\"\n @keyup=\"${this.requestParamFunction}\"\n .value=\"${this.fillRequestWithDefault === 'true' ? defaultVal : ''}\"\n />`\n : ''}\n\n <div style=\"min-width:50px; margin-bottom: 1rem;\">\n ${this.exampleListTemplate.call(this, param, paramSchema.type)}\n </div>\n </td>\n ${this.renderStyle === 'focused'\n ? html`\n <td colspan=\"2\" style=\"vertical-align: top\">\n ${param.description\n ? html`\n <div class=\"param-description\" style=\"margin-top: 1rem;\">\n ${unsafeHTML(marked(param.description))}\n </div>`\n : ''\n }\n ${paramSchema.default || paramSchema.s || paramSchema.allowedValues || paramSchema.pattern\n ? html`\n <div class=\"param-constraint\" style=\"margin-top: 1rem;\">\n ${paramSchema.constraints.length ? html`<span style=\"font-weight:bold\">Constraints: </span>${paramSchema.constraints.join(', ')}<br>` : ''}\n ${paramSchema.pattern ? html`\n <div class=\"tooltip tooltip-replace\" style=\"cursor: pointer; max-width: 100%; display: flex;\">\n <div style=\"white-space:nowrap; font-weight:bold; margin-right: 2px;\">Pattern: </div>\n <div style=\"white-space:nowrap; text-overflow:ellipsis; max-width:100%; overflow:hidden;\">${paramSchema.pattern}</div>\n <br>\n <div class=\"tooltip-text\" style=\"position: absolute; display:block;\">${paramSchema.pattern}</div>\n </div>\n ` : ''}\n ${paramSchema.allowedValues && paramSchema.allowedValues.split('┃').map((v, i) => html`\n ${i > 0 ? '|' : html`<span style=\"font-weight:bold\">Allowed: </span>`}\n ${html`\n <a part=\"anchor anchor-param-constraint\" class = \"${this.allowTry === 'true' ? '' : 'inactive-link'}\"\n data-type=\"${paramSchema.type === 'array' ? 'array' : 'string'}\"\n data-enum=\"${v.trim()}\"\n @click=\"${(e) => {\n const inputEl = e.target.closest('table').querySelector(`[data-pname=\"${param.name}\"]`);\n if (inputEl) {\n inputEl.value = e.target.dataset.type === 'array' ? [e.target.dataset.enum] : e.target.dataset.enum;\n }\n }}\"\n >\n ${v} \n </a>`\n }`)}\n </div>`\n : ''\n }\n </td> \n </tr>`\n : ''\n }\n `);\n }\n\n return html`\n <div class=\"table-title top-gap\">${title}${paramLocation === 'path' ? html`<span style='color:var(--red);'>*</span>` : ''}</div>\n <div style=\"display:block; overflow-x:auto; max-width:100%;\">\n <table role=\"presentation\" class=\"m-table\" style=\"width:100%; word-break:break-word;\">\n ${tableRows}\n </table>\n </div>`;\n }\n\n renderExample(example, paramType, paramName) {\n return html`\n <a\n part=\"anchor anchor-param-example\"\n class=\"${this.allowTry === 'true' ? '' : 'inactive-link'}\"\n data-example-type=\"${paramType === 'array' ? paramType : 'string'}\"\n data-example=\"${Array.isArray(example.exampleValue) ? example.exampleValue?.join('~|~') : example.exampleValue}\"\n @click=\"${(e) => {\n const inputEl = e.target.closest('table').querySelector(`[data-pname=\"${paramName}\"]`);\n if (inputEl) {\n inputEl.value = paramType === 'array' ? (e.target.dataset.example.split('~|~') || []) : e.target.dataset.example;\n }\n }}\">${Array.isArray(example.exampleValue) ? example.exampleValue?.join(', ') : example.exampleValue}\n </a>\n `;\n }\n\n renderShortFormatExamples(examples, paramType, paramName) {\n return html`${examples.map((example, i) => html`\n ${i === 0 ? '' : '┃'}\n ${this.renderExample(example, paramType, paramName)}`)}`;\n }\n\n renderLongFormatExamples(exampleList, paramType, paramName) {\n return html`\n <ul style=\"margin-block-start: 0.25em;\">\n ${exampleList.map(example =>\n html`\n <li>\n ${this.renderExample(example, paramType, paramName)}\n ${example.exampleSummary?.length > 0 ? html`<span>&lpar;${example.exampleSummary}&rpar;</span>` : ''}\n ${example.exampleDescription?.length > 0 ? html`<p>${unsafeHTML(marked(example.exampleDescription))}</p>` : ''}\n </li>`\n )}\n </ul>`;\n }\n\n /* eslint-disable indent */\n\n exampleListTemplate(param, paramType) {\n const paramName = param.name;\n const paramSchema = getTypeInfo(param.schema, { includeNulls: this.includeNulls });\n\n const examples = generateExample(\n param.examples || param.example && { Example: { value: param.example } } || paramSchema.examples || paramSchema.example && { Example: { value: paramSchema.example } },\n null, param.schema, null, false, true, 'json', false);\n\n const someExampleWithSummaryOrDescription = examples.some((x) => x.exampleSummary?.length > 0 || x.exampleDescription?.length > 0);\n if (examples.length === 1) {\n return html` ${examples.length > 0\n ? html`<span style=\"font-weight:bold\">Example: </span>\n ${\n someExampleWithSummaryOrDescription\n ? this.renderLongFormatExamples(examples, paramType, paramName)\n : this.renderShortFormatExamples(examples, paramType, paramName)\n }`\n : ''}`;\n }\n\n return html` ${examples.length > 1\n ? html`<span style=\"font-weight:bold\">Examples: </span>\n ${\n someExampleWithSummaryOrDescription\n ? this.renderLongFormatExamples(examples, paramType, paramName)\n : this.renderShortFormatExamples(examples, paramType, paramName)\n }`\n : ''}`;\n }\n\n resetRequestBodySelection() {\n this.selectedRequestBodyType = '';\n this.selectedRequestBodyExample = '';\n this.clearResponseData();\n }\n\n // Request-Body Event Handlers\n onSelectExample(e) {\n this.selectedRequestBodyExample = e.target.value;\n const exampleDropdownEl = e.target;\n window.setTimeout((selectEl) => {\n const exampleTextareaEl = selectEl.closest('.example-panel').querySelector('.request-body-param');\n const userInputExampleTextareaEl = selectEl.closest('.example-panel').querySelector('.request-body-param-user-input');\n userInputExampleTextareaEl.value = exampleTextareaEl.value;\n }, 0, exampleDropdownEl);\n }\n\n onMimeTypeChange(e) {\n this.selectedRequestBodyType = e.target.value;\n const mimeDropdownEl = e.target;\n this.selectedRequestBodyExample = '';\n window.setTimeout((selectEl) => {\n const exampleTextareaEl = selectEl.closest('.request-body-container').querySelector('.request-body-param');\n if (exampleTextareaEl) {\n const userInputExampleTextareaEl = selectEl.closest('.request-body-container').querySelector('.request-body-param-user-input');\n userInputExampleTextareaEl.value = exampleTextareaEl.value;\n }\n }, 0, mimeDropdownEl);\n }\n\n requestBodyTemplate() {\n if (!this.request_body) {\n return '';\n }\n if (Object.keys(this.request_body).length === 0) {\n return '';\n }\n\n if (this.method === 'get' || this.method === 'head') {\n return '';\n }\n\n // Variable to store partial HTMLs\n let reqBodyTypeSelectorHtml = '';\n let reqBodyFileInputHtml = '';\n let reqBodySchemaHtml = '';\n let reqBodyDefaultHtml = '';\n let bodyTabNameUseBody = true;\n\n const requestBodyTypes = [];\n const content = this.request_body.content;\n for (const mimeType in content) {\n requestBodyTypes.push({\n mimeType,\n schema: content[mimeType].schema,\n example: content[mimeType].example,\n examples: content[mimeType].examples,\n });\n }\n\n if (!content[this.selectedRequestBodyType]) {\n this.selectedRequestBodyType = requestBodyTypes[0]?.mimeType;\n }\n\n // MIME Type selector\n reqBodyTypeSelectorHtml = requestBodyTypes.length === 1\n ? ''\n : html`\n <select aria-label=\"mime type\" style=\"min-width:100px; max-width:100%; margin-bottom:-1px;\" @change = '${(e) => this.onMimeTypeChange(e)}'>\n ${requestBodyTypes.map((reqBody) => html`\n <option value = '${reqBody.mimeType}' ?selected = '${reqBody.mimeType === this.selectedRequestBodyType}'>\n ${reqBody.mimeType}\n </option> `)\n }\n </select>\n `;\n\n // For Loop - Main\n const reqBody = requestBodyTypes.find(req => req.mimeType === this.selectedRequestBodyType);\n // Generate Example\n if (this.selectedRequestBodyType.includes('json') || this.selectedRequestBodyType.includes('xml') || this.selectedRequestBodyType.includes('text')) {\n const reqBodyExamples = generateExample(\n reqBody.examples ? reqBody.examples : '',\n reqBody.example ? reqBody.example : '',\n reqBody.schema,\n reqBody.mimeType,\n false,\n true,\n 'text',\n true\n );\n\n if (!this.selectedRequestBodyExample) {\n this.selectedRequestBodyExample = (reqBodyExamples.length > 0 ? reqBodyExamples[0].exampleId : '');\n }\n const displayedBodyExample = reqBodyExamples.find(v => v.exampleId === this.selectedRequestBodyExample) || reqBodyExamples[0];\n reqBodyDefaultHtml = html`\n <div class = 'example-panel border-top pad-top-8'>\n ${reqBodyExamples.length === 1\n ? ''\n : html`\n <select aria-label='request body example' style=\"min-width:100px; max-width:100%; margin-bottom:-1px;\" @change='${(e) => this.onSelectExample(e)}'>\n ${reqBodyExamples.map((v) => html`<option value=\"${v.exampleId}\" ?selected=${v.exampleId === this.selectedRequestBodyExample}> \n ${v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary ? v.exampleSummary : v.exampleId} \n </option>`)}\n </select>`\n }\n ${displayedBodyExample ? html`\n <div class=\"example\" data-default = '${displayedBodyExample.exampleId}'>\n ${displayedBodyExample.exampleSummary && displayedBodyExample.exampleSummary.length > 80 ? html`<div style=\"padding: 4px 0\"> ${displayedBodyExample.exampleSummary} </div>` : ''}\n ${displayedBodyExample.exampleDescription ? html`<div class=\"m-markdown-small\" style=\"padding: 4px 0\"> ${unsafeHTML(marked(displayedBodyExample.exampleDescription || ''))} </div>` : ''}\n <!-- this textarea is for user to edit the example -->\n <slot name=\"${this.elementId}--request-body\">\n <textarea \n class = \"textarea request-body-param-user-input\"\n part = \"textarea textarea-param\"\n spellcheck = \"false\"\n data-ptype = \"${reqBody.mimeType}\" \n data-default = \"${displayedBodyExample.exampleFormat === 'text' ? displayedBodyExample.exampleValue : JSON.stringify(displayedBodyExample.exampleValue, null, 8)}\"\n data-default-format = \"${displayedBodyExample.exampleFormat}\"\n style=\"width:100%; resize:vertical;\"\n .value=\"${this.fillRequestWithDefault === 'true' ? (displayedBodyExample.exampleFormat === 'text' ? displayedBodyExample.exampleValue : JSON.stringify(displayedBodyExample.exampleValue, null, 8)) : ''}\"\n ></textarea>\n </slot>\n\n <!-- This textarea(hidden) is to store the original example value, this will remain unchanged when users switches from one example to another, its is used to populate the editable textarea -->\n <textarea \n class = \"textarea is-hidden request-body-param ${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)}\" \n spellcheck = \"false\"\n data-ptype = \"${reqBody.mimeType}\" \n style=\"width:100%; resize:vertical; display:none\"\n .value=\"${(displayedBodyExample.exampleFormat === 'text' ? displayedBodyExample.exampleValue : JSON.stringify(displayedBodyExample.exampleValue, null, 8))}\"\n ></textarea>\n </div>`\n : ''}\n\n </div>\n `;\n } else if (this.selectedRequestBodyType.includes('form-urlencoded') || this.selectedRequestBodyType.includes('form-data')) {\n bodyTabNameUseBody = false;\n const schemaAsObj = schemaInObjectNotation(reqBody.schema, { includeNulls: this.includeNulls });\n reqBodyDefaultHtml = getRequestFormTable.call(this, schemaAsObj, this.selectedRequestBodyType);\n } else if (mediaFileRegex.test(this.selectedRequestBodyType) || textFileRegex.test(this.selectedRequestBodyType)) {\n reqBodyFileInputHtml = html`\n <div class = \"small-font-size bold-text row\">\n <input type=\"file\" part=\"file-input\" style=\"max-width:100%\" class=\"request-body-param-file\" data-ptype=\"${reqBody.mimeType}\" spellcheck=\"false\" />\n </div> \n `;\n }\n\n // Generate Schema\n if (reqBody.mimeType.includes('json') || reqBody.mimeType.includes('xml') || reqBody.mimeType.includes('text') || reqBody.mimeType.includes('form-')) {\n const schemaAsObj = schemaInObjectNotation(reqBody.schema, { includeNulls: this.includeNulls });\n if (this.schemaStyle === 'table') {\n reqBodySchemaHtml = html`\n ${reqBodySchemaHtml}\n <schema-table\n class = '${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)} pad-top-8'\n style = 'display: ${this.selectedRequestBodyType === reqBody.mimeType ? 'block' : 'none'};'\n .data = '${schemaAsObj}'\n schema-expand-level = \"${this.schemaExpandLevel}\"\n schema-hide-read-only = \"${this.schemaHideReadOnly.includes(this.method)}\"\n schema-hide-write-only = false\n > </schema-table>\n `;\n } else {\n reqBodySchemaHtml = html`\n ${reqBodySchemaHtml}\n <schema-tree\n class = '${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)} pad-top-8'\n style = 'display: ${this.selectedRequestBodyType === reqBody.mimeType ? 'block' : 'none'};'\n .data = '${schemaAsObj}'\n schema-expand-level = \"${this.schemaExpandLevel}\"\n schema-hide-read-only = \"${this.schemaHideReadOnly.includes(this.method)}\"\n schema-hide-write-only = false\n > </schema-tree>\n `;\n }\n }\n\n return html`\n <div class='request-body-container' data-selected-request-body-type=\"${this.selectedRequestBodyType}\">\n <div class=\"table-title top-gap row\">\n REQUEST BODY ${this.request_body.required ? html`<span class=\"mono-font\" style='color:var(--red)'>*</span>` : ''} \n <span style = \"font-weight:normal; margin-left:5px\"> ${this.selectedRequestBodyType}</span>\n <span style=\"flex:1\"></span>\n ${reqBodyTypeSelectorHtml}\n </div>\n ${this.request_body.description ? html`<div class=\"m-markdown\" style=\"margin-bottom:12px\">${unsafeHTML(marked(this.request_body.description))}</div>` : ''}\n \n ${reqBodySchemaHtml || reqBodyDefaultHtml\n ? html`\n <div class=\"tab-panel col\" style=\"border-width:0 0 1px 0;\">\n <div class=\"tab-buttons row\" @click=\"${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}\">\n <button class=\"tab-btn ${this.activeSchemaTab === 'model' ? 'active' : ''}\" data-tab=\"model\" >${getI18nText('operations.model')}</button>\n <button class=\"tab-btn ${this.activeSchemaTab !== 'model' ? 'active' : ''}\" data-tab=\"body\">${bodyTabNameUseBody ? getI18nText('operations.body') : getI18nText('operations.form')}</button>\n </div>\n ${html`<div class=\"tab-content col\" style=\"display: ${this.activeSchemaTab === 'model' ? 'block' : 'none'}\"> ${reqBodySchemaHtml}</div>`}\n ${html`<div class=\"tab-content col\" style=\"display: ${this.activeSchemaTab === 'model' ? 'none' : 'block'}\"> ${reqBodyDefaultHtml}</div>`}\n </div>`\n : html`${reqBodyFileInputHtml}`\n }\n </div> \n `;\n }\n\n // formDataTemplate(schema, mimeType, exampleValue = '') {\n // return html`\n // <textarea\n // class = \"textarea dynamic-form-param ${mimeType}\"\n // part = \"textarea textarea-param\"\n // spellcheck = \"false\"\n // data-pname=\"dynamic-form\"\n // data-ptype=\"${mimeType}\"\n // style=\"width:100%\"\n // >${exampleValue}</textarea>\n // ${schema.description ? html`<span class=\"m-markdown-small\">${unsafeHTML(marked(schema.description))}</span>` : ''}\n // `;\n // }\n\n apiResponseTabTemplate() {\n const responseFormat = this.responseHeaders.includes('json') ? 'json' : (this.responseHeaders.includes('html') || this.responseHeaders.includes('xml')) ? 'html' : '';\n return html`\n <div class=\"row\" style=\"font-size:var(--font-size-small); margin:5px 0\">\n ${this.responseMessage\n ? html`<div class=\"response-message ${this.responseStatus}\">Response Status: ${this.responseMessage}\n ${this.responseElapsedMs ? html`<span><br>Execution Time: ${this.responseElapsedMs}ms</span>` : ''}\n </div>` : ''\n }\n <div style=\"flex:1\"></div>\n <button class=\"m-btn\" part=\"btn btn-outline\" @click=\"${this.clearResponseData}\">CLEAR RESPONSE</button>\n </div>\n <div class=\"tab-panel col\" style=\"border-width:0 0 1px 0;\">\n <div id=\"tab_buttons\" class=\"tab-buttons row\" @click=\"${(e) => {\n if (e.target.classList.contains('tab-btn') === false) { return; }\n this.activeResponseTab = e.target.dataset.tab;\n }}\">\n <button class=\"tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}\" data-tab = 'response'>${getI18nText('operations.response')}</button>\n <button class=\"tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}\" data-tab = 'headers'>${getI18nText('operations.response-headers')}</button>\n <button class=\"tab-btn ${this.activeResponseTab === 'curl' ? 'active' : ''}\" data-tab = 'curl'>CURL</button>\n </div>\n ${this.responseIsBlob\n ? html`\n <div class=\"tab-content col\" style=\"flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};\">\n <button class=\"m-btn thin-border mar-top-8\" style=\"width:135px\" @click=\"${this.downloadResponseBlob}\" part=\"btn btn-outline\">DOWNLOAD</button>\n ${this.responseBlobType === 'view'\n ? html`<button class=\"m-btn thin-border mar-top-8\" style=\"width:135px\" @click=\"${this.viewResponseBlob}\" part=\"btn btn-outline\">VIEW (NEW TAB)</button>`\n : ''\n }\n </div>`\n : html`\n <div class=\"tab-content col m-markdown\" style=\"flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};\" >\n ${this.responseText\n ? html`<button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(this.responseText, e); }}' part=\"btn btn-fill\">${getI18nText('operations.copy')}</button>`\n : ''\n }\n <pre style=\"min-height: 60px\" @copy='${() => { copyToClipboard(window.getSelection().toString()); }}'>${responseFormat\n ? html`<code>${unsafeHTML(Prism.highlight(this.responseText, Prism.languages[responseFormat], responseFormat))}</code>`\n : `${this.responseText}`\n }\n </pre>\n </div>`\n }\n <div class=\"tab-content col m-markdown\" style=\"flex:1;display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'};\" >\n <button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(this.responseHeaders, e); }}' part=\"btn btn-fill\">${getI18nText('operations.copy')}</button>\n <pre><code>${unsafeHTML(Prism.highlight(this.responseHeaders, Prism.languages.css, 'css'))}</code></pre>\n </div>\n <div class=\"tab-content col m-markdown\" style=\"flex:1;display:${this.activeResponseTab === 'curl' ? 'flex' : 'none'};\">\n <button class=\"m-btn outline-primary toolbar-copy-btn\" @click='${(e) => { copyToClipboard(this.curlSyntax, e); }}' part=\"btn btn-fill\">${getI18nText('operations.copy')}</button>\n <pre class=\"fs-exclude\" data-hj-suppress data-sl=\"mask\">\n <code>${unsafeHTML(Prism.highlight(this.curlSyntax.trim(), Prism.languages.shell, 'shell'))}</code>\n </pre>\n </div>\n </div>`;\n }\n\n apiCallTemplate() {\n return html`\n <div style=\"display:flex; align-items:flex-end; margin:16px 0; font-size:var(--font-size-small);\">\n ${\n this.parameters.length > 0 || this.request_body\n ? html`\n <button class=\"m-btn thin-border\" part=\"btn btn-outline\" style=\"margin-right:5px;\" @click=\"${this.onClearRequestData}\">\n ${getI18nText('operations.clear')}\n </button>`\n : ''\n }\n <button class=\"m-btn primary btn-execute thin-border\" part=\"btn btn-fill btn-try\" @click=\"${this.onTryClick}\">${getI18nText('operations.execute')}</button>\n </div>\n ${this.responseMessage === '' ? '' : this.apiResponseTabTemplate()}\n `;\n }\n /* eslint-enable indent */\n\n onClearRequestData(e) {\n const requestPanelEl = e.target.closest('.request-panel');\n const requestPanelInputEls = [...requestPanelEl.querySelectorAll('input, tag-input, textarea:not(.is-hidden)')];\n requestPanelInputEls.forEach((el) => { el.value = ''; });\n\n const event = { bubbles: true, composed: true, detail: { explorerLocation: this.elementId, operation: { method: this.method, path: this.path }, type: 'RequestCleared' } };\n this.dispatchEvent(new CustomEvent('event', event));\n }\n\n async onTryClick() {\n const tryBtnEl = this.querySelectorAll('.btn-execute')[0];\n let curlData = '';\n let curlForm = '';\n const closestRespContainer = this.closest('.expanded-req-resp-container, .req-resp-container');\n const respEl = closestRespContainer && closestRespContainer.getElementsByTagName('api-response')[0];\n const acceptHeader = respEl?.selectedMimeType;\n const requestPanelEl = this.closest('.request-panel');\n const pathParamEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='path']\")];\n const queryParamEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='query']\")];\n const queryParamObjTypeEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='query-object']\")];\n const headerParamEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='header']\")];\n const requestBodyContainerEl = requestPanelEl.querySelector('.request-body-container');\n\n let pathUrl = `${this.serverUrl.replace(/\\/$/, '')}${this.path.replaceAll(' ', '')}`;\n\n // Generate URL using Path Params\n pathParamEls.map((el) => {\n pathUrl = pathUrl.replace(`{${el.dataset.pname}}`, encodeURIComponent(el.value) || '-');\n });\n\n // Handle relative serverUrls\n if (!pathUrl.startsWith('http')) {\n const newUrl = new URL(pathUrl, window.location.href);\n pathUrl = newUrl.toString();\n }\n\n const fetchUrl = new URL(pathUrl);\n\n const fetchOptions = {\n method: this.method.toUpperCase(),\n headers: new Headers()\n };\n\n // Query Params\n if (queryParamEls.length > 0) {\n queryParamEls.forEach((el) => {\n if (el.dataset.array === 'false') {\n if (el.value !== '') {\n fetchUrl.searchParams.append(el.dataset.pname, el.value);\n }\n } else {\n const paramSerializeStyle = el.dataset.paramSerializeStyle;\n const paramSerializeExplode = el.dataset.paramSerializeExplode;\n let vals = ((el.value && Array.isArray(el.value)) ? el.value : []);\n vals = Array.isArray(vals) ? vals.filter((v) => v !== '') : [];\n if (vals.length > 0) {\n if (paramSerializeStyle === 'spaceDelimited') {\n fetchUrl.searchParams.append(el.dataset.pname, vals.join(' ').replace(/^\\s|\\s$/g, ''));\n } else if (paramSerializeStyle === 'pipeDelimited') {\n fetchUrl.searchParams.append(el.dataset.pname, vals.join('|').replace(/^\\||\\|$/g, ''));\n } else {\n if (paramSerializeExplode === 'true') { // eslint-disable-line no-lonely-if\n vals.forEach((v) => { fetchUrl.searchParams.append(el.dataset.pname, v); });\n } else {\n fetchUrl.searchParams.append(el.dataset.pname, vals.join(',').replace(/^,|,$/g, ''));\n }\n }\n }\n }\n });\n }\n\n // Query Params (Dynamic - create from JSON)\n if (queryParamObjTypeEls.length > 0) {\n queryParamObjTypeEls.map((el) => {\n try {\n let queryParamObj = {};\n const paramSerializeStyle = el.dataset.paramSerializeStyle;\n const paramSerializeExplode = el.dataset.paramSerializeExplode;\n queryParamObj = Object.assign(queryParamObj, JSON.parse(el.value.replace(/\\s+/g, ' ')));\n for (const key in queryParamObj) {\n if (typeof queryParamObj[key] === 'object') {\n if (Array.isArray(queryParamObj[key])) {\n if (paramSerializeStyle === 'spaceDelimited') {\n fetchUrl.searchParams.append(key, queryParamObj[key].join(' '));\n } else if (paramSerializeStyle === 'pipeDelimited') {\n fetchUrl.searchParams.append(key, queryParamObj[key].join('|'));\n } else {\n if (paramSerializeExplode === 'true') { // eslint-disable-line no-lonely-if\n queryParamObj[key].forEach((v) => {\n fetchUrl.searchParams.append(key, v);\n });\n } else {\n fetchUrl.searchParams.append(key, queryParamObj[key]);\n }\n }\n }\n } else {\n fetchUrl.searchParams.append(key, queryParamObj[key]);\n }\n }\n } catch (err) {\n console.log('OpenAPI Explorer: unable to parse %s into object', el.value); // eslint-disable-line no-console\n }\n });\n }\n\n // Add Authentication api keys if provided\n this.api_keys.filter((v) => v.finalKeyValue).forEach((v) => {\n if (v.in === 'query') {\n fetchUrl.searchParams.append(v.name, v.finalKeyValue);\n return;\n }\n\n // Otherwise put it in the header\n fetchOptions.headers.append(v.name, v.finalKeyValue);\n });\n\n if (acceptHeader) {\n // Uses the acceptHeader from Response panel\n fetchOptions.headers.append('Accept', acceptHeader);\n } else if (this.accept) {\n fetchOptions.headers.append('Accept', this.accept);\n }\n\n // Add Header Params\n headerParamEls.map((el) => {\n if (el.value) {\n fetchOptions.headers.append(el.dataset.pname, el.value);\n }\n });\n\n // Request Body Params\n if (requestBodyContainerEl) {\n const requestBodyType = requestBodyContainerEl.dataset.selectedRequestBodyType;\n if (requestBodyType.includes('form-urlencoded')) {\n // url-encoded Form Params (dynamic) - Parse JSON and generate Params\n const formUrlDynamicTextAreaEl = requestPanelEl.querySelector(\"[data-ptype='dynamic-form']\");\n if (formUrlDynamicTextAreaEl) {\n const val = formUrlDynamicTextAreaEl.value;\n const formUrlDynParams = new URLSearchParams();\n let proceed = true;\n let tmpObj;\n if (val) {\n try {\n tmpObj = JSON.parse(val);\n } catch (err) {\n proceed = false;\n console.warn('OpenAPI Explorer: Invalid JSON provided', err); // eslint-disable-line no-console\n }\n } else {\n proceed = false;\n }\n if (proceed) {\n for (const prop in tmpObj) {\n formUrlDynParams.append(prop, JSON.stringify(tmpObj[prop]));\n }\n fetchOptions.body = formUrlDynParams;\n curlData = ` \\\\\\n -d ${formUrlDynParams.toString()}`;\n }\n } else {\n // url-encoded Form Params (regular)\n const formUrlEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='form-urlencode']\")];\n const formUrlParams = new URLSearchParams();\n formUrlEls\n .filter((v) => (v.type !== 'file'))\n .forEach((el) => {\n if (el.dataset.array === 'false') {\n if (el.value) {\n formUrlParams.append(el.dataset.pname, el.value);\n }\n } else {\n const vals = (el.value && Array.isArray(el.value)) ? el.value.join(',') : '';\n formUrlParams.append(el.dataset.pname, vals);\n }\n });\n fetchOptions.body = formUrlParams;\n curlData = ` \\\\\\n -d ${formUrlParams.toString()}`;\n }\n } else if (requestBodyType.includes('form-data')) {\n const formDataParams = new FormData();\n const formDataEls = [...requestPanelEl.querySelectorAll(\"[data-ptype='form-data']\")];\n formDataEls.forEach((el) => {\n if (el.dataset.array === 'false') {\n if (el.type === 'file' && el.files[0]) {\n formDataParams.append(el.dataset.pname, el.files[0], el.files[0].name);\n curlForm += ` \\\\\\n -F \"${el.dataset.pname}=@${el.files[0].name}\"`;\n } else if (el.value) {\n formDataParams.append(el.dataset.pname, el.value);\n curlForm += ` \\\\\\n -F \"${el.dataset.pname}=${el.value}\"`;\n }\n } else if (el.value && Array.isArray(el.value)) {\n el.value.forEach((v) => {\n curlForm += ` \\\\\\n -F \"${el.dataset.pname}[]=${v}\"`;\n });\n formDataParams.append(el.dataset.pname, el.value.join(','));\n }\n });\n fetchOptions.body = formDataParams;\n } else if (mediaFileRegex.test(requestBodyType) || textFileRegex.test(requestBodyType)) {\n const bodyParamFileEl = requestPanelEl.querySelector('.request-body-param-file');\n if (bodyParamFileEl && bodyParamFileEl.files[0]) {\n fetchOptions.body = bodyParamFileEl.files[0];\n curlData = ` \\\\\\n --data-binary @${bodyParamFileEl.files[0].name}`;\n }\n } else if (requestBodyType.includes('json') || requestBodyType.includes('xml') || requestBodyType.includes('text')) {\n const exampleTextAreaEl = requestPanelEl.querySelector('.request-body-param-user-input');\n if (exampleTextAreaEl && exampleTextAreaEl.value) {\n fetchOptions.body = exampleTextAreaEl.value;\n if (requestBodyType.includes('json')) {\n try {\n curlData = ` \\\\\\n -d '${JSON.stringify(JSON.parse(exampleTextAreaEl.value))}'`;\n } catch (err) { /* Ignore unparseable JSON */ }\n }\n\n if (!curlData) {\n // Save single quotes wrapped => 'text' => `\"'\"text\"'\"`\n curlData = ` \\\\\\n -d '${exampleTextAreaEl.value.replace(/'/g, '\\'\"\\'\"\\'')}'`;\n }\n }\n }\n // Common for all request-body\n if (!requestBodyType.includes('form-data')) {\n // For multipart/form-data don't set the content-type to allow creation of browser generated part boundaries\n fetchOptions.headers.append('Content-Type', requestBodyType);\n }\n }\n\n this.responseIsBlob = false;\n this.respContentDisposition = '';\n if (this.responseBlobUrl) {\n URL.revokeObjectURL(this.responseBlobUrl);\n this.responseBlobUrl = '';\n }\n\n if (this.fetchCredentials) {\n fetchOptions.credentials = this.fetchCredentials;\n }\n\n // Options is legacy usage, documentation has been updated to reference properties of the fetch option directly, but older usages may still be using options\n const fetchRequest = { explorerLocation: this.elementId, url: fetchUrl.toString(), options: fetchOptions, ...fetchOptions };\n const event = {\n bubbles: true,\n composed: true,\n detail: {\n request: fetchRequest,\n },\n };\n this.dispatchEvent(new CustomEvent('before-try', event));\n this.dispatchEvent(new CustomEvent('request', event));\n const newFetchOptions = {\n method: fetchRequest.method || fetchOptions.method,\n headers: fetchRequest.headers || fetchOptions.headers,\n credentials: fetchRequest.credentials || fetchOptions.credentials,\n body: fetchRequest.body || fetchOptions.body\n };\n const fetchRequestObject = new Request(fetchRequest.url, newFetchOptions);\n\n const curl = `curl -X ${this.method.toUpperCase()} \"${fetchUrl.toString()}\"`;\n const curlHeaders = [...newFetchOptions.headers.entries()].reduce((acc, [key, value]) => `${acc} \\\\\\n -H \"${key}: ${value}\"`, '');\n this.curlSyntax = `${curl}${curlHeaders}${curlData}${curlForm}`;\n\n let fetchResponse;\n try {\n let respBlob;\n let respJson;\n let respText;\n tryBtnEl.disabled = true;\n const fetchStart = new Date();\n\n this.responseStatus = '';\n this.responseMessage = '';\n this.responseUrl = '';\n this.responseHeaders = '';\n this.responseText = '⌛';\n\n this.requestUpdate();\n const awaiter = new Promise(resolve => setTimeout(resolve, 200));\n fetchResponse = await fetch(fetchRequestObject);\n this.responseElapsedMs = new Date() - fetchStart;\n await awaiter;\n\n tryBtnEl.disabled = false;\n this.responseStatus = fetchResponse.ok ? 'success' : 'error';\n this.responseMessage = fetchResponse.statusText ? `${fetchResponse.statusText} (${fetchResponse.status})` : fetchResponse.status;\n this.responseUrl = fetchResponse.url;\n this.responseHeaders = '';\n const headers = {};\n fetchResponse.headers.forEach((hdrVal, hdr) => {\n this.responseHeaders = `${this.responseHeaders}${hdr.trim()}: ${hdrVal}\\n`;\n headers[hdr.trim()] = hdrVal && hdrVal.trim();\n });\n const contentType = fetchResponse.headers.get('content-type');\n const respEmpty = (await fetchResponse.clone().text()).length === 0;\n if (respEmpty) {\n this.responseText = '';\n } else if (contentType) {\n if (contentType.includes('json')) {\n if ((/charset=[^\"']+/).test(contentType)) {\n const encoding = contentType.split('charset=')[1];\n const buffer = await fetchResponse.arrayBuffer();\n try {\n respText = new TextDecoder(encoding).decode(buffer);\n } catch (_) {\n respText = new TextDecoder('utf-8').decode(buffer);\n }\n try {\n this.responseText = JSON.stringify(JSON.parse(respText), null, 8);\n } catch (_) {\n this.responseText = respText;\n }\n } else {\n respJson = await fetchResponse.json();\n this.responseText = JSON.stringify(respJson, null, 8);\n }\n } else if (textFileRegex.test(contentType)) {\n this.responseIsBlob = true;\n this.responseBlobType = 'download';\n } else if (mediaFileRegex.test(contentType)) {\n this.responseIsBlob = true;\n this.responseBlobType = 'view';\n } else {\n respText = await fetchResponse.text();\n if (contentType.includes('xml')) {\n this.responseText = formatXml(respText, { textNodesOnSameLine: true, indentor: ' ' });\n } else {\n this.responseText = respText;\n }\n }\n if (this.responseIsBlob) {\n const contentDisposition = fetchResponse.headers.get('content-disposition');\n const filenameRegex = /filename[^;=\\n]*=((['\"]).*?\\2|[^;\\n]*)/;\n const filename = filenameRegex.exec(contentDisposition);\n this.respContentDisposition = filename && filename[1] && filename[1].replace(/['\"]/g, '') || `download.${mimeTypeResolver.extension(contentType) || 'file'}`;\n respBlob = await fetchResponse.blob();\n this.responseBlobUrl = URL.createObjectURL(respBlob);\n }\n } else {\n respText = await fetchResponse.text();\n this.responseText = respText;\n }\n const responseEvent = {\n bubbles: true,\n composed: true,\n detail: {\n explorerLocation: this.elementId,\n request: fetchRequest,\n response: {\n headers,\n body: respJson || respText || respBlob || fetchResponse.body,\n status: fetchResponse.status,\n },\n },\n };\n this.dispatchEvent(new CustomEvent('after-try', responseEvent));\n this.dispatchEvent(new CustomEvent('response', responseEvent));\n } catch (error) {\n tryBtnEl.disabled = false;\n this.responseMessage = `${error.message} (Check the browser network tab for more information.)`;\n this.responseStatus = 'error';\n const responseEvent = {\n bubbles: true,\n composed: true,\n detail: {\n explorerLocation: this.elementId,\n error,\n request: fetchRequest,\n },\n };\n document.dispatchEvent(new CustomEvent('after-try', responseEvent));\n document.dispatchEvent(new CustomEvent('response', responseEvent));\n }\n }\n\n onAddRemoveFileInput(e, pname, ptype) {\n if (e.target.tagName.toLowerCase() !== 'button') {\n return;\n }\n\n if (e.target.classList.contains('file-input-remove-btn')) {\n // Remove File Input Set\n const el = e.target.closest('.input-set');\n el.remove();\n return;\n }\n const el = e.target.closest('.file-input-container');\n\n // Add File Input Set\n\n // Container\n const newInputContainerEl = document.createElement('div');\n newInputContainerEl.setAttribute('class', 'input-set row');\n\n // File Input\n const newInputEl = document.createElement('input');\n newInputEl.type = 'file';\n newInputEl.setAttribute('class', 'file-input');\n newInputEl.setAttribute('data-pname', pname);\n newInputEl.setAttribute('data-ptype', ptype.includes('form-urlencode') ? 'form-urlencode' : 'form-data');\n newInputEl.setAttribute('data-array', 'false');\n newInputEl.setAttribute('data-file-array', 'true');\n\n // Remover Button\n const newRemoveBtnEl = document.createElement('button');\n newRemoveBtnEl.setAttribute('class', 'file-input-remove-btn');\n newRemoveBtnEl.innerHTML = '&#x2715;';\n\n newInputContainerEl.appendChild(newInputEl);\n newInputContainerEl.appendChild(newRemoveBtnEl);\n el.insertBefore(newInputContainerEl, e.target);\n // el.appendChild(newInputContainerEl);\n }\n\n downloadResponseBlob() {\n if (this.responseBlobUrl) {\n const a = document.createElement('a');\n document.body.appendChild(a);\n a.style = 'display: none';\n a.href = this.responseBlobUrl;\n a.download = this.respContentDisposition;\n a.click();\n a.remove();\n }\n }\n\n viewResponseBlob() {\n if (this.responseBlobUrl) {\n const a = document.createElement('a');\n document.body.appendChild(a);\n a.style = 'display: none';\n a.href = this.responseBlobUrl;\n a.target = '_blank';\n a.click();\n a.remove();\n }\n }\n\n clearResponseData() {\n this.responseUrl = '';\n this.responseHeaders = '';\n this.responseText = '';\n this.responseStatus = '';\n this.responseMessage = '';\n this.responseElapsedMs = 0;\n this.responseIsBlob = false;\n this.responseBlobType = '';\n this.respContentDisposition = '';\n if (this.responseBlobUrl) {\n URL.revokeObjectURL(this.responseBlobUrl);\n this.responseBlobUrl = '';\n }\n }\n\n requestParamFunction(event) {\n if (event.key === 'Enter') {\n this.onTryClick();\n event.preventDefault();\n }\n }\n\n disconnectedCallback() {\n // Cleanup ObjectURL forthe blob data if this component created one\n if (this.responseBlobUrl) {\n URL.revokeObjectURL(this.responseBlobUrl);\n this.responseBlobUrl = '';\n }\n super.disconnectedCallback();\n }\n}\n\n// Register the element with the browser\nif (!customElements.get('openapi-explorer')) {\n customElements.define('api-request', ApiRequest);\n}\n"],"names":[],"sourceRoot":""}
@@ -228,7 +228,7 @@ export default class ApiRequest extends LitElement {
228
228
  }
229
229
  }
230
230
 
231
- tableRows.push(html` <tr> <td colspan="1" style="width:160px;min-width:50px;vertical-align:top"> <div class="param-name ${paramSchema.deprecated ? 'deprecated' : ''}" style="margin-top:1rem"> ${param.name}${!paramSchema.deprecated && param.required ? html`<span style="color:var(--red)">*</span>` : ''} </div> <div class="param-type" style="margin-bottom:1rem"> ${paramSchema.type === 'array' ? `${paramSchema.arrayType}` : `${paramSchema.format ? paramSchema.format : paramSchema.type}`}${!paramSchema.deprecated && param.required ? html`<span style="opacity:0">*</span>` : ''} </div> </td> <td colspan="2" style="min-width:160px;vertical-align:top"> ${this.allowTry === 'true' ? paramSchema.type === 'array' && html` <tag-input class="request-param" style="width:100%;margin-top:1rem;margin-bottom:1rem" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" data-array="true" placeholder="${paramSchema.example || (Array.isArray(defaultVal) ? defaultVal[0] : defaultVal) || 'add-multiple ↩'}" .value="${Array.isArray(defaultVal) ? defaultVal : defaultVal.split(',')}"></tag-input>` || paramSchema.type === 'object' && html` <textarea class="textarea small request-param" part="textarea small textarea-param" rows="3" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" spellcheck="false" placeholder="${paramSchema.example || defaultVal || ''}" style="width:100%;margin-top:1rem;margin-bottom:1rem" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}"></textarea>` || html` <input type="${paramSchema.format === 'password' ? 'password' : 'text'}" spellcheck="false" style="width:100%;margin-top:1rem;margin-bottom:1rem" placeholder="${paramSchema.example || defaultVal || ''}" class="request-param" part="textbox textbox-param" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-array="false" @keyup="${this.requestParamFunction}" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}">` : ''} <div style="min-width:50px;margin-bottom:1rem"> ${this.exampleListTemplate.call(this, param, paramSchema.type)} </div> </td> ${this.renderStyle === 'focused' ? html` <td colspan="2"> ${param.description ? html` <div class="param-description"> ${unsafeHTML(marked(param.description))} </div>` : ''} ${paramSchema.default || paramSchema.s || paramSchema.allowedValues || paramSchema.pattern ? html` <div class="param-constraint"> ${paramSchema.constraints.length ? html`<span style="font-weight:700">Constraints: </span>${paramSchema.constraints.join(', ')}<br>` : ''} ${paramSchema.pattern ? html` <div class="tooltip tooltip-replace" style="cursor:pointer;max-width:100%;display:flex"> <div style="white-space:nowrap;font-weight:700;margin-right:2px">Pattern: </div> <div style="white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden">${paramSchema.pattern}</div> <br> <div class="tooltip-text" style="position:absolute;display:block">${paramSchema.pattern}</div> </div> ` : ''} ${paramSchema.allowedValues && paramSchema.allowedValues.split('┃').map((v, i) => html` ${i > 0 ? '|' : html`<span style="font-weight:700">Allowed: </span>`} ${html` <a part="anchor anchor-param-constraint" class="${this.allowTry === 'true' ? '' : 'inactive-link'}" data-type="${paramSchema.type === 'array' ? 'array' : 'string'}" data-enum="${v.trim()}" @click="${e => {
231
+ tableRows.push(html` <tr> <td colspan="1" style="width:160px;min-width:50px;vertical-align:top"> <div class="param-name ${paramSchema.deprecated ? 'deprecated' : ''}" style="margin-top:1rem"> ${param.name}${!paramSchema.deprecated && param.required ? html`<span style="color:var(--red)">*</span>` : ''} </div> <div class="param-type" style="margin-bottom:1rem"> ${paramSchema.type === 'array' ? `${paramSchema.arrayType}` : `${paramSchema.format ? paramSchema.format : paramSchema.type}`}${!paramSchema.deprecated && param.required ? html`<span style="opacity:0">*</span>` : ''} </div> </td> <td colspan="2" style="min-width:160px;vertical-align:top"> ${this.allowTry === 'true' ? paramSchema.type === 'array' && html` <tag-input class="request-param" style="width:100%;margin-top:1rem;margin-bottom:1rem" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" data-array="true" placeholder="${paramSchema.example || (Array.isArray(defaultVal) ? defaultVal[0] : defaultVal) || 'add-multiple ↩'}" .value="${Array.isArray(defaultVal) ? defaultVal : defaultVal.split(',')}"></tag-input>` || paramSchema.type === 'object' && html` <textarea class="textarea small request-param" part="textarea small textarea-param" rows="3" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" spellcheck="false" placeholder="${paramSchema.example || defaultVal || ''}" style="width:100%;margin-top:1rem;margin-bottom:1rem" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}"></textarea>` || html` <input type="${paramSchema.format === 'password' ? 'password' : 'text'}" spellcheck="false" style="width:100%;margin-top:1rem;margin-bottom:1rem" placeholder="${paramSchema.example || defaultVal || ''}" class="request-param" part="textbox textbox-param" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-array="false" @keyup="${this.requestParamFunction}" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}">` : ''} <div style="min-width:50px;margin-bottom:1rem"> ${this.exampleListTemplate.call(this, param, paramSchema.type)} </div> </td> ${this.renderStyle === 'focused' ? html` <td colspan="2" style="vertical-align:top"> ${param.description ? html` <div class="param-description" style="margin-top:1rem"> ${unsafeHTML(marked(param.description))} </div>` : ''} ${paramSchema.default || paramSchema.s || paramSchema.allowedValues || paramSchema.pattern ? html` <div class="param-constraint" style="margin-top:1rem"> ${paramSchema.constraints.length ? html`<span style="font-weight:700">Constraints: </span>${paramSchema.constraints.join(', ')}<br>` : ''} ${paramSchema.pattern ? html` <div class="tooltip tooltip-replace" style="cursor:pointer;max-width:100%;display:flex"> <div style="white-space:nowrap;font-weight:700;margin-right:2px">Pattern: </div> <div style="white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden">${paramSchema.pattern}</div> <br> <div class="tooltip-text" style="position:absolute;display:block">${paramSchema.pattern}</div> </div> ` : ''} ${paramSchema.allowedValues && paramSchema.allowedValues.split('┃').map((v, i) => html` ${i > 0 ? '|' : html`<span style="font-weight:700">Allowed: </span>`} ${html` <a part="anchor anchor-param-constraint" class="${this.allowTry === 'true' ? '' : 'inactive-link'}" data-type="${paramSchema.type === 'array' ? 'array' : 'string'}" data-enum="${v.trim()}" @click="${e => {
232
232
  const inputEl = e.target.closest('table').querySelector(`[data-pname="${param.name}"]`);
233
233
 
234
234
  if (inputEl) {
@@ -103,6 +103,8 @@ export default class SchemaTable extends LitElement {
103
103
  }
104
104
 
105
105
  if (typeof data === 'object') {
106
+ var _data$Metadata, _data$Metadata$constr;
107
+
106
108
  const flags = data['::flags'] || {};
107
109
 
108
110
  if (flags['🆁'] && this.schemaHideReadOnly === 'true') {
@@ -114,7 +116,7 @@ export default class SchemaTable extends LitElement {
114
116
  }
115
117
 
116
118
  const displayLine = [title && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
117
- return html` ${newSchemaLevel >= 0 && key ? html` <div class="tr ${newSchemaLevel <= this.schemaExpandLevel ? '' : 'collapsed'} ${data['::type']}" data-obj="${keyLabel}"> <div class="td no-select key ${data['::deprecated'] ? 'deprecated' : ''}" style="padding-left:${leftPadding}px;cursor:pointer" @click="${e => this.toggleObjectExpand(e, keyLabel)}"> <div style="display:flex;align-items:center"> ${keyLabel || keyDescr ? html`<div class="obj-toggle" data-obj="${keyLabel}">▾</div>` : ''} ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? html`<span class="xxx-of-key" style="margin-left:-6px">${keyLabel}</span><span class="${isOneOfLabel ? 'xxx-of-key' : 'xxx-of-descr'}">${keyDescr}</span>` : keyLabel.endsWith('*') ? html`<span class="key-label" style="display:inline-block;margin-left:-6px"> ${keyLabel.substring(0, keyLabel.length - 1)}</span><span style="color:var(--red)">*</span>` : html`<span class="key-label" style="display:inline-block;margin-left:-6px">${keyLabel === '::props' ? '' : keyLabel}</span>`} </div> </div> <div class="td key-type"> <div>${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}</div> <div class="attributes" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}">${flags['🆁'] || flags['🆆'] || ''}</div> </div> <div class="td key-descr"> <span class="m-markdown-small">${unsafeHTML(marked(displayLine))}</span> ${data['::metadata'].constraints.length ? html`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''} </div> </div>` : html` ${data['::type'] === 'array' && dataType === 'array' ? html`<div class="tr"> <div class="td"> ${dataType} </div> </div>` : ''} `} <div class="object-body"> ${Array.isArray(data) && data[0] ? html`${this.generateTree(data[0], 'xxx-of-option', '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : html` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? html`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} <div> </div></div>`;
119
+ return html` ${newSchemaLevel >= 0 && key ? html` <div class="tr ${newSchemaLevel <= this.schemaExpandLevel ? '' : 'collapsed'} ${data['::type']}" data-obj="${keyLabel}"> <div class="td no-select key ${data['::deprecated'] ? 'deprecated' : ''}" style="padding-left:${leftPadding}px;cursor:pointer" @click="${e => this.toggleObjectExpand(e, keyLabel)}"> <div style="display:flex;align-items:center"> ${keyLabel || keyDescr ? html`<div class="obj-toggle" data-obj="${keyLabel}">▾</div>` : ''} ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? html`<span class="xxx-of-key" style="margin-left:-6px">${keyLabel}</span><span class="${isOneOfLabel ? 'xxx-of-key' : 'xxx-of-descr'}">${keyDescr}</span>` : keyLabel.endsWith('*') ? html`<span class="key-label" style="display:inline-block;margin-left:-6px"> ${keyLabel.substring(0, keyLabel.length - 1)}</span><span style="color:var(--red)">*</span>` : html`<span class="key-label" style="display:inline-block;margin-left:-6px">${keyLabel === '::props' ? '' : keyLabel}</span>`} </div> </div> <div class="td key-type"> <div>${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}</div> <div class="attributes" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}">${flags['🆁'] || flags['🆆'] || ''}</div> </div> <div class="td key-descr"> <span class="m-markdown-small">${unsafeHTML(marked(displayLine))}</span> ${(_data$Metadata = data['::metadata']) !== null && _data$Metadata !== void 0 && (_data$Metadata$constr = _data$Metadata.constraints) !== null && _data$Metadata$constr !== void 0 && _data$Metadata$constr.length ? html`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''} </div> </div>` : html` ${data['::type'] === 'array' && dataType === 'array' ? html`<div class="tr"> <div class="td"> ${dataType} </div> </div>` : ''} `} <div class="object-body"> ${Array.isArray(data) && data[0] ? html`${this.generateTree(data[0], 'xxx-of-option', '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : html` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? html`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} <div> </div></div>`;
118
120
  } // For Primitive Data types
119
121
 
120
122
 
@@ -142,6 +142,8 @@ export default class SchemaTree extends LitElement {
142
142
  }
143
143
 
144
144
  if (typeof data === 'object') {
145
+ var _data$Metadata, _data$Metadata$constr;
146
+
145
147
  if (flags['🆁'] && this.schemaHideReadOnly === 'true') {
146
148
  return undefined;
147
149
  }
@@ -151,7 +153,7 @@ export default class SchemaTree extends LitElement {
151
153
  }
152
154
 
153
155
  const displayLine = [flags['🆁'] || flags['🆆'], title && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
154
- return html` <div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type'] && data['::type'].startsWith('xxx-of') ? '' : 'collapsed'} ${data['::type'] || 'no-type-info'}"> <div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style="min-width:${minFieldColWidth}px"> ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? html`<span class="key-label xxx-of-key">${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>` : keyLabel === '::props' || keyLabel === '::ARRAY~OF' ? '' : schemaLevel > 0 ? html`<span class="key-label"> ${keyLabel.replace(/\*$/, '')}${keyLabel.endsWith('*') ? html`<span style="color:var(--red)">*</span>` : ''}: </span>` : ''} ${openBracket} </div> <div class="td key-descr"> <span class="m-markdown-small" style="vertical-align:middle" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}"> ${unsafeHTML(marked(displayLine))} </span> ${this.schemaDescriptionExpanded ? html` ${data['::metadata'].constraints.length ? html`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''}` : ''} </div> </div> <div class="inside-bracket-wrapper"> <div class="inside-bracket ${data['::type'] || 'no-type-info'}" style="padding-left:${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' ? 0 : leftPadding}px"> ${Array.isArray(data) && data[0] ? html`${this.generateTree(data[0], 'xxx-of-option', '', data[0]['::flags'] || {}, '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : html` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? html`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], data[dataKey]['::array-type'] || '', data[dataKey]['::flags'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} </div> ${data['::type'] && data['::type'].includes('xxx-of') ? '' : html`<div class="close-bracket"> ${closeBracket} </div>`} </div> `;
156
+ return html` <div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type'] && data['::type'].startsWith('xxx-of') ? '' : 'collapsed'} ${data['::type'] || 'no-type-info'}"> <div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style="min-width:${minFieldColWidth}px"> ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? html`<span class="key-label xxx-of-key">${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>` : keyLabel === '::props' || keyLabel === '::ARRAY~OF' ? '' : schemaLevel > 0 ? html`<span class="key-label"> ${keyLabel.replace(/\*$/, '')}${keyLabel.endsWith('*') ? html`<span style="color:var(--red)">*</span>` : ''}: </span>` : ''} ${openBracket} </div> <div class="td key-descr"> <span class="m-markdown-small" style="vertical-align:middle" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}"> ${unsafeHTML(marked(displayLine))} </span> ${this.schemaDescriptionExpanded ? html` ${(_data$Metadata = data['::metadata']) !== null && _data$Metadata !== void 0 && (_data$Metadata$constr = _data$Metadata.constraints) !== null && _data$Metadata$constr !== void 0 && _data$Metadata$constr.length ? html`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''}` : ''} </div> </div> <div class="inside-bracket-wrapper"> <div class="inside-bracket ${data['::type'] || 'no-type-info'}" style="padding-left:${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' ? 0 : leftPadding}px"> ${Array.isArray(data) && data[0] ? html`${this.generateTree(data[0], 'xxx-of-option', '', data[0]['::flags'] || {}, '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : html` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? html`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], data[dataKey]['::array-type'] || '', data[dataKey]['::flags'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} </div> ${data['::type'] && data['::type'].includes('xxx-of') ? '' : html`<div class="close-bracket"> ${closeBracket} </div>`} </div> `;
155
157
  } // For Primitive Data types
156
158
 
157
159
 
@@ -249,7 +249,7 @@ class ApiRequest extends _lit.LitElement {
249
249
  }
250
250
  }
251
251
 
252
- tableRows.push((0, _lit.html)` <tr> <td colspan="1" style="width:160px;min-width:50px;vertical-align:top"> <div class="param-name ${paramSchema.deprecated ? 'deprecated' : ''}" style="margin-top:1rem"> ${param.name}${!paramSchema.deprecated && param.required ? (0, _lit.html)`<span style="color:var(--red)">*</span>` : ''} </div> <div class="param-type" style="margin-bottom:1rem"> ${paramSchema.type === 'array' ? `${paramSchema.arrayType}` : `${paramSchema.format ? paramSchema.format : paramSchema.type}`}${!paramSchema.deprecated && param.required ? (0, _lit.html)`<span style="opacity:0">*</span>` : ''} </div> </td> <td colspan="2" style="min-width:160px;vertical-align:top"> ${this.allowTry === 'true' ? paramSchema.type === 'array' && (0, _lit.html)` <tag-input class="request-param" style="width:100%;margin-top:1rem;margin-bottom:1rem" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" data-array="true" placeholder="${paramSchema.example || (Array.isArray(defaultVal) ? defaultVal[0] : defaultVal) || 'add-multiple ↩'}" .value="${Array.isArray(defaultVal) ? defaultVal : defaultVal.split(',')}"></tag-input>` || paramSchema.type === 'object' && (0, _lit.html)` <textarea class="textarea small request-param" part="textarea small textarea-param" rows="3" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" spellcheck="false" placeholder="${paramSchema.example || defaultVal || ''}" style="width:100%;margin-top:1rem;margin-bottom:1rem" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}"></textarea>` || (0, _lit.html)` <input type="${paramSchema.format === 'password' ? 'password' : 'text'}" spellcheck="false" style="width:100%;margin-top:1rem;margin-bottom:1rem" placeholder="${paramSchema.example || defaultVal || ''}" class="request-param" part="textbox textbox-param" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-array="false" @keyup="${this.requestParamFunction}" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}">` : ''} <div style="min-width:50px;margin-bottom:1rem"> ${this.exampleListTemplate.call(this, param, paramSchema.type)} </div> </td> ${this.renderStyle === 'focused' ? (0, _lit.html)` <td colspan="2"> ${param.description ? (0, _lit.html)` <div class="param-description"> ${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(param.description))} </div>` : ''} ${paramSchema.default || paramSchema.s || paramSchema.allowedValues || paramSchema.pattern ? (0, _lit.html)` <div class="param-constraint"> ${paramSchema.constraints.length ? (0, _lit.html)`<span style="font-weight:700">Constraints: </span>${paramSchema.constraints.join(', ')}<br>` : ''} ${paramSchema.pattern ? (0, _lit.html)` <div class="tooltip tooltip-replace" style="cursor:pointer;max-width:100%;display:flex"> <div style="white-space:nowrap;font-weight:700;margin-right:2px">Pattern: </div> <div style="white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden">${paramSchema.pattern}</div> <br> <div class="tooltip-text" style="position:absolute;display:block">${paramSchema.pattern}</div> </div> ` : ''} ${paramSchema.allowedValues && paramSchema.allowedValues.split('┃').map((v, i) => (0, _lit.html)` ${i > 0 ? '|' : (0, _lit.html)`<span style="font-weight:700">Allowed: </span>`} ${(0, _lit.html)` <a part="anchor anchor-param-constraint" class="${this.allowTry === 'true' ? '' : 'inactive-link'}" data-type="${paramSchema.type === 'array' ? 'array' : 'string'}" data-enum="${v.trim()}" @click="${e => {
252
+ tableRows.push((0, _lit.html)` <tr> <td colspan="1" style="width:160px;min-width:50px;vertical-align:top"> <div class="param-name ${paramSchema.deprecated ? 'deprecated' : ''}" style="margin-top:1rem"> ${param.name}${!paramSchema.deprecated && param.required ? (0, _lit.html)`<span style="color:var(--red)">*</span>` : ''} </div> <div class="param-type" style="margin-bottom:1rem"> ${paramSchema.type === 'array' ? `${paramSchema.arrayType}` : `${paramSchema.format ? paramSchema.format : paramSchema.type}`}${!paramSchema.deprecated && param.required ? (0, _lit.html)`<span style="opacity:0">*</span>` : ''} </div> </td> <td colspan="2" style="min-width:160px;vertical-align:top"> ${this.allowTry === 'true' ? paramSchema.type === 'array' && (0, _lit.html)` <tag-input class="request-param" style="width:100%;margin-top:1rem;margin-bottom:1rem" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" data-array="true" placeholder="${paramSchema.example || (Array.isArray(defaultVal) ? defaultVal[0] : defaultVal) || 'add-multiple ↩'}" .value="${Array.isArray(defaultVal) ? defaultVal : defaultVal.split(',')}"></tag-input>` || paramSchema.type === 'object' && (0, _lit.html)` <textarea class="textarea small request-param" part="textarea small textarea-param" rows="3" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${defaultVal}" data-param-serialize-style="${paramStyle}" data-param-serialize-explode="${paramExplode}" spellcheck="false" placeholder="${paramSchema.example || defaultVal || ''}" style="width:100%;margin-top:1rem;margin-bottom:1rem" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}"></textarea>` || (0, _lit.html)` <input type="${paramSchema.format === 'password' ? 'password' : 'text'}" spellcheck="false" style="width:100%;margin-top:1rem;margin-bottom:1rem" placeholder="${paramSchema.example || defaultVal || ''}" class="request-param" part="textbox textbox-param" data-ptype="${paramLocation}" data-pname="${param.name}" data-default="${Array.isArray(defaultVal) ? defaultVal.join('~|~') : defaultVal}" data-array="false" @keyup="${this.requestParamFunction}" .value="${this.fillRequestWithDefault === 'true' ? defaultVal : ''}">` : ''} <div style="min-width:50px;margin-bottom:1rem"> ${this.exampleListTemplate.call(this, param, paramSchema.type)} </div> </td> ${this.renderStyle === 'focused' ? (0, _lit.html)` <td colspan="2" style="vertical-align:top"> ${param.description ? (0, _lit.html)` <div class="param-description" style="margin-top:1rem"> ${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(param.description))} </div>` : ''} ${paramSchema.default || paramSchema.s || paramSchema.allowedValues || paramSchema.pattern ? (0, _lit.html)` <div class="param-constraint" style="margin-top:1rem"> ${paramSchema.constraints.length ? (0, _lit.html)`<span style="font-weight:700">Constraints: </span>${paramSchema.constraints.join(', ')}<br>` : ''} ${paramSchema.pattern ? (0, _lit.html)` <div class="tooltip tooltip-replace" style="cursor:pointer;max-width:100%;display:flex"> <div style="white-space:nowrap;font-weight:700;margin-right:2px">Pattern: </div> <div style="white-space:nowrap;text-overflow:ellipsis;max-width:100%;overflow:hidden">${paramSchema.pattern}</div> <br> <div class="tooltip-text" style="position:absolute;display:block">${paramSchema.pattern}</div> </div> ` : ''} ${paramSchema.allowedValues && paramSchema.allowedValues.split('┃').map((v, i) => (0, _lit.html)` ${i > 0 ? '|' : (0, _lit.html)`<span style="font-weight:700">Allowed: </span>`} ${(0, _lit.html)` <a part="anchor anchor-param-constraint" class="${this.allowTry === 'true' ? '' : 'inactive-link'}" data-type="${paramSchema.type === 'array' ? 'array' : 'string'}" data-enum="${v.trim()}" @click="${e => {
253
253
  const inputEl = e.target.closest('table').querySelector(`[data-pname="${param.name}"]`);
254
254
 
255
255
  if (inputEl) {
@@ -117,6 +117,8 @@ class SchemaTable extends _lit.LitElement {
117
117
  }
118
118
 
119
119
  if (typeof data === 'object') {
120
+ var _data$Metadata, _data$Metadata$constr;
121
+
120
122
  const flags = data['::flags'] || {};
121
123
 
122
124
  if (flags['🆁'] && this.schemaHideReadOnly === 'true') {
@@ -128,7 +130,7 @@ class SchemaTable extends _lit.LitElement {
128
130
  }
129
131
 
130
132
  const displayLine = [title && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
131
- return (0, _lit.html)` ${newSchemaLevel >= 0 && key ? (0, _lit.html)` <div class="tr ${newSchemaLevel <= this.schemaExpandLevel ? '' : 'collapsed'} ${data['::type']}" data-obj="${keyLabel}"> <div class="td no-select key ${data['::deprecated'] ? 'deprecated' : ''}" style="padding-left:${leftPadding}px;cursor:pointer" @click="${e => this.toggleObjectExpand(e, keyLabel)}"> <div style="display:flex;align-items:center"> ${keyLabel || keyDescr ? (0, _lit.html)`<div class="obj-toggle" data-obj="${keyLabel}">▾</div>` : ''} ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? (0, _lit.html)`<span class="xxx-of-key" style="margin-left:-6px">${keyLabel}</span><span class="${isOneOfLabel ? 'xxx-of-key' : 'xxx-of-descr'}">${keyDescr}</span>` : keyLabel.endsWith('*') ? (0, _lit.html)`<span class="key-label" style="display:inline-block;margin-left:-6px"> ${keyLabel.substring(0, keyLabel.length - 1)}</span><span style="color:var(--red)">*</span>` : (0, _lit.html)`<span class="key-label" style="display:inline-block;margin-left:-6px">${keyLabel === '::props' ? '' : keyLabel}</span>`} </div> </div> <div class="td key-type"> <div>${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}</div> <div class="attributes" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}">${flags['🆁'] || flags['🆆'] || ''}</div> </div> <div class="td key-descr"> <span class="m-markdown-small">${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(displayLine))}</span> ${data['::metadata'].constraints.length ? (0, _lit.html)`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''} </div> </div>` : (0, _lit.html)` ${data['::type'] === 'array' && dataType === 'array' ? (0, _lit.html)`<div class="tr"> <div class="td"> ${dataType} </div> </div>` : ''} `} <div class="object-body"> ${Array.isArray(data) && data[0] ? (0, _lit.html)`${this.generateTree(data[0], 'xxx-of-option', '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : (0, _lit.html)` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? (0, _lit.html)`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} <div> </div></div>`;
133
+ return (0, _lit.html)` ${newSchemaLevel >= 0 && key ? (0, _lit.html)` <div class="tr ${newSchemaLevel <= this.schemaExpandLevel ? '' : 'collapsed'} ${data['::type']}" data-obj="${keyLabel}"> <div class="td no-select key ${data['::deprecated'] ? 'deprecated' : ''}" style="padding-left:${leftPadding}px;cursor:pointer" @click="${e => this.toggleObjectExpand(e, keyLabel)}"> <div style="display:flex;align-items:center"> ${keyLabel || keyDescr ? (0, _lit.html)`<div class="obj-toggle" data-obj="${keyLabel}">▾</div>` : ''} ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? (0, _lit.html)`<span class="xxx-of-key" style="margin-left:-6px">${keyLabel}</span><span class="${isOneOfLabel ? 'xxx-of-key' : 'xxx-of-descr'}">${keyDescr}</span>` : keyLabel.endsWith('*') ? (0, _lit.html)`<span class="key-label" style="display:inline-block;margin-left:-6px"> ${keyLabel.substring(0, keyLabel.length - 1)}</span><span style="color:var(--red)">*</span>` : (0, _lit.html)`<span class="key-label" style="display:inline-block;margin-left:-6px">${keyLabel === '::props' ? '' : keyLabel}</span>`} </div> </div> <div class="td key-type"> <div>${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}</div> <div class="attributes" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}">${flags['🆁'] || flags['🆆'] || ''}</div> </div> <div class="td key-descr"> <span class="m-markdown-small">${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(displayLine))}</span> ${(_data$Metadata = data['::metadata']) !== null && _data$Metadata !== void 0 && (_data$Metadata$constr = _data$Metadata.constraints) !== null && _data$Metadata$constr !== void 0 && _data$Metadata$constr.length ? (0, _lit.html)`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''} </div> </div>` : (0, _lit.html)` ${data['::type'] === 'array' && dataType === 'array' ? (0, _lit.html)`<div class="tr"> <div class="td"> ${dataType} </div> </div>` : ''} `} <div class="object-body"> ${Array.isArray(data) && data[0] ? (0, _lit.html)`${this.generateTree(data[0], 'xxx-of-option', '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : (0, _lit.html)` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? (0, _lit.html)`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} <div> </div></div>`;
132
134
  } // For Primitive Data types
133
135
 
134
136
 
@@ -157,6 +157,8 @@ class SchemaTree extends _lit.LitElement {
157
157
  }
158
158
 
159
159
  if (typeof data === 'object') {
160
+ var _data$Metadata, _data$Metadata$constr;
161
+
160
162
  if (flags['🆁'] && this.schemaHideReadOnly === 'true') {
161
163
  return undefined;
162
164
  }
@@ -166,7 +168,7 @@ class SchemaTree extends _lit.LitElement {
166
168
  }
167
169
 
168
170
  const displayLine = [flags['🆁'] || flags['🆆'], title && `**${title}${description ? ':' : ''}**`, description].filter(v => v).join(' ');
169
- return (0, _lit.html)` <div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type'] && data['::type'].startsWith('xxx-of') ? '' : 'collapsed'} ${data['::type'] || 'no-type-info'}"> <div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style="min-width:${minFieldColWidth}px"> ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? (0, _lit.html)`<span class="key-label xxx-of-key">${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>` : keyLabel === '::props' || keyLabel === '::ARRAY~OF' ? '' : schemaLevel > 0 ? (0, _lit.html)`<span class="key-label"> ${keyLabel.replace(/\*$/, '')}${keyLabel.endsWith('*') ? (0, _lit.html)`<span style="color:var(--red)">*</span>` : ''}: </span>` : ''} ${openBracket} </div> <div class="td key-descr"> <span class="m-markdown-small" style="vertical-align:middle" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}"> ${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(displayLine))} </span> ${this.schemaDescriptionExpanded ? (0, _lit.html)` ${data['::metadata'].constraints.length ? (0, _lit.html)`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''}` : ''} </div> </div> <div class="inside-bracket-wrapper"> <div class="inside-bracket ${data['::type'] || 'no-type-info'}" style="padding-left:${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' ? 0 : leftPadding}px"> ${Array.isArray(data) && data[0] ? (0, _lit.html)`${this.generateTree(data[0], 'xxx-of-option', '', data[0]['::flags'] || {}, '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : (0, _lit.html)` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? (0, _lit.html)`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], data[dataKey]['::array-type'] || '', data[dataKey]['::flags'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} </div> ${data['::type'] && data['::type'].includes('xxx-of') ? '' : (0, _lit.html)`<div class="close-bracket"> ${closeBracket} </div>`} </div> `;
171
+ return (0, _lit.html)` <div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type'] && data['::type'].startsWith('xxx-of') ? '' : 'collapsed'} ${data['::type'] || 'no-type-info'}"> <div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style="min-width:${minFieldColWidth}px"> ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION') ? (0, _lit.html)`<span class="key-label xxx-of-key">${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>` : keyLabel === '::props' || keyLabel === '::ARRAY~OF' ? '' : schemaLevel > 0 ? (0, _lit.html)`<span class="key-label"> ${keyLabel.replace(/\*$/, '')}${keyLabel.endsWith('*') ? (0, _lit.html)`<span style="color:var(--red)">*</span>` : ''}: </span>` : ''} ${openBracket} </div> <div class="td key-descr"> <span class="m-markdown-small" style="vertical-align:middle" title="${flags['🆁'] && 'Read only attribute' || flags['🆆'] && 'Write only attribute' || ''}"> ${(0, _unsafeHtml.unsafeHTML)((0, _marked.marked)(displayLine))} </span> ${this.schemaDescriptionExpanded ? (0, _lit.html)` ${(_data$Metadata = data['::metadata']) !== null && _data$Metadata !== void 0 && (_data$Metadata$constr = _data$Metadata.constraints) !== null && _data$Metadata$constr !== void 0 && _data$Metadata$constr.length ? (0, _lit.html)`<div style="display:inline-block;line-break:anywhere;margin-right:8px"><span class="bold-text">Constraints: </span>${data['::metadata'].constraints.join(', ')}</div><br>` : ''}` : ''} </div> </div> <div class="inside-bracket-wrapper"> <div class="inside-bracket ${data['::type'] || 'no-type-info'}" style="padding-left:${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' ? 0 : leftPadding}px"> ${Array.isArray(data) && data[0] ? (0, _lit.html)`${this.generateTree(data[0], 'xxx-of-option', '', data[0]['::flags'] || {}, '::ARRAY~OF', data[0]['::title'], data[0]['::description'], newSchemaLevel, newIndentLevel)}` : (0, _lit.html)` ${Object.keys(data).map(dataKey => !['::metadata', '::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::dataTypeLabel', '::flags'].includes(dataKey) || data[dataKey]['::type'] === 'array' && data[dataKey]['::type'] === 'object' ? (0, _lit.html)`${this.generateTree(data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey], data[dataKey]['::type'], data[dataKey]['::array-type'] || '', data[dataKey]['::flags'], dataKey, data[dataKey]['::title'], data[dataKey]['::description'], newSchemaLevel, newIndentLevel)}` : '')}`} </div> ${data['::type'] && data['::type'].includes('xxx-of') ? '' : (0, _lit.html)`<div class="close-bracket"> ${closeBracket} </div>`} </div> `;
170
172
  } // For Primitive Data types
171
173
 
172
174
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-explorer",
3
- "version": "1.0.564",
3
+ "version": "1.0.567",
4
4
  "description": "OpenAPI Explorer - API viewer with dynamically generated components, documentation, and interaction console",
5
5
  "author": "Rhosys Developers <developers@rhosys.ch>",
6
6
  "type": "module",