rapidoc 9.3.6 → 9.3.8
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/.eslintrc +9 -1
- package/dist/index.html +1010 -6
- package/dist/index.html.gz +0 -0
- package/dist/rapidoc-min.js +444 -428
- package/dist/rapidoc-min.js.LICENSE.txt +1 -8
- 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 +576 -373
- package/dist/report.html +2 -2
- package/index.html +1006 -209
- package/{index1.html → index_bak.html} +13 -6
- package/jsconfig.json +1 -1
- package/package.json +8 -8
- package/src/components/api-request.js +144 -100
- package/src/components/api-response.js +12 -13
- package/src/components/json-tree.js +1 -1
- package/src/components/schema-table.js +16 -6
- package/src/components/schema-tree.js +15 -10
- package/src/json-schema-viewer.js +7 -2
- package/src/rapidoc-mini.js +22 -4
- package/src/rapidoc.js +35 -19
- package/src/styles/border-styles.js +2 -2
- package/src/styles/endpoint-styles.js +13 -10
- package/src/styles/flex-styles.js +1 -1
- package/src/styles/font-styles.js +13 -13
- package/src/styles/input-styles.js +8 -3
- package/src/styles/nav-styles.js +1 -1
- package/src/styles/schema-styles.js +12 -9
- package/src/templates/advance-search-template.js +2 -1
- package/src/templates/callback-template.js +3 -1
- package/src/templates/code-samples-template.js +3 -3
- package/src/templates/endpoint-template.js +33 -28
- package/src/templates/expanded-endpoint-template.js +7 -3
- package/src/templates/json-schema-viewer-template.js +3 -3
- package/src/templates/logo-template.js +1 -1
- package/src/templates/main-body-template.js +6 -17
- package/src/templates/navbar-template.js +6 -6
- package/src/templates/security-scheme-template.js +14 -10
- package/src/utils/common-utils.js +5 -9
- package/src/utils/schema-utils.js +65 -16
- package/src/utils/spec-parser.js +77 -7
- package/src/utils/theme.js +4 -6
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
<meta charset="utf-8">
|
|
6
6
|
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
|
|
7
7
|
<title>RapiDoc</title>
|
|
8
|
+
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.18.1/build/styles/default.min.css">
|
|
9
|
+
<script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.18.1/build/highlight.min.js"></script>
|
|
8
10
|
</head>
|
|
9
11
|
|
|
10
12
|
<script>
|
|
@@ -26,27 +28,32 @@
|
|
|
26
28
|
https://assets.zuora.com/zuora-documentation/swagger.yaml <<< Large spec with lot of markdown
|
|
27
29
|
./specs/petstore_anyof.yaml <<< contains complex one-of with inline primitives and recursive objects
|
|
28
30
|
./specs/oneof1.yaml <<< nested oneof
|
|
31
|
+
https://cesdev.eng.sonicwall.com/api/q/openapi
|
|
29
32
|
-->
|
|
30
33
|
<rapi-doc
|
|
31
|
-
spec-url = "./specs/
|
|
32
|
-
route-prefix="#tab-pets/"
|
|
34
|
+
spec-url = "./specs/temp.yaml"
|
|
33
35
|
id="thedoc"
|
|
34
36
|
theme = "dark"
|
|
35
|
-
render-style="
|
|
37
|
+
render-style="focused"
|
|
36
38
|
schema-style="tree"
|
|
37
|
-
|
|
39
|
+
show-method-in-nav-bar = "true"
|
|
40
|
+
use-path-in-nav-bar = "true"
|
|
38
41
|
show-components = "true"
|
|
39
42
|
show-info = "true"
|
|
40
43
|
show-header = "true"
|
|
41
|
-
allow-search = "
|
|
44
|
+
allow-search = "true"
|
|
42
45
|
allow-advanced-search = "true"
|
|
43
46
|
allow-spec-url-load="false"
|
|
44
|
-
allow-spec-file-load="false"
|
|
45
47
|
allow-spec-file-download="true"
|
|
46
48
|
allow-server-selection = "true"
|
|
47
49
|
allow-authentication = "true"
|
|
50
|
+
update-route="false"
|
|
51
|
+
remove-endpoints-with-badge-label-as="one"
|
|
48
52
|
match-type="regex"
|
|
49
53
|
persist-auth="true"
|
|
54
|
+
scroll-behavior="smooth"
|
|
55
|
+
allow-try = "false"
|
|
56
|
+
show-curl-before-try = "true"
|
|
50
57
|
></rapi-doc>
|
|
51
58
|
<!--
|
|
52
59
|
<rapi-doc-mini
|
package/jsconfig.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rapidoc",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.8",
|
|
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,10 +33,10 @@
|
|
|
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.33",
|
|
37
37
|
"base64-arraybuffer": "^1.0.2",
|
|
38
38
|
"buffer": "^6.0.3",
|
|
39
|
-
"lit": "^3.2.
|
|
39
|
+
"lit": "^3.2.1",
|
|
40
40
|
"marked": "4.3.0",
|
|
41
41
|
"prismjs": "^1.29.0",
|
|
42
42
|
"randexp": "^0.5.3",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"lint-fix": "./node_modules/eslint/bin/eslint.js --fix ./src/**"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@babel/core": "^7.25.
|
|
56
|
-
"@babel/eslint-parser": "^7.25.
|
|
57
|
-
"@babel/preset-env": "^7.25.
|
|
55
|
+
"@babel/core": "^7.25.8",
|
|
56
|
+
"@babel/eslint-parser": "^7.25.8",
|
|
57
|
+
"@babel/preset-env": "^7.25.8",
|
|
58
58
|
"babel-loader": "^9.2.1",
|
|
59
59
|
"babel-plugin-template-html-minifier": "^4.1.0",
|
|
60
60
|
"clean-webpack-plugin": "^4.0.0",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"eslint": "^8.57.1",
|
|
64
64
|
"eslint-config-airbnb": "^19.0.4",
|
|
65
65
|
"eslint-import-resolver-webpack": "^0.13.9",
|
|
66
|
-
"eslint-plugin-import": "^2.
|
|
66
|
+
"eslint-plugin-import": "^2.31.0",
|
|
67
67
|
"eslint-webpack-plugin": "4.2.0",
|
|
68
68
|
"file-loader": "^6.2.0",
|
|
69
69
|
"filemanager-webpack-plugin": "^8.0.0",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"style-loader": "^4.0.0",
|
|
73
73
|
"terser-webpack-plugin": "^5.3.10",
|
|
74
74
|
"unminified-webpack-plugin": "^3.0.0",
|
|
75
|
-
"webpack": "^5.
|
|
75
|
+
"webpack": "^5.95.0",
|
|
76
76
|
"webpack-bundle-analyzer": "^4.10.2",
|
|
77
77
|
"webpack-cli": "^5.1.4",
|
|
78
78
|
"webpack-dev-server": "4.11.1"
|
|
@@ -2,6 +2,7 @@ import { LitElement, html, css } from 'lit';
|
|
|
2
2
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js'; // eslint-disable-line import/extensions
|
|
3
3
|
import { guard } from 'lit/directives/guard.js'; // eslint-disable-line import/extensions
|
|
4
4
|
import { live } from 'lit/directives/live.js'; // eslint-disable-line import/extensions
|
|
5
|
+
import { ifDefined } from 'lit/directives/if-defined.js'; // eslint-disable-line import/extensions
|
|
5
6
|
import { marked } from 'marked';
|
|
6
7
|
import formatXml from 'xml-but-prettier';
|
|
7
8
|
import Prism from 'prismjs';
|
|
@@ -20,7 +21,7 @@ import { schemaInObjectNotation,
|
|
|
20
21
|
normalizeExamples,
|
|
21
22
|
getSchemaFromParam,
|
|
22
23
|
json2xml,
|
|
23
|
-
|
|
24
|
+
standardizeExample,
|
|
24
25
|
anyExampleWithSummaryOrDescription } from '~/utils/schema-utils';
|
|
25
26
|
import '~/components/json-tree';
|
|
26
27
|
import '~/components/schema-tree';
|
|
@@ -99,6 +100,9 @@ export default class ApiRequest extends LitElement {
|
|
|
99
100
|
TabStyles,
|
|
100
101
|
PrismStyles,
|
|
101
102
|
css`
|
|
103
|
+
:host {
|
|
104
|
+
container-type: inline-size;
|
|
105
|
+
}
|
|
102
106
|
*, *:before, *:after { box-sizing: border-box; }
|
|
103
107
|
:where(button, input[type="checkbox"], [tabindex="0"]):focus-visible { box-shadow: var(--focus-shadow); }
|
|
104
108
|
:where(input[type="text"], input[type="password"], select, textarea):focus-visible { border-color: var(--primary-color); }
|
|
@@ -183,13 +187,13 @@ export default class ApiRequest extends LitElement {
|
|
|
183
187
|
opacity: 1;
|
|
184
188
|
}
|
|
185
189
|
|
|
186
|
-
@
|
|
190
|
+
@container (min-width: 768px) {
|
|
187
191
|
.textarea {
|
|
188
192
|
padding:8px;
|
|
189
193
|
}
|
|
190
194
|
}
|
|
191
195
|
|
|
192
|
-
@
|
|
196
|
+
@container (max-width: 470px) {
|
|
193
197
|
.hide-in-small-screen {
|
|
194
198
|
display:none;
|
|
195
199
|
}
|
|
@@ -199,6 +203,7 @@ export default class ApiRequest extends LitElement {
|
|
|
199
203
|
];
|
|
200
204
|
}
|
|
201
205
|
|
|
206
|
+
/* eslint-disable indent */
|
|
202
207
|
render() {
|
|
203
208
|
return html`
|
|
204
209
|
<div class="col regular-font request-panel ${'read focused'.includes(this.renderStyle) || this.callback === 'true' ? 'read-mode' : 'view-mode'}">
|
|
@@ -270,7 +275,6 @@ export default class ApiRequest extends LitElement {
|
|
|
270
275
|
}
|
|
271
276
|
}
|
|
272
277
|
|
|
273
|
-
/* eslint-disable indent */
|
|
274
278
|
renderExample(example, paramType, paramName) {
|
|
275
279
|
return html`
|
|
276
280
|
${paramType === 'array' ? '[' : ''}
|
|
@@ -353,7 +357,7 @@ export default class ApiRequest extends LitElement {
|
|
|
353
357
|
let paramStyle = 'form';
|
|
354
358
|
let paramExplode = true;
|
|
355
359
|
let paramAllowReserved = false;
|
|
356
|
-
if (paramType === 'query') {
|
|
360
|
+
if (paramType === 'query' || paramType === 'header' || paramType === 'path') {
|
|
357
361
|
if (param.style && 'form spaceDelimited pipeDelimited'.includes(param.style)) {
|
|
358
362
|
paramStyle = param.style;
|
|
359
363
|
} else if (serializeStyle) {
|
|
@@ -368,12 +372,12 @@ export default class ApiRequest extends LitElement {
|
|
|
368
372
|
}
|
|
369
373
|
// openapi 3.1.0 spec based examples (which must be Object(string : { value:any, summary?: string, description?: string})
|
|
370
374
|
const example = normalizeExamples(
|
|
371
|
-
(param.examples
|
|
372
|
-
||
|
|
373
|
-
||
|
|
374
|
-
|| mimeTypeElem?.examples
|
|
375
|
-
||
|
|
376
|
-
||
|
|
375
|
+
(standardizeExample(param.examples)
|
|
376
|
+
|| standardizeExample(param.example)
|
|
377
|
+
|| standardizeExample(mimeTypeElem?.example)
|
|
378
|
+
|| standardizeExample(mimeTypeElem?.examples)
|
|
379
|
+
|| standardizeExample(paramSchema.examples)
|
|
380
|
+
|| standardizeExample(paramSchema.example)
|
|
377
381
|
),
|
|
378
382
|
paramSchema.type,
|
|
379
383
|
);
|
|
@@ -381,8 +385,8 @@ export default class ApiRequest extends LitElement {
|
|
|
381
385
|
example.exampleVal = generateExample(
|
|
382
386
|
declaredParamSchema,
|
|
383
387
|
serializeStyle || 'json',
|
|
384
|
-
|
|
385
|
-
|
|
388
|
+
{},
|
|
389
|
+
{},
|
|
386
390
|
this.callback === 'true' || this.webhook === 'true' ? true : false, // eslint-disable-line no-unneeded-ternary
|
|
387
391
|
this.callback === 'true' || this.webhook === 'true' ? false : true, // eslint-disable-line no-unneeded-ternary
|
|
388
392
|
true,
|
|
@@ -395,7 +399,10 @@ export default class ApiRequest extends LitElement {
|
|
|
395
399
|
<tr title="${param.deprecated ? 'Deprecated' : ''}">
|
|
396
400
|
<td rowspan="${this.allowTry === 'true' ? '1' : '2'}" style="width:${labelColWidth}; min-width:100px;">
|
|
397
401
|
<div class="param-name ${param.deprecated ? 'deprecated' : ''}" >
|
|
398
|
-
${param.deprecated
|
|
402
|
+
${param.deprecated
|
|
403
|
+
? html`<svg viewBox="0 0 10 10" width="10" height="10" style="stroke:var(--red); margin-right:-6px"><path d="M2 2L8 8M2 8L8 2"/></svg>`
|
|
404
|
+
: ''
|
|
405
|
+
}
|
|
399
406
|
${param.required ? html`<span style='color:var(--red)'>*</span>` : ''}
|
|
400
407
|
${param.name}
|
|
401
408
|
</div>
|
|
@@ -412,6 +419,7 @@ export default class ApiRequest extends LitElement {
|
|
|
412
419
|
${paramSchema.type === 'array'
|
|
413
420
|
? html`
|
|
414
421
|
<tag-input class="request-param"
|
|
422
|
+
id = "tag-input-request-param-${param.name}"
|
|
415
423
|
style = "width:100%"
|
|
416
424
|
data-ptype = "${paramType}"
|
|
417
425
|
data-pname = "${param.name}"
|
|
@@ -430,58 +438,60 @@ export default class ApiRequest extends LitElement {
|
|
|
430
438
|
</tag-input>`
|
|
431
439
|
: paramSchema.type === 'object'
|
|
432
440
|
? html`
|
|
433
|
-
<div class="tab-panel col" style="border-width:0 0 1px 0;">
|
|
434
|
-
<div class="tab-buttons row" @click="${(e) => {
|
|
441
|
+
<div part="tab-panel" class="tab-panel col" style="border-width:0 0 1px 0;">
|
|
442
|
+
<div part="tab-btn-row" class="tab-buttons row" @click="${(e) => {
|
|
435
443
|
if (e.target.tagName.toLowerCase() === 'button') {
|
|
436
444
|
const newState = { ...this.activeParameterSchemaTabs };
|
|
437
445
|
newState[param.name] = e.target.dataset.tab;
|
|
438
446
|
this.activeParameterSchemaTabs = newState;
|
|
439
447
|
}
|
|
440
448
|
}}">
|
|
441
|
-
<button class="tab-btn ${this.activeParameterSchemaTabs[param.name] === 'example' ? 'active' : ''}" data-tab = 'example'>EXAMPLE </button>
|
|
442
|
-
<button class="tab-btn ${this.activeParameterSchemaTabs[param.name] !== 'example' ? 'active' : ''}" data-tab = 'schema'>SCHEMA</button>
|
|
449
|
+
<button part="tab-btn" class="tab-btn ${this.activeParameterSchemaTabs[param.name] === 'example' ? 'active' : ''}" data-tab = 'example'>EXAMPLE </button>
|
|
450
|
+
<button part="tab-btn" class="tab-btn ${this.activeParameterSchemaTabs[param.name] !== 'example' ? 'active' : ''}" data-tab = 'schema'>SCHEMA</button>
|
|
443
451
|
</div>
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
452
|
+
|
|
453
|
+
${html`<div part="tab-content" class="tab-content col" data-tab = 'example' style="display:${this.activeParameterSchemaTabs[param.name] === 'example' ? 'block' : 'none'}; padding-left:5px; width:100%">
|
|
454
|
+
<textarea
|
|
455
|
+
id = "textarea-request-param-${param.name}"
|
|
456
|
+
class = "textarea request-param"
|
|
457
|
+
part = "textarea textarea-param"
|
|
458
|
+
data-ptype = "${paramType}-object"
|
|
459
|
+
data-pname = "${param.name}"
|
|
460
|
+
data-example = "${example.exampleVal}"
|
|
461
|
+
data-param-serialize-style = "${paramStyle}"
|
|
462
|
+
data-param-serialize-explode = "${paramExplode}"
|
|
463
|
+
data-param-allow-reserved = "${paramAllowReserved}"
|
|
464
|
+
data-x-fill-example = "${param['x-fill-example'] || 'yes'}"
|
|
465
|
+
spellcheck = "false"
|
|
466
|
+
.textContent="${param['x-fill-example'] === 'no' ? '' : live(this.fillRequestFieldsWithExample === 'true' ? (typeof example.exampleVal === 'object' ? JSON.stringify(example.exampleVal, null, 2) : example.exampleVal) : '')}"
|
|
467
|
+
style = "resize:vertical; width:100%; height: ${'read focused'.includes(this.renderStyle) ? '180px' : '120px'};"
|
|
468
|
+
@input=${(e) => {
|
|
469
|
+
const requestPanelEl = this.getRequestPanel(e);
|
|
470
|
+
this.liveCURLSyntaxUpdate(requestPanelEl);
|
|
471
|
+
}}
|
|
472
|
+
></textarea>
|
|
473
|
+
</div>`
|
|
474
|
+
}
|
|
475
|
+
${html`<div part="tab-content" class="tab-content col" data-tab = 'schema' style="display:${this.activeParameterSchemaTabs[param.name] !== 'example' ? 'block' : 'none'}; padding-left:5px; width:100%;">
|
|
476
|
+
<schema-tree
|
|
477
|
+
class = 'json'
|
|
478
|
+
style = 'display: block'
|
|
479
|
+
.data = '${schemaAsObj}'
|
|
480
|
+
schema-expand-level = "${this.schemaExpandLevel}"
|
|
481
|
+
schema-description-expanded = "${this.schemaDescriptionExpanded}"
|
|
482
|
+
allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}"
|
|
483
|
+
schema-hide-read-only = "${this.schemaHideReadOnly.includes(this.method)}"
|
|
484
|
+
schema-hide-write-only = "${this.schemaHideWriteOnly.includes(this.method)}"
|
|
485
|
+
exportparts = "wrap-request-btn:wrap-request-btn, btn:btn, btn-fill:btn-fill, btn-outline:btn-outline, btn-try:btn-try, btn-clear:btn-clear, btn-clear-resp:btn-clear-resp,
|
|
486
|
+
file-input:file-input, textbox:textbox, textbox-param:textbox-param, textarea:textarea, textarea-param:textarea-param,
|
|
487
|
+
anchor:anchor, anchor-param-example:anchor-param-example"
|
|
488
|
+
> </schema-tree>
|
|
489
|
+
</div>`
|
|
490
|
+
}
|
|
491
|
+
</div>`
|
|
483
492
|
: html`
|
|
484
493
|
<input type="${paramSchema.format === 'password' ? 'password' : 'text'}" spellcheck="false" style="width:100%"
|
|
494
|
+
id="input-request-param-${param.name}"
|
|
485
495
|
class="request-param"
|
|
486
496
|
part="textbox textbox-param"
|
|
487
497
|
data-ptype="${paramType}"
|
|
@@ -641,8 +651,8 @@ export default class ApiRequest extends LitElement {
|
|
|
641
651
|
reqBodyExamples = generateExample(
|
|
642
652
|
reqBody.schema,
|
|
643
653
|
reqBody.mimeType,
|
|
644
|
-
reqBody.examples,
|
|
645
|
-
reqBody.example,
|
|
654
|
+
standardizeExample(reqBody.examples),
|
|
655
|
+
standardizeExample(reqBody.example),
|
|
646
656
|
this.callback === 'true' || this.webhook === 'true' ? true : false, // eslint-disable-line no-unneeded-ternary
|
|
647
657
|
this.callback === 'true' || this.webhook === 'true' ? false : true, // eslint-disable-line no-unneeded-ternary
|
|
648
658
|
'text',
|
|
@@ -725,7 +735,7 @@ export default class ApiRequest extends LitElement {
|
|
|
725
735
|
if (reqBody.mimeType === this.selectedRequestBodyType) {
|
|
726
736
|
reqBodyFileInputHtml = html`
|
|
727
737
|
<div class = "small-font-size bold-text row">
|
|
728
|
-
<input type="file" part="file-input" style="max-width:100%" class="request-body-param-file" data-ptype="${reqBody.mimeType}" spellcheck="false" />
|
|
738
|
+
<input id="input-request-body-param-file" type="file" part="file-input" style="max-width:100%" class="request-body-param-file" data-ptype="${reqBody.mimeType}" spellcheck="false" />
|
|
729
739
|
</div>
|
|
730
740
|
`;
|
|
731
741
|
}
|
|
@@ -780,13 +790,13 @@ export default class ApiRequest extends LitElement {
|
|
|
780
790
|
|
|
781
791
|
${(this.selectedRequestBodyType.includes('json') || this.selectedRequestBodyType.includes('xml') || this.selectedRequestBodyType.includes('text') || this.selectedRequestBodyType.includes('jose'))
|
|
782
792
|
? html`
|
|
783
|
-
<div class="tab-panel col" style="border-width:0 0 1px 0;">
|
|
784
|
-
<div class="tab-buttons row" @click="${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}">
|
|
785
|
-
<button class="tab-btn ${this.activeSchemaTab === 'example' ? 'active' : ''}" data-tab = 'example'>EXAMPLE</button>
|
|
786
|
-
<button class="tab-btn ${this.activeSchemaTab !== 'example' ? 'active' : ''}" data-tab = 'schema'>SCHEMA</button>
|
|
793
|
+
<div part="tab-panel" class="tab-panel col" style="border-width:0 0 1px 0;">
|
|
794
|
+
<div part="tab-btn-row" class="tab-buttons row" @click="${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}">
|
|
795
|
+
<button part="tab-btn" class="tab-btn ${this.activeSchemaTab === 'example' ? 'active' : ''}" data-tab = 'example'>EXAMPLE</button>
|
|
796
|
+
<button part="tab-btn" class="tab-btn ${this.activeSchemaTab !== 'example' ? 'active' : ''}" data-tab = 'schema'>SCHEMA</button>
|
|
787
797
|
</div>
|
|
788
|
-
${html`<div class="tab-content col" style="display:${this.activeSchemaTab === 'example' ? 'block' : 'none'};"> ${reqBodyExampleHtml}</div>`}
|
|
789
|
-
${html`<div class="tab-content col" style="display:${this.activeSchemaTab === 'example' ? 'none' : 'block'};"> ${reqBodySchemaHtml}</div>`}
|
|
798
|
+
${html`<div part="tab-content" class="tab-content col" style="display:${this.activeSchemaTab === 'example' ? 'block' : 'none'};"> ${reqBodyExampleHtml}</div>`}
|
|
799
|
+
${html`<div part="tab-content" class="tab-content col" style="display:${this.activeSchemaTab === 'example' ? 'none' : 'block'};"> ${reqBodySchemaHtml}</div>`}
|
|
790
800
|
</div>`
|
|
791
801
|
: html`
|
|
792
802
|
${reqBodyFileInputHtml}
|
|
@@ -802,8 +812,8 @@ export default class ApiRequest extends LitElement {
|
|
|
802
812
|
const formdataPartExample = generateExample(
|
|
803
813
|
fieldSchema,
|
|
804
814
|
'json',
|
|
805
|
-
fieldSchema.examples,
|
|
806
|
-
fieldSchema.example,
|
|
815
|
+
standardizeExample(fieldSchema.examples),
|
|
816
|
+
standardizeExample(fieldSchema.example),
|
|
807
817
|
this.callback === 'true' || this.webhook === 'true' ? true : false, // eslint-disable-line no-unneeded-ternary
|
|
808
818
|
this.callback === 'true' || this.webhook === 'true' ? false : true, // eslint-disable-line no-unneeded-ternary
|
|
809
819
|
'text',
|
|
@@ -811,7 +821,7 @@ export default class ApiRequest extends LitElement {
|
|
|
811
821
|
);
|
|
812
822
|
|
|
813
823
|
return html`
|
|
814
|
-
<div class="tab-panel row" style="min-height:220px; border-left: 6px solid var(--light-border-color); align-items: stretch;">
|
|
824
|
+
<div part="tab-panel" class="tab-panel row" style="min-height:220px; border-left: 6px solid var(--light-border-color); align-items: stretch;">
|
|
815
825
|
<div style="width:24px; background-color:var(--light-border-color)">
|
|
816
826
|
<div class="row" style="flex-direction:row-reverse; width:160px; height:24px; transform:rotate(270deg) translateX(-160px); transform-origin:top left; display:block;" @click="${(e) => {
|
|
817
827
|
if (e.target.classList.contains('v-tab-btn')) {
|
|
@@ -852,7 +862,7 @@ export default class ApiRequest extends LitElement {
|
|
|
852
862
|
${html`
|
|
853
863
|
<div class="tab-content col" data-tab = 'schema' style="display:${this.activeSchemaTab !== 'example' ? 'block' : 'none'}; padding-left:5px; width:100%;">
|
|
854
864
|
<schema-tree
|
|
855
|
-
.data =
|
|
865
|
+
.data = "${formdataPartSchema}"
|
|
856
866
|
schema-expand-level = "${this.schemaExpandLevel}"
|
|
857
867
|
schema-description-expanded = "${this.schemaDescriptionExpanded}"
|
|
858
868
|
allow-schema-description-expand-toggle = "${this.allowSchemaDescriptionExpandToggle}",
|
|
@@ -1014,7 +1024,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1014
1024
|
curlSyntaxTemplate(display = 'flex') {
|
|
1015
1025
|
return html`
|
|
1016
1026
|
<div class="col m-markdown" style="flex:1; display:${display}; position:relative; max-width: 100%;">
|
|
1017
|
-
<button class="toolbar-btn" style = "position:absolute; top:12px; right:8px" @click='${(e) => { copyToClipboard(this.curlSyntax.replace(/\\$/, ''), e); }}' part="btn btn-fill"> Copy </button>
|
|
1027
|
+
<button class="toolbar-btn" style = "position:absolute; top:12px; right:8px" @click='${(e) => { copyToClipboard(this.curlSyntax.trim().replace(/\\$/, ''), e); }}' part="btn btn-fill"> Copy </button>
|
|
1018
1028
|
<pre style="white-space:pre"><code>${unsafeHTML(Prism.highlight(this.curlSyntax.trim().replace(/\\$/, ''), Prism.languages.shell, 'shell'))}</code></pre>
|
|
1019
1029
|
</div>
|
|
1020
1030
|
`;
|
|
@@ -1045,22 +1055,22 @@ export default class ApiRequest extends LitElement {
|
|
|
1045
1055
|
<div style="flex:1"></div>
|
|
1046
1056
|
<button class="m-btn" part="btn btn-outline btn-clear-response" @click="${this.clearResponseData}">CLEAR RESPONSE</button>
|
|
1047
1057
|
</div>
|
|
1048
|
-
<div class="tab-panel col" style="border-width:0 0 1px 0;">
|
|
1049
|
-
<div id="tab_buttons" class="tab-buttons row" @click="${(e) => {
|
|
1058
|
+
<div part="tab-panel" class="tab-panel col" style="border-width:0 0 1px 0;">
|
|
1059
|
+
<div id="tab_buttons" part="tab-btn-row" class="tab-buttons row" @click="${(e) => {
|
|
1050
1060
|
if (e.target.classList.contains('tab-btn') === false) { return; }
|
|
1051
1061
|
this.activeResponseTab = e.target.dataset.tab;
|
|
1052
1062
|
}}">
|
|
1053
|
-
<button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab = 'response' > RESPONSE</button>
|
|
1054
|
-
<button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab = 'headers' > RESPONSE HEADERS</button>
|
|
1063
|
+
<button part="tab-btn" class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab = 'response' > RESPONSE</button>
|
|
1064
|
+
<button part="tab-btn" class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab = 'headers' > RESPONSE HEADERS</button>
|
|
1055
1065
|
${this.showCurlBeforeTry === 'true'
|
|
1056
1066
|
? ''
|
|
1057
|
-
: html`<button class="tab-btn ${this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab = 'curl'>CURL</button>`}
|
|
1067
|
+
: html`<button part="tab-btn" class="tab-btn ${this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab = 'curl'>CURL</button>`}
|
|
1058
1068
|
</div>
|
|
1059
1069
|
${this.responseIsBlob
|
|
1060
1070
|
? html`
|
|
1061
|
-
<div class="tab-content col" style="flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};">
|
|
1071
|
+
<div part="tab-content" class="tab-content col" style="flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};">
|
|
1062
1072
|
${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>`
|
|
1073
|
+
? html`<img style="max-height:var(--resp-area-height, 400px); object-fit:contain;" class="mar-top-8" src="${ifDefined(this.responseBlobUrl)}"></img>`
|
|
1064
1074
|
: ''
|
|
1065
1075
|
}
|
|
1066
1076
|
<button class="m-btn thin-border mar-top-8" style="width:135px" @click='${(e) => { downloadResource(this.responseBlobUrl, this.respContentDisposition, e); }}' part="btn btn-outline">
|
|
@@ -1072,12 +1082,12 @@ export default class ApiRequest extends LitElement {
|
|
|
1072
1082
|
}
|
|
1073
1083
|
</div>`
|
|
1074
1084
|
: html`
|
|
1075
|
-
<div class="tab-content col m-markdown" style="flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};" >
|
|
1085
|
+
<div part="tab-content" class="tab-content col m-markdown" style="flex:1; display:${this.activeResponseTab === 'response' ? 'flex' : 'none'};" >
|
|
1076
1086
|
<button class="toolbar-btn" style="position:absolute; top:12px; right:8px" @click='${(e) => { copyToClipboard(this.responseText, e); }}' part="btn btn-fill"> Copy </button>
|
|
1077
1087
|
<pre style="white-space:pre; min-height:50px; height:var(--resp-area-height, 400px); resize:vertical; overflow:auto">${responseContent}</pre>
|
|
1078
1088
|
</div>`
|
|
1079
1089
|
}
|
|
1080
|
-
<div class="tab-content col m-markdown" style="flex:1; display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'};" >
|
|
1090
|
+
<div part="tab-content" class="tab-content col m-markdown" style="flex:1; display:${this.activeResponseTab === 'headers' ? 'flex' : 'none'};" >
|
|
1081
1091
|
<button class="toolbar-btn" style = "position:absolute; top:12px; right:8px" @click='${(e) => { copyToClipboard(this.responseHeaders, e); }}' part="btn btn-fill"> Copy </button>
|
|
1082
1092
|
<pre style="white-space:pre"><code>${unsafeHTML(Prism.highlight(this.responseHeaders, Prism.languages.css, 'css'))}</code></pre>
|
|
1083
1093
|
</div>
|
|
@@ -1086,18 +1096,8 @@ export default class ApiRequest extends LitElement {
|
|
|
1086
1096
|
}
|
|
1087
1097
|
|
|
1088
1098
|
apiCallTemplate() {
|
|
1089
|
-
let selectServerDropdownHtml = '';
|
|
1090
|
-
|
|
1091
|
-
if (this.servers && this.servers.length > 0) {
|
|
1092
|
-
selectServerDropdownHtml = html`
|
|
1093
|
-
<select style="min-width:100px;" @change='${(e) => { this.serverUrl = e.target.value; }}'>
|
|
1094
|
-
${this.servers.map((v) => html`<option value = "${v.url}"> ${v.url} - ${v.description} </option>`)}
|
|
1095
|
-
</select>
|
|
1096
|
-
`;
|
|
1097
|
-
}
|
|
1098
1099
|
const selectedServerHtml = html`
|
|
1099
1100
|
<div style="display:flex; flex-direction:column;">
|
|
1100
|
-
${selectServerDropdownHtml}
|
|
1101
1101
|
${this.serverUrl
|
|
1102
1102
|
? html`
|
|
1103
1103
|
<div style="display:flex; align-items:baseline;">
|
|
@@ -1127,7 +1127,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1127
1127
|
: `${this.api_keys.length} API keys applied`
|
|
1128
1128
|
}
|
|
1129
1129
|
</div>`
|
|
1130
|
-
: html`<div class="gray-text">Required <span style="color:var(--red)">(None Applied)</span>`
|
|
1130
|
+
: html`<div class="gray-text">Required <span style="color:var(--red)">(None Applied)</span> </div>`
|
|
1131
1131
|
}`
|
|
1132
1132
|
: html`<span class="gray-text"> Not Required </span>`
|
|
1133
1133
|
}
|
|
@@ -1263,7 +1263,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1263
1263
|
}
|
|
1264
1264
|
}
|
|
1265
1265
|
}
|
|
1266
|
-
} catch
|
|
1266
|
+
} catch {
|
|
1267
1267
|
console.error('RapiDoc: unable to parse %s into object', el.value); // eslint-disable-line no-console
|
|
1268
1268
|
}
|
|
1269
1269
|
if (queryParam.toString()) {
|
|
@@ -1301,7 +1301,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1301
1301
|
|
|
1302
1302
|
buildFetchHeaders(requestPanelEl) {
|
|
1303
1303
|
const respEl = this.closest('.expanded-req-resp-container, .req-resp-container')?.getElementsByTagName('api-response')[0];
|
|
1304
|
-
const headerParamEls = [...requestPanelEl.querySelectorAll("[data-ptype='header']")];
|
|
1304
|
+
const headerParamEls = [...requestPanelEl.querySelectorAll("[data-ptype='header'], [data-ptype='header-object']")];
|
|
1305
1305
|
const requestBodyContainerEl = requestPanelEl.querySelector('.request-body-container');
|
|
1306
1306
|
const acceptHeader = respEl?.selectedMimeType;
|
|
1307
1307
|
const reqHeaders = new Headers();
|
|
@@ -1322,7 +1322,38 @@ export default class ApiRequest extends LitElement {
|
|
|
1322
1322
|
// Add Header Params
|
|
1323
1323
|
headerParamEls.map((el) => {
|
|
1324
1324
|
if (el.value) {
|
|
1325
|
-
|
|
1325
|
+
if (el.dataset.ptype === 'header-object') {
|
|
1326
|
+
/* CONVERT
|
|
1327
|
+
a header value from below object style
|
|
1328
|
+
{
|
|
1329
|
+
"key1": "val1",
|
|
1330
|
+
"key2": {
|
|
1331
|
+
"key2_1": "val2_1",
|
|
1332
|
+
"key2_2": {
|
|
1333
|
+
"key2_2_1": "val2_2_1"
|
|
1334
|
+
}
|
|
1335
|
+
},
|
|
1336
|
+
"key3": "val3"
|
|
1337
|
+
};
|
|
1338
|
+
|
|
1339
|
+
TO >>>
|
|
1340
|
+
key1=val1, key2={"key2_1":"val2_1","key2_2":{"key2_2_1":"val2_2_1"}}, key3=val3
|
|
1341
|
+
*/
|
|
1342
|
+
const headerObjVal = JSON.parse(el.value.replace(/\n/g, '').trim());
|
|
1343
|
+
const firstLevelKeySeparator = el.dataset.paramSerializeExplode === 'true' ? '=' : ',';
|
|
1344
|
+
const headerStrVal = Object.keys(headerObjVal)
|
|
1345
|
+
.map((key) => {
|
|
1346
|
+
const value = headerObjVal[key];
|
|
1347
|
+
if (typeof value === 'object') {
|
|
1348
|
+
return `${key}${firstLevelKeySeparator}${JSON.stringify(value)}`;
|
|
1349
|
+
}
|
|
1350
|
+
return `${key}${firstLevelKeySeparator}${value}`;
|
|
1351
|
+
})
|
|
1352
|
+
.join(',');
|
|
1353
|
+
reqHeaders.append(el.dataset.pname, headerStrVal);
|
|
1354
|
+
} else {
|
|
1355
|
+
reqHeaders.append(el.dataset.pname, el.value);
|
|
1356
|
+
}
|
|
1326
1357
|
}
|
|
1327
1358
|
});
|
|
1328
1359
|
|
|
@@ -1334,7 +1365,6 @@ export default class ApiRequest extends LitElement {
|
|
|
1334
1365
|
reqHeaders.append('Content-Type', requestBodyType);
|
|
1335
1366
|
}
|
|
1336
1367
|
}
|
|
1337
|
-
|
|
1338
1368
|
return reqHeaders;
|
|
1339
1369
|
}
|
|
1340
1370
|
|
|
@@ -1497,11 +1527,12 @@ export default class ApiRequest extends LitElement {
|
|
|
1497
1527
|
respHeadersObj[hdr] = hdrVal;
|
|
1498
1528
|
this.responseHeaders = `${this.responseHeaders}${hdr}: ${hdrVal}\n`;
|
|
1499
1529
|
});
|
|
1500
|
-
|
|
1530
|
+
let contentType = fetchResponse.headers.get('content-type');
|
|
1501
1531
|
const respEmpty = (await fetchResponse.clone().text()).length === 0;
|
|
1502
1532
|
if (respEmpty) {
|
|
1503
1533
|
this.responseText = '';
|
|
1504
1534
|
} else if (contentType) {
|
|
1535
|
+
contentType = contentType.split(';')[0].trim();
|
|
1505
1536
|
if (contentType === 'application/x-ndjson') {
|
|
1506
1537
|
this.responseText = await fetchResponse.text();
|
|
1507
1538
|
} else if (contentType.includes('json')) {
|
|
@@ -1542,8 +1573,21 @@ export default class ApiRequest extends LitElement {
|
|
|
1542
1573
|
}
|
|
1543
1574
|
}
|
|
1544
1575
|
if (this.responseIsBlob) {
|
|
1545
|
-
const contentDisposition = fetchResponse.headers.get('content-disposition');
|
|
1546
|
-
|
|
1576
|
+
const contentDisposition = fetchResponse.headers.get('content-disposition') || '';
|
|
1577
|
+
let filenameFromContentDeposition = 'filename';
|
|
1578
|
+
if (contentDisposition) {
|
|
1579
|
+
const filenameStarRegexMatch = contentDisposition.match(/filename\*=\s*UTF-8''([^;]+)/); // Support Headers like >>> Content-Disposition: attachment; filename*=UTF-8''example%20file.pdf
|
|
1580
|
+
if (filenameStarRegexMatch) {
|
|
1581
|
+
filenameFromContentDeposition = decodeURIComponent(filenameStarRegexMatch[1]); // the filename* format in the Content-Disposition header follows RFC 5987, which allows encoding non-ASCII characters using percent encoding. so example%20file.pdf becomes example file.pdf
|
|
1582
|
+
} else {
|
|
1583
|
+
// Fallback to the regular filename format
|
|
1584
|
+
const filenameMatch = contentDisposition.match(/filename="?([^"]+)"?/); // Content-Disposition: attachment; filename=example.pdf
|
|
1585
|
+
if (filenameMatch) {
|
|
1586
|
+
filenameFromContentDeposition = filenameMatch[1];
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
this.respContentDisposition = filenameFromContentDeposition;
|
|
1547
1591
|
respBlob = await fetchResponse.blob();
|
|
1548
1592
|
this.responseBlobUrl = URL.createObjectURL(respBlob);
|
|
1549
1593
|
}
|
|
@@ -1635,7 +1679,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1635
1679
|
fetchHeaders.set(key, tempHeaderArray.join(', '));
|
|
1636
1680
|
});
|
|
1637
1681
|
|
|
1638
|
-
curlHeaders = Array.from(fetchHeaders).map(([key, value]) => ` -H
|
|
1682
|
+
curlHeaders = Array.from(fetchHeaders).map(([key, value]) => ` -H '${key}: ${value}'`).join('\\\n');
|
|
1639
1683
|
if (curlHeaders) {
|
|
1640
1684
|
curlHeaders = `${curlHeaders} \\\n`;
|
|
1641
1685
|
}
|
|
@@ -1667,7 +1711,7 @@ export default class ApiRequest extends LitElement {
|
|
|
1667
1711
|
if (requestBodyType.includes('json')) {
|
|
1668
1712
|
try {
|
|
1669
1713
|
curlData = ` -d '${JSON.stringify(JSON.parse(exampleTextAreaEl.value))}' \\\n`;
|
|
1670
|
-
} catch
|
|
1714
|
+
} catch {
|
|
1671
1715
|
// Ignore.
|
|
1672
1716
|
}
|
|
1673
1717
|
}
|