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