rapidoc 12.0.0 → 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 (77) hide show
  1. package/README.md +127 -25
  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 +541 -1309
  5. package/dist/rapidoc-min.js.LICENSE.txt +381 -0
  6. package/package.json +21 -18
  7. package/src/README.md +150 -0
  8. package/src/components/README.md +91 -0
  9. package/src/components/api-request.ts +43 -0
  10. package/src/components/api-response.ts +9 -4
  11. package/src/components/schema-base-element.ts +18 -4
  12. package/src/components/schema-table.ts +58 -13
  13. package/src/components/schema-tree.ts +7 -0
  14. package/src/components/tag-input.ts +5 -9
  15. package/src/flow.js +3 -0
  16. package/src/rapi-flow.ts +1178 -0
  17. package/src/rapidoc-mini.ts +27 -6
  18. package/src/rapidoc.ts +108 -62
  19. package/src/styles/README.md +96 -0
  20. package/src/styles/css-bundle.js +2 -2
  21. package/src/styles/endpoint-styles.js +6 -1
  22. package/src/styles/flow-styles.js +248 -0
  23. package/src/styles/nav-styles.js +39 -15
  24. package/src/styles/schema-styles.js +13 -5
  25. package/src/styles/theme-tokens.js +2 -2
  26. package/src/templates/README.md +89 -0
  27. package/src/templates/api-response-template.js +14 -10
  28. package/src/templates/callback-template.js +1 -1
  29. package/src/templates/downloads-template.js +12 -27
  30. package/src/templates/endpoint-template.js +15 -24
  31. package/src/templates/expanded-endpoint-template.js +8 -4
  32. package/src/templates/focused-endpoint-template.js +4 -3
  33. package/src/templates/navbar-template.js +20 -11
  34. package/src/templates/request-body-template.js +29 -7
  35. package/src/templates/request-params-template.js +15 -4
  36. package/src/templates/security-scheme-template.js +11 -2
  37. package/src/templates/server-template.js +3 -2
  38. package/src/utils/README.md +146 -0
  39. package/src/utils/arazzo/README.md +119 -0
  40. package/src/utils/arazzo/components.js +15 -0
  41. package/src/utils/arazzo/graph.js +269 -0
  42. package/src/utils/arazzo/index.js +52 -0
  43. package/src/utils/arazzo/operations.js +106 -0
  44. package/src/utils/arazzo/parse.js +196 -0
  45. package/src/utils/arazzo/refs.js +40 -0
  46. package/src/utils/arazzo/svg.js +707 -0
  47. package/src/utils/curl-utils.js +5 -2
  48. package/src/utils/highlighter.js +3 -0
  49. package/src/utils/mcp/README.md +155 -0
  50. package/src/utils/mcp/common.js +45 -346
  51. package/src/utils/mcp/manifest.js +382 -0
  52. package/src/utils/mcp/project/server.ts +53 -0
  53. package/src/utils/mcp/project.js +88 -0
  54. package/src/utils/mcp/runtime.js +289 -0
  55. package/src/utils/mcp/schema.js +98 -0
  56. package/src/utils/mcp/workflow-runtime.js +374 -0
  57. package/src/utils/mcp/workflows.js +240 -0
  58. package/src/utils/mcp/zip.js +102 -0
  59. package/src/utils/mcp-generator.js +29 -125
  60. package/src/utils/mock-interceptor.js +134 -85
  61. package/src/utils/request-utils.js +61 -0
  62. package/src/utils/schema-utils.js +33 -6
  63. package/src/utils/slugger.js +5 -7
  64. package/src/utils/spec-parser.js +190 -164
  65. package/src/utils/url-utils.js +36 -1
  66. package/dist/rapidoc-static-min.js +0 -13542
  67. package/src/static/index.d.ts +0 -149
  68. package/src/static/index.js +0 -62
  69. package/src/static/navigation.js +0 -497
  70. package/src/static/render.js +0 -490
  71. package/src/static/serializer.js +0 -216
  72. package/src/utils/mcp/generators/csharp.js +0 -242
  73. package/src/utils/mcp/generators/go.js +0 -298
  74. package/src/utils/mcp/generators/java.js +0 -330
  75. package/src/utils/mcp/generators/python.js +0 -248
  76. package/src/utils/mcp/generators/rust.js +0 -281
  77. package/src/utils/mcp/generators/typescript.js +0 -290
@@ -1,490 +0,0 @@
1
- /**
2
- * Framework-agnostic static pre-rendering engine for RapiDoc.
3
- *
4
- * Runs seamlessly in Node.js >= 22, Bun, Astro, Nuxt, Next.js, and custom SSG scripts.
5
- */
6
-
7
- // Safe idempotent customElements registry in pure Node/Bun/SSR environments
8
- if (typeof globalThis.customElements === "undefined") {
9
- const registry = new Map();
10
- globalThis.customElements = {
11
- define: (name, constructor) => {
12
- registry.set(name, constructor);
13
- },
14
- get: (name) => registry.get(name),
15
- whenDefined: () => Promise.resolve(),
16
- };
17
- } else if (globalThis.customElements && !globalThis.customElements.__safeDefinePatched) {
18
- const origDefine = globalThis.customElements.define;
19
- globalThis.customElements.define = function (name, constructor, options) {
20
- if (!this.get(name)) {
21
- try {
22
- origDefine.call(this, name, constructor, options);
23
- } catch {
24
- // Safe fallback if already registered in registry
25
- }
26
- }
27
- };
28
- globalThis.customElements.__safeDefinePatched = true;
29
- }
30
-
31
- if (
32
- typeof CustomElementRegistry !== "undefined" &&
33
- !CustomElementRegistry.prototype.__safeDefinePatched
34
- ) {
35
- const origProtoDefine = CustomElementRegistry.prototype.define;
36
- CustomElementRegistry.prototype.define = function (name, constructor, options) {
37
- if (!this.get(name)) {
38
- try {
39
- origProtoDefine.call(this, name, constructor, options);
40
- } catch {
41
- // Safe fallback if already registered in registry
42
- }
43
- }
44
- };
45
- CustomElementRegistry.prototype.__safeDefinePatched = true;
46
- }
47
-
48
- import ProcessSpec from "../utils/spec-parser.js";
49
- import mainBodyTemplate from "../templates/main-body-template.js";
50
- import { expandedEndpointBodyTemplate } from "../templates/expanded-endpoint-template.js";
51
- import { schemaToAST } from "../utils/schema-utils.js";
52
- import SchemaTable from "../components/schema-table.ts";
53
- import SchemaTree from "../components/schema-tree.ts";
54
- import { getBundledCss } from "../styles/css-bundle.js";
55
- import { DEFAULT_THEME } from "../styles/theme-tokens.js";
56
- import { renderTemplateToString, escapeHtml } from "./serializer.js";
57
-
58
- function toKebabCase(str) {
59
- return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
60
- }
61
-
62
- function toCamelCase(str) {
63
- return str.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
64
- }
65
-
66
- /**
67
- * Resolves an OpenAPI specification from a file path, URL, JSON/YAML string, or JS object.
68
- *
69
- * @param {string|Object} specInput
70
- * @param {Object} [options]
71
- * @returns {Promise<Object>} Fully parsed and dereferenced OpenAPI specification
72
- */
73
- export async function resolveSpecInput(specInput, options = {}) {
74
- if (!specInput) {
75
- throw new Error("OpenAPI specification input is required (file path, URL, string, or object).");
76
- }
77
-
78
- // Already resolved/parsed spec object (from ProcessSpec)
79
- if (
80
- typeof specInput === "object" &&
81
- specInput !== null &&
82
- Array.isArray(specInput.securitySchemes)
83
- ) {
84
- return specInput;
85
- }
86
-
87
- let rawSpec = specInput;
88
-
89
- if (typeof specInput === "string") {
90
- const trimmed = specInput.trim();
91
-
92
- // Check if it's inlined JSON or multiline YAML
93
- if (trimmed.startsWith("{") || trimmed.startsWith("[") || trimmed.includes("\n")) {
94
- try {
95
- rawSpec = JSON.parse(trimmed);
96
- } catch {
97
- rawSpec = trimmed;
98
- }
99
- } else if (!trimmed.startsWith("http://") && !trimmed.startsWith("https://")) {
100
- // Local file path in Node.js / Bun
101
- if (typeof process !== "undefined" && process.versions?.node) {
102
- try {
103
- const fs = await import("node:fs");
104
- if (fs.existsSync(trimmed)) {
105
- const content = fs.readFileSync(trimmed, "utf-8");
106
- try {
107
- rawSpec = JSON.parse(content);
108
- } catch {
109
- rawSpec = content;
110
- }
111
- }
112
- } catch {
113
- // If filesystem read fails, fall through to default loader
114
- }
115
- }
116
- }
117
- }
118
-
119
- return ProcessSpec(
120
- rawSpec,
121
- options.generateMissingTags ?? options["generate-missing-tags"] ?? false,
122
- options.sortTags ?? options["sort-tags"] ?? false,
123
- options.sortSchemas ?? options["sort-schemas"] ?? false,
124
- options.sortEndpointsBy ?? options["sort-endpoints-by"] ?? "none",
125
- options.apiKey ?? options.apiKeyName ?? options["api-key-name"] ?? "",
126
- options.apiKeyLocation ?? options["api-key-location"] ?? "",
127
- options.apiKeyValue ?? options["api-key-value"] ?? "",
128
- options.serverUrl ?? options["server-url"] ?? "",
129
- options.matchPaths ?? options["match-paths"] ?? "",
130
- options.matchType ?? options["match-type"] ?? "",
131
- options.removeEndpointsWithBadgeLabelAs ??
132
- options["remove-endpoints-with-badge-label-as"] ??
133
- "",
134
- );
135
- }
136
-
137
- /**
138
- * Pre-renders an entire OpenAPI documentation page into static HTML.
139
- *
140
- * Supported output modes:
141
- * - 'dsd' (default): Declarative Shadow DOM `<rapi-doc><template shadowrootmode="open">...</template></rapi-doc>`.
142
- * Delivers zero FOUC, instant first paint, and automatic hydration when client bundle loads.
143
- * - 'html' / 'light': Semantic Light DOM `<div class="rapidoc-static-container">...</div>`.
144
- *
145
- * @param {Object} options
146
- * @param {string|Object} options.spec - Specification file path, URL, raw string, or parsed object
147
- * @param {'read'|'view'|'focused'} [options.renderStyle='read'] - Layout style
148
- * @param {string} [options.theme='ember'] - Theme preset ('ember', 'carbon', 'cobalt', 'jade', 'indigo') or hex
149
- * @param {'dark'|'light'|'system'} [options.colorScheme='dark'] - Color scheme
150
- * @param {'row'|'column'} [options.layout] - Layout orientation ('column' default for read/focused, 'row' for view)
151
- * @param {boolean|string} [options.showHeader=true] - Whether to render top header
152
- * @param {boolean|string} [options.showSideNav=true] - Whether to render sidebar navigation
153
- * @param {boolean|string} [options.showInfo=true] - Whether to render spec overview & info
154
- * @param {boolean|string} [options.allowSearch=true] - Whether search is available
155
- * @param {boolean|string} [options.allowAdvancedSearch=false] - Whether advanced search dialog is pre-rendered
156
- * @param {boolean|string} [options.allowServerSelection=true] - Whether to show server selection
157
- * @param {boolean|string} [options.allowAuthentication=true] - Whether to render auth security schemes
158
- * @param {boolean|string} [options.allowTry=true] - Whether try-it console is included
159
- * @param {'table'|'tree'} [options.schemaStyle='table'] - Default schema display style
160
- * @param {number} [options.schemaExpandLevel=99999] - Schema nesting expansion level
161
- * @param {'example'|'schema'} [options.defaultSchemaTab='example'] - Active tab in schema views
162
- * @param {'dsd'|'html'|'light'} [options.outputMode='dsd'] - Pre-rendered container mode
163
- * @param {boolean} [options.includeStyles=true] - Whether to include bundled CSS in the output
164
- * @returns {Promise<string>} Fully rendered static HTML string
165
- */
166
- export async function renderRapiDoc(options = {}) {
167
- // Normalize option names to support both camelCase and kebab-case
168
- const normalized = {};
169
- for (const [key, val] of Object.entries(options)) {
170
- normalized[key] = val;
171
- normalized[toCamelCase(key)] = val;
172
- }
173
-
174
- const spec = options.spec ?? normalized.spec;
175
- const renderStyle = normalized.renderStyle ?? "read";
176
- const theme = normalized.theme ?? DEFAULT_THEME;
177
- const colorScheme = normalized.colorScheme ?? "dark";
178
- const showHeader = normalized.showHeader ?? true;
179
- const showSideNav = normalized.showSideNav ?? true;
180
- const showInfo = normalized.showInfo ?? true;
181
- const allowSearch = normalized.allowSearch ?? true;
182
- const allowAdvancedSearch = normalized.allowAdvancedSearch ?? false;
183
- const allowServerSelection = normalized.allowServerSelection ?? true;
184
- const allowAuthentication = normalized.allowAuthentication ?? true;
185
- const allowTry = normalized.allowTry ?? true;
186
- const schemaStyle = normalized.schemaStyle ?? "table";
187
- const schemaExpandLevel = normalized.schemaExpandLevel ?? 99999;
188
- const defaultSchemaTab = normalized.defaultSchemaTab ?? "example";
189
- const outputMode = normalized.outputMode ?? "dsd";
190
- const includeStyles = normalized.includeStyles ?? true;
191
- const pageDirection = normalized.pageDirection ?? "ltr";
192
-
193
- const defaultLayout = renderStyle === "read" || renderStyle === "focused" ? "column" : "row";
194
- const layout = normalized.layout || defaultLayout;
195
-
196
- const resolvedSpec = await resolveSpecInput(spec, normalized);
197
-
198
- const INTERNAL_KEYS = new Set([
199
- "spec",
200
- "outputMode",
201
- "includeStyles",
202
- "inlineSpec",
203
- "focusedElementId",
204
- ]);
205
-
206
- // Pass any custom options into the template context
207
- const customContextProps = {};
208
- for (const [key, val] of Object.entries(normalized)) {
209
- if (!INTERNAL_KEYS.has(key) && val !== undefined && val !== null) {
210
- customContextProps[key] = typeof val === "boolean" ? String(val) : val;
211
- }
212
- }
213
-
214
- const context = {
215
- ...customContextProps,
216
- resolvedSpec,
217
- renderStyle,
218
- layout,
219
- theme,
220
- colorScheme,
221
- showHeader: String(showHeader),
222
- showSideNav: String(showSideNav),
223
- showInfo: String(showInfo),
224
- allowSearch: String(allowSearch),
225
- allowAdvancedSearch: String(allowAdvancedSearch),
226
- allowServerSelection: String(allowServerSelection),
227
- allowAuthentication: String(allowAuthentication),
228
- allowTry: String(allowTry),
229
- schemaStyle,
230
- schemaExpandLevel,
231
- defaultSchemaTab,
232
- pageDirection,
233
- config: {
234
- renderStyle,
235
- schemaStyle,
236
- schemaExpandLevel,
237
- defaultSchemaTab,
238
- allowTry: String(allowTry),
239
- },
240
- matchPaths: normalized.matchPaths || "",
241
- selectedServer: resolvedSpec.servers?.[0],
242
- focusedElementId:
243
- options.focusedElementId ||
244
- (showInfo === "false" || showInfo === false
245
- ? resolvedSpec.tags?.[0]?.paths?.[0]?.elementId || ""
246
- : "overview"),
247
- handleHref: () => {},
248
- };
249
-
250
- const templateResult = mainBodyTemplate.call(context);
251
- const serializedBody = renderTemplateToString(templateResult);
252
-
253
- if (outputMode === "html" || outputMode === "light") {
254
- const scopeClass = "rapidoc-static-container";
255
- const cssText = includeStyles
256
- ? `<style>${getBundledCss({ theme, colorScheme, scope: `.${scopeClass}` })}</style>`
257
- : "";
258
- return `<div class="${scopeClass}" data-theme="${escapeHtml(theme)}" data-color-scheme="${escapeHtml(colorScheme)}" data-render-style="${escapeHtml(renderStyle)}" data-layout="${escapeHtml(layout)}" data-schema-style="${escapeHtml(schemaStyle)}">
259
- ${cssText}
260
- ${serializedBody}
261
- </div>`;
262
- }
263
-
264
- // Default: Declarative Shadow DOM (DSD)
265
- const cssText = includeStyles ? `<style>${getBundledCss({ theme, colorScheme })}</style>` : "";
266
- const specScript =
267
- options.inlineSpec !== false && typeof spec === "object" && spec !== null
268
- ? ` <script type="application/json" slot="rapidoc-spec">${JSON.stringify(spec).replace(/</g, "\\u003c")}</script>\n`
269
- : "";
270
-
271
- // Construct complete attributes map to ensure exact client hydration parity
272
- const attrsMap = new Map();
273
- attrsMap.set("theme", theme);
274
- attrsMap.set("color-scheme", colorScheme);
275
- attrsMap.set("render-style", renderStyle);
276
- attrsMap.set("layout", layout);
277
- attrsMap.set("schema-style", schemaStyle);
278
- attrsMap.set("schema-expand-level", String(schemaExpandLevel));
279
- attrsMap.set("default-schema-tab", defaultSchemaTab);
280
- attrsMap.set("show-header", String(showHeader));
281
- attrsMap.set("show-side-nav", String(showSideNav));
282
- attrsMap.set("show-info", String(showInfo));
283
- attrsMap.set("allow-search", String(allowSearch));
284
- attrsMap.set("allow-advanced-search", String(allowAdvancedSearch));
285
- attrsMap.set("allow-server-selection", String(allowServerSelection));
286
- attrsMap.set("allow-authentication", String(allowAuthentication));
287
- attrsMap.set("allow-try", String(allowTry));
288
- attrsMap.set("page-direction", pageDirection);
289
-
290
- // Reflect any additional user-provided options to custom element attributes (converted to kebab-case)
291
- for (const [key, val] of Object.entries(options)) {
292
- const camel = toCamelCase(key);
293
- if (!INTERNAL_KEYS.has(camel) && !INTERNAL_KEYS.has(key) && val !== undefined && val !== null) {
294
- const kebab = toKebabCase(camel);
295
- attrsMap.set(kebab, typeof val === "boolean" ? String(val) : String(val));
296
- }
297
- }
298
-
299
- if (typeof spec === "string" && (spec.startsWith("http://") || spec.startsWith("https://"))) {
300
- attrsMap.set("spec-url", spec);
301
- }
302
-
303
- const attrsString = Array.from(attrsMap.entries())
304
- .map(([name, value]) => `${name}="${escapeHtml(value)}"`)
305
- .join(" ");
306
-
307
- return `<rapi-doc ${attrsString}>
308
- ${specScript} <template shadowrootmode="open">
309
- ${cssText}
310
- ${serializedBody}
311
- </template>
312
- </rapi-doc>`;
313
- }
314
-
315
- /**
316
- * Pre-renders a single isolated endpoint / operation into static HTML.
317
- * Ideal for embedding individual API operations in Markdown/MDX guides (Cosmo Cargo / Zudoku style).
318
- *
319
- * @param {Object} options
320
- * @param {string|Object} options.spec - Specification file path, URL, raw string, or parsed object
321
- * @param {string} options.path - Operation path (e.g. '/v1/shipments' or '/pet/{petId}')
322
- * @param {string} options.method - HTTP method ('get', 'post', 'put', 'delete', etc.)
323
- * @param {'read'|'view'} [options.renderStyle='read'] - Layout style
324
- * @param {'row'|'column'} [options.layout='column'] - Layout orientation
325
- * @param {string} [options.theme='ember'] - Theme preset name or hex
326
- * @param {'dark'|'light'|'system'} [options.colorScheme='dark'] - Color scheme
327
- * @param {boolean} [options.includeStyles=true] - Whether to prepend scoped CSS
328
- * @returns {Promise<string>} Rendered HTML string of the isolated endpoint
329
- */
330
- export async function renderEndpoint(options = {}) {
331
- const {
332
- spec,
333
- path: targetPathStr,
334
- method: targetMethodStr,
335
- renderStyle = "read",
336
- layout = "column",
337
- theme = DEFAULT_THEME,
338
- colorScheme = "dark",
339
- includeStyles = true,
340
- allowTry = false,
341
- } = options;
342
-
343
- if (!targetPathStr || !targetMethodStr) {
344
- throw new Error("Both `path` and `method` are required for renderEndpoint().");
345
- }
346
-
347
- const normalizedMethod = targetMethodStr.toLowerCase().trim();
348
- const resolvedSpec = await resolveSpecInput(spec, options);
349
-
350
- // Search across tags for matching operation
351
- let matchedPath = null;
352
- let matchedTagName = "";
353
- let matchedTagDescription = "";
354
- let isFirstOperation = false;
355
-
356
- for (const tag of resolvedSpec.tags || []) {
357
- const foundIdx = (tag.paths || []).findIndex(
358
- (p) => p.path === targetPathStr && p.method.toLowerCase() === normalizedMethod,
359
- );
360
- if (foundIdx !== -1) {
361
- matchedPath = tag.paths[foundIdx];
362
- matchedTagName = tag.name;
363
- matchedTagDescription = tag.description || "";
364
- isFirstOperation = foundIdx === 0;
365
- break;
366
- }
367
- }
368
-
369
- if (!matchedPath) {
370
- throw new Error(
371
- `Endpoint not found in spec: ${targetMethodStr.toUpperCase()} ${targetPathStr}`,
372
- );
373
- }
374
-
375
- const context = {
376
- resolvedSpec,
377
- renderStyle,
378
- layout,
379
- theme,
380
- colorScheme,
381
- fillRequestFieldsWithExample: "true",
382
- allowTry: String(allowTry),
383
- config: {
384
- renderStyle,
385
- schemaStyle: options.schemaStyle || "table",
386
- allowTry: String(allowTry),
387
- },
388
- selectedServer: resolvedSpec.servers?.[0],
389
- };
390
-
391
- const renderedTemplate = expandedEndpointBodyTemplate.call(
392
- context,
393
- matchedPath,
394
- matchedTagName,
395
- matchedTagDescription,
396
- isFirstOperation,
397
- );
398
- const serializedHtml = renderTemplateToString(renderedTemplate);
399
-
400
- const containerClass = "rapidoc-endpoint-container";
401
- const cssText = includeStyles
402
- ? `<style>${getBundledCss({ theme, colorScheme, scope: `.${containerClass}` })}</style>`
403
- : "";
404
-
405
- return `<div class="${containerClass} ${renderStyle}-mode" data-theme="${theme}" data-color-scheme="${colorScheme}">
406
- ${cssText}
407
- ${serializedHtml}
408
- </div>`;
409
- }
410
-
411
- /**
412
- * Pre-renders an isolated JSON Schema or component schema into static HTML.
413
- *
414
- * @param {Object} options
415
- * @param {Object|string} options.schema - JSON Schema object, or name of schema in `components.schemas`
416
- * @param {Object|string} [options.spec] - Optional OpenAPI spec to resolve schema names against
417
- * @param {'table'|'tree'} [options.style='table'] - Display style ('table' or 'tree')
418
- * @param {number} [options.schemaExpandLevel=99999] - Level of initial property expansion
419
- * @param {string} [options.theme='ember'] - Theme preset name or hex
420
- * @param {'dark'|'light'|'system'} [options.colorScheme='dark'] - Color scheme
421
- * @param {boolean} [options.includeStyles=true] - Whether to prepend scoped CSS
422
- * @returns {Promise<string>} Rendered schema HTML string
423
- */
424
- export async function renderSchema(options = {}) {
425
- const {
426
- schema,
427
- spec,
428
- style = "table",
429
- schemaExpandLevel = 99999,
430
- theme = DEFAULT_THEME,
431
- colorScheme = "dark",
432
- includeStyles = true,
433
- } = options;
434
-
435
- let resolvedSchema = schema;
436
-
437
- if (typeof schema === "string") {
438
- if (!spec) {
439
- throw new Error(`When schema is a string name ('${schema}'), options.spec must be provided.`);
440
- }
441
- const resolvedSpec = await resolveSpecInput(spec);
442
- let schemaObj = (typeof spec === "object" && spec.components?.schemas?.[schema]) || null;
443
- if (!schemaObj) {
444
- const schemasGroup = (resolvedSpec.components || []).find((c) => c.name === "Schemas");
445
- const found = (schemasGroup?.subComponents || []).find((sc) => sc.name === schema);
446
- schemaObj = found?.component;
447
- }
448
- if (!schemaObj) {
449
- throw new Error(`Schema '${schema}' not found in spec components.schemas.`);
450
- }
451
- resolvedSchema = schemaObj;
452
- }
453
-
454
- if (!resolvedSchema || typeof resolvedSchema !== "object") {
455
- throw new Error("Invalid schema provided to renderSchema().");
456
- }
457
-
458
- const ast = schemaToAST(resolvedSchema);
459
- let renderedTemplate;
460
-
461
- if (style === "tree") {
462
- const tree = new SchemaTree();
463
- tree.data = ast;
464
- tree.schemaExpandLevel = schemaExpandLevel;
465
- renderedTemplate = tree.render();
466
- } else {
467
- const table = new SchemaTable();
468
- table.data = ast;
469
- table.schemaExpandLevel = schemaExpandLevel;
470
- renderedTemplate = table.render();
471
- }
472
-
473
- const serializedHtml = renderTemplateToString(renderedTemplate);
474
- const containerClass = "rapidoc-schema-container";
475
- const cssText = includeStyles
476
- ? `<style>${getBundledCss({ theme, colorScheme, scope: `.${containerClass}` })}</style>`
477
- : "";
478
-
479
- return `<div class="${containerClass}" data-theme="${theme}" data-color-scheme="${colorScheme}">
480
- ${cssText}
481
- ${serializedHtml}
482
- </div>`;
483
- }
484
-
485
- export default {
486
- resolveSpecInput,
487
- renderRapiDoc,
488
- renderEndpoint,
489
- renderSchema,
490
- };