rapidoc 9.3.4 → 9.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.html CHANGED
@@ -31,7 +31,7 @@
31
31
  https://cesdev.eng.sonicwall.com/api/q/openapi
32
32
  -->
33
33
  <rapi-doc
34
- spec-url = "./specs/temp.yaml"
34
+ spec-url = "./specs/petstore.yaml"
35
35
  id="thedoc"
36
36
  theme = "dark"
37
37
  render-style="view"
@@ -50,6 +50,7 @@
50
50
  update-route="false"
51
51
  match-type="regex"
52
52
  persist-auth="true"
53
+ scroll-behavior="smooth"
53
54
  ></rapi-doc>
54
55
  <!--
55
56
  <rapi-doc-mini
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rapidoc",
3
- "version": "9.3.4",
3
+ "version": "9.3.5",
4
4
  "description": "RapiDoc - Open API spec viewer with built in console",
5
5
  "author": "Mrinmoy Majumdar <mrin9@yahoo.com>",
6
6
  "homepage": "https://rapidocweb.com",
@@ -33,12 +33,13 @@
33
33
  "module": "dist/rapidoc-min.js",
34
34
  "mode": "production",
35
35
  "dependencies": {
36
- "@apitools/openapi-parser": "0.0.30",
36
+ "@apitools/openapi-parser": "0.0.32",
37
37
  "base64-arraybuffer": "^1.0.2",
38
38
  "buffer": "^6.0.3",
39
- "lit": "^2.6.1",
40
- "marked": "^4.2.12",
39
+ "lit": "^3.2.0",
40
+ "marked": "4.3.0",
41
41
  "prismjs": "^1.29.0",
42
+ "randexp": "^0.5.3",
42
43
  "xml-but-prettier": "^1.0.1"
43
44
  },
44
45
  "scripts": {
@@ -51,32 +52,32 @@
51
52
  "lint-fix": "./node_modules/eslint/bin/eslint.js --fix ./src/**"
52
53
  },
53
54
  "devDependencies": {
54
- "@babel/core": "^7.20.12",
55
- "@babel/eslint-parser": "^7.19.1",
56
- "@babel/preset-env": "^7.20.2",
57
- "babel-loader": "^9.1.2",
55
+ "@babel/core": "^7.25.2",
56
+ "@babel/eslint-parser": "^7.25.1",
57
+ "@babel/preset-env": "^7.25.4",
58
+ "babel-loader": "^9.2.1",
58
59
  "babel-plugin-template-html-minifier": "^4.1.0",
59
60
  "clean-webpack-plugin": "^4.0.0",
60
- "compression-webpack-plugin": "^10.0.0",
61
- "css-loader": "^6.7.3",
62
- "eslint": "^8.32.0",
61
+ "compression-webpack-plugin": "^11.1.0",
62
+ "css-loader": "^7.1.2",
63
+ "eslint": "^8.57.1",
63
64
  "eslint-config-airbnb": "^19.0.4",
64
- "eslint-import-resolver-webpack": "^0.13.2",
65
- "eslint-plugin-import": "^2.27.0",
66
- "eslint-webpack-plugin": "3.2.0",
65
+ "eslint-import-resolver-webpack": "^0.13.9",
66
+ "eslint-plugin-import": "^2.30.0",
67
+ "eslint-webpack-plugin": "4.2.0",
67
68
  "file-loader": "^6.2.0",
68
69
  "filemanager-webpack-plugin": "^8.0.0",
69
- "html-webpack-plugin": "^5.5.0",
70
+ "html-webpack-plugin": "^5.6.0",
70
71
  "inspectpack": "^4.7.1",
71
- "style-loader": "^3.3.1",
72
- "terser-webpack-plugin": "^5.3.6",
72
+ "style-loader": "^4.0.0",
73
+ "terser-webpack-plugin": "^5.3.10",
73
74
  "unminified-webpack-plugin": "^3.0.0",
74
- "webpack": "^5.75.0",
75
- "webpack-bundle-analyzer": "^4.7.0",
76
- "webpack-cli": "^5.0.1",
77
- "webpack-dev-server": "^4.11.1"
75
+ "webpack": "^5.94.0",
76
+ "webpack-bundle-analyzer": "^4.10.2",
77
+ "webpack-cli": "^5.1.4",
78
+ "webpack-dev-server": "4.11.1"
78
79
  },
79
80
  "engines": {
80
- "node": ">=10.21.0"
81
+ "node": ">=18.16.0"
81
82
  }
82
83
  }
@@ -279,7 +279,8 @@ export default class ApiRequest extends LitElement {
279
279
  style="display:inline-block; min-width:24px; text-align:center"
280
280
  class="${this.allowTry === 'true' ? '' : 'inactive-link'}"
281
281
  data-example-type="${paramType === 'array' ? paramType : 'string'}"
282
- data-example="${example.value && Array.isArray(example.value) ? example.value?.join('~|~') : example.value || ''}"
282
+ data-example="${example.value && Array.isArray(example.value) ? example.value?.join('~|~') : (typeof example.value === 'object' ? JSON.stringify(example.value, null, 2) : example.value) || ''}"
283
+ title="${example.value && Array.isArray(example.value) ? example.value?.join('~|~') : (typeof example.value === 'object' ? JSON.stringify(example.value, null, 2) : example.value) || ''}"
283
284
  @click="${(e) => {
284
285
  const inputEl = e.target.closest('table').querySelector(`[data-pname="${paramName}"]`);
285
286
  if (inputEl) {
@@ -453,7 +454,7 @@ export default class ApiRequest extends LitElement {
453
454
  data-param-allow-reserved = "${paramAllowReserved}"
454
455
  data-x-fill-example = "${param['x-fill-example'] || 'yes'}"
455
456
  spellcheck = "false"
456
- .textContent="${param['x-fill-example'] === 'no' ? '' : live(this.fillRequestFieldsWithExample === 'true' ? example.exampleVal : '')}"
457
+ .textContent="${param['x-fill-example'] === 'no' ? '' : live(this.fillRequestFieldsWithExample === 'true' ? (typeof example.exampleVal === 'object' ? JSON.stringify(example.exampleVal, null, 2) : example.exampleVal) : '')}"
457
458
  style = "resize:vertical; width:100%; height: ${'read focused'.includes(this.renderStyle) ? '180px' : '120px'};"
458
459
  @input=${(e) => {
459
460
  const requestPanelEl = this.getRequestPanel(e);
@@ -691,6 +692,12 @@ export default class ApiRequest extends LitElement {
691
692
  const requestPanelEl = this.getRequestPanel(e);
692
693
  this.liveCURLSyntaxUpdate(requestPanelEl);
693
694
  }}
695
+ @keydown=${(e) => {
696
+ if ((e.keyCode === 10 || e.keyCode === 13) && e.ctrlKey) {
697
+ return this.onTryClick(e);
698
+ }
699
+ }}
700
+
694
701
  ></textarea>
695
702
  </div>
696
703
  `)}
@@ -907,7 +914,7 @@ export default class ApiRequest extends LitElement {
907
914
  data-example = "${Array.isArray(fieldExamples) ? fieldExamples.join('~|~') : fieldExamples}"
908
915
  data-array = "true"
909
916
  placeholder = "add-multiple &#x21a9;"
910
- .value = "${Array.isArray(fieldExamples) ? Array.isArray(fieldExamples[0]) ? fieldExamples[0] : [fieldExamples[0]] : [fieldExamples]}"
917
+ .value = "${Array.isArray(fieldExamples) ? Array.isArray(fieldExamples[0]) ? fieldExamples[0] : fieldExamples : []}"
911
918
  >
912
919
  </tag-input>
913
920
  `
@@ -1052,10 +1059,14 @@ export default class ApiRequest extends LitElement {
1052
1059
  ${this.responseIsBlob
1053
1060
  ? html`
1054
1061
  <div class="tab-content col" style="flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};">
1062
+ ${this.responseBlobType === 'image'
1063
+ ? html`<img style="max-height:var(--resp-area-height, 400px); object-fit:contain;" class="mar-top-8" src="${this.responseBlobUrl}"></img>`
1064
+ : ''
1065
+ }
1055
1066
  <button class="m-btn thin-border mar-top-8" style="width:135px" @click='${(e) => { downloadResource(this.responseBlobUrl, this.respContentDisposition, e); }}' part="btn btn-outline">
1056
1067
  DOWNLOAD
1057
1068
  </button>
1058
- ${this.responseBlobType === 'view'
1069
+ ${this.responseBlobType === 'view' || this.responseBlobType === 'image'
1059
1070
  ? html`<button class="m-btn thin-border mar-top-8" style="width:135px" @click='${(e) => { viewResource(this.responseBlobUrl, e); }}' part="btn btn-outline">VIEW (NEW TAB)</button>`
1060
1071
  : ''
1061
1072
  }
@@ -1217,7 +1228,7 @@ export default class ApiRequest extends LitElement {
1217
1228
  const queryParam = new URLSearchParams();
1218
1229
  try {
1219
1230
  let queryParamObj = {};
1220
- const { paramSerializeStyle, paramSerializeExplode } = el.dataset;
1231
+ const { paramSerializeStyle, paramSerializeExplode, pname } = el.dataset;
1221
1232
  queryParamObj = Object.assign(queryParamObj, JSON.parse(el.value.replace(/\s+/g, ' ')));
1222
1233
  if (el.dataset.paramAllowReserved === 'true') {
1223
1234
  queryParamsWithReservedCharsAllowed.push(el.dataset.pname);
@@ -1230,24 +1241,25 @@ export default class ApiRequest extends LitElement {
1230
1241
  }
1231
1242
  } else {
1232
1243
  for (const key in queryParamObj) {
1244
+ const pKey = `${pname}[${key}]`;
1233
1245
  if (typeof queryParamObj[key] === 'object') {
1234
1246
  if (Array.isArray(queryParamObj[key])) {
1235
1247
  if (paramSerializeStyle === 'spaceDelimited') {
1236
- queryParam.append(key, queryParamObj[key].join(' '));
1248
+ queryParam.append(pKey, queryParamObj[key].join(' '));
1237
1249
  } else if (paramSerializeStyle === 'pipeDelimited') {
1238
- queryParam.append(key, queryParamObj[key].join('|'));
1250
+ queryParam.append(pKey, queryParamObj[key].join('|'));
1239
1251
  } else {
1240
1252
  if (paramSerializeExplode === 'true') { // eslint-disable-line no-lonely-if
1241
1253
  queryParamObj[key].forEach((v) => {
1242
- queryParam.append(key, v);
1254
+ queryParam.append(pKey, v);
1243
1255
  });
1244
1256
  } else {
1245
- queryParam.append(key, queryParamObj[key]);
1257
+ queryParam.append(pKey, queryParamObj[key]);
1246
1258
  }
1247
1259
  }
1248
1260
  }
1249
1261
  } else {
1250
- queryParam.append(key, queryParamObj[key]);
1262
+ queryParam.append(pKey, queryParamObj[key]);
1251
1263
  }
1252
1264
  }
1253
1265
  }
@@ -1459,6 +1471,23 @@ export default class ApiRequest extends LitElement {
1459
1471
  const startTime = performance.now();
1460
1472
  fetchResponse = await fetch(fetchRequest, { signal });
1461
1473
  const endTime = performance.now();
1474
+ // Allow to modify response
1475
+ /*
1476
+ let resolveModifiedResponse; // Create a promise that will be resolved from the event listener
1477
+ const modifiedResponsePromise = new Promise((resolve) => {
1478
+ resolveModifiedResponse = resolve;
1479
+ });
1480
+ this.dispatchEvent(new CustomEvent('fetched-try', {
1481
+ bubbles: true,
1482
+ composed: true,
1483
+ detail: {
1484
+ request: fetchRequest,
1485
+ response: fetchResponse,
1486
+ resolveModifiedResponse, // pass the resolver function
1487
+ },
1488
+ }));
1489
+ fetchResponse = await modifiedResponsePromise; // Wait for the modified response
1490
+ */
1462
1491
  responseClone = fetchResponse.clone(); // create a response clone to allow reading response body again (response.json, response.text etc)
1463
1492
  tryBtnEl.disabled = false;
1464
1493
  this.responseMessage = html`${fetchResponse.statusText ? `${fetchResponse.statusText}:${fetchResponse.status}` : fetchResponse.status} <div style="color:var(--light-fg)"> Took ${Math.round(endTime - startTime)} milliseconds </div>`;
@@ -1498,6 +1527,9 @@ export default class ApiRequest extends LitElement {
1498
1527
  } else if (/^font\/|tar$|zip$|7z$|rtf$|msword$|excel$|\/pdf$|\/octet-stream$|^application\/vnd\./.test(contentType)) {
1499
1528
  this.responseIsBlob = true;
1500
1529
  this.responseBlobType = 'download';
1530
+ } else if (/^image/.test(contentType)) {
1531
+ this.responseIsBlob = true;
1532
+ this.responseBlobType = 'image';
1501
1533
  } else if (/^audio|^image|^video/.test(contentType)) {
1502
1534
  this.responseIsBlob = true;
1503
1535
  this.responseBlobType = 'view';
@@ -1597,6 +1629,12 @@ export default class ApiRequest extends LitElement {
1597
1629
 
1598
1630
  curl = `curl -X ${this.method.toUpperCase()} "${curlUrl}" \\\n`;
1599
1631
 
1632
+ fetchHeaders.forEach((value, key) => {
1633
+ let tempHeaderArray = value.split(',');
1634
+ tempHeaderArray = tempHeaderArray.map((el) => el.trim()).filter((string, index) => tempHeaderArray.indexOf(string) === index);
1635
+ fetchHeaders.set(key, tempHeaderArray.join(', '));
1636
+ });
1637
+
1600
1638
  curlHeaders = Array.from(fetchHeaders).map(([key, value]) => ` -H "${key}: ${value}"`).join('\\\n');
1601
1639
  if (curlHeaders) {
1602
1640
  curlHeaders = `${curlHeaders} \\\n`;
@@ -123,7 +123,7 @@ export default class SchemaTable extends LitElement {
123
123
  `;
124
124
  }
125
125
 
126
- generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0, readOrWrite = '') {
126
+ generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0, readOrWrite = '', isDeprecated = false) {
127
127
  if (this.schemaHideReadOnly === 'true') {
128
128
  if (dataType === 'array') {
129
129
  if (readOrWrite === 'readonly') {
@@ -198,8 +198,8 @@ export default class SchemaTable extends LitElement {
198
198
  return html`
199
199
  ${newSchemaLevel >= 0 && key
200
200
  ? html`
201
- <div class='tr ${newSchemaLevel <= this.schemaExpandLevel ? 'expanded' : 'collapsed'} ${data['::type']}' data-obj='${keyLabel}' title="${data['::deprecated'] ? 'Deprecated' : ''}">
202
- <div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style='padding-left:${leftPadding}px'>
201
+ <div class='tr ${newSchemaLevel <= this.schemaExpandLevel ? 'expanded' : 'collapsed'} ${data['::type']}' data-obj='${keyLabel}' title="${isDeprecated || data['::deprecated'] ? 'Deprecated' : ''}">
202
+ <div class="td key ${isDeprecated || data['::deprecated'] ? 'deprecated' : ''}" style='padding-left:${leftPadding}px'>
203
203
  ${(keyLabel || keyDescr)
204
204
  ? html`
205
205
  <span class='obj-toggle ${newSchemaLevel < this.schemaExpandLevel ? 'expanded' : 'collapsed'}' data-obj='${keyLabel}'>
@@ -210,8 +210,8 @@ export default class SchemaTable extends LitElement {
210
210
  ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION')
211
211
  ? html`<span class="xxx-of-key" style="margin-left:-6px">${keyLabel}</span><span class="${isOneOfLabel ? 'xxx-of-key' : 'xxx-of-descr'}">${keyDescr}</span>`
212
212
  : keyLabel.endsWith('*')
213
- ? html`<span class="key-label" style="display:inline-block; margin-left:-6px;">${data['::deprecated'] ? '✗' : ''} ${keyLabel.substring(0, keyLabel.length - 1)}</span><span style='color:var(--red);'>*</span>`
214
- : html`<span class="key-label" style="display:inline-block; margin-left:-6px;">${data['::deprecated'] ? '✗' : ''} ${keyLabel === '::props' ? '' : keyLabel}</span>`
213
+ ? html`<span class="key-label" style="display:inline-block; margin-left:-6px;">${isDeprecated || data['::deprecated'] ? '✗' : ''} ${keyLabel.substring(0, keyLabel.length - 1)}</span><span style='color:var(--red);'>*</span>`
214
+ : html`<span class="key-label" style="display:inline-block; margin-left:-6px;">${isDeprecated || data['::deprecated'] ? '✗' : ''} ${keyLabel === '::props' ? '' : keyLabel}</span>`
215
215
  }
216
216
  ${data['::type'] === 'xxx-of' && dataType === 'array' ? html`<span style="color:var(--primary-color)">ARRAY</span>` : ''}
217
217
  </div>
@@ -239,10 +239,10 @@ export default class SchemaTable extends LitElement {
239
239
  ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel, '')}`
240
240
  : html`
241
241
  ${Object.keys(data).map((dataKey) => html`
242
- ${['::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite', '::dataTypeLabel'].includes(dataKey)
242
+ ${['::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite', '::dataTypeLabel', '::nullable'].includes(dataKey)
243
243
  ? data[dataKey]['::type'] === 'array' || data[dataKey]['::type'] === 'object'
244
244
  ? html`${this.generateTree(
245
- data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
245
+ data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
246
246
  data[dataKey]['::type'],
247
247
  data[dataKey]['::array-type'] || '',
248
248
  dataKey,
@@ -261,6 +261,7 @@ export default class SchemaTable extends LitElement {
261
261
  newSchemaLevel,
262
262
  newIndentLevel,
263
263
  data[dataKey]['::readwrite'] ? data[dataKey]['::readwrite'] : '',
264
+ isDeprecated || data[dataKey]['::deprecated'],
264
265
  )}`
265
266
  }
266
267
  `)}
@@ -294,9 +295,9 @@ export default class SchemaTable extends LitElement {
294
295
  </div>`;
295
296
  }
296
297
  return html`
297
- <div class = "tr primitive" title="${deprecated ? 'Deprecated' : ''}">
298
- <div class="td key ${deprecated}" style='padding-left:${leftPadding}px'>
299
- ${deprecated ? html`<span style='color:var(--red);'>✗</span>` : ''}
298
+ <div class = "tr primitive" title="${isDeprecated || deprecated ? 'Deprecated' : ''}">
299
+ <div class="td key ${isDeprecated || deprecated ? 'deprecated' : ''}" style='padding-left:${leftPadding}px'>
300
+ ${isDeprecated || deprecated ? html`<span style='color:var(--red);'>✗</span>` : ''}
300
301
  ${keyLabel?.endsWith('*')
301
302
  ? html`
302
303
  <span class="key-label">${keyLabel.substring(0, keyLabel.length - 1)}</span>
@@ -186,9 +186,9 @@ export default class SchemaTree extends LitElement {
186
186
  closeBracket = '}]';
187
187
  } else {
188
188
  if (schemaLevel < this.schemaExpandLevel) {
189
- openBracket = html`<span class="open-bracket object">{</span>`;
189
+ openBracket = html`<span class="open-bracket object">${data['::nullable'] ? 'null┃' : ''}{</span>`;
190
190
  } else {
191
- openBracket = html`<span class="open-bracket object">{...}</span>`;
191
+ openBracket = html`<span class="open-bracket object">${data['::nullable'] ? 'null┃' : ''}{...}</span>`;
192
192
  }
193
193
  closeBracket = '}';
194
194
  }
@@ -212,7 +212,7 @@ export default class SchemaTree extends LitElement {
212
212
  }
213
213
  if (typeof data === 'object') {
214
214
  return html`
215
- <div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type']?.startsWith('xxx-of') ? 'expanded' : 'collapsed'} ${data['::type'] || 'no-type-info'}" title="${data['::deprecated'] ? 'Deprecated' : ''}">
215
+ <div class="tr ${schemaLevel < this.schemaExpandLevel || data['::type']?.startsWith('xxx-of') ? 'expanded' : 'collapsed'} ${data['::type'] || 'no-type-info'}${data['::nullable'] ? ' nullable' : ''}" title="${data['::deprecated'] ? 'Deprecated' : ''}">
216
216
  <div class="td key ${data['::deprecated'] ? 'deprecated' : ''}" style='min-width:${minFieldColWidth}px'>
217
217
  ${data['::type'] === 'xxx-of-option' || data['::type'] === 'xxx-of-array' || key.startsWith('::OPTION')
218
218
  ? html`<span class='key-label xxx-of-key'> ${keyLabel}</span><span class="xxx-of-descr">${keyDescr}</span>`
@@ -234,7 +234,7 @@ export default class SchemaTree extends LitElement {
234
234
  ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel, data[0]['::readwrite'])}`
235
235
  : html`
236
236
  ${Object.keys(data).map((dataKey) => html`
237
- ${['::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite', '::dataTypeLabel'].includes(dataKey)
237
+ ${['::title', '::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite', '::dataTypeLabel', '::nullable'].includes(dataKey)
238
238
  ? data[dataKey]['::type'] === 'array' || data[dataKey]['::type'] === 'object'
239
239
  ? html`${this.generateTree(
240
240
  data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
@@ -351,6 +351,7 @@ export default class SchemaTree extends LitElement {
351
351
 
352
352
  toggleObjectExpand(e) {
353
353
  const rowEl = e.target.closest('.tr');
354
+ const nullable = rowEl.classList.contains('nullable');
354
355
  if (rowEl.classList.contains('expanded')) {
355
356
  rowEl.classList.replace('expanded', 'collapsed');
356
357
  e.target.innerHTML = e.target.classList.contains('array-of-object')
@@ -359,7 +360,7 @@ export default class SchemaTree extends LitElement {
359
360
  ? '[[...]]'
360
361
  : e.target.classList.contains('array')
361
362
  ? '[...]'
362
- : '{...}';
363
+ : `${nullable ? 'null┃' : ''}{...}`;
363
364
  } else {
364
365
  rowEl.classList.replace('collapsed', 'expanded');
365
366
  e.target.innerHTML = e.target.classList.contains('array-of-object')
@@ -367,7 +368,7 @@ export default class SchemaTree extends LitElement {
367
368
  : e.target.classList.contains('array-of-array')
368
369
  ? `[[ ${e.target.dataset.arrayType}`
369
370
  : e.target.classList.contains('object')
370
- ? '{'
371
+ ? `${nullable ? 'null┃' : ''}{`
371
372
  : '[';
372
373
  }
373
374
  }
@@ -287,6 +287,7 @@ export default class JsonSchemaViewer extends LitElement {
287
287
  specUrl,
288
288
  this.generateMissingTags === 'true',
289
289
  this.sortTags === 'true',
290
+ this.sortSchemas === 'true',
290
291
  this.getAttribute('sort-endpoints-by'),
291
292
  );
292
293
  this.loading = false;
package/src/rapidoc.js CHANGED
@@ -55,6 +55,7 @@ export default class RapiDoc extends LitElement {
55
55
  routePrefix: { type: String, attribute: 'route-prefix' },
56
56
  specUrl: { type: String, attribute: 'spec-url' },
57
57
  sortTags: { type: String, attribute: 'sort-tags' },
58
+ sortSchemas: { type: String, attribute: 'sort-schemas' },
58
59
  generateMissingTags: { type: String, attribute: 'generate-missing-tags' },
59
60
  sortEndpointsBy: { type: String, attribute: 'sort-endpoints-by' },
60
61
  specFile: { type: String, attribute: false },
@@ -99,6 +100,7 @@ export default class RapiDoc extends LitElement {
99
100
  allowSchemaDescriptionExpandToggle: { type: String, attribute: 'allow-schema-description-expand-toggle' },
100
101
  showComponents: { type: String, attribute: 'show-components' },
101
102
  pageDirection: { type: String, attribute: 'page-direction' },
103
+ scrollBehavior: { type: String, attribute: 'scroll-behavior' },
102
104
 
103
105
  // Main Colors and Font
104
106
  theme: { type: String },
@@ -491,6 +493,7 @@ export default class RapiDoc extends LitElement {
491
493
  if (!this.updateRoute || !'true, false,'.includes(`${this.updateRoute},`)) { this.updateRoute = 'true'; }
492
494
  if (!this.routePrefix) { this.routePrefix = '#'; }
493
495
  if (!this.sortTags || !'true, false,'.includes(`${this.sortTags},`)) { this.sortTags = 'false'; }
496
+ if (!this.sortSchemas || !'true, false,'.includes(`${this.sortSchemas},`)) { this.sortSchemas = 'false'; }
494
497
  if (!this.generateMissingTags || !'true, false,'.includes(`${this.generateMissingTags},`)) { this.generateMissingTags = 'false'; }
495
498
  if (!this.sortEndpointsBy || !'method, path, summary, none,'.includes(`${this.sortEndpointsBy},`)) { this.sortEndpointsBy = 'path'; }
496
499
 
@@ -511,6 +514,7 @@ export default class RapiDoc extends LitElement {
511
514
  if (!this.infoDescriptionHeadingsInNavBar || !'true, false,'.includes(`${this.infoDescriptionHeadingsInNavBar},`)) { this.infoDescriptionHeadingsInNavBar = 'false'; }
512
515
  if (!this.fetchCredentials || !'omit, same-origin, include,'.includes(`${this.fetchCredentials},`)) { this.fetchCredentials = ''; }
513
516
  if (!this.matchType || !'includes regex'.includes(this.matchType)) { this.matchType = 'includes'; }
517
+ if (!this.scrollBehavior || !'smooth, auto,'.includes(`${this.scrollBehavior},`)) { this.scrollBehavior = 'auto'; }
514
518
 
515
519
  if (!this.showAdvancedSearchDialog) { this.showAdvancedSearchDialog = false; }
516
520
 
@@ -726,6 +730,7 @@ export default class RapiDoc extends LitElement {
726
730
  specUrl,
727
731
  this.generateMissingTags === 'true',
728
732
  this.sortTags === 'true',
733
+ this.sortSchemas === 'true',
729
734
  this.getAttribute('sort-endpoints-by'),
730
735
  this.getAttribute('api-key-name'),
731
736
  this.getAttribute('api-key-location'),
@@ -860,7 +865,7 @@ export default class RapiDoc extends LitElement {
860
865
  window.setTimeout(() => {
861
866
  const gotoEl = this.shadowRoot.getElementById(tmpElementId);
862
867
  if (gotoEl) {
863
- gotoEl.scrollIntoView({ behavior: 'auto', block: 'start' });
868
+ gotoEl.scrollIntoView({ behavior: this.scrollBehavior, block: 'start' });
864
869
  if (this.updateRoute === 'true') {
865
870
  this.replaceHistoryState(tmpElementId);
866
871
  }
@@ -904,7 +909,7 @@ export default class RapiDoc extends LitElement {
904
909
  if (this.updateRoute === 'true') {
905
910
  this.replaceHistoryState(entry.target.id);
906
911
  }
907
- newNavEl.scrollIntoView({ behavior: 'auto', block: 'center' });
912
+ newNavEl.scrollIntoView({ behavior: this.scrollBehavior, block: 'center' });
908
913
  newNavEl.classList.add('active');
909
914
  newNavEl.part.add('section-navbar-active-item');
910
915
  }
@@ -925,7 +930,7 @@ export default class RapiDoc extends LitElement {
925
930
  if (e.target.getAttribute('href').startsWith('#')) {
926
931
  const gotoEl = this.shadowRoot.getElementById(e.target.getAttribute('href').replace('#', ''));
927
932
  if (gotoEl) {
928
- gotoEl.scrollIntoView({ behavior: 'auto', block: 'start' });
933
+ gotoEl.scrollIntoView({ behavior: this.scrollBehavior, block: 'start' });
929
934
  }
930
935
  }
931
936
  }
@@ -978,7 +983,7 @@ export default class RapiDoc extends LitElement {
978
983
  const contentEl = this.shadowRoot.getElementById(elementId);
979
984
  if (contentEl) {
980
985
  isValidElementId = true;
981
- contentEl.scrollIntoView({ behavior: 'auto', block: 'start' });
986
+ contentEl.scrollIntoView({ behavior: this.scrollBehavior, block: 'start' });
982
987
  } else {
983
988
  isValidElementId = false;
984
989
  }
@@ -1005,7 +1010,7 @@ export default class RapiDoc extends LitElement {
1005
1010
 
1006
1011
  if (newNavEl) {
1007
1012
  if (scrollNavItemToView) {
1008
- newNavEl.scrollIntoView({ behavior: 'auto', block: 'center' });
1013
+ newNavEl.scrollIntoView({ behavior: this.scrollBehavior, block: 'center' });
1009
1014
  }
1010
1015
  await sleep(0);
1011
1016
  const oldNavEl = this.shadowRoot.querySelector('.nav-bar-tag.active, .nav-bar-path.active, .nav-bar-info.active, .nav-bar-h1.active, .nav-bar-h2.active, .operations.active');
@@ -59,9 +59,9 @@ export default function searchByPropertiesModalTemplate() {
59
59
  }
60
60
  }"
61
61
  >
62
- <span class="upper bold-text method-fg ${path.method}">${path.method}</span>
63
- <span>${path.path}</span>
64
- <span class="regular-font gray-text">${path.summary}</span>
62
+ <span style="pointer-events: none" class="upper bold-text method-fg ${path.method}">${path.method}</span>
63
+ <span style="pointer-events: none">${path.path}</span>
64
+ <span style="pointer-events: none" class="regular-font gray-text">${path.summary}</span>
65
65
  </div>
66
66
  `)
67
67
  }
@@ -204,7 +204,7 @@ export default function endpointTemplate(showExpandCollapse = true, showTags = t
204
204
  ? html`
205
205
  <div class='regular-font section-gap section-tag ${tag.expanded ? 'expanded' : 'collapsed'}'>
206
206
  <div class='section-tag-header' @click="${() => { tag.expanded = !tag.expanded; this.requestUpdate(); }}">
207
- <div id='${tag.elementId}' class="sub-title tag" style="color:var(--primary-color)">${tag.name}</div>
207
+ <div id='${tag.elementId}' class="sub-title tag" style="color:var(--primary-color)">${tag.displayName}</div>
208
208
  </div>
209
209
  <div class='section-tag-body'>
210
210
  <slot name="${tag.elementId}"></slot>
@@ -174,7 +174,7 @@ export default function expandedEndpointTemplate() {
174
174
  return html`
175
175
  ${this.resolvedSpec.tags.map((tag) => html`
176
176
  <section id="${tag.elementId}" part="section-tag" class="regular-font section-gap--read-mode observe-me" style="border-top:1px solid var(--primary-color);">
177
- <div class="title tag" part="section-tag-title label-tag-title">${tag.name}</div>
177
+ <div class="title tag" part="section-tag-title label-tag-title">${tag.displayName}</div>
178
178
  <slot name="${tag.elementId}"></slot>
179
179
  <div class="regular-font-size">
180
180
  ${
@@ -38,7 +38,7 @@ function defaultContentTemplate() {
38
38
  /* eslint-disable indent */
39
39
  function focusedTagBodyTemplate(tag) {
40
40
  return html`
41
- <h1 id="${tag.elementId}">${tag.name}</h1>
41
+ <h1 id="${tag.elementId}">${tag.displayName}</h1>
42
42
  ${this.onNavTagClick === 'show-description' && tag.description
43
43
  ? html`
44
44
  <div class="m-markdown">
@@ -181,7 +181,7 @@ export default function navbarTemplate() {
181
181
  data-first-path-id='${tag.firstPathId}'
182
182
  tabindex='0'
183
183
  >
184
- <div style="pointer-events:none;">${tag.name}</div>
184
+ <div style="pointer-events:none;">${tag.displayName}</div>
185
185
  <div class='nav-bar-tag-icon' tabindex='0' data-action='expand-collapse-tag'></div>
186
186
  </div>
187
187
  `
@@ -257,7 +257,7 @@ export default function navbarTemplate() {
257
257
  </div>
258
258
  ${component.subComponents.filter((p) => p.expanded !== false).map((p) => html`
259
259
  <div class='nav-bar-path' data-action='navigate' data-content-id='cmp--${p.id}' id='link-cmp--${p.id}'>
260
- <span> ${p.name} </span>
260
+ <span style = 'pointer-events: none;'> ${p.name} </span>
261
261
  </div>`)
262
262
  }`
263
263
  : ''))
@@ -105,7 +105,7 @@ async function fetchAccessToken(tokenUrl, clientId, clientSecret, redirectUrl, g
105
105
  }
106
106
  if (sendClientSecretIn === 'header') {
107
107
  headers.set('Authorization', `Basic ${Buffer.from(`${clientId}:${clientSecret}`, 'utf8').toString('base64')}`);
108
- } else {
108
+ } else if (grantType !== 'authorization_code') {
109
109
  urlFormParams.append('client_id', clientId);
110
110
  urlFormParams.append('client_secret', clientSecret);
111
111
  }
@@ -256,7 +256,7 @@ async function onInvokeOAuthFlow(securitySchemeId, flowType, authUrl, tokenUrl,
256
256
 
257
257
  /* eslint-disable indent */
258
258
 
259
- function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, authFlow, defaultScopes = [], receiveTokenIn = 'header') {
259
+ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, authFlow, defaultScopes = [], receiveTokenIn = 'header', receiveTokenInOptions = undefined) {
260
260
  let { authorizationUrl, tokenUrl, refreshUrl } = authFlow;
261
261
  const pkceOnly = authFlow['x-pkce-only'] || false;
262
262
  const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0);
@@ -350,8 +350,8 @@ function oAuthFlowTemplate(flowName, clientId, clientSecret, securitySchemeId, a
350
350
  style = "margin:0 5px;${pkceOnly ? 'display:none;' : ''}"
351
351
  >
352
352
  <select style="margin-right:5px;${pkceOnly ? 'display:none;' : ''}" class="${flowName} ${securitySchemeId} oauth-send-client-secret-in">
353
- <option value = 'header' .selected = ${receiveTokenIn === 'header'} > Authorization Header </option>
354
- <option value = 'request-body' .selected = ${receiveTokenIn === 'request-body'}> Request Body </option>
353
+ ${(!receiveTokenInOptions || receiveTokenInOptions.includes('header')) ? html`<option value = 'header' .selected = ${receiveTokenIn === 'header'} > Authorization Header </option>` : ''}
354
+ ${(!receiveTokenInOptions || receiveTokenInOptions.includes('request-body')) ? html` <option value = 'request-body' .selected = ${receiveTokenIn === 'request-body'}> Request Body </option>` : ''}
355
355
  </select>`
356
356
  : ''
357
357
  }
@@ -483,6 +483,7 @@ export default function securitySchemeTemplate() {
483
483
  v.flows[f],
484
484
  (v.flows[f]['x-default-scopes'] || v['x-default-scopes']),
485
485
  (v.flows[f]['x-receive-token-in'] || v['x-receive-token-in']),
486
+ (v.flows[f]['x-receive-token-in-options'] || v['x-receive-token-in-options']),
486
487
  ))}
487
488
  </td>
488
489
  </tr>
@@ -55,7 +55,7 @@ export function componentIsInSearch(searchVal, component) {
55
55
 
56
56
  export function pathIsInSearch(searchVal, path, matchType = 'includes') {
57
57
  if (matchType === 'includes') {
58
- const stringToSearch = `${path.method} ${path.path} ${path.summary || path.description || ''} ${path.operationId || ''}`.toLowerCase();
58
+ const stringToSearch = `${path.method} ${path.path} ${path.summary || ''} ${path.description || ''} ${path.operationId || ''}`.toLowerCase();
59
59
  return stringToSearch.includes(searchVal.toLowerCase());
60
60
  }
61
61
  const regex = new RegExp(searchVal, 'i');