rapidoc 9.3.4 → 9.3.6
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/README.md +2 -7
- package/dist/index.html +1 -1
- package/dist/index.html.gz +0 -0
- package/dist/rapidoc-min.js +529 -525
- package/dist/rapidoc-min.js.LICENSE.txt +8 -4
- package/dist/rapidoc-min.js.LICENSE.txt.gz +0 -0
- package/dist/rapidoc-min.js.gz +0 -0
- package/dist/rapidoc-min.js.map +1 -1
- package/dist/rapidoc-min.js.map.gz +0 -0
- package/dist/rapidoc.js +1900 -8151
- package/dist/report.html +5 -5
- package/index.html +3 -2
- package/package.json +23 -22
- package/src/components/api-request.js +49 -11
- package/src/components/schema-table.js +11 -10
- package/src/components/schema-tree.js +7 -6
- package/src/json-schema-viewer.js +1 -0
- package/src/rapidoc.js +10 -5
- package/src/templates/advance-search-template.js +3 -3
- package/src/templates/endpoint-template.js +1 -1
- package/src/templates/expanded-endpoint-template.js +1 -1
- package/src/templates/focused-endpoint-template.js +1 -1
- package/src/templates/navbar-template.js +2 -2
- package/src/templates/security-scheme-template.js +5 -4
- package/src/utils/common-utils.js +1 -1
- package/src/utils/schema-utils.js +32 -5
- package/src/utils/spec-parser.js +8 -3
package/index.html
CHANGED
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
https://cesdev.eng.sonicwall.com/api/q/openapi
|
|
32
32
|
-->
|
|
33
33
|
<rapi-doc
|
|
34
|
-
spec-url = "
|
|
34
|
+
spec-url = "https://api.apis.guru/v2/specs/azure.com/azureactivedirectory/2017-04-01/swagger.yaml"
|
|
35
35
|
id="thedoc"
|
|
36
36
|
theme = "dark"
|
|
37
|
-
render-style="
|
|
37
|
+
render-style="read"
|
|
38
38
|
schema-style="table"
|
|
39
39
|
show-method-in-nav-bar = "true"
|
|
40
40
|
use-path-in-nav-bar = "true"
|
|
@@ -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.
|
|
3
|
+
"version": "9.3.6",
|
|
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.
|
|
36
|
+
"@apitools/openapi-parser": "0.0.32",
|
|
37
37
|
"base64-arraybuffer": "^1.0.2",
|
|
38
38
|
"buffer": "^6.0.3",
|
|
39
|
-
"lit": "^2.
|
|
40
|
-
"marked": "
|
|
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.
|
|
55
|
-
"@babel/eslint-parser": "^7.
|
|
56
|
-
"@babel/preset-env": "^7.
|
|
57
|
-
"babel-loader": "^9.1
|
|
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": "^
|
|
61
|
-
"css-loader": "^
|
|
62
|
-
"eslint": "^8.
|
|
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.
|
|
65
|
-
"eslint-plugin-import": "^2.
|
|
66
|
-
"eslint-webpack-plugin": "
|
|
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.
|
|
70
|
+
"html-webpack-plugin": "^5.6.0",
|
|
70
71
|
"inspectpack": "^4.7.1",
|
|
71
|
-
"style-loader": "^
|
|
72
|
-
"terser-webpack-plugin": "^5.3.
|
|
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
|
-
"webpack-bundle-analyzer": "^4.
|
|
76
|
-
"webpack-cli": "^5.
|
|
77
|
-
"webpack-dev-server": "
|
|
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": ">=
|
|
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 ↩"
|
|
910
|
-
.value = "${Array.isArray(fieldExamples) ? Array.isArray(fieldExamples[0]) ? fieldExamples[0] :
|
|
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(
|
|
1248
|
+
queryParam.append(pKey, queryParamObj[key].join(' '));
|
|
1237
1249
|
} else if (paramSerializeStyle === 'pipeDelimited') {
|
|
1238
|
-
queryParam.append(
|
|
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(
|
|
1254
|
+
queryParam.append(pKey, v);
|
|
1243
1255
|
});
|
|
1244
1256
|
} else {
|
|
1245
|
-
queryParam.append(
|
|
1257
|
+
queryParam.append(pKey, queryParamObj[key]);
|
|
1246
1258
|
}
|
|
1247
1259
|
}
|
|
1248
1260
|
}
|
|
1249
1261
|
} else {
|
|
1250
|
-
queryParam.append(
|
|
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>`;
|
|
@@ -1468,7 +1497,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1468
1497
|
respHeadersObj[hdr] = hdrVal;
|
|
1469
1498
|
this.responseHeaders = `${this.responseHeaders}${hdr}: ${hdrVal}\n`;
|
|
1470
1499
|
});
|
|
1471
|
-
const contentType = fetchResponse.headers.get('content-type');
|
|
1500
|
+
const contentType = fetchResponse.headers.get('content-type').split(';')[0].trim();
|
|
1472
1501
|
const respEmpty = (await fetchResponse.clone().text()).length === 0;
|
|
1473
1502
|
if (respEmpty) {
|
|
1474
1503
|
this.responseText = '';
|
|
@@ -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
|
-
|
|
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"
|
|
189
|
+
openBracket = html`<span class="open-bracket object">${data['::nullable'] ? 'null┃' : ''}{</span>`;
|
|
190
190
|
} else {
|
|
191
|
-
openBracket = html`<span class="open-bracket object"
|
|
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
|
}
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 || tag.name}</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 || tag.name}</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 || tag.name}</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 || tag.name}</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
|
-
|
|
354
|
-
|
|
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');
|