rapidoc 9.1.3 → 9.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/index.html.gz +0 -0
  3. package/dist/rapidoc-min.js +2 -2
  4. package/dist/rapidoc-min.js.LICENSE.txt +17 -1
  5. package/dist/rapidoc-min.js.LICENSE.txt.gz +0 -0
  6. package/dist/rapidoc-min.js.gz +0 -0
  7. package/dist/report.html +6 -5
  8. package/docker/Dockerfile +5 -5
  9. package/docs/api.html +12 -5
  10. package/docs/examples/dynamic-query-params.html +1 -0
  11. package/docs/examples/readwrite.html +40 -0
  12. package/docs/examples.html +3 -2
  13. package/docs/index.html +2 -2
  14. package/docs/list.html +6 -2
  15. package/docs/quickstart.html +1 -1
  16. package/docs/rapidoc-min.js +2 -2
  17. package/docs/specs/code-highlight.yaml +1 -1
  18. package/docs/specs/data-types.yaml +0 -1
  19. package/docs/specs/examples.yaml +11 -0
  20. package/docs/specs/petstore_extended.yaml +1 -1
  21. package/docs/specs/readwrite.yaml +90 -0
  22. package/docs/specs/temp.json +24 -105
  23. package/docs/specs/temp.yaml +20 -282
  24. package/docs/welcome.html +3 -3
  25. package/index.html +8 -5
  26. package/package.json +22 -21
  27. package/src/components/api-request.js +78 -41
  28. package/src/components/api-response.js +10 -10
  29. package/src/components/schema-table.js +51 -14
  30. package/src/components/schema-tree.js +59 -18
  31. package/src/components/tag-input.js +8 -1
  32. package/src/json-schema-viewer.js +1 -1
  33. package/src/rapidoc-mini.js +5 -1
  34. package/src/rapidoc.js +5 -1
  35. package/src/styles/font-styles.js +3 -2
  36. package/src/styles/nav-styles.js +2 -2
  37. package/src/templates/components-template.js +5 -5
  38. package/src/templates/endpoint-template.js +1 -1
  39. package/src/templates/expanded-endpoint-template.js +1 -1
  40. package/src/templates/focused-endpoint-template.js +1 -1
  41. package/src/templates/header-template.js +1 -1
  42. package/src/templates/json-schema-viewer-template.js +8 -8
  43. package/src/templates/main-body-template.js +4 -1
  44. package/src/templates/navbar-template.js +2 -2
  45. package/src/templates/overview-template.js +5 -2
  46. package/src/templates/security-scheme-template.js +48 -13
  47. package/src/templates/server-template.js +1 -1
  48. package/src/utils/common-utils.js +2 -1
  49. package/src/utils/schema-utils.js +14 -9
  50. package/src/utils/spec-parser.js +3 -3
  51. package/webpack.config.js +1 -0
  52. package/docs/specs/tenants.json +0 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rapidoc",
3
- "version": "9.1.3",
3
+ "version": "9.1.4",
4
4
  "description": "RapiDoc - Open API spec viewer with built in console",
5
5
  "author": "Mrinmoy Majumdar <mrin9@yahoo.com>",
6
6
  "repository": {
@@ -29,12 +29,13 @@
29
29
  "module": "dist/rapidoc-min.js",
30
30
  "mode": "production",
31
31
  "dependencies": {
32
- "@apitools/openapi-parser": "^0.0.9",
32
+ "@apitools/openapi-parser": "^0.0.10",
33
33
  "base64-arraybuffer": "^1.0.1",
34
+ "buffer": "^6.0.3",
34
35
  "lit-element": "2.5.1",
35
36
  "lit-html": "1.4.1",
36
- "marked": "^3.0.4",
37
- "prismjs": "^1.25.0"
37
+ "marked": "^4.0.10",
38
+ "prismjs": "^1.26.0"
38
39
  },
39
40
  "scripts": {
40
41
  "build": "NODE_ENV=production webpack --mode=production",
@@ -46,30 +47,30 @@
46
47
  "lint-fix": "./node_modules/eslint/bin/eslint.js --fix ./src/**"
47
48
  },
48
49
  "devDependencies": {
49
- "@babel/core": "^7.15.5",
50
- "@babel/eslint-parser": "^7.15.7",
51
- "@babel/preset-env": "^7.15.6",
52
- "babel-loader": "^8.2.2",
50
+ "@babel/core": "^7.16.7",
51
+ "@babel/eslint-parser": "^7.16.5",
52
+ "@babel/preset-env": "^7.16.8",
53
+ "babel-loader": "^8.2.3",
53
54
  "babel-plugin-template-html-minifier": "^4.1.0",
54
55
  "clean-webpack-plugin": "^4.0.0",
55
- "compression-webpack-plugin": "^9.0.0",
56
- "css-loader": "^6.3.0",
56
+ "compression-webpack-plugin": "^9.2.0",
57
+ "css-loader": "^6.5.1",
57
58
  "eslint": "^7.32.0",
58
- "eslint-config-airbnb": "^18.2.1",
59
- "eslint-import-resolver-webpack": "^0.13.1",
59
+ "eslint-config-airbnb": "^19.0.4",
60
+ "eslint-import-resolver-webpack": "^0.13.2",
60
61
  "eslint-loader": "^4.0.2",
61
- "eslint-plugin-import": "^2.24.2",
62
- "eslint-webpack-plugin": "3.0.1",
62
+ "eslint-plugin-import": "^2.25.4",
63
+ "eslint-webpack-plugin": "3.1.1",
63
64
  "file-loader": "^6.2.0",
64
65
  "filemanager-webpack-plugin": "^6.1.7",
65
- "html-webpack-plugin": "^5.3.2",
66
+ "html-webpack-plugin": "^5.5.0",
66
67
  "inspectpack": "^4.7.1",
67
- "style-loader": "^3.3.0",
68
- "terser-webpack-plugin": "^5.2.4",
69
- "webpack": "^5.54.0",
70
- "webpack-bundle-analyzer": "^4.4.2",
71
- "webpack-cli": "^4.8.0",
72
- "webpack-dev-server": "^4.3.0"
68
+ "style-loader": "^3.3.1",
69
+ "terser-webpack-plugin": "^5.3.0",
70
+ "webpack": "^5.66.0",
71
+ "webpack-bundle-analyzer": "^4.5.0",
72
+ "webpack-cli": "^4.9.1",
73
+ "webpack-dev-server": "^4.7.3"
73
74
  },
74
75
  "engines": {
75
76
  "node": ">=10.21.0"
@@ -1,9 +1,10 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
- import marked from 'marked';
2
+ import { marked } from 'marked';
3
3
  import Prism from 'prismjs';
4
4
 
5
5
  import { unsafeHTML } from 'lit-html/directives/unsafe-html';
6
- // import { live } from 'lit-html/directives/live';
6
+ import { guard } from 'lit-html/directives/guard';
7
+ import { live } from 'lit-html/directives/live';
7
8
  import TableStyles from '~/styles/table-styles';
8
9
  import FlexStyles from '~/styles/flex-styles';
9
10
  import InputStyles from '~/styles/input-styles';
@@ -192,11 +193,11 @@ export default class ApiRequest extends LitElement {
192
193
  ${this.callback === 'true' ? 'CALLBACK REQUEST' : 'REQUEST'}
193
194
  </div>
194
195
  <div>
195
- ${this.inputParametersTemplate('path')}
196
- ${this.inputParametersTemplate('query')}
196
+ ${guard([this.parameters, this.activeParameterSchemaTabs], () => this.inputParametersTemplate('path'))}
197
+ ${guard([this.parameters, this.activeParameterSchemaTabs], () => this.inputParametersTemplate('query'))}
197
198
  ${this.requestBodyTemplate()}
198
- ${this.inputParametersTemplate('header')}
199
- ${this.inputParametersTemplate('cookie')}
199
+ ${guard([this.parameters, this.activeParameterSchemaTabs], () => this.inputParametersTemplate('header'))}
200
+ ${guard([this.parameters, this.activeParameterSchemaTabs], () => this.inputParametersTemplate('cookie'))}
200
201
  ${this.allowTry === 'false' ? '' : html`${this.apiCallTemplate()}`}
201
202
  </div>
202
203
  </div>
@@ -245,7 +246,7 @@ export default class ApiRequest extends LitElement {
245
246
  }
246
247
  }
247
248
  }"
248
- >${v.description || v.summary || v.value}</a>
249
+ >${v.value && Array.isArray(v.value) ? (v.value?.join(', ')) : (v.value || '')}</a>
249
250
  ${paramType === 'array' ? '] ' : ''}
250
251
  `)}
251
252
  `
@@ -284,6 +285,7 @@ export default class ApiRequest extends LitElement {
284
285
  // let exampleList = [];
285
286
  let paramStyle = 'form';
286
287
  let paramExplode = true;
288
+ let paramAllowReserved = false;
287
289
  if (paramType === 'query') {
288
290
  if (param.style && 'form spaceDelimited pipeDelimited'.includes(param.style)) {
289
291
  paramStyle = param.style;
@@ -293,6 +295,9 @@ export default class ApiRequest extends LitElement {
293
295
  if (typeof param.explode === 'boolean') {
294
296
  paramExplode = param.explode;
295
297
  }
298
+ if (typeof param.allowReserved === 'boolean') {
299
+ paramAllowReserved = param.allowReserved;
300
+ }
296
301
  }
297
302
 
298
303
  // openapi 3.1.0 spec based examples (which must be Object(string : { value:any, summary?: string, description?: string})
@@ -308,10 +313,10 @@ export default class ApiRequest extends LitElement {
308
313
  );
309
314
  if (!example.exampleVal && paramSchema.type === 'object') {
310
315
  example.exampleVal = generateExample(
311
- '',
312
- '',
313
316
  declaredParamSchema,
314
317
  serializeStyle || 'json',
318
+ '',
319
+ '',
315
320
  true,
316
321
  true,
317
322
  'text',
@@ -344,6 +349,7 @@ export default class ApiRequest extends LitElement {
344
349
  data-example = "${Array.isArray(example.exampleVal) ? example.exampleVal.join('~|~') : example.exampleVal}"
345
350
  data-param-serialize-style = "${paramStyle}"
346
351
  data-param-serialize-explode = "${paramExplode}"
352
+ data-param-allow-reserved = "${paramAllowReserved}"
347
353
  data-array = "true"
348
354
  placeholder = "add-multiple &#x21a9;"
349
355
  .value = "${Array.isArray(example.exampleVal) ? example.exampleVal : example.exampleVal}"
@@ -372,6 +378,7 @@ export default class ApiRequest extends LitElement {
372
378
  data-example = "${example.exampleVal}"
373
379
  data-param-serialize-style = "${paramStyle}"
374
380
  data-param-serialize-explode = "${paramExplode}"
381
+ data-param-allow-reserved = "${paramAllowReserved}"
375
382
  spellcheck = "false"
376
383
  .textContent = "${this.fillRequestFieldsWithExample === 'true' ? example.exampleVal : ''}"
377
384
  style = "resize:vertical; width:100%; height: ${'read focused'.includes(this.renderStyle) ? '180px' : '120px'};"
@@ -387,7 +394,7 @@ export default class ApiRequest extends LitElement {
387
394
  schema-description-expanded = "${this.schemaDescriptionExpanded}"
388
395
  allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}",
389
396
  schema-hide-read-only = "${this.schemaHideReadOnly.includes(this.method)}"
390
- schema-hide-write-only = false
397
+ schema-hide-write-only = "false"
391
398
  > </schema-tree>
392
399
  </div>`
393
400
  }
@@ -399,8 +406,9 @@ export default class ApiRequest extends LitElement {
399
406
  data-ptype="${paramType}"
400
407
  data-pname="${param.name}"
401
408
  data-example="${Array.isArray(example.exampleVal) ? example.exampleVal.join('~|~') : example.exampleVal}"
409
+ data-param-allow-reserved = "${paramAllowReserved}"
402
410
  data-array="false"
403
- .value="${this.fillRequestFieldsWithExample === 'true' ? example.exampleVal : ''}"
411
+ .value="${live(this.fillRequestFieldsWithExample === 'true' ? example.exampleVal : '')}"
404
412
  />`
405
413
  }
406
414
  </td>`
@@ -535,10 +543,10 @@ export default class ApiRequest extends LitElement {
535
543
  // Generate Example
536
544
  if (reqBody.mimeType === this.selectedRequestBodyType) {
537
545
  reqBodyExamples = generateExample(
538
- reqBody.examples,
539
- reqBody.example,
540
546
  reqBody.schema,
541
547
  reqBody.mimeType,
548
+ reqBody.examples,
549
+ reqBody.example,
542
550
  false,
543
551
  true,
544
552
  'text',
@@ -594,10 +602,10 @@ export default class ApiRequest extends LitElement {
594
602
  } else if (this.selectedRequestBodyType.includes('form-urlencoded') || this.selectedRequestBodyType.includes('form-data')) {
595
603
  if (reqBody.mimeType === this.selectedRequestBodyType) {
596
604
  const ex = generateExample(
597
- reqBody.examples,
598
- reqBody.example,
599
605
  reqBody.schema,
600
606
  reqBody.mimeType,
607
+ reqBody.examples,
608
+ reqBody.example,
601
609
  false,
602
610
  true,
603
611
  'text',
@@ -607,7 +615,7 @@ export default class ApiRequest extends LitElement {
607
615
  reqBodyFormHtml = this.formDataTemplate(reqBody.schema, reqBody.mimeType, (ex[0] ? ex[0].exampleValue : ''));
608
616
  }
609
617
  }
610
- } else if ((RegExp('^audio/|^image/|^video/|^font/|tar$|zip$|7z$|rtf$|msword$|excel$|/pdf$|/octet-stream$').test(this.selectedRequestBodyType))) {
618
+ } else if ((/^audio\/|^image\/|^video\/|^font\/|tar$|zip$|7z$|rtf$|msword$|excel$|\/pdf$|\/octet-stream$/.test(this.selectedRequestBodyType))) {
611
619
  if (reqBody.mimeType === this.selectedRequestBodyType) {
612
620
  reqBodyFileInputHtml = html`
613
621
  <div class = "small-font-size bold-text row">
@@ -631,21 +639,21 @@ export default class ApiRequest extends LitElement {
631
639
  schema-description-expanded = "${this.schemaDescriptionExpanded}"
632
640
  allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}",
633
641
  schema-hide-read-only = "${this.schemaHideReadOnly.includes(this.method)}"
634
- schema-hide-write-only = false
642
+ schema-hide-write-only = "false"
635
643
  > </schema-table>
636
644
  `;
637
645
  } else if (this.schemaStyle === 'tree') {
638
646
  reqBodySchemaHtml = html`
639
647
  ${reqBodySchemaHtml}
640
648
  <schema-tree
641
- class = '${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)}'
642
- style = 'display: ${this.selectedRequestBodyType === reqBody.mimeType ? 'block' : 'none'};'
643
- .data = '${schemaAsObj}'
649
+ class = "${reqBody.mimeType.substring(reqBody.mimeType.indexOf('/') + 1)}"
650
+ style = "display: ${this.selectedRequestBodyType === reqBody.mimeType ? 'block' : 'none'};"
651
+ .data = "${schemaAsObj}"
644
652
  schema-expand-level = "${this.schemaExpandLevel}"
645
653
  schema-description-expanded = "${this.schemaDescriptionExpanded}"
646
654
  allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}",
647
- schema-hide-read-only = "${this.schemaHideReadOnly.includes(this.method)}"
648
- schema-hide-write-only = false
655
+ schema-hide-read-only = "true"
656
+ schema-hide-write-only = "false"
649
657
  > </schema-tree>
650
658
  `;
651
659
  }
@@ -686,10 +694,10 @@ export default class ApiRequest extends LitElement {
686
694
  // This template is used when form-data param should be send as a object (application/json, application/xml)
687
695
  const formdataPartSchema = schemaInObjectNotation(fieldSchema, {});
688
696
  const formdataPartExample = generateExample(
689
- fieldSchema.examples,
690
- fieldSchema.example,
691
697
  fieldSchema,
692
698
  'json',
699
+ fieldSchema.examples,
700
+ fieldSchema.example,
693
701
  false,
694
702
  true,
695
703
  'text',
@@ -1061,12 +1069,17 @@ export default class ApiRequest extends LitElement {
1061
1069
  });
1062
1070
 
1063
1071
  // Query Params
1064
- const urlQueryParam = new URLSearchParams();
1072
+ const urlQueryParamsMap = new Map();
1073
+ const queryParamsWithReservedCharsAllowed = [];
1065
1074
  if (queryParamEls.length > 0) {
1066
1075
  queryParamEls.forEach((el) => {
1076
+ const queryParam = new URLSearchParams();
1077
+ if (el.dataset.paramAllowReserved === 'true') {
1078
+ queryParamsWithReservedCharsAllowed.push(el.dataset.pname);
1079
+ }
1067
1080
  if (el.dataset.array === 'false') {
1068
1081
  if (el.value !== '') {
1069
- urlQueryParam.append(el.dataset.pname, el.value);
1082
+ queryParam.append(el.dataset.pname, el.value);
1070
1083
  }
1071
1084
  } else {
1072
1085
  const paramSerializeStyle = el.dataset.paramSerializeStyle;
@@ -1075,64 +1088,88 @@ export default class ApiRequest extends LitElement {
1075
1088
  vals = Array.isArray(vals) ? vals.filter((v) => v !== '') : [];
1076
1089
  if (vals.length > 0) {
1077
1090
  if (paramSerializeStyle === 'spaceDelimited') {
1078
- urlQueryParam.append(el.dataset.pname, vals.join(' ').replace(/^\s|\s$/g, ''));
1091
+ queryParam.append(el.dataset.pname, vals.join(' ').replace(/^\s|\s$/g, ''));
1079
1092
  } else if (paramSerializeStyle === 'pipeDelimited') {
1080
- urlQueryParam.append(el.dataset.pname, vals.join('|').replace(/^\||\|$/g, ''));
1093
+ queryParam.append(el.dataset.pname, vals.join('|').replace(/^\||\|$/g, ''));
1081
1094
  } else {
1082
1095
  if (paramSerializeExplode === 'true') { // eslint-disable-line no-lonely-if
1083
- vals.forEach((v) => { urlQueryParam.append(el.dataset.pname, v); });
1096
+ vals.forEach((v) => { queryParam.append(el.dataset.pname, v); });
1084
1097
  } else {
1085
- urlQueryParam.append(el.dataset.pname, vals.join(',').replace(/^,|,$/g, ''));
1098
+ queryParam.append(el.dataset.pname, vals.join(',').replace(/^,|,$/g, ''));
1086
1099
  }
1087
1100
  }
1088
1101
  }
1089
1102
  }
1103
+ if (queryParam.toString()) {
1104
+ urlQueryParamsMap.set(el.dataset.pname, queryParam);
1105
+ }
1090
1106
  });
1091
1107
  }
1092
1108
 
1093
1109
  // Query Params (Dynamic - create from JSON)
1094
1110
  if (queryParamObjTypeEls.length > 0) {
1095
1111
  queryParamObjTypeEls.map((el) => {
1112
+ const queryParam = new URLSearchParams();
1096
1113
  try {
1097
1114
  let queryParamObj = {};
1098
1115
  const paramSerializeStyle = el.dataset.paramSerializeStyle;
1099
1116
  const paramSerializeExplode = el.dataset.paramSerializeExplode;
1100
1117
  queryParamObj = Object.assign(queryParamObj, JSON.parse(el.value.replace(/\s+/g, ' ')));
1118
+ if (el.dataset.paramAllowReserved === 'true') {
1119
+ queryParamsWithReservedCharsAllowed.push(el.dataset.pname);
1120
+ }
1101
1121
  if ('json xml'.includes(paramSerializeStyle)) {
1102
1122
  if (paramSerializeStyle === 'json') {
1103
- urlQueryParam.append(el.dataset.pname, JSON.stringify(queryParamObj));
1123
+ queryParam.append(el.dataset.pname, JSON.stringify(queryParamObj));
1104
1124
  } else if (paramSerializeStyle === 'xml') {
1105
- urlQueryParam.append(el.dataset.pname, json2xml(queryParamObj));
1125
+ queryParam.append(el.dataset.pname, json2xml(queryParamObj));
1106
1126
  }
1107
1127
  } else {
1108
1128
  for (const key in queryParamObj) {
1109
1129
  if (typeof queryParamObj[key] === 'object') {
1110
1130
  if (Array.isArray(queryParamObj[key])) {
1111
1131
  if (paramSerializeStyle === 'spaceDelimited') {
1112
- urlQueryParam.append(key, queryParamObj[key].join(' '));
1132
+ queryParam.append(key, queryParamObj[key].join(' '));
1113
1133
  } else if (paramSerializeStyle === 'pipeDelimited') {
1114
- urlQueryParam.append(key, queryParamObj[key].join('|'));
1134
+ queryParam.append(key, queryParamObj[key].join('|'));
1115
1135
  } else {
1116
1136
  if (paramSerializeExplode === 'true') { // eslint-disable-line no-lonely-if
1117
1137
  queryParamObj[key].forEach((v) => {
1118
- urlQueryParam.append(key, v);
1138
+ queryParam.append(key, v);
1119
1139
  });
1120
1140
  } else {
1121
- urlQueryParam.append(key, queryParamObj[key]);
1141
+ queryParam.append(key, queryParamObj[key]);
1122
1142
  }
1123
1143
  }
1124
1144
  }
1125
1145
  } else {
1126
- urlQueryParam.append(key, queryParamObj[key]);
1146
+ queryParam.append(key, queryParamObj[key]);
1127
1147
  }
1128
1148
  }
1129
1149
  }
1130
1150
  } catch (err) {
1131
1151
  console.log('RapiDoc: unable to parse %s into object', el.value); // eslint-disable-line no-console
1132
1152
  }
1153
+ if (queryParam.toString()) {
1154
+ urlQueryParamsMap.set(el.dataset.pname, queryParam);
1155
+ }
1156
+ });
1157
+ }
1158
+ let urlQueryParamString = '';
1159
+ if (urlQueryParamsMap.size) {
1160
+ urlQueryParamString = '?';
1161
+ urlQueryParamsMap.forEach((val, pname) => {
1162
+ if (queryParamsWithReservedCharsAllowed.includes(pname)) {
1163
+ urlQueryParamString += `${pname}=`;
1164
+ urlQueryParamString += val.getAll(pname).join(`&${pname}=`);
1165
+ urlQueryParamString += '&';
1166
+ } else {
1167
+ urlQueryParamString += `${val.toString()}&`;
1168
+ }
1133
1169
  });
1170
+ urlQueryParamString = urlQueryParamString.slice(0, -1);
1134
1171
  }
1135
- fetchUrl = `${fetchUrl}${urlQueryParam.toString() ? '?' : ''}${urlQueryParam.toString()}`;
1172
+ fetchUrl = `${fetchUrl}${urlQueryParamString}`;
1136
1173
 
1137
1174
  // Add authentication Query-Param if provided
1138
1175
  this.api_keys
@@ -1243,7 +1280,7 @@ export default class ApiRequest extends LitElement {
1243
1280
  }
1244
1281
  });
1245
1282
  fetchOptions.body = formDataParams;
1246
- } else if ((RegExp('^audio/|^image/|^video/|^font/|tar$|zip$|7z$|rtf$|msword$|excel$|/pdf$|/octet-stream$').test(requestBodyType))) {
1283
+ } else if (/^audio\/|^image\/|^video\/|^font\/|tar$|zip$|7z$|rtf$|msword$|excel$|\/pdf$|\/octet-stream$/.test(requestBodyType)) {
1247
1284
  const bodyParamFileEl = requestPanelEl.querySelector('.request-body-param-file');
1248
1285
  if (bodyParamFileEl?.files[0]) {
1249
1286
  fetchOptions.body = bodyParamFileEl.files[0];
@@ -1341,10 +1378,10 @@ export default class ApiRequest extends LitElement {
1341
1378
  this.responseText = JSON.stringify(respJson, null, 2);
1342
1379
  }
1343
1380
  // eslint-disable-next-line no-useless-escape
1344
- } else if (RegExp('^font/|tar$|zip$|7z$|rtf$|msword$|excel$|/pdf$|/octet-stream$|^application\/vnd\.').test(contentType)) {
1381
+ } else if (/^font\/|tar$|zip$|7z$|rtf$|msword$|excel$|\/pdf$|\/octet-stream$|^application\/vnd\./.test(contentType)) {
1345
1382
  this.responseIsBlob = true;
1346
1383
  this.responseBlobType = 'download';
1347
- } else if (RegExp('^audio|^image|^video').test(contentType)) {
1384
+ } else if (/^audio|^image|^video/.test(contentType)) {
1348
1385
  this.responseIsBlob = true;
1349
1386
  this.responseBlobType = 'view';
1350
1387
  } else {
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
- import marked from 'marked';
2
+ import { marked } from 'marked';
3
3
  import { unsafeHTML } from 'lit-html/directives/unsafe-html';
4
4
  import { schemaInObjectNotation, generateExample } from '~/utils/schema-utils';
5
5
  import FontStyles from '~/styles/font-styles';
@@ -114,10 +114,10 @@ export default class ApiResponse extends LitElement {
114
114
  const schemaTree = schemaInObjectNotation(mimeRespObj.schema, {});
115
115
  // Generate Example
116
116
  const respExamples = generateExample(
117
- mimeRespObj.examples,
118
- mimeRespObj.example,
119
117
  mimeRespObj.schema,
120
118
  mimeResp,
119
+ mimeRespObj.examples,
120
+ mimeRespObj.example,
121
121
  true,
122
122
  false,
123
123
  mimeResp.includes('json') ? 'json' : 'text',
@@ -302,23 +302,23 @@ export default class ApiResponse extends LitElement {
302
302
  ${this.schemaStyle === 'table'
303
303
  ? html`
304
304
  <schema-table
305
- render-style = '${this.renderStyle}'
306
- .data = '${mimeRespDetails.schemaTree}'
305
+ render-style = "${this.renderStyle}"
306
+ .data = "${mimeRespDetails.schemaTree}"
307
307
  schema-expand-level = "${this.schemaExpandLevel}"
308
308
  schema-description-expanded = "${this.schemaDescriptionExpanded}"
309
309
  allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}",
310
- schema-hide-read-only = false
311
- schema-hide-write-only = ${this.schemaHideWriteOnly}
310
+ schema-hide-read-only = "false"
311
+ schema-hide-write-only = "${this.schemaHideWriteOnly}"
312
312
  > </schema-tree> `
313
313
  : html`
314
314
  <schema-tree
315
- render-style = '${this.renderStyle}'
315
+ render-style = "${this.renderStyle}"
316
316
  .data = '${mimeRespDetails.schemaTree}'
317
317
  schema-expand-level = "${this.schemaExpandLevel}"
318
318
  schema-description-expanded = "${this.schemaDescriptionExpanded}"
319
319
  allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}",
320
- schema-hide-read-only = false
321
- schema-hide-write-only = ${this.schemaHideWriteOnly}
320
+ schema-hide-read-only = "false"
321
+ schema-hide-write-only = "${this.schemaHideWriteOnly}"
322
322
  > </schema-tree>`
323
323
  }`;
324
324
  }
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, css } from 'lit-element';
2
- import marked from 'marked';
2
+ import { marked } from 'marked';
3
3
  import { unsafeHTML } from 'lit-html/directives/unsafe-html';
4
4
  import FontStyles from '~/styles/font-styles';
5
5
  import SchemaStyles from '~/styles/schema-styles';
@@ -123,11 +123,31 @@ export default class SchemaTable extends LitElement {
123
123
  `;
124
124
  }
125
125
 
126
- generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0) {
126
+ generateTree(data, dataType = 'object', arrayType = '', key = '', description = '', schemaLevel = 0, indentLevel = 0, readOrWrite = '') {
127
+ if (this.schemaHideReadOnly === 'true') {
128
+ if (dataType === 'array') {
129
+ if (readOrWrite === 'readonly') {
130
+ return;
131
+ }
132
+ }
133
+ if (data['::readwrite'] === 'readonly') {
134
+ return;
135
+ }
136
+ }
137
+ if (this.schemaHideWriteOnly === 'true') {
138
+ if (dataType === 'array') {
139
+ if (readOrWrite === 'writeonly') {
140
+ return;
141
+ }
142
+ }
143
+ if (data['::readwrite'] === 'writeonly') {
144
+ return;
145
+ }
146
+ }
147
+
127
148
  const newSchemaLevel = data['::type']?.startsWith('xxx-of') ? schemaLevel : (schemaLevel + 1);
128
149
  const newIndentLevel = dataType === 'xxx-of-option' || data['::type'] === 'xxx-of-option' || key.startsWith('::OPTION') ? indentLevel : (indentLevel + 1);
129
150
  const leftPadding = 16 * newIndentLevel; // 2 space indentation at each level
130
-
131
151
  if (!data) {
132
152
  return html`<div class="null" style="display:inline;">null</div>`;
133
153
  }
@@ -189,7 +209,10 @@ export default class SchemaTable extends LitElement {
189
209
  }
190
210
  ${data['::type'] === 'xxx-of' && dataType === 'array' ? html`<span style="color:var(--primary-color)">ARRAY</span>` : ''}
191
211
  </div>
192
- <div class='td key-type'>${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}</div>
212
+ <div class='td key-type' title="${data['::readwrite'] === 'readonly' ? 'Read-Only' : data['::readwrite'] === 'writeonly' ? 'Write-Only' : ''}">
213
+ ${(data['::type'] || '').includes('xxx-of') ? '' : detailObjType}
214
+ ${data['::readwrite'] === 'readonly' ? ' 🆁' : data['::readwrite'] === 'writeonly' ? ' 🆆' : ''}
215
+ </div>
193
216
  <div class='td key-descr m-markdown-small' style='line-height:1.7'>${unsafeHTML(marked(description || ''))}</div>
194
217
  </div>`
195
218
  : html`
@@ -197,7 +220,9 @@ export default class SchemaTable extends LitElement {
197
220
  ? html`
198
221
  <div class='tr'>
199
222
  <div class='td key'></div>
200
- <div class='td key-type'> ${arrayType && arrayType !== 'object' ? `${dataType} of ${arrayType}` : dataType}</div>
223
+ <div class='td key-type'>
224
+ ${arrayType && arrayType !== 'object' ? `${dataType} of ${arrayType}` : dataType}
225
+ </div>
201
226
  <div class='td key-descr'></div>
202
227
  </div>`
203
228
  : ''
@@ -206,10 +231,10 @@ export default class SchemaTable extends LitElement {
206
231
  }
207
232
  <div class='object-body'>
208
233
  ${Array.isArray(data) && data[0]
209
- ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel)}`
234
+ ? html`${this.generateTree(data[0], 'xxx-of-option', '', '::ARRAY~OF', '', newSchemaLevel, newIndentLevel, '')}`
210
235
  : html`
211
236
  ${Object.keys(data).map((dataKey) => html`
212
- ${['::description', '::type', '::props', '::deprecated', '::array-type'].includes(dataKey)
237
+ ${['::description', '::type', '::props', '::deprecated', '::array-type', '::readwrite'].includes(dataKey)
213
238
  ? data[dataKey]['::type'] === 'array' || data[dataKey]['::type'] === 'object'
214
239
  ? html`${this.generateTree(
215
240
  data[dataKey]['::type'] === 'array' ? data[dataKey]['::props'] : data[dataKey],
@@ -219,6 +244,7 @@ export default class SchemaTable extends LitElement {
219
244
  data[dataKey]['::description'],
220
245
  newSchemaLevel,
221
246
  newIndentLevel,
247
+ data[dataKey]['::readwrite'] ? data[dataKey]['::readwrite'] : '',
222
248
  )}`
223
249
  : ''
224
250
  : html`${this.generateTree(
@@ -229,6 +255,7 @@ export default class SchemaTable extends LitElement {
229
255
  data[dataKey]['::description'],
230
256
  newSchemaLevel,
231
257
  newIndentLevel,
258
+ data[dataKey]['::readwrite'] ? data[dataKey]['::readwrite'] : '',
232
259
  )}`
233
260
  }
234
261
  `)}
@@ -239,17 +266,29 @@ export default class SchemaTable extends LitElement {
239
266
  }
240
267
 
241
268
  // For Primitive Data types
242
- const [type, readorWriteOnly, constraint, defaultValue, allowedValues, pattern, schemaDescription, schemaTitle, deprecated] = data.split('~|~');
243
- if (readorWriteOnly === '🆁' && this.schemaHideReadOnly === 'true') {
269
+ const [type, readOrWriteOnly, constraint, defaultValue, allowedValues, pattern, schemaDescription, schemaTitle, deprecated] = data.split('~|~');
270
+ if (readOrWriteOnly === '🆁' && this.schemaHideReadOnly === 'true') {
244
271
  return;
245
272
  }
246
- if (readorWriteOnly === '🆆' && this.schemaHideWriteOnly === 'true') {
273
+ if (readOrWriteOnly === '🆆' && this.schemaHideWriteOnly === 'true') {
247
274
  return;
248
275
  }
249
276
  const dataTypeCss = type.replace(/┃.*/g, '').replace(/[^a-zA-Z0-9+]/g, '').substring(0, 4).toLowerCase();
277
+ let dataTypeHtml = '';
278
+ if (dataType === 'array') {
279
+ dataTypeHtml = html`
280
+ <div class='td key-type ${dataTypeCss}' title="${readOrWrite === 'readonly' ? 'Read-Only' : readOrWriteOnly === 'writeonly' ? 'Write-Only' : ''}">
281
+ [${type}] ${readOrWrite === 'readonly' ? '🆁' : readOrWrite === 'writeonly' ? '🆆' : ''}
282
+ </div>`;
283
+ } else {
284
+ dataTypeHtml = html`
285
+ <div class='td key-type ${dataTypeCss}' title="${readOrWriteOnly === '🆁' ? 'Read-Only' : readOrWriteOnly === '🆆' ? 'Write-Only' : ''}">
286
+ ${type} ${readOrWriteOnly}
287
+ </div>`;
288
+ }
250
289
  return html`
251
290
  <div class = "tr primitive">
252
- <div class="td key ${deprecated}" style='padding-left:${leftPadding}px' >
291
+ <div class="td key ${deprecated}" style='padding-left:${leftPadding}px'>
253
292
  ${keyLabel?.endsWith('*')
254
293
  ? html`<span class="key-label">${keyLabel.substring(0, keyLabel.length - 1)}</span><span style='color:var(--red);'>*</span>`
255
294
  : key.startsWith('::OPTION')
@@ -257,9 +296,7 @@ export default class SchemaTable extends LitElement {
257
296
  : html`${keyLabel ? html`<span class="key-label"> ${keyLabel}</span>` : html`<span class="xxx-of-descr">${schemaTitle}</span>`}`
258
297
  }
259
298
  </div>
260
- <div class='td key-type ${dataTypeCss}'>
261
- ${dataType === 'array' ? `[${type}]` : type}
262
- <span style="font-family: var(--font-mono);">${readorWriteOnly} </span> </div>
299
+ ${dataTypeHtml}
263
300
  <div class='td key-descr'>
264
301
  ${dataType === 'array' ? html`<span class="m-markdown-small">${unsafeHTML(marked(description))}</span>` : ''}
265
302
  ${constraint ? html`<div style='display:inline-block; line-break:anywhere; margin-right:8px;'> <span class='bold-text'>Constraints: </span> ${constraint}</div>` : ''}