rapidoc 11.0.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -31
- package/dist/rapidoc-min.js +1424 -213
- package/dist/rapidoc-static-min.js +13542 -0
- package/package.json +48 -34
- package/src/components/api-request.ts +869 -0
- package/src/components/api-response.ts +509 -0
- package/src/components/json-tree.ts +171 -0
- package/src/components/schema-base-element.ts +315 -0
- package/src/components/schema-table.ts +430 -0
- package/src/components/schema-tree.ts +386 -0
- package/src/components/tag-input.ts +184 -0
- package/src/index.js +6 -0
- package/src/oauth-receiver.ts +29 -0
- package/src/rapidoc-mini.ts +582 -0
- package/src/rapidoc.ts +1808 -0
- package/src/static/index.d.ts +149 -0
- package/src/static/index.js +62 -0
- package/src/static/navigation.js +497 -0
- package/src/static/render.js +490 -0
- package/src/static/serializer.js +216 -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 +559 -0
- package/src/styles/flex-styles.js +16 -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 +609 -0
- package/src/styles/param-list-styles.js +261 -0
- package/src/styles/schema-styles.js +288 -0
- package/src/styles/tab-styles.js +106 -0
- package/src/styles/theme-tokens.js +582 -0
- package/src/templates/advanced-search-dialog-template.js +94 -0
- package/src/templates/api-response-template.js +219 -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 +85 -0
- package/src/templates/endpoint-template.js +386 -0
- package/src/templates/expanded-endpoint-template.js +266 -0
- package/src/templates/focused-endpoint-template.js +145 -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 +489 -0
- package/src/templates/overview-template.js +104 -0
- package/src/templates/request-body-template.js +651 -0
- package/src/templates/request-params-template.js +474 -0
- package/src/templates/security-scheme-template.js +1263 -0
- package/src/templates/server-template.js +152 -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 +123 -0
- package/src/utils/highlighter.js +416 -0
- package/src/utils/markdown-utils.js +110 -0
- package/src/utils/mcp/common.js +467 -0
- package/src/utils/mcp/generators/csharp.js +242 -0
- package/src/utils/mcp/generators/go.js +298 -0
- package/src/utils/mcp/generators/java.js +330 -0
- package/src/utils/mcp/generators/python.js +248 -0
- package/src/utils/mcp/generators/rust.js +281 -0
- package/src/utils/mcp/generators/typescript.js +290 -0
- package/src/utils/mcp-generator.js +143 -0
- package/src/utils/mock-interceptor.js +508 -0
- package/src/utils/oauth-utils.js +87 -0
- package/src/utils/request-utils.js +203 -0
- package/src/utils/response-utils.js +203 -0
- package/src/utils/sanitize.js +57 -0
- package/src/utils/schema-utils.js +1927 -0
- package/src/utils/slugger.js +189 -0
- package/src/utils/spec-parser.js +915 -0
- package/src/utils/url-utils.js +211 -0
- package/src/utils/xml-utils.js +61 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { json2xml } from "./schema-utils.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Replaces all occurrences of path parameters in a URL path template.
|
|
5
|
+
* Example: replacePathParams('/users/{id}/details', { id: '123' }) => '/users/123/details'
|
|
6
|
+
*/
|
|
7
|
+
export function replacePathParams(pathTemplate = "", pathParams = {}) {
|
|
8
|
+
let resolvedPath = pathTemplate;
|
|
9
|
+
if (!pathParams || typeof pathParams !== "object") {
|
|
10
|
+
return resolvedPath;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
for (const [key, rawValue] of Object.entries(pathParams)) {
|
|
14
|
+
const value = rawValue !== undefined && rawValue !== null ? String(rawValue) : "";
|
|
15
|
+
// Replace all occurrences of {paramName}
|
|
16
|
+
const token = `{${key}}`;
|
|
17
|
+
resolvedPath = resolvedPath.replaceAll(token, encodeURIComponent(value));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return resolvedPath;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Serializes a single query parameter into an array of [key, value] tuples based on OpenAPI style and explode rules.
|
|
25
|
+
*/
|
|
26
|
+
export function serializeQueryParam(name, rawValue, options = {}) {
|
|
27
|
+
const {
|
|
28
|
+
style = "form",
|
|
29
|
+
explode = style === "form",
|
|
30
|
+
isArray = Array.isArray(rawValue),
|
|
31
|
+
isObject = false,
|
|
32
|
+
} = options;
|
|
33
|
+
|
|
34
|
+
if (rawValue === undefined || rawValue === null || rawValue === "") {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Handle Object types (from JSON input or object values)
|
|
39
|
+
if (isObject || (typeof rawValue === "object" && !Array.isArray(rawValue))) {
|
|
40
|
+
let obj = rawValue;
|
|
41
|
+
if (typeof rawValue === "string") {
|
|
42
|
+
try {
|
|
43
|
+
obj = JSON.parse(rawValue);
|
|
44
|
+
} catch {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!obj || typeof obj !== "object") {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (style === "json") {
|
|
54
|
+
return [[name, JSON.stringify(obj)]];
|
|
55
|
+
}
|
|
56
|
+
if (style === "xml") {
|
|
57
|
+
return [[name, json2xml(obj)]];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const result = [];
|
|
61
|
+
for (const key of Object.keys(obj)) {
|
|
62
|
+
const pKey = `${name}[${key}]`;
|
|
63
|
+
const val = obj[key];
|
|
64
|
+
|
|
65
|
+
if (val !== undefined && val !== null) {
|
|
66
|
+
if (typeof val === "object" && Array.isArray(val)) {
|
|
67
|
+
const filtered = val.filter((v) => v !== "" && v !== undefined && v !== null);
|
|
68
|
+
if (filtered.length > 0) {
|
|
69
|
+
if (style === "spaceDelimited") {
|
|
70
|
+
result.push([pKey, filtered.join(" ")]);
|
|
71
|
+
} else if (style === "pipeDelimited") {
|
|
72
|
+
result.push([pKey, filtered.join("|")]);
|
|
73
|
+
} else if (explode) {
|
|
74
|
+
filtered.forEach((v) => result.push([pKey, String(v)]));
|
|
75
|
+
} else {
|
|
76
|
+
result.push([pKey, filtered.join(",")]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} else if (typeof val === "object") {
|
|
80
|
+
result.push([pKey, JSON.stringify(val)]);
|
|
81
|
+
} else {
|
|
82
|
+
result.push([pKey, String(val)]);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Handle Array types
|
|
90
|
+
if (isArray || Array.isArray(rawValue)) {
|
|
91
|
+
const rawArr = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
92
|
+
const vals = rawArr.filter((v) => v !== "" && v !== undefined && v !== null);
|
|
93
|
+
|
|
94
|
+
if (vals.length === 0) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (style === "spaceDelimited") {
|
|
99
|
+
return [[name, vals.join(" ")]];
|
|
100
|
+
}
|
|
101
|
+
if (style === "pipeDelimited") {
|
|
102
|
+
return [[name, vals.join("|")]];
|
|
103
|
+
}
|
|
104
|
+
if (explode) {
|
|
105
|
+
return vals.map((v) => [name, String(v)]);
|
|
106
|
+
}
|
|
107
|
+
// Default form style unexploded: comma-delimited
|
|
108
|
+
return [[name, vals.join(",")]];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Handle Primitive types
|
|
112
|
+
return [[name, String(rawValue)]];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* RFC 3986 allowable reserved characters when allowReserved: true
|
|
117
|
+
* Encodes special delimiters & and = so query string structure remains intact,
|
|
118
|
+
* while leaving other reserved chars (:/?#[]@!$'()*+,;) unencoded.
|
|
119
|
+
*/
|
|
120
|
+
function encodeReservedQueryValue(value) {
|
|
121
|
+
return encodeURI(value).replace(/&/g, "%26").replace(/=/g, "%3D").replace(/\+/g, "%2B");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Builds the query string from a collection of query parameter descriptors.
|
|
126
|
+
*/
|
|
127
|
+
export function buildQueryString(queryParams = []) {
|
|
128
|
+
if (!Array.isArray(queryParams) || queryParams.length === 0) {
|
|
129
|
+
return "";
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const parts = [];
|
|
133
|
+
|
|
134
|
+
for (const param of queryParams) {
|
|
135
|
+
const {
|
|
136
|
+
name,
|
|
137
|
+
value,
|
|
138
|
+
style = "form",
|
|
139
|
+
explode = style === "form",
|
|
140
|
+
allowReserved = false,
|
|
141
|
+
isArray = false,
|
|
142
|
+
isObject = false,
|
|
143
|
+
} = param;
|
|
144
|
+
|
|
145
|
+
const entries = serializeQueryParam(name, value, { style, explode, isArray, isObject });
|
|
146
|
+
|
|
147
|
+
for (const [k, v] of entries) {
|
|
148
|
+
const encodedKey = encodeURIComponent(k);
|
|
149
|
+
const encodedValue = allowReserved ? encodeReservedQueryValue(v) : encodeURIComponent(v);
|
|
150
|
+
parts.push(`${encodedKey}=${encodedValue}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return parts.join("&");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* The OAuth redirect URL for the `oauth-receiver` attribute. A relative value (the default
|
|
159
|
+
* `oauth-receiver.html`) is resolved against the current page's folder, as it always was; a value starting
|
|
160
|
+
* with `/` is a path from the site root, and a full URL is used as is, so a whole site can register one
|
|
161
|
+
* redirect URL with its OAuth provider.
|
|
162
|
+
*
|
|
163
|
+
* @param {{origin: string, pathname: string}} location - e.g. window.location
|
|
164
|
+
* @param {string} receiver - the oauth-receiver attribute
|
|
165
|
+
* @returns {URL}
|
|
166
|
+
*/
|
|
167
|
+
export function oauthReceiverUrl(location, receiver = "oauth-receiver.html") {
|
|
168
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(receiver)) return new URL(receiver);
|
|
169
|
+
if (receiver.startsWith("/")) return new URL(receiver, location.origin);
|
|
170
|
+
const folder = location.pathname.substring(0, location.pathname.lastIndexOf("/"));
|
|
171
|
+
return new URL(`${location.origin}${folder}/${receiver}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Safely joins server URL and path template, preventing duplicate or missing slashes.
|
|
176
|
+
*/
|
|
177
|
+
export function joinServerAndPath(serverUrl = "", path = "") {
|
|
178
|
+
const cleanServer = (serverUrl || "").replace(/\/+$/, "");
|
|
179
|
+
const cleanPath = path ? `/${path.replace(/^\/+/, "")}` : "";
|
|
180
|
+
return `${cleanServer}${cleanPath}`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Constructs the final fetch URL with resolved path parameters, serialized query string,
|
|
185
|
+
* and optional authentication tokens.
|
|
186
|
+
*/
|
|
187
|
+
export function constructFetchURL({
|
|
188
|
+
serverUrl = "",
|
|
189
|
+
path = "",
|
|
190
|
+
pathParams = {},
|
|
191
|
+
queryParams = [],
|
|
192
|
+
apiKeys = [],
|
|
193
|
+
} = {}) {
|
|
194
|
+
let resolvedPath = replacePathParams(path, pathParams);
|
|
195
|
+
const queryString = buildQueryString(queryParams);
|
|
196
|
+
|
|
197
|
+
if (queryString) {
|
|
198
|
+
resolvedPath = `${resolvedPath}${resolvedPath.includes("?") ? "&" : "?"}${queryString}`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Append query-based authentication parameters
|
|
202
|
+
if (Array.isArray(apiKeys)) {
|
|
203
|
+
apiKeys
|
|
204
|
+
.filter((k) => k && k.in === "query" && k.finalKeyValue)
|
|
205
|
+
.forEach((k) => {
|
|
206
|
+
resolvedPath = `${resolvedPath}${resolvedPath.includes("?") ? "&" : "?"}${encodeURIComponent(k.name)}=${encodeURIComponent(k.finalKeyValue)}`;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return joinServerAndPath(serverUrl, resolvedPath);
|
|
211
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats/prettifies an XML string with indentation.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} xml - The XML string to format.
|
|
5
|
+
* @param {object} [options]
|
|
6
|
+
* @param {string} [options.indentor=' '] - The indentation string (e.g. ' ' or '\t').
|
|
7
|
+
* @param {boolean} [options.textNodesOnSameLine=true] - Keep simple text nodes on the same line as their opening and closing tags.
|
|
8
|
+
* @returns {string} Formatted XML string.
|
|
9
|
+
*/
|
|
10
|
+
export function formatXml(xml, { indentor = " ", textNodesOnSameLine = true } = {}) {
|
|
11
|
+
if (!xml || typeof xml !== "string") {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Tokenize by XML tags (including declarations, comments, and CDATA) while preserving text
|
|
16
|
+
const tokens = xml
|
|
17
|
+
.split(/(<[^>]+>)/g)
|
|
18
|
+
.map((s) => s.trim())
|
|
19
|
+
.filter(Boolean);
|
|
20
|
+
|
|
21
|
+
let depth = 0;
|
|
22
|
+
const lines = [];
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
25
|
+
const token = tokens[i];
|
|
26
|
+
const isClosing = token.startsWith("</");
|
|
27
|
+
const isSelfClosing = token.endsWith("/>");
|
|
28
|
+
const isOpening = /^<[^/!?]/.test(token) && !isSelfClosing;
|
|
29
|
+
|
|
30
|
+
if (isClosing) {
|
|
31
|
+
depth = Math.max(0, depth - 1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const indent = indentor.repeat(depth);
|
|
35
|
+
|
|
36
|
+
// Lookahead for OpeningTag -> Text -> ClosingTag to collapse into one line
|
|
37
|
+
if (
|
|
38
|
+
textNodesOnSameLine &&
|
|
39
|
+
isOpening &&
|
|
40
|
+
i + 2 < tokens.length &&
|
|
41
|
+
!tokens[i + 1].startsWith("<") &&
|
|
42
|
+
tokens[i + 2].startsWith("</")
|
|
43
|
+
) {
|
|
44
|
+
const openTag = token.match(/^<([a-zA-Z0-9_\-:]+)/)?.[1];
|
|
45
|
+
const closeTag = tokens[i + 2].match(/^<\/([a-zA-Z0-9_\-:]+)/)?.[1];
|
|
46
|
+
if (openTag && closeTag && openTag === closeTag) {
|
|
47
|
+
lines.push(`${indent}${token}${tokens[i + 1]}${tokens[i + 2]}`);
|
|
48
|
+
i += 2;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
lines.push(`${indent}${token}`);
|
|
54
|
+
|
|
55
|
+
if (isOpening) {
|
|
56
|
+
depth++;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return lines.join("\n");
|
|
61
|
+
}
|