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.
- package/README.md +171 -54
- package/dist/rapidoc-flow-min.js +580 -0
- package/dist/rapidoc-flow-min.js.LICENSE.txt +171 -0
- package/dist/rapidoc-min.js +645 -202
- package/dist/rapidoc-min.js.LICENSE.txt +381 -0
- package/package.json +57 -42
- package/src/README.md +150 -0
- package/src/components/README.md +91 -0
- package/src/components/api-request.ts +912 -0
- package/src/components/api-response.ts +514 -0
- package/src/components/json-tree.ts +171 -0
- package/src/components/schema-base-element.ts +329 -0
- package/src/components/schema-table.ts +475 -0
- package/src/components/schema-tree.ts +393 -0
- package/src/components/tag-input.ts +180 -0
- package/src/flow.js +3 -0
- package/src/index.js +6 -0
- package/src/oauth-receiver.ts +29 -0
- package/src/rapi-flow.ts +1178 -0
- package/src/rapidoc-mini.ts +603 -0
- package/src/rapidoc.ts +1854 -0
- package/src/styles/README.md +96 -0
- package/src/styles/auth-styles.js +318 -0
- package/src/styles/border-styles.js +24 -0
- package/src/styles/css-bundle.js +129 -0
- package/src/styles/custom-styles.js +8 -0
- package/src/styles/dialog-box-styles.js +102 -0
- package/src/styles/endpoint-styles.js +564 -0
- package/src/styles/flex-styles.js +16 -0
- package/src/styles/flow-styles.js +248 -0
- package/src/styles/font-styles.js +432 -0
- package/src/styles/info-styles.js +36 -0
- package/src/styles/input-styles.js +555 -0
- package/src/styles/layout-styles.js +396 -0
- package/src/styles/microlighter-styles.js +99 -0
- package/src/styles/nav-styles.js +633 -0
- package/src/styles/param-list-styles.js +261 -0
- package/src/styles/schema-styles.js +296 -0
- package/src/styles/tab-styles.js +106 -0
- package/src/styles/theme-tokens.js +582 -0
- package/src/templates/README.md +89 -0
- package/src/templates/advanced-search-dialog-template.js +94 -0
- package/src/templates/api-response-template.js +223 -0
- package/src/templates/callback-template.js +86 -0
- package/src/templates/code-samples-template.js +52 -0
- package/src/templates/components-template.js +86 -0
- package/src/templates/downloads-template.js +70 -0
- package/src/templates/endpoint-template.js +377 -0
- package/src/templates/expanded-endpoint-template.js +270 -0
- package/src/templates/focused-endpoint-template.js +146 -0
- package/src/templates/header-template.js +92 -0
- package/src/templates/logo-template.js +21 -0
- package/src/templates/main-body-template.js +102 -0
- package/src/templates/navbar-template.js +498 -0
- package/src/templates/overview-template.js +104 -0
- package/src/templates/request-body-template.js +673 -0
- package/src/templates/request-params-template.js +485 -0
- package/src/templates/security-scheme-template.js +1272 -0
- package/src/templates/server-template.js +153 -0
- package/src/utils/README.md +146 -0
- package/src/utils/arazzo/README.md +119 -0
- package/src/utils/arazzo/components.js +15 -0
- package/src/utils/arazzo/graph.js +269 -0
- package/src/utils/arazzo/index.js +52 -0
- package/src/utils/arazzo/operations.js +106 -0
- package/src/utils/arazzo/parse.js +196 -0
- package/src/utils/arazzo/refs.js +40 -0
- package/src/utils/arazzo/svg.js +707 -0
- package/src/utils/auto-color-scheme.js +99 -0
- package/src/utils/bind-navbar.js +175 -0
- package/src/utils/color-utils.js +59 -0
- package/src/utils/common-utils.js +191 -0
- package/src/utils/curl-utils.js +126 -0
- package/src/utils/highlighter.js +419 -0
- package/src/utils/markdown-utils.js +110 -0
- package/src/utils/mcp/README.md +155 -0
- package/src/utils/mcp/common.js +166 -0
- package/src/utils/mcp/manifest.js +382 -0
- package/src/utils/mcp/project/server.ts +53 -0
- package/src/utils/mcp/project.js +88 -0
- package/src/utils/mcp/runtime.js +289 -0
- package/src/utils/mcp/schema.js +98 -0
- package/src/utils/mcp/workflow-runtime.js +374 -0
- package/src/utils/mcp/workflows.js +240 -0
- package/src/utils/mcp/zip.js +102 -0
- package/src/utils/mcp-generator.js +47 -0
- package/src/utils/mock-interceptor.js +557 -0
- package/src/utils/oauth-utils.js +87 -0
- package/src/utils/request-utils.js +264 -0
- package/src/utils/response-utils.js +203 -0
- package/src/utils/sanitize.js +57 -0
- package/src/utils/schema-utils.js +1954 -0
- package/src/utils/slugger.js +187 -0
- package/src/utils/spec-parser.js +941 -0
- package/src/utils/url-utils.js +246 -0
- 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`.
|