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,582 @@
1
+ import { css, unsafeCSS } from "lit";
2
+
3
+ export const DEFAULT_THEME = "ember";
4
+
5
+ /**
6
+ * Brand theme presets (the `theme` attribute), as CSS declaration lists. Each one sets the accent and, where the theme tints
7
+ * its surfaces, the background and foreground for the dark and the light color scheme; every other
8
+ * token (card, muted, border, input, ...) is derived from those two in section 3. A theme rule outranks the
9
+ * shared color-scheme rules, so a theme that sets a surface for one scheme must set it for the other too.
10
+ *
11
+ * - 'ember' (default): orange-red accent over neutral charcoal
12
+ * - 'carbon': monochrome, near-black surfaces and a white accent
13
+ * - 'cobalt': matte steel-blue accent over grey-blue slate, with cards darker than the page
14
+ * - 'jade': daisyUI-style green accent over slate-navy, with cards darker than the page
15
+ * - 'indigo': indigo accent over indigo-black
16
+ */
17
+ export const THEMES = {
18
+ ember: {
19
+ dark: `
20
+ --primary: #f76b39;
21
+ --primary-foreground: #000000;
22
+ `,
23
+ light: `
24
+ --primary: #f76b39;
25
+ --primary-foreground: #000000;
26
+ `,
27
+ },
28
+ carbon: {
29
+ dark: `
30
+ --primary: #fafafa;
31
+ --primary-foreground: #18181b;
32
+ --ring: #a1a1aa;
33
+ --background: #121214;
34
+ --foreground: #e4e4e7;
35
+ `,
36
+ light: `
37
+ --primary: #18181b;
38
+ --primary-foreground: #fafafa;
39
+ --ring: #52525b;
40
+ --background: #ffffff;
41
+ --foreground: #18181b;
42
+ `,
43
+ },
44
+ cobalt: {
45
+ dark: `
46
+ --primary: #7aa2d6;
47
+ --primary-foreground: #0f1a2a;
48
+ --background: #1e2530;
49
+ --foreground: #b4bcc8;
50
+ --card: #181e27;
51
+ --card-foreground: #ced5df;
52
+ `,
53
+ light: `
54
+ --primary: #3a6cb0;
55
+ --primary-foreground: #ffffff;
56
+ --background: #ffffff;
57
+ --foreground: #243244;
58
+ --card: color-mix(in srgb, var(--background) 94%, var(--foreground));
59
+ --card-foreground: color-mix(in srgb, var(--foreground) 90%, #000000);
60
+ `,
61
+ },
62
+ jade: {
63
+ dark: `
64
+ --primary: #00d390;
65
+ --primary-foreground: #0b1f17;
66
+ --background: #1d232a;
67
+ --foreground: #a6adbb;
68
+ --card: #181e25;
69
+ --card-foreground: #c8cfd9;
70
+ `,
71
+ light: `
72
+ --primary: #047857;
73
+ --primary-foreground: #ffffff;
74
+ --background: #ffffff;
75
+ --foreground: #1a2e26;
76
+ --card: color-mix(in srgb, var(--background) 94%, var(--foreground));
77
+ --card-foreground: color-mix(in srgb, var(--foreground) 90%, #000000);
78
+ `,
79
+ },
80
+ indigo: {
81
+ dark: `
82
+ --primary: #818cf8;
83
+ --primary-foreground: #1e1b4b;
84
+ --background: #0f0e1c;
85
+ --foreground: #e4e2f5;
86
+ `,
87
+ light: `
88
+ --primary: #4f46e5;
89
+ --primary-foreground: #ffffff;
90
+ --background: #ffffff;
91
+ --foreground: #1e1b3a;
92
+ `,
93
+ },
94
+ };
95
+
96
+ export const THEME_PRESETS = Object.keys(THEMES);
97
+
98
+ /**
99
+ * The :host rules for one preset: dark (the default scheme), light, and light again for
100
+ * color-scheme="system" when the OS prefers light. The default preset also applies without a theme attribute.
101
+ * The selector shapes are what getThemeTokensCss (css-bundle.js) rewrites for the portal's light DOM.
102
+ */
103
+ function presetCss(name, { dark, light }) {
104
+ const selector = (scheme) => {
105
+ const suffix = scheme ? `[color-scheme='${scheme}']` : "";
106
+ const hosts = [`:host([theme='${name}']${suffix})`];
107
+ if (name === DEFAULT_THEME) hosts.push(`:host(:not([theme])${suffix})`);
108
+ return hosts.join(",\n ");
109
+ };
110
+ return `
111
+ /* --------- ${name.toUpperCase()}${name === DEFAULT_THEME ? " (default)" : ""} --------- */
112
+ ${selector()} {${dark}}
113
+ ${selector("light")} {${light}}
114
+ @media (prefers-color-scheme: light) {
115
+ ${selector("system")} {${light}}
116
+ }
117
+ `;
118
+ }
119
+
120
+ const presetsCss = unsafeCSS(
121
+ Object.entries(THEMES)
122
+ .map(([name, schemes]) => presetCss(name, schemes))
123
+ .join(""),
124
+ );
125
+
126
+ /**
127
+ * Checks if a string is a valid CSS hex color code (#rgb, #rrggbb, #rrggbbaa).
128
+ * @param {string} color - Color string to validate.
129
+ * @returns {boolean} True if the string is a valid hex color code.
130
+ */
131
+ export function isValidHexColor(color) {
132
+ if (!color || typeof color !== "string") return false;
133
+ return /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(color.trim());
134
+ }
135
+
136
+ /**
137
+ * Checks if a theme string is valid: must match an allowed preset name or be a valid hex color code.
138
+ * @param {string} theme - Theme name or hex string to validate.
139
+ * @returns {boolean} True if theme is supported.
140
+ */
141
+ export function isValidTheme(theme) {
142
+ if (!theme || typeof theme !== "string") return false;
143
+ const trimmed = theme.trim().toLowerCase();
144
+ return THEME_PRESETS.includes(trimmed) || isValidHexColor(theme);
145
+ }
146
+
147
+ /**
148
+ * Normalizes and validates the theme attribute value.
149
+ * - Allowed presets are normalized to lowercase.
150
+ * - Valid hex color codes are preserved as-is.
151
+ * - Any invalid, unrecognized, or missing value defaults to DEFAULT_THEME.
152
+ *
153
+ * @param {string} theme - The raw theme attribute value.
154
+ * @returns {{ theme: string }}
155
+ */
156
+ export function normalizeTheme(theme) {
157
+ if (!theme || typeof theme !== "string") {
158
+ return { theme: DEFAULT_THEME };
159
+ }
160
+ const trimmed = theme.trim();
161
+ const lower = trimmed.toLowerCase();
162
+ if (THEME_PRESETS.includes(lower)) {
163
+ return { theme: lower };
164
+ }
165
+ if (isValidHexColor(trimmed)) {
166
+ return { theme: trimmed };
167
+ }
168
+ return { theme: DEFAULT_THEME };
169
+ }
170
+
171
+ /**
172
+ * Determines whether a color parameter is a custom brand hex code rather than a preset name.
173
+ * @param {string} color - Theme identifier or color code.
174
+ * @returns {boolean}
175
+ */
176
+ export function isCustomColor(color) {
177
+ if (!color || typeof color !== "string") return false;
178
+ const trimmed = color.trim().toLowerCase();
179
+ if (THEME_PRESETS.includes(trimmed)) return false;
180
+ return isValidHexColor(color);
181
+ }
182
+
183
+ /**
184
+ * Calculates whether a hex color is perceived as light using standard YIQ luminance formula.
185
+ * Used to ensure accessible high-contrast text foreground (pure black on light vs white on dark).
186
+ * @param {string} color - Hex color code (#rgb, #rrggbb, #rrggbbaa).
187
+ * @returns {boolean} True if color luminance >= 128 (light).
188
+ */
189
+ export function isLightColor(color) {
190
+ if (!color || typeof color !== "string") return false;
191
+ let hex = color.trim().replace(/^#/, "");
192
+ if (hex.length === 3) {
193
+ hex = hex
194
+ .split("")
195
+ .map((c) => c + c)
196
+ .join("");
197
+ }
198
+ if (hex.length === 6 || hex.length === 8) {
199
+ const r = parseInt(hex.slice(0, 2), 16);
200
+ const g = parseInt(hex.slice(2, 4), 16);
201
+ const b = parseInt(hex.slice(4, 6), 16);
202
+ const yiq = (r * 299 + g * 587 + b * 114) / 1000;
203
+ return yiq >= 128;
204
+ }
205
+ return false;
206
+ }
207
+
208
+ /**
209
+ * Dynamically applies custom corporate brand hex colors to the host element.
210
+ * Calculates luminance and injects `--primary` and `--primary-foreground` (`--ring` follows `--primary`).
211
+ * @param {HTMLElement} element - Custom element host target.
212
+ * @param {string} themeVal - User-supplied theme attribute value.
213
+ */
214
+ export function applyCustomTheme(element, themeVal) {
215
+ if (!element || !element.style) return;
216
+ if (
217
+ typeof themeVal !== "string" ||
218
+ THEME_PRESETS.includes(themeVal.trim().toLowerCase()) ||
219
+ !isValidHexColor(themeVal)
220
+ ) {
221
+ element.style.removeProperty("--primary");
222
+ element.style.removeProperty("--primary-foreground");
223
+ return;
224
+ }
225
+ const hex = themeVal.trim();
226
+ element.style.setProperty("--primary", hex);
227
+ const fg = isLightColor(hex) ? "#000000" : "#ffffff";
228
+ element.style.setProperty("--primary-foreground", fg);
229
+ }
230
+
231
+ export default css`
232
+ /* =========================================================================
233
+ 1. ROOT DESIGN TOKEN DEFAULTS (:host)
234
+ ========================================================================= */
235
+ :host {
236
+ /* --- Fonts (shadcn/ui) --- */
237
+ --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
238
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Roboto Mono', monospace;
239
+
240
+ /* --- Headings & Prose (RapiDoc headings and markdown descriptions) --- */
241
+ --heading-font: var(--font-sans);
242
+ --heading-weight: 600;
243
+ --heading-line-height: 1.25;
244
+ --heading-letter-spacing: normal;
245
+ --heading-color: var(--foreground);
246
+ --heading-margin-top: 1.5em;
247
+ --heading-margin-bottom: 0.5em;
248
+ --h1-font-size: 2rem;
249
+ --h2-font-size: 1.5rem;
250
+ --h3-font-size: 1.25rem;
251
+ --h4-font-size: 1rem;
252
+ --h5-font-size: 0.875rem;
253
+ --h6-font-size: 0.8125rem;
254
+ --label-heading-font-size: var(--font-size-small);
255
+ --line-height: 1.6;
256
+ --paragraph-spacing: 1em;
257
+
258
+ /* --- Corner Radius (shadcn/ui) --- */
259
+ --radius: 0.25rem;
260
+
261
+ /* --- Sizes & Layout --- */
262
+ /* xs is the floor: badges, chips and tiny buttons never go below it. description is for
263
+ short prose next to data (parameter and property descriptions). */
264
+ --font-size-xs: 11px;
265
+ --font-size-small: 12px;
266
+ --font-size-description: 13px;
267
+ --font-size-mono: 13px;
268
+ --font-size-regular: 14px;
269
+ --resp-area-height: 400px;
270
+ --table-schema-key-width: 240px;
271
+ --table-schema-key-text-overflow: ellipsis;
272
+ --table-schema-key-whitespace: nowrap;
273
+ --scroll-margin-top: 120px;
274
+
275
+ /* --- Parameter lists (request parameters, form fields, response headers) --- */
276
+ --param-label-width: 12rem;
277
+ --param-gap: 0.5rem;
278
+ --param-row-gap: 0.25rem;
279
+ --param-padding: 0.5rem;
280
+ --auth-scheme-padding: 0.75rem;
281
+ --value-list-gap: 0.375rem;
282
+ --value-list-row-gap: 0.125rem;
283
+ --value-list-label-gap: 0.25rem;
284
+
285
+ /* --- Focus Ring & Selection --- */
286
+ --ring: var(--primary);
287
+ --focus-shadow: 0 0 0 1px transparent, 0 0 0 2px color-mix(in srgb, var(--ring) 40%, transparent);
288
+ --selection-bg: color-mix(in srgb, var(--primary) 25%, transparent);
289
+ --selection-fg: var(--foreground);
290
+
291
+ /* --- Navigation Sidebar (shadcn/ui sidebar tokens) --- */
292
+ --sidebar-width: 18.75rem;
293
+ --sidebar-item-padding: 0.4375rem 1rem 0.4375rem 0.625rem;
294
+ --sidebar-logo-max-height: 60px;
295
+ --sidebar: var(--background);
296
+ --sidebar-foreground: var(--foreground);
297
+ --sidebar-primary: var(--primary);
298
+ --sidebar-accent-foreground: var(--foreground);
299
+ --sidebar-border: var(--border);
300
+ --sidebar-ring: var(--ring);
301
+ }
302
+
303
+ /* =========================================================================
304
+ 2. SCALE & GEOMETRY TOKENS (radius, scale, nav-item-spacing)
305
+ ========================================================================= */
306
+
307
+ /* --- 2A. Corner Radius Scale (radius) --- */
308
+ :host([radius='none']) {
309
+ --radius: 0px;
310
+ }
311
+ :host([radius='sm']),
312
+ :host(:not([radius])) {
313
+ --radius: 0.25rem;
314
+ }
315
+ :host([radius='md']) {
316
+ --radius: 0.375rem;
317
+ }
318
+ :host([radius='lg']) {
319
+ --radius: 0.5rem;
320
+ }
321
+ :host([radius='full']) {
322
+ --radius: 9999px;
323
+ }
324
+
325
+ /* --- 2B. UI Scale & Typography (scale) --- */
326
+ :host([scale='sm']) {
327
+ --font-size-xs: 11px;
328
+ --font-size-small: 11px;
329
+ --font-size-description: 12px;
330
+ --font-size-mono: 12px;
331
+ --font-size-regular: 13px;
332
+ --sidebar-width: 17rem;
333
+ }
334
+ :host([scale='default']),
335
+ :host(:not([scale])) {
336
+ --font-size-xs: 11px;
337
+ --font-size-small: 12px;
338
+ --font-size-description: 13px;
339
+ --font-size-mono: 13px;
340
+ --font-size-regular: 14px;
341
+ --sidebar-width: 18.75rem;
342
+ }
343
+ :host([scale='lg']) {
344
+ --font-size-xs: 12px;
345
+ --font-size-small: 14px;
346
+ --font-size-description: 15px;
347
+ --font-size-mono: 15px;
348
+ --font-size-regular: 16px;
349
+ --sidebar-width: 21rem;
350
+ }
351
+
352
+ /* --- 2C. Navigation Density (nav-item-spacing) --- */
353
+ :host([nav-item-spacing='compact']) {
354
+ --sidebar-item-padding: 0.3125rem 1rem 0.3125rem 0.625rem;
355
+ }
356
+ :host([nav-item-spacing='default']),
357
+ :host(:not([nav-item-spacing])) {
358
+ --sidebar-item-padding: 0.4375rem 1rem 0.4375rem 0.625rem;
359
+ }
360
+ :host([nav-item-spacing='relaxed']) {
361
+ --sidebar-item-padding: 0.625rem 1rem 0.625rem 0.625rem;
362
+ }
363
+
364
+ /* =========================================================================
365
+ 3. SURFACE & COLOR SCHEME (color-scheme)
366
+ ========================================================================= */
367
+
368
+ /* --------- 3A. DARK (Default) --------- */
369
+ :host,
370
+ :host([color-scheme='dark']),
371
+ :host([color-scheme='system']),
372
+ :host(:not([color-scheme])) {
373
+ /* Surfaces: neutral charcoal. Tinted themes override these two; everything below is derived from them. */
374
+ --background: #1f1f23;
375
+ --foreground: #d4d4d8;
376
+
377
+ /* Card Vars:
378
+ card (bg) : dialog/modal popups, table headers (th), floating tooltips, and catalog cards
379
+ card-foreground : Text & icon color on elevated surfaces (dialog content, table header labels, tooltip text, schema type badges)
380
+ */
381
+ --card: color-mix(in srgb, var(--background) 92%, var(--foreground));
382
+ --card-foreground: color-mix(in srgb, var(--foreground) 90%, #ffffff);
383
+
384
+ /* Muted Vars:
385
+ muted (bg) : input tags, secondary buttons, table footers, and code backgrounds
386
+ muted-foreground : inactive tabs, parameter descriptions, schema constraints, and timestamps
387
+ */
388
+ --muted: color-mix(in srgb, var(--background) 86%, var(--foreground));
389
+ --muted-foreground: color-mix(in srgb, var(--foreground) 65%, var(--background));
390
+
391
+ /* Border Vars:
392
+ border: dividing lines for tables, cards, sections, and panels
393
+ */
394
+ --border: color-mix(in srgb, var(--background) 85%, var(--foreground));
395
+
396
+ --sidebar-accent: color-mix(in srgb, var(--background) 88%, var(--foreground));
397
+
398
+ --input: oklch(from var(--border) calc(l + 0.05) c h);
399
+ --input-background: color-mix(in srgb, var(--background) 80%, #000000);
400
+
401
+ /* HTTP Method Badges (Dark Mode: High Vibrancy) */
402
+ --method-get: #5c98f9ff;
403
+ --method-post: #68cc97;
404
+ --method-put: #f59e0b;
405
+ --method-delete: #f75252ff;
406
+ --method-patch: #a78bfa; /* violet-400: 4.5:1 or more as text on the dark background */
407
+ --method-head: #eab308;
408
+ --method-options: #06b6d4;
409
+ --method-trace: #ec4899;
410
+ --method-query: #818cf8;
411
+ --method-default: #64748b;
412
+ --method-badge-fg: #000000;
413
+
414
+ --destructive: #ef4444;
415
+
416
+ /* Named colours (also used by x-badges: color: blue | green | ...) */
417
+ --blue: #3b82f6;
418
+ --green: #10b981;
419
+ --orange: #f59e0b;
420
+ --red: #ef4444;
421
+ --purple: #8b5cf6;
422
+ --yellow: #eab308;
423
+ --pink: #ec4899;
424
+ --brown: #d97706;
425
+
426
+ /* Syntax Highlighting */
427
+ --syntax-comment: #8b949e;
428
+ --syntax-keyword: #ff7b72;
429
+ --syntax-operator: #c9d1d9;
430
+ --syntax-string: #a5d6ff;
431
+ --syntax-constant: #79c0ff;
432
+ --syntax-function: #d2a8ff;
433
+ --syntax-type: #d2a8ff;
434
+ --syntax-variable: #ffa657;
435
+ --syntax-property: #79c0ff;
436
+ --syntax-tag: #7ee787;
437
+ --syntax-selector: #d2a8ff;
438
+ --syntax-inserted: #7ee787;
439
+ --syntax-deleted: #ff7b72;
440
+
441
+ /* Code Blocks */
442
+
443
+ --code-bg: var(--input-background);
444
+ }
445
+
446
+ /* --------- 3B. LIGHT --------- */
447
+ :host([color-scheme='light']) {
448
+ /* Surfaces */
449
+ --background: #ffffff;
450
+ --foreground: #27272a;
451
+
452
+ /* Card Vars:
453
+ card (bg) : dialog/modal popups, table headers (th), floating tooltips, and catalog cards
454
+ card-foreground : Text & icon color on elevated surfaces
455
+ */
456
+ --card: color-mix(in srgb, var(--background) 94%, var(--foreground));
457
+ --card-foreground: color-mix(in srgb, var(--foreground) 90%, #000000);
458
+
459
+ /* Muted Vars:
460
+ muted (bg) : input tags, secondary buttons, table footers, and code backgrounds
461
+ muted-foreground : inactive tabs, parameter descriptions, schema constraints, and timestamps
462
+ */
463
+ --muted: color-mix(in srgb, var(--background) 94%, var(--foreground));
464
+ --muted-foreground: color-mix(in srgb, var(--foreground) 60%, var(--background));
465
+
466
+ /* Border Vars:
467
+ border: dividing lines for tables, cards, sections, and panels
468
+ */
469
+ --border: color-mix(in srgb, var(--background) 85%, var(--foreground));
470
+
471
+ --sidebar-accent: color-mix(in srgb, var(--background) 92%, var(--foreground));
472
+
473
+ --input: color-mix(in srgb, var(--border) 75%, var(--foreground));
474
+ /* Light: fields are white, so they stand out on the tinted card surface */
475
+ --input-background: var(--background);
476
+
477
+ /* HTTP Method Badges (Light Mode: High Contrast). White badge text, and the colors used as text on
478
+ the tinted card surface, keep WCAG AA contrast (4.5:1). */
479
+ --method-get: #2563eb;
480
+ --method-post: #047857;
481
+ --method-put: #c2410c;
482
+ --method-delete: #b91c1c;
483
+ --method-patch: #7c3aed;
484
+ --method-head: #b45309;
485
+ --method-options: #0e7490;
486
+ --method-trace: #be185d;
487
+ --method-query: #4f46e5;
488
+ --method-default: #475569;
489
+ --method-badge-fg: #ffffff;
490
+
491
+ --destructive: #dc2626;
492
+
493
+ /* Named colours (also used by x-badges: color: blue | green | ...) */
494
+ --blue: #2768f4ff;
495
+ --green: #059669;
496
+ --orange: #d97706;
497
+ --red: #dc2626;
498
+ --purple: #7c3aed;
499
+ --yellow: #b45309;
500
+ --pink: #db2777;
501
+ --brown: #92400e;
502
+
503
+ /* Syntax Highlighting */
504
+ --syntax-comment: #6e7781;
505
+ --syntax-keyword: #cf222e;
506
+ --syntax-operator: #24292f;
507
+ --syntax-string: #0a3069;
508
+ --syntax-constant: #0550ae;
509
+ --syntax-function: #8250df;
510
+ --syntax-type: #8250df;
511
+ --syntax-variable: #953800;
512
+ --syntax-property: #0550ae;
513
+ --syntax-tag: #116329;
514
+ --syntax-selector: #8250df;
515
+ --syntax-inserted: #116329;
516
+ --syntax-deleted: #cf222e;
517
+
518
+ /* Code Blocks */
519
+
520
+ --code-bg: color-mix(in srgb, var(--background) 96%, var(--foreground));
521
+ }
522
+
523
+ /* --------- 3C. SYSTEM --------- */
524
+ @media (prefers-color-scheme: light) {
525
+ :host([color-scheme='system']) {
526
+ --background: #ffffff;
527
+ --foreground: #27272a;
528
+ --card: color-mix(in srgb, var(--background) 94%, var(--foreground));
529
+ --card-foreground: color-mix(in srgb, var(--foreground) 90%, #000000);
530
+ --muted: color-mix(in srgb, var(--background) 94%, var(--foreground));
531
+ --muted-foreground: color-mix(in srgb, var(--foreground) 60%, var(--background));
532
+ --border: color-mix(in srgb, var(--background) 85%, var(--foreground));
533
+ --sidebar-accent: color-mix(in srgb, var(--background) 92%, var(--foreground));
534
+ --input: color-mix(in srgb, var(--border) 75%, var(--foreground));
535
+ --input-background: var(--background);
536
+
537
+ --method-get: #2563eb;
538
+ --method-post: #047857;
539
+ --method-put: #c2410c;
540
+ --method-delete: #b91c1c;
541
+ --method-patch: #7c3aed;
542
+ --method-head: #b45309;
543
+ --method-options: #0e7490;
544
+ --method-trace: #be185d;
545
+ --method-query: #4f46e5;
546
+ --method-default: #475569;
547
+ --method-badge-fg: #ffffff;
548
+
549
+ --destructive: #dc2626;
550
+
551
+ --blue: #2768f4ff;
552
+ --green: #059669;
553
+ --orange: #d97706;
554
+ --red: #dc2626;
555
+ --purple: #7c3aed;
556
+ --yellow: #b45309;
557
+ --pink: #db2777;
558
+ --brown: #92400e;
559
+
560
+ --syntax-comment: #6e7781;
561
+ --syntax-keyword: #cf222e;
562
+ --syntax-operator: #24292f;
563
+ --syntax-string: #0a3069;
564
+ --syntax-constant: #0550ae;
565
+ --syntax-function: #8250df;
566
+ --syntax-type: #8250df;
567
+ --syntax-variable: #953800;
568
+ --syntax-property: #0550ae;
569
+ --syntax-tag: #116329;
570
+ --syntax-selector: #8250df;
571
+ --syntax-inserted: #116329;
572
+ --syntax-deleted: #cf222e;
573
+
574
+ --code-bg: color-mix(in srgb, var(--background) 96%, var(--foreground));
575
+ }
576
+ }
577
+
578
+ /* =========================================================================
579
+ 4. BRAND THEME PRESETS (theme), generated from THEMES above
580
+ ========================================================================= */
581
+ ${presetsCss}
582
+ `;
@@ -0,0 +1,89 @@
1
+ # `src/templates` — `<rapi-doc>` render templates
2
+
3
+ ## Overview
4
+
5
+ Lit `html` template functions, no classes. Each is called with `this` bound to its host, so
6
+ `this.*` is the host's reactive state and methods. `main-body-template.js` is the entry used by
7
+ `<rapi-doc>`, `<rapi-doc-mini>` and the static renderer (`@rapidoc/prerender`, `packages/rapidoc-prerender/src/`). Three files render inside
8
+ `<api-request>` (`src/components/`): `request-params-template.js`, `request-body-template.js`,
9
+ `api-response-template.js`.
10
+
11
+ Templates read `this.resolvedSpec` (built by `utils/spec-parser.js`) and compose the elements in
12
+ `src/components/`. They do not parse specs or define styles. The exception to "render only" is
13
+ `security-scheme-template.js`, which also owns API key and OAuth logic (token fetch, popup,
14
+ persistence).
15
+
16
+ ## Interface
17
+
18
+ Default exports are section templates; named exports are helpers used by other templates or hosts.
19
+
20
+ - `mainBodyTemplate(isMini, pathsExpanded)`: page shell; picks layout from `this.renderStyle`.
21
+ - Sections: `headerTemplate`, `navbarTemplate`, `overviewTemplate`, `downloadsTemplate`,
22
+ `serverTemplate`, `securitySchemeTemplate`, `endpointTemplate` (view mode),
23
+ `expandedEndpointTemplate` (read mode), `focusedEndpointTemplate`, `componentsTemplate`,
24
+ `callbackTemplate`, `codeSamplesTemplate`, `advancedSearchDialogTemplate`, `logoTemplate`.
25
+ - Used by hosts: `setApiServer` (`server-template.js`); `applyApiKey`, `onClearAllApiKeys`,
26
+ `recoverPersistedApiKeys` (`security-scheme-template.js`); `expandedEndpointBodyTemplate`
27
+ (static renderer); navbar helpers such as `expandCollapseNavBarTag` (`utils/bind-navbar.js`).
28
+ - Inside `<api-request>`: `inputParametersTemplate`, `requestBodyTemplate`, `apiCallTemplate`.
29
+ - Events (all `bubbles`, `composed`): `api-server-change` (`[server-template.js:setApiServer]`);
30
+ `before-authorize`, cancelable, for `authorizationCode` and `implicit` flows; and
31
+ `before-token-request`, cancelable, before each token fetch (listeners may edit
32
+ `detail.request`), both in `security-scheme-template.js`.
33
+
34
+ ## Invariants
35
+
36
+ - **Headings.** Titles are real `<h1>`–`<h6>` with `class="rapidoc-heading"` and
37
+ `part="heading heading-N"`, never styled divs; the outline is checked by
38
+ `tests/unit/semantic-markup.test.js`.
39
+ - **Exported parts.** A part added inside `<api-request>` / `<api-response>` must be added to the
40
+ `exportparts` lists in `endpoint-template.js`, `expanded-endpoint-template.js` and
41
+ `callback-template.js` (the lists differ today); the semantic-markup test catches omissions.
42
+ - **String flags.** Host flags are compared as exact strings (`=== "true"` or `=== "false"`),
43
+ never by truthiness; `[focused-endpoint-template.js:focusedEndpointTemplate]` also accepts
44
+ boolean `false` for `showInfo`.
45
+ - **Markdown.** Every `marked` result passes through `sanitizeHTML` before `unsafeHTML`.
46
+ - **Loading states.** `mainBodyTemplate` returns `""` without `resolvedSpec`, then renders
47
+ `#spec-not-found` on `specLoadError`, a loader while loading, and an error on `loadFailed`.
48
+ `navbarTemplate` returns a stub `<nav part="section-navbar">` in those cases.
49
+ - **Navigation ids.** An operation root has `id="${path.elementId}"`; its nav link is
50
+ `id="link-${elementId}"` with `data-content-id` on navigate items (expandable tags carry
51
+ `data-first-path-id` instead).
52
+ - **Schema hide flags.** In `endpoint-template.js` and `expanded-endpoint-template.js`, `"never"`
53
+ yields `"false"`; otherwise requests hide read-only and responses hide write-only fields,
54
+ inverted for webhooks. `callback-template.js` always uses the webhook direction.
55
+ - **Auth.** `[security-scheme-template.js:applyApiKey]` returns `false` for an unknown scheme or an
56
+ empty value, so an empty value never clears a key. OAuth uses a fresh `state` and `nonce` per
57
+ sign-in and PKCE (`S256`) when its checkbox is checked; a reply is accepted only when
58
+ `isExpectedOAuthReply` matches. Relative OAuth URLs resolve against the selected server's
59
+ `computedUrl` (or its origin).
60
+ - **Persistence.** With `persistAuth === "true"`, `localStorage["rapidoc"]` holds
61
+ `{ securitySchemeId, value }` per apiKey / bearer scheme; Basic credentials are never stored.
62
+ `removeApiKey` deletes one entry; `[security-scheme-template.js:onClearAllApiKeys]` empties it.
63
+ - **Server variables.** `[server-template.js:onApiServerVarChange]` reads every input in the
64
+ enclosing `<ul class="server-vars">` and recomputes `selectedServer.computedUrl`; the list
65
+ class is what it looks up, so keep it.
66
+
67
+ ## Side Effects
68
+
69
+ - Render writes host state: `mainBodyTemplate` calls `recoverPersistedApiKeys` on every render
70
+ (before the `specLoadError` check), which can call `requestUpdate()` during render;
71
+ `requestBodyTemplate` sets the selected body type and example when unset;
72
+ `focusedEndpointTemplate` sets `focusedElementId` and expands its nav item.
73
+ - Handlers mutate `resolvedSpec` (`expanded` flags in `endpoint-template.js`; scheme values in
74
+ `security-scheme-template.js`) and host tab state, then call `requestUpdate()`.
75
+ - `localStorage` key `rapidoc` (see Persistence); no `sessionStorage`.
76
+ - `security-scheme-template.js`: `fetch` to the token URL, `window.open` for sign-in
77
+ (`console.error` if blocked), a `BroadcastChannel` and `window` `message` listener while
78
+ waiting, `document` `keydown` listener for popovers.
79
+ - Clipboard, downloads and new tabs through `utils/common-utils.js`; navbar handlers toggle
80
+ classes and `aria-expanded` directly in the DOM.
81
+
82
+ ## Verification
83
+
84
+ - `npm run test:unit` (repo root; tests in `tests/unit/`): `semantic-markup.test.js` (outline,
85
+ `exportparts`), `auth-host-note.test.js`, `request-body-form.test.js`,
86
+ `multipart-part-types.test.js`, `example-dropdown.test.js`, `query-json-array.test.js`,
87
+ `param-content-example.test.js`, `server-description.test.js`, `unused-tags.test.js`,
88
+ `spec-parser-tag-groups.test.js`.
89
+ - After edits: `npm run build:rapidoc`, `npm run lint`, `npm run format-fix`.