rapidoc 11.0.0 → 12.0.0

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 (80) hide show
  1. package/README.md +46 -31
  2. package/dist/rapidoc-min.js +1424 -213
  3. package/dist/rapidoc-static-min.js +13542 -0
  4. package/package.json +48 -34
  5. package/src/components/api-request.ts +869 -0
  6. package/src/components/api-response.ts +509 -0
  7. package/src/components/json-tree.ts +171 -0
  8. package/src/components/schema-base-element.ts +315 -0
  9. package/src/components/schema-table.ts +430 -0
  10. package/src/components/schema-tree.ts +386 -0
  11. package/src/components/tag-input.ts +184 -0
  12. package/src/index.js +6 -0
  13. package/src/oauth-receiver.ts +29 -0
  14. package/src/rapidoc-mini.ts +582 -0
  15. package/src/rapidoc.ts +1808 -0
  16. package/src/static/index.d.ts +149 -0
  17. package/src/static/index.js +62 -0
  18. package/src/static/navigation.js +497 -0
  19. package/src/static/render.js +490 -0
  20. package/src/static/serializer.js +216 -0
  21. package/src/styles/auth-styles.js +318 -0
  22. package/src/styles/border-styles.js +24 -0
  23. package/src/styles/css-bundle.js +129 -0
  24. package/src/styles/custom-styles.js +8 -0
  25. package/src/styles/dialog-box-styles.js +102 -0
  26. package/src/styles/endpoint-styles.js +559 -0
  27. package/src/styles/flex-styles.js +16 -0
  28. package/src/styles/font-styles.js +432 -0
  29. package/src/styles/info-styles.js +36 -0
  30. package/src/styles/input-styles.js +555 -0
  31. package/src/styles/layout-styles.js +396 -0
  32. package/src/styles/microlighter-styles.js +99 -0
  33. package/src/styles/nav-styles.js +609 -0
  34. package/src/styles/param-list-styles.js +261 -0
  35. package/src/styles/schema-styles.js +288 -0
  36. package/src/styles/tab-styles.js +106 -0
  37. package/src/styles/theme-tokens.js +582 -0
  38. package/src/templates/advanced-search-dialog-template.js +94 -0
  39. package/src/templates/api-response-template.js +219 -0
  40. package/src/templates/callback-template.js +86 -0
  41. package/src/templates/code-samples-template.js +52 -0
  42. package/src/templates/components-template.js +86 -0
  43. package/src/templates/downloads-template.js +85 -0
  44. package/src/templates/endpoint-template.js +386 -0
  45. package/src/templates/expanded-endpoint-template.js +266 -0
  46. package/src/templates/focused-endpoint-template.js +145 -0
  47. package/src/templates/header-template.js +92 -0
  48. package/src/templates/logo-template.js +21 -0
  49. package/src/templates/main-body-template.js +102 -0
  50. package/src/templates/navbar-template.js +489 -0
  51. package/src/templates/overview-template.js +104 -0
  52. package/src/templates/request-body-template.js +651 -0
  53. package/src/templates/request-params-template.js +474 -0
  54. package/src/templates/security-scheme-template.js +1263 -0
  55. package/src/templates/server-template.js +152 -0
  56. package/src/utils/auto-color-scheme.js +99 -0
  57. package/src/utils/bind-navbar.js +175 -0
  58. package/src/utils/color-utils.js +59 -0
  59. package/src/utils/common-utils.js +191 -0
  60. package/src/utils/curl-utils.js +123 -0
  61. package/src/utils/highlighter.js +416 -0
  62. package/src/utils/markdown-utils.js +110 -0
  63. package/src/utils/mcp/common.js +467 -0
  64. package/src/utils/mcp/generators/csharp.js +242 -0
  65. package/src/utils/mcp/generators/go.js +298 -0
  66. package/src/utils/mcp/generators/java.js +330 -0
  67. package/src/utils/mcp/generators/python.js +248 -0
  68. package/src/utils/mcp/generators/rust.js +281 -0
  69. package/src/utils/mcp/generators/typescript.js +290 -0
  70. package/src/utils/mcp-generator.js +143 -0
  71. package/src/utils/mock-interceptor.js +508 -0
  72. package/src/utils/oauth-utils.js +87 -0
  73. package/src/utils/request-utils.js +203 -0
  74. package/src/utils/response-utils.js +203 -0
  75. package/src/utils/sanitize.js +57 -0
  76. package/src/utils/schema-utils.js +1927 -0
  77. package/src/utils/slugger.js +189 -0
  78. package/src/utils/spec-parser.js +915 -0
  79. package/src/utils/url-utils.js +211 -0
  80. package/src/utils/xml-utils.js +61 -0
@@ -0,0 +1,651 @@
1
+ /**
2
+ * Renders request body form inputs, JSON/XML textareas, MIME type dropdown, and schema preview panels for <api-request>.
3
+ */
4
+ import { html } from "lit";
5
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
6
+ import { live } from "lit/directives/live.js";
7
+ import { repeat } from "lit/directives/repeat.js";
8
+ import { ifDefined } from "lit/directives/if-defined.js";
9
+ import { sanitizeHTML } from "../utils/sanitize.js";
10
+ import { marked } from "marked";
11
+ import {
12
+ schemaToAST,
13
+ getTypeInfo,
14
+ isBinaryFileField,
15
+ generateExample,
16
+ normalizeExamples,
17
+ standardizeExample,
18
+ EMPTY_ARRAY,
19
+ getMergedProperties,
20
+ getMergedRequired,
21
+ } from "~/utils/schema-utils";
22
+ import "~/components/schema-tree";
23
+ import "~/components/schema-table";
24
+ import "~/components/tag-input";
25
+ import {
26
+ exampleListTemplate,
27
+ constraintListTemplate,
28
+ examplesBesideConstraints,
29
+ renderExample,
30
+ } from "~/templates/request-params-template";
31
+
32
+ export function formDataParamAsObjectTemplate(fieldName, fieldSchema, mimeType) {
33
+ // This template is used when form-data param should be send as a object (application/json, application/xml)
34
+ const formdataPartSchema = schemaToAST(fieldSchema);
35
+ const formdataPartExample = generateExample(
36
+ fieldSchema,
37
+ "json",
38
+ standardizeExample(fieldSchema.examples),
39
+ standardizeExample(fieldSchema.example),
40
+ this.callback === "true" || this.webhook === "true" ? true : false,
41
+ this.callback === "true" || this.webhook === "true" ? false : true,
42
+ "text",
43
+ false,
44
+ );
45
+
46
+ return html`
47
+ <div part="tab-panel" class="tab-panel row" style="min-height:220px; border-left: 6px solid var(--border); align-items: stretch;">
48
+ <div style="width:24px; background:var(--border)">
49
+ <div
50
+ class="row"
51
+ style="flex-direction:row-reverse; width:160px; height:24px; transform:rotate(270deg) translateX(-160px); transform-origin:top left; display:block;"
52
+ @click="${(e) => {
53
+ if (e.target.classList.contains("v-tab-btn")) {
54
+ const { tab } = e.target.dataset;
55
+ if (tab) {
56
+ const tabPanelEl = e.target.closest(".tab-panel");
57
+ const selectedTabBtnEl = tabPanelEl.querySelector(`.v-tab-btn[data-tab="${tab}"]`);
58
+ const otherTabBtnEl = [
59
+ ...tabPanelEl.querySelectorAll(`.v-tab-btn:not([data-tab="${tab}"])`),
60
+ ];
61
+ const selectedTabContentEl = tabPanelEl.querySelector(
62
+ `.tab-content[data-tab="${tab}"]`,
63
+ );
64
+ const otherTabContentEl = [
65
+ ...tabPanelEl.querySelectorAll(`.tab-content:not([data-tab="${tab}"])`),
66
+ ];
67
+ selectedTabBtnEl.classList.add("active");
68
+ selectedTabContentEl.style.display = "block";
69
+ otherTabBtnEl.forEach((el) => {
70
+ el.classList.remove("active");
71
+ });
72
+ otherTabContentEl.forEach((el) => {
73
+ el.style.display = "none";
74
+ });
75
+ }
76
+ }
77
+ if (e.target.tagName.toLowerCase() === "button") {
78
+ this.activeSchemaTab = e.target.dataset.tab;
79
+ }
80
+ }}"
81
+ >
82
+ <button class="v-tab-btn ${this.activeSchemaTab === "example" ? "active" : ""}" data-tab="example">EXAMPLE</button>
83
+ <button class="v-tab-btn ${this.activeSchemaTab !== "example" ? "active" : ""}" data-tab="schema">SCHEMA</button>
84
+ </div>
85
+ </div>
86
+ ${html` <div
87
+ class="tab-content col"
88
+ data-tab="example"
89
+ style="display:${this.activeSchemaTab === "example" ? "block" : "none"}; padding-left:5px; width:100%"
90
+ >
91
+ <textarea
92
+ class="textarea"
93
+ part="textarea textarea-param"
94
+ style="width:100%; border:none; resize:vertical;"
95
+ data-array="false"
96
+ data-ptype="${mimeType.includes("form-urlencode") ? "form-urlencode" : "form-data"}"
97
+ data-pname="${fieldName}"
98
+ data-example="${formdataPartExample[0]?.exampleValue || ""}"
99
+ .value="${live(this.fillRequestFieldsWithExample === "true" ? formdataPartExample[0]?.exampleValue || "" : "")}"
100
+ spellcheck="false"
101
+ ></textarea>
102
+ </div>`}
103
+ ${html` <div
104
+ class="tab-content col"
105
+ data-tab="schema"
106
+ style="display:${this.activeSchemaTab !== "example" ? "block" : "none"}; padding-left:5px; width:100%;"
107
+ >
108
+ ${
109
+ this.schemaStyle === "table"
110
+ ? html`
111
+ <schema-table
112
+ .data="${formdataPartSchema}"
113
+ schema-expand-level="${this.schemaExpandLevel}"
114
+ schema-description-expanded="${this.schemaDescriptionExpanded}"
115
+ allow-schema-description-expand-toggle="${this.allowSchemaDescriptionExpandToggle}"
116
+ exportparts="schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
117
+ >
118
+ </schema-table>
119
+ `
120
+ : html`
121
+ <schema-tree
122
+ .data="${formdataPartSchema}"
123
+ schema-expand-level="${this.schemaExpandLevel}"
124
+ schema-description-expanded="${this.schemaDescriptionExpanded}"
125
+ allow-schema-description-expand-toggle="${this.allowSchemaDescriptionExpandToggle}"
126
+ exportparts="schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
127
+ >
128
+ </schema-tree>
129
+ `
130
+ }
131
+ </div>`}
132
+ </div>
133
+ `;
134
+ }
135
+
136
+ export function formDataTemplate(schema, mimeType, exampleValue = "") {
137
+ const formFieldItems = [];
138
+ const properties = getMergedProperties(schema);
139
+ const required = getMergedRequired(schema);
140
+ if (Object.keys(properties).length > 0) {
141
+ for (const fieldName in properties) {
142
+ const fieldSchema = properties[fieldName];
143
+ if (fieldSchema.readOnly) {
144
+ continue;
145
+ }
146
+ const fieldExamples = fieldSchema.examples || fieldSchema.example || "";
147
+ const fieldType = fieldSchema.type;
148
+ const paramSchema = getTypeInfo(fieldSchema);
149
+ const example = normalizeExamples(
150
+ paramSchema.examples || paramSchema.example,
151
+ paramSchema.type,
152
+ );
153
+ const hasConstraint =
154
+ fieldType !== "object" &&
155
+ (paramSchema.default ||
156
+ paramSchema.constrain ||
157
+ paramSchema.allowedValues ||
158
+ paramSchema.pattern);
159
+ const inlineExamples = examplesBesideConstraints(
160
+ fieldSchema.description,
161
+ hasConstraint,
162
+ example.exampleList,
163
+ );
164
+ formFieldItems.push(
165
+ html` <li
166
+ class="param ${fieldSchema.deprecated ? "deprecated" : ""}"
167
+ part="param"
168
+ title="${fieldSchema.deprecated ? "Deprecated" : ""}"
169
+ >
170
+ <div class="param-label" part="param-label">
171
+ <div class="param-name ${fieldSchema.deprecated ? "deprecated" : ""}" part="param-name">
172
+ ${fieldName}${required.includes(fieldName) || fieldSchema.required ? html`<span class="param-required" title="Required">*</span>` : ""}
173
+ </div>
174
+ <div class="param-type" part="param-type">
175
+ ${
176
+ paramSchema.type === "array" || paramSchema.type.split("┃").includes("array")
177
+ ? `${paramSchema.arrayType || paramSchema.type}`
178
+ : `${paramSchema.format && !paramSchema.type.includes("┃") ? paramSchema.format : paramSchema.contentMediaType && !paramSchema.type.includes("┃") ? paramSchema.contentMediaType : paramSchema.type}`
179
+ }
180
+ </div>
181
+ </div>
182
+ ${
183
+ fieldType !== "object" && this.allowTry !== "true"
184
+ ? ""
185
+ : html`<div class="param-input" part="param-input">
186
+ ${
187
+ fieldType === "array"
188
+ ? isBinaryFileField(fieldSchema.items)
189
+ ? html`
190
+ <div class="file-input-container col" style="align-items:flex-start; width:100%;">
191
+ ${repeat(
192
+ this.fileInputKeys[fieldName] ?? [0],
193
+ (key) => key,
194
+ (key, index) => html`
195
+ <div class="input-set row" style="width:100%; margin-top: ${index > 0 ? "4px" : "0"};">
196
+ <input
197
+ type="file"
198
+ part="file-input"
199
+ style="width:100%"
200
+ data-pname="${fieldName}"
201
+ data-ptype="${mimeType.includes("form-urlencode") ? "form-urlencode" : "form-data"}"
202
+ data-array="false"
203
+ data-file-array="true"
204
+ />
205
+ <button
206
+ class="file-input-remove-btn"
207
+ aria-label="Remove file"
208
+ title="Remove"
209
+ @click="${() => this.onRemoveFileInput(fieldName, key)}"
210
+ >
211
+ &#x2715;
212
+ </button>
213
+ </div>
214
+ `,
215
+ )}
216
+ <button
217
+ class="btn btn-primary btn-sm file-input-add-btn"
218
+ part="btn btn-fill"
219
+ @click="${() => this.onAddFileInput(fieldName)}"
220
+ >
221
+ ADD
222
+ </button>
223
+ </div>
224
+ `
225
+ : html`
226
+ <tag-input
227
+ style="width:100%"
228
+ data-ptype="${mimeType.includes("form-urlencode") ? "form-urlencode" : "form-data"}"
229
+ data-pname="${fieldName}"
230
+ data-example="${Array.isArray(fieldExamples) ? fieldExamples.join("~|~") : fieldExamples}"
231
+ data-array="true"
232
+ placeholder="add-multiple &#x21a9;"
233
+ .value="${
234
+ Array.isArray(fieldExamples)
235
+ ? Array.isArray(fieldExamples[0])
236
+ ? fieldExamples[0]
237
+ : fieldExamples
238
+ : EMPTY_ARRAY
239
+ }"
240
+ >
241
+ </tag-input>
242
+ `
243
+ : html` ${
244
+ fieldType === "object"
245
+ ? formDataParamAsObjectTemplate.call(
246
+ this,
247
+ fieldName,
248
+ fieldSchema,
249
+ mimeType,
250
+ )
251
+ : html`
252
+ ${
253
+ this.allowTry === "true"
254
+ ? html`<input
255
+ .value="${this.fillRequestFieldsWithExample === "true" ? example.exampleVal : ""}"
256
+ spellcheck="false"
257
+ type="${isBinaryFileField(fieldSchema) ? "file" : fieldSchema.format === "password" ? "password" : "text"}"
258
+ part="textbox textbox-param"
259
+ style="width:100%"
260
+ data-ptype="${mimeType.includes("form-urlencode") ? "form-urlencode" : "form-data"}"
261
+ data-pname="${fieldName}"
262
+ data-example="${Array.isArray(fieldExamples) ? fieldExamples[0] : fieldExamples}"
263
+ data-array="false"
264
+ />`
265
+ : ""
266
+ }
267
+ `
268
+ }`
269
+ }
270
+ </div>`
271
+ }
272
+ ${
273
+ hasConstraint
274
+ ? constraintListTemplate(
275
+ paramSchema,
276
+ paramSchema.allowedValues &&
277
+ String(paramSchema.allowedValues)
278
+ .split("┃")
279
+ .map(
280
+ (v) =>
281
+ html`<button
282
+ type="button"
283
+ part="anchor anchor-param-constraint"
284
+ class="value-chip"
285
+ ?disabled="${this.allowTry !== "true"}"
286
+ data-type="${paramSchema.type === "array" ? paramSchema.type : "string"}"
287
+ data-enum="${v.trim()}"
288
+ @click="${(e) => {
289
+ const inputEl = e.target
290
+ .closest(".param-list")
291
+ .querySelector(`[data-pname="${fieldName}"]`);
292
+ if (inputEl) {
293
+ if (e.target.dataset.type === "array") {
294
+ inputEl.value = [e.target.dataset.enum];
295
+ } else {
296
+ inputEl.value = e.target.dataset.enum;
297
+ }
298
+ const requestPanelEl = this.getRequestPanel(e);
299
+ this.liveCURLSyntaxUpdate(requestPanelEl);
300
+ }
301
+ }}"
302
+ >
303
+ ${v}
304
+ </button>`,
305
+ ),
306
+ inlineExamples &&
307
+ example.exampleList.map((x) =>
308
+ renderExample.call(this, x, paramSchema.type, fieldName),
309
+ ),
310
+ )
311
+ : ""
312
+ }
313
+ ${
314
+ fieldType === "object"
315
+ ? ""
316
+ : html`<div class="param-details" part="param-details">
317
+ ${fieldSchema.description ? html`<div class="m-markdown-small">${unsafeHTML(sanitizeHTML(marked(fieldSchema.description)))}</div>` : ""}
318
+ ${inlineExamples ? "" : exampleListTemplate.call(this, fieldName, paramSchema.type, example.exampleList)}
319
+ </div>`
320
+ }
321
+ </li>`,
322
+ );
323
+ }
324
+ return html`
325
+ <div class="param-list-container">
326
+ <ul
327
+ class="param-list"
328
+ part="param-list"
329
+ role="list"
330
+ @input="${(e) => {
331
+ const requestPanelEl = this.getRequestPanel(e);
332
+ this.liveCURLSyntaxUpdate(requestPanelEl);
333
+ }}"
334
+ @change="${(e) => {
335
+ const requestPanelEl = this.getRequestPanel(e);
336
+ this.liveCURLSyntaxUpdate(requestPanelEl);
337
+ }}"
338
+ >
339
+ ${formFieldItems}
340
+ </ul>
341
+ </div>
342
+ `;
343
+ }
344
+
345
+ return html`
346
+ <textarea
347
+ class="textarea dynamic-form-param ${mimeType}"
348
+ part="textarea textarea-param"
349
+ spellcheck="false"
350
+ data-pname="dynamic-form"
351
+ data-ptype="${mimeType}"
352
+ .value="${live(exampleValue)}"
353
+ style="width:100%"
354
+ ></textarea>
355
+ ${schema.description ? html`<span class="m-markdown-small"> ${unsafeHTML(sanitizeHTML(marked(schema.description)))} </span>` : ""}
356
+ `;
357
+ }
358
+
359
+ export default function requestBodyTemplate() {
360
+ if (!this.request_body) {
361
+ return "";
362
+ }
363
+ if (Object.keys(this.request_body).length === 0) {
364
+ return "";
365
+ }
366
+
367
+ // Variable to store partial HTMLs
368
+ let reqBodyTypeSelectorHtml = "";
369
+ let reqBodyFileInputHtml = "";
370
+ let reqBodyFormHtml = "";
371
+ let reqBodySchemaHtml = "";
372
+ let reqBodyExampleHtml = "";
373
+
374
+ const requestBodyTypes = [];
375
+ const { content } = this.request_body;
376
+ for (const mimeType in content) {
377
+ requestBodyTypes.push({
378
+ mimeType,
379
+ schema: content[mimeType].schema,
380
+ example: content[mimeType].example,
381
+ examples: content[mimeType].examples,
382
+ });
383
+ // Fallback guard: If selectedRequestBodyType was cleared (e.g., after focused-mode navigation),
384
+ // automatically latch onto the first available MIME type (e.g., application/json).
385
+ if (!this.selectedRequestBodyType) {
386
+ this.selectedRequestBodyType = mimeType;
387
+ }
388
+ }
389
+ // MIME Type selector
390
+ reqBodyTypeSelectorHtml =
391
+ requestBodyTypes.length === 1
392
+ ? ""
393
+ : html`
394
+ <select class="select-sm" aria-label="request body media type" @change="${(e) => this.onMimeTypeChange(e)}">
395
+ ${requestBodyTypes.map(
396
+ (reqBody) => html`
397
+ <option value="${reqBody.mimeType}" ?selected="${reqBody.mimeType === this.selectedRequestBodyType}">
398
+ ${reqBody.mimeType}
399
+ </option>
400
+ `,
401
+ )}
402
+ </select>
403
+ `;
404
+
405
+ // For Loop - Main
406
+ requestBodyTypes.forEach((reqBody) => {
407
+ let schemaAsObj;
408
+ let reqBodyExamples = [];
409
+
410
+ if (
411
+ this.selectedRequestBodyType.includes("json") ||
412
+ this.selectedRequestBodyType.includes("xml") ||
413
+ this.selectedRequestBodyType.includes("text") ||
414
+ this.selectedRequestBodyType.includes("jose")
415
+ ) {
416
+ // Generate Example
417
+ if (reqBody.mimeType === this.selectedRequestBodyType) {
418
+ reqBodyExamples = generateExample(
419
+ reqBody.schema,
420
+ reqBody.mimeType,
421
+ standardizeExample(reqBody.examples),
422
+ standardizeExample(reqBody.example),
423
+ this.callback === "true" || this.webhook === "true" ? true : false,
424
+ this.callback === "true" || this.webhook === "true" ? false : true,
425
+ "text",
426
+ false,
427
+ );
428
+ if (!this.selectedRequestBodyExample) {
429
+ this.selectedRequestBodyExample =
430
+ reqBodyExamples.length > 0 ? reqBodyExamples[0].exampleId : "";
431
+ }
432
+ reqBodyExampleHtml = html`
433
+ ${reqBodyExampleHtml}
434
+ <div class="example-panel">
435
+ ${
436
+ reqBodyExamples.length === 1
437
+ ? ""
438
+ : html`
439
+ <select class="select-sm example-select" aria-label="request body examples" @change="${(e) => this.onSelectExample(e)}">
440
+ ${reqBodyExamples.map(
441
+ (v) =>
442
+ html`<option value="${v.exampleId}" ?selected=${v.exampleId === this.selectedRequestBodyExample}>
443
+ ${v.exampleSummary.length > 80 ? v.exampleId : v.exampleSummary ? v.exampleSummary : v.exampleId}
444
+ </option>`,
445
+ )}
446
+ </select>
447
+ `
448
+ }
449
+ ${reqBodyExamples
450
+ .filter((v) => v.exampleId === this.selectedRequestBodyExample)
451
+ .map(
452
+ (v) => html`
453
+ <div
454
+ class="example ${v.exampleId === this.selectedRequestBodyExample ? "example-selected" : ""}"
455
+ data-example="${v.exampleId}"
456
+ >
457
+ ${v.exampleSummary && v.exampleSummary.length > 80 ? html`<div style="padding: 4px 0">${v.exampleSummary}</div>` : ""}
458
+ ${
459
+ v.exampleDescription
460
+ ? html`<div class="m-markdown-small" style="padding: 4px 0">
461
+ ${unsafeHTML(sanitizeHTML(marked(v.exampleDescription || "")))}
462
+ </div>`
463
+ : ""
464
+ }
465
+ <!-- This pre(hidden) is to store the original example value, this will remain unchanged when users switches from one example to another, its is used to populate the editable textarea -->
466
+ <pre
467
+ class="textarea is-hidden request-body-param ${reqBody.mimeType.substring(reqBody.mimeType.indexOf("/") + 1)}"
468
+ spellcheck="false"
469
+ data-ptype="${reqBody.mimeType}"
470
+ style="width:100%; resize:vertical; display:none"
471
+ >
472
+ ${v.exampleFormat === "text" ? v.exampleValue : JSON.stringify(v.exampleValue, null, 2)}</pre>
473
+
474
+ <!-- this textarea is for user to edit the example -->
475
+ <textarea
476
+ class="textarea request-body-param-user-input"
477
+ part="textarea textarea-param"
478
+ spellcheck="false"
479
+ data-ptype="${reqBody.mimeType}"
480
+ data-example="${v.exampleFormat === "text" ? v.exampleValue : JSON.stringify(v.exampleValue, null, 2)}"
481
+ data-example-format="${v.exampleFormat}"
482
+ style="width:100%; resize:vertical;"
483
+ .value="${
484
+ this.fillRequestFieldsWithExample === "true"
485
+ ? v.exampleFormat === "text"
486
+ ? v.exampleValue
487
+ : JSON.stringify(v.exampleValue, null, 2)
488
+ : ""
489
+ }"
490
+ @input=${(e) => {
491
+ const requestPanelEl = this.getRequestPanel(e);
492
+ this.liveCURLSyntaxUpdate(requestPanelEl);
493
+ }}
494
+ @keydown=${(e) => {
495
+ if ((e.keyCode === 10 || e.keyCode === 13) && e.ctrlKey) {
496
+ return this.onTryClick(e);
497
+ }
498
+ }}
499
+ ></textarea>
500
+ </div>
501
+ `,
502
+ )}
503
+ </div>
504
+ `;
505
+ }
506
+ } else if (
507
+ this.selectedRequestBodyType.includes("form-urlencoded") ||
508
+ this.selectedRequestBodyType.includes("form-data")
509
+ ) {
510
+ if (reqBody.mimeType === this.selectedRequestBodyType) {
511
+ const ex = generateExample(
512
+ reqBody.schema,
513
+ reqBody.mimeType,
514
+ reqBody.examples,
515
+ reqBody.example,
516
+ this.callback === "true" || this.webhook === "true" ? true : false,
517
+ this.callback === "true" || this.webhook === "true" ? false : true,
518
+ "text",
519
+ false,
520
+ );
521
+ if (reqBody.schema) {
522
+ reqBodyFormHtml = formDataTemplate.call(
523
+ this,
524
+ reqBody.schema,
525
+ reqBody.mimeType,
526
+ ex[0] ? ex[0].exampleValue : "",
527
+ );
528
+ }
529
+ }
530
+ } else if (
531
+ /^audio\/|^image\/|^video\/|^font\/|tar$|zip$|7z$|rtf$|msword$|excel$|\/pdf$|\/octet-stream$/.test(
532
+ this.selectedRequestBodyType,
533
+ )
534
+ ) {
535
+ if (reqBody.mimeType === this.selectedRequestBodyType) {
536
+ reqBodyFileInputHtml = html`
537
+ <input
538
+ id="input-request-body-param-file"
539
+ type="file"
540
+ part="file-input"
541
+ style="max-width:100%"
542
+ class="request-body-param-file small-font-size bold-text"
543
+ data-ptype="${reqBody.mimeType}"
544
+ spellcheck="false"
545
+ />
546
+ `;
547
+ }
548
+ }
549
+
550
+ // Generate Schema
551
+ if (
552
+ reqBody.mimeType.includes("json") ||
553
+ reqBody.mimeType.includes("xml") ||
554
+ reqBody.mimeType.includes("text") ||
555
+ this.selectedRequestBodyType.includes("jose")
556
+ ) {
557
+ schemaAsObj = schemaToAST(reqBody.schema);
558
+ if (this.schemaStyle === "table") {
559
+ reqBodySchemaHtml = html`
560
+ ${reqBodySchemaHtml}
561
+ <schema-table
562
+ class="${reqBody.mimeType.substring(reqBody.mimeType.indexOf("/") + 1)}"
563
+ style="display: ${this.selectedRequestBodyType === reqBody.mimeType ? "block" : "none"};"
564
+ .data="${schemaAsObj}"
565
+ schema-expand-level="${this.schemaExpandLevel}"
566
+ schema-description-expanded="${this.schemaDescriptionExpanded}"
567
+ allow-schema-description-expand-toggle="${this.allowSchemaDescriptionExpandToggle}"
568
+ schema-hide-read-only="${this.schemaHideReadOnly}"
569
+ schema-hide-write-only="${this.schemaHideWriteOnly}"
570
+ exportparts="schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
571
+ >
572
+ </schema-table>
573
+ `;
574
+ } else if (this.schemaStyle === "tree") {
575
+ reqBodySchemaHtml = html`
576
+ ${reqBodySchemaHtml}
577
+ <schema-tree
578
+ class="${reqBody.mimeType.substring(reqBody.mimeType.indexOf("/") + 1)}"
579
+ style="display: ${this.selectedRequestBodyType === reqBody.mimeType ? "block" : "none"};"
580
+ .data="${schemaAsObj}"
581
+ schema-expand-level="${this.schemaExpandLevel}"
582
+ schema-description-expanded="${this.schemaDescriptionExpanded}"
583
+ allow-schema-description-expand-toggle="${this.allowSchemaDescriptionExpandToggle}"
584
+ schema-hide-read-only="${this.schemaHideReadOnly}"
585
+ schema-hide-write-only="${this.schemaHideWriteOnly}"
586
+ exportparts="schema-description:schema-description, schema-multiline-toggle:schema-multiline-toggle"
587
+ >
588
+ </schema-tree>
589
+ `;
590
+ }
591
+ }
592
+ });
593
+
594
+ return html`
595
+ <div class="request-body-container" data-selected-request-body-type="${ifDefined(this.selectedRequestBodyType)}">
596
+ <div class="table-title top-gap row" style="justify-content:space-between; align-items:center;">
597
+ <h5 class="rapidoc-heading label-heading" part="heading heading-5">
598
+ Request body ${this.request_body.required ? html`<span class="mono-font" style="color:var(--destructive)">*</span>` : ""}
599
+ <span style="font-weight:normal; margin-left:5px; text-transform:none"> ${this.selectedRequestBodyType}</span>
600
+ </h5>
601
+ ${reqBodyTypeSelectorHtml}
602
+ </div>
603
+ ${
604
+ this.request_body.description
605
+ ? html`<div class="m-markdown" style="margin-bottom:12px">
606
+ ${unsafeHTML(sanitizeHTML(marked(this.request_body.description)))}
607
+ </div>`
608
+ : ""
609
+ }
610
+ ${
611
+ this.selectedRequestBodyType.includes("json") ||
612
+ this.selectedRequestBodyType.includes("xml") ||
613
+ this.selectedRequestBodyType.includes("text") ||
614
+ this.selectedRequestBodyType.includes("jose")
615
+ ? html` <div part="tab-panel" class="tab-panel col">
616
+ <div
617
+ part="tab-btn-row"
618
+ class="tab-buttons row"
619
+ @click="${(e) => {
620
+ if (e.target.tagName.toLowerCase() === "button") {
621
+ this.activeSchemaTab = e.target.dataset.tab;
622
+ }
623
+ }}"
624
+ >
625
+ <button part="tab-btn" class="tab-btn ${this.activeSchemaTab === "example" ? "active" : ""}" data-tab="example">
626
+ EXAMPLE
627
+ </button>
628
+ <button part="tab-btn" class="tab-btn ${this.activeSchemaTab !== "example" ? "active" : ""}" data-tab="schema">
629
+ SCHEMA
630
+ </button>
631
+ </div>
632
+ ${html`<div
633
+ part="tab-content"
634
+ class="tab-content col"
635
+ style="display:${this.activeSchemaTab === "example" ? "block" : "none"};"
636
+ >
637
+ ${reqBodyExampleHtml}
638
+ </div>`}
639
+ ${html`<div
640
+ part="tab-content"
641
+ class="tab-content col"
642
+ style="display:${this.activeSchemaTab === "example" ? "none" : "block"};"
643
+ >
644
+ ${reqBodySchemaHtml}
645
+ </div>`}
646
+ </div>`
647
+ : html` ${reqBodyFileInputHtml} ${reqBodyFormHtml}`
648
+ }
649
+ </div>
650
+ `;
651
+ }