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,290 +0,0 @@
1
- /**
2
- * Single-file TypeScript MCP Server Generator
3
- * Uses official @modelcontextprotocol/sdk and zod.
4
- */
5
- import { toSnakeCase, estimateTokenCost } from "../common.js";
6
-
7
- export function generateTypeScriptMcpServer(metadata, tools, resources, workflows, options = {}) {
8
- const serverName = toSnakeCase(options.serverName || metadata.title || "rapidoc_mcp_server");
9
- const budget = estimateTokenCost(tools, resources, workflows);
10
- const defaultBaseUrl = metadata.servers?.[0]?.url || "http://localhost:3000";
11
-
12
- const toolDefinitions = tools
13
- .map((t) => {
14
- // Build Zod schema properties
15
- const zodProps = t.parameters
16
- .map((p) => {
17
- let zodType = "z.string()";
18
- if (p.type === "integer" || p.type === "number") zodType = "z.number()";
19
- else if (p.type === "boolean") zodType = "z.boolean()";
20
- else if (p.type === "array") zodType = "z.array(z.string())";
21
- else if (p.type === "object") zodType = "z.record(z.any())";
22
-
23
- if (p.description) {
24
- zodType += `.describe(${JSON.stringify(p.description)})`;
25
- }
26
- if (!p.required) {
27
- zodType += ".optional()";
28
- }
29
- return ` ${JSON.stringify(p.name)}: ${zodType},`;
30
- })
31
- .join("\n");
32
-
33
- const allZodProps = zodProps
34
- ? `${zodProps}\n apiKey: z.string().optional().describe('Optional Bearer API key override for multi-tenant sessions'),`
35
- : ` apiKey: z.string().optional().describe('Optional Bearer API key override for multi-tenant sessions'),`;
36
-
37
- const pathSubstitution = t.path.replace(/\{([^}]+)\}/g, '${encodeURIComponent(args["$1"])}');
38
-
39
- const headerParams = t.parameters.filter((p) => p.in === "header");
40
- const headerAppends = headerParams
41
- .map(
42
- (p) =>
43
- ` if (args[${JSON.stringify(p.name)}]) {\n headers[${JSON.stringify(p.name)}] = String(args[${JSON.stringify(p.name)}]);\n }`,
44
- )
45
- .join("\n");
46
-
47
- return `
48
- // Tool: ${t.name} (${t.method} ${t.path})
49
- // ${t.isConsequential ? "⚠️ Consequential/Destructive action" : "Safe/Read-only action"}
50
- server.tool(
51
- ${JSON.stringify(t.name)},
52
- ${JSON.stringify(t.description + (t.isConsequential ? " (Requires confirmation)" : ""))},
53
- {
54
- ${allZodProps}
55
- },
56
- async (args: any) => {
57
- const targetUrl = new URL(\`\${BASE_URL.replace(/\\/$/, '')}${pathSubstitution}\`);
58
- let url = targetUrl.toString();
59
- const queryParams = new URLSearchParams();
60
- ${t.parameters
61
- .filter((p) => p.in === "query")
62
- .map(
63
- (p) =>
64
- ` if (args[${JSON.stringify(p.name)}] !== undefined) queryParams.set(${JSON.stringify(p.name)}, String(args[${JSON.stringify(p.name)}]));`,
65
- )
66
- .join("\n")}
67
- const qs = queryParams.toString();
68
- if (qs) url += (url.includes('?') ? '&' : '?') + qs;
69
-
70
- const headers: Record<string, string> = {
71
- 'Accept': 'application/json',
72
- 'Content-Type': 'application/json',
73
- };
74
- ${headerAppends ? "\n" + headerAppends + "\n" : ""} const resolvedKey = args?.apiKey || API_KEY;
75
- if (resolvedKey) headers['Authorization'] = \`Bearer \${resolvedKey}\`;
76
-
77
- const fetchOptions: RequestInit = {
78
- method: ${JSON.stringify(t.method)},
79
- headers,
80
- };
81
-
82
- ${
83
- ["POST", "PUT", "PATCH"].includes(t.method)
84
- ? ` const bodyPayload: Record<string, any> = {};
85
- ${t.parameters
86
- .filter((p) => p.in === "body")
87
- .map(
88
- (p) =>
89
- ` if (args[${JSON.stringify(p.name)}] !== undefined) bodyPayload[${JSON.stringify(p.name)}] = args[${JSON.stringify(p.name)}];`,
90
- )
91
- .join("\n")}
92
- if (Object.keys(bodyPayload).length > 0) {
93
- fetchOptions.body = JSON.stringify(bodyPayload);
94
- }`
95
- : ""
96
- }
97
-
98
- try {
99
- const response = await fetch(url, fetchOptions);
100
- const text = await response.text();
101
- let data = text;
102
- try { data = JSON.parse(text); } catch {}
103
- return {
104
- content: [{ type: 'text', text: typeof data === 'string' ? data : JSON.stringify(data, null, 2) }],
105
- };
106
- } catch (err: any) {
107
- return {
108
- isError: true,
109
- content: [{ type: 'text', text: \`Error invoking ${t.name}: \${err.message}\` }],
110
- };
111
- }
112
- }
113
- );`;
114
- })
115
- .join("\n");
116
-
117
- const resourceDefinitions = resources
118
- .map((r) => {
119
- return `
120
- // Resource: ${r.name} (${r.uri})
121
- server.resource(
122
- ${JSON.stringify(r.name)},
123
- ${JSON.stringify(r.uri)},
124
- async (uri) => {
125
- const targetUrl = new URL(\`\${BASE_URL.replace(/\\/$/, '')}${r.path}\`);
126
- const resolvedKey = uri.searchParams?.get('apiKey') || uri.searchParams?.get('api_key') || API_KEY;
127
- if (uri.searchParams) {
128
- uri.searchParams.forEach((val, key) => {
129
- if (!['apikey', 'api_key'].includes(key.toLowerCase())) {
130
- targetUrl.searchParams.set(key, val);
131
- }
132
- });
133
- }
134
- const headers: Record<string, string> = { 'Accept': ${JSON.stringify(r.mimeType)} };
135
- if (resolvedKey) headers['Authorization'] = \`Bearer \${resolvedKey}\`;
136
-
137
- const res = await fetch(targetUrl.toString(), { headers });
138
- const text = await res.text();
139
- return {
140
- contents: [{
141
- uri: uri.href,
142
- text,
143
- mimeType: ${JSON.stringify(r.mimeType)},
144
- }],
145
- };
146
- }
147
- );`;
148
- })
149
- .join("\n");
150
-
151
- const workflowDefinitions = workflows
152
- .map((w) => {
153
- const paramKeys = w.parameters ? Object.keys(w.parameters) : [];
154
- const zodProps = paramKeys
155
- .map(
156
- (k) =>
157
- ` ${JSON.stringify(k)}: z.string().describe(${JSON.stringify(w.parameters[k].description || "")}),`,
158
- )
159
- .concat([
160
- ` apiKey: z.string().optional().describe('Optional Bearer API key override for multi-tenant sessions'),`,
161
- ])
162
- .join("\n");
163
- const firstParam = paramKeys[0] || "id";
164
-
165
- return `
166
- // Composite Workflow: ${w.name}
167
- // Collapses multi-step atomic REST calls into 1 tool call
168
- server.tool(
169
- ${JSON.stringify(w.name)},
170
- ${JSON.stringify(w.description || "Composite workflow")},
171
- {
172
- ${zodProps}
173
- },
174
- async (args: any) => {
175
- const results: Record<string, any> = {};
176
- const headers: Record<string, string> = { 'Accept': 'application/json' };
177
- const resolvedKey = args?.apiKey || API_KEY;
178
- if (resolvedKey) headers['Authorization'] = \`Bearer \${resolvedKey}\`;
179
-
180
- try {
181
- ${(w.steps || [])
182
- .map((s, idx) => {
183
- return ` // Step ${idx + 1}: ${s.call}
184
- const stepUrl_${idx} = \`\${BASE_URL.replace(/\\/$/, '')}/api/\${encodeURIComponent(args[${JSON.stringify(firstParam)}] || '')}\`;
185
- const resp_${idx} = await fetch(stepUrl_${idx}, { headers });
186
- results[${JSON.stringify(s.call)}] = await resp_${idx}.json();`;
187
- })
188
- .join("\n")}
189
- return {
190
- content: [{ type: 'text', text: JSON.stringify(results, null, 2) }],
191
- };
192
- } catch (err: any) {
193
- return {
194
- isError: true,
195
- content: [{ type: 'text', text: \`Workflow ${w.name} failed: \${err.message}\` }],
196
- };
197
- }
198
- }
199
- );`;
200
- })
201
- .join("\n");
202
-
203
- return `/**
204
- * Auto-generated by RapiDoc Curated MCP Generator
205
- * Spec: ${metadata.title} (v${metadata.version})
206
- *
207
- * [MULTI-TENANCY & AUTHENTICATION]
208
- * - Local Stdio Mode: Claude Desktop, Cursor, and local agents use API_KEY from environment.
209
- * - Multi-Tenant / Agent Mode: When running in a shared service, the calling AI agent can pass
210
- * per-session credentials directly in the \`apiKey\` parameter of any tool.
211
- *
212
- * [TOKEN BUDGET DIAGNOSTIC]
213
- * - Total Tools: ${budget.totalTools}
214
- * - Total Resources: ${budget.totalResources}
215
- * - Total Workflows: ${budget.totalWorkflows}
216
- * - Estimated Prompt Context Overhead: ~${budget.estimatedTokens.toLocaleString()} tokens/turn
217
- ${budget.warnings.map((w) => ` * - ⚠️ ${w}`).join("\n")}
218
- *
219
- * [HOW TO RUN]
220
- * 1. npm install @modelcontextprotocol/sdk zod
221
- * 2. API_KEY="your-key" npx tsx server.ts
222
- */
223
-
224
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
225
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
226
- import { z } from 'zod';
227
-
228
- const API_KEY = process.env.API_KEY || '';
229
- const BASE_URL = process.env.API_BASE_URL || ${JSON.stringify(defaultBaseUrl)};
230
-
231
- const server = new McpServer({
232
- name: ${JSON.stringify(serverName)},
233
- version: ${JSON.stringify(metadata.version)},
234
- });
235
-
236
- ${resourceDefinitions}
237
- ${toolDefinitions}
238
- ${workflowDefinitions}
239
-
240
- async function main() {
241
- const transport = new StdioServerTransport();
242
- await server.connect(transport);
243
- console.error(\`[MCP] ${serverName} running on stdio\`);
244
- }
245
-
246
- main().catch((err) => {
247
- console.error('[MCP] Fatal error running server:', err);
248
- process.exit(1);
249
- });
250
- `;
251
- }
252
-
253
- export function generateTypeScriptFiles(serverCode, metadata, options = {}) {
254
- const packageJson = {
255
- name: toSnakeCase(options.serverName || metadata.title || "rapidoc-mcp-server"),
256
- version: metadata.version || "1.0.0",
257
- type: "module",
258
- scripts: {
259
- start: "npx tsx server.ts",
260
- },
261
- dependencies: {
262
- "@modelcontextprotocol/sdk": "^1.6.0",
263
- zod: "^3.24.0",
264
- },
265
- devDependencies: {
266
- tsx: "^4.19.0",
267
- typescript: "^5.7.0",
268
- },
269
- };
270
-
271
- const readme = `# ${metadata.title} - MCP Server (TypeScript)
272
-
273
- Auto-generated by RapiDoc Curated MCP Generator.
274
-
275
- ### Prerequisites
276
- - Node.js 18+
277
- - \`npm install\`
278
-
279
- ### Running the Server
280
- \`\`\`bash
281
- API_KEY="your-key" npm start
282
- \`\`\`
283
- `;
284
-
285
- return {
286
- "server.ts": serverCode,
287
- "package.json": JSON.stringify(packageJson, null, 2),
288
- "README.md": readme,
289
- };
290
- }