@marlinjai/clearify 1.5.3 → 1.6.1
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 +1 -1
- package/dist/node/{chunk-NY3VVUQ3.js → chunk-7IXPTIHW.js} +1 -1
- package/dist/node/{chunk-UOVBAJMR.js → chunk-7VYQMIW2.js} +37 -47
- package/dist/node/node/build.js +2 -2
- package/dist/node/node/index.js +2 -2
- package/dist/node/vite-plugin/index.js +1 -1
- package/package.json +2 -2
- package/src/theme/Sidebar.tsx +60 -0
- package/src/theme/components/OpenAPI.tsx +42 -448
- package/src/theme/components/OpenAPIPage.tsx +93 -3
- package/src/theme/components/openapi/ApiHeader.tsx +119 -0
- package/src/theme/components/openapi/CodeExamples.tsx +100 -0
- package/src/theme/components/openapi/MethodBadge.tsx +48 -0
- package/src/theme/components/openapi/OperationCard.tsx +198 -0
- package/src/theme/components/openapi/ParameterTable.tsx +134 -0
- package/src/theme/components/openapi/ResponseList.tsx +148 -0
- package/src/theme/components/openapi/SchemaViewer.tsx +377 -0
- package/src/theme/components/openapi/TagGroup.tsx +105 -0
- package/src/theme/components/openapi/generate-snippets.ts +102 -0
- package/src/theme/components/openapi/index.ts +8 -0
- package/src/theme/styles/globals.css +7 -124
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
interface SnippetInput {
|
|
2
|
+
method: string;
|
|
3
|
+
path: string;
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
parameters?: Array<{ name: string; in: string; required?: boolean; schema?: { type?: string } }>;
|
|
6
|
+
requestBody?: Record<string, any>;
|
|
7
|
+
security?: Array<Record<string, string[]>>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function generateSnippets(input: SnippetInput): { label: string; code: string }[] {
|
|
11
|
+
const { method, path, baseUrl, parameters = [], requestBody, security } = input;
|
|
12
|
+
const upper = method.toUpperCase();
|
|
13
|
+
const url = `${baseUrl}${path}`;
|
|
14
|
+
|
|
15
|
+
// Replace path params with placeholder values
|
|
16
|
+
const urlWithParams = url.replace(/\{(\w+)\}/g, ':$1');
|
|
17
|
+
|
|
18
|
+
const hasBody = !!requestBody;
|
|
19
|
+
const bodySchema = requestBody?.content?.['application/json']?.schema;
|
|
20
|
+
const bodyExample = bodySchema ? generateExample(bodySchema) : null;
|
|
21
|
+
const bodyJson = bodyExample ? JSON.stringify(bodyExample, null, 2) : null;
|
|
22
|
+
|
|
23
|
+
const hasAuth = security && security.length > 0;
|
|
24
|
+
const authHeader = hasAuth ? 'Authorization: Bearer YOUR_TOKEN' : '';
|
|
25
|
+
|
|
26
|
+
const queryParams = parameters.filter(p => p.in === 'query');
|
|
27
|
+
const queryString = queryParams.length > 0
|
|
28
|
+
? '?' + queryParams.map(p => `${p.name}=VALUE`).join('&')
|
|
29
|
+
: '';
|
|
30
|
+
|
|
31
|
+
// curl
|
|
32
|
+
const curlParts = [`curl -X ${upper} '${urlWithParams}${queryString}'`];
|
|
33
|
+
if (hasAuth) curlParts.push(` -H '${authHeader}'`);
|
|
34
|
+
if (hasBody) {
|
|
35
|
+
curlParts.push(" -H 'Content-Type: application/json'");
|
|
36
|
+
curlParts.push(` -d '${bodyJson}'`);
|
|
37
|
+
}
|
|
38
|
+
const curl = curlParts.join(' \\\n');
|
|
39
|
+
|
|
40
|
+
// JavaScript fetch
|
|
41
|
+
const fetchHeaders: string[] = [];
|
|
42
|
+
if (hasAuth) fetchHeaders.push(` 'Authorization': 'Bearer YOUR_TOKEN'`);
|
|
43
|
+
if (hasBody) fetchHeaders.push(` 'Content-Type': 'application/json'`);
|
|
44
|
+
|
|
45
|
+
let jsParts = `const response = await fetch('${urlWithParams}${queryString}', {\n method: '${upper}',\n`;
|
|
46
|
+
if (fetchHeaders.length > 0) {
|
|
47
|
+
jsParts += ` headers: {\n${fetchHeaders.join(',\n')}\n },\n`;
|
|
48
|
+
}
|
|
49
|
+
if (hasBody) {
|
|
50
|
+
jsParts += ` body: JSON.stringify(${bodyJson}),\n`;
|
|
51
|
+
}
|
|
52
|
+
jsParts += '});\n\nconst data = await response.json();';
|
|
53
|
+
|
|
54
|
+
// Python requests
|
|
55
|
+
let pyParts = `import requests\n\n`;
|
|
56
|
+
pyParts += `response = requests.${method.toLowerCase()}(\n '${urlWithParams}${queryString}'`;
|
|
57
|
+
if (hasAuth || hasBody) pyParts += ',';
|
|
58
|
+
pyParts += '\n';
|
|
59
|
+
if (hasAuth) {
|
|
60
|
+
pyParts += ` headers={'Authorization': 'Bearer YOUR_TOKEN'}`;
|
|
61
|
+
if (hasBody) pyParts += ',';
|
|
62
|
+
pyParts += '\n';
|
|
63
|
+
}
|
|
64
|
+
if (hasBody) {
|
|
65
|
+
pyParts += ` json=${bodyJson},\n`;
|
|
66
|
+
}
|
|
67
|
+
pyParts += ')\n\ndata = response.json()';
|
|
68
|
+
|
|
69
|
+
return [
|
|
70
|
+
{ label: 'curl', code: curl },
|
|
71
|
+
{ label: 'JavaScript', code: jsParts },
|
|
72
|
+
{ label: 'Python', code: pyParts },
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Generate a minimal example object from a JSON Schema */
|
|
77
|
+
function generateExample(schema: Record<string, any>): any {
|
|
78
|
+
if (schema.example !== undefined) return schema.example;
|
|
79
|
+
|
|
80
|
+
switch (schema.type) {
|
|
81
|
+
case 'string':
|
|
82
|
+
return schema.enum?.[0] ?? schema.default ?? 'string';
|
|
83
|
+
case 'number':
|
|
84
|
+
case 'integer':
|
|
85
|
+
return schema.default ?? schema.minimum ?? 0;
|
|
86
|
+
case 'boolean':
|
|
87
|
+
return schema.default ?? true;
|
|
88
|
+
case 'array':
|
|
89
|
+
return schema.items ? [generateExample(schema.items)] : [];
|
|
90
|
+
case 'object': {
|
|
91
|
+
const obj: Record<string, any> = {};
|
|
92
|
+
if (schema.properties) {
|
|
93
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
94
|
+
obj[key] = generateExample(prop as Record<string, any>);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return obj;
|
|
98
|
+
}
|
|
99
|
+
default:
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { ApiHeader } from './ApiHeader.js';
|
|
2
|
+
export { TagGroup } from './TagGroup.js';
|
|
3
|
+
export { OperationCard } from './OperationCard.js';
|
|
4
|
+
export { ParameterTable } from './ParameterTable.js';
|
|
5
|
+
export { SchemaViewer } from './SchemaViewer.js';
|
|
6
|
+
export { CodeExamples } from './CodeExamples.js';
|
|
7
|
+
export { ResponseList } from './ResponseList.js';
|
|
8
|
+
export { MethodBadge } from './MethodBadge.js';
|
|
@@ -362,130 +362,13 @@ a:hover {
|
|
|
362
362
|
100% { background-position: 200% 0; }
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
-
/* ─── OpenAPI
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
max-width: none !important;
|
|
369
|
-
padding-left: 0 !important;
|
|
370
|
-
padding-right: 0 !important;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/* Prevent clearify-prose typography and global styles from bleeding into Scalar */
|
|
374
|
-
.clearify-openapi-container h1,
|
|
375
|
-
.clearify-openapi-container h2,
|
|
376
|
-
.clearify-openapi-container h3,
|
|
377
|
-
.clearify-openapi-container h4 {
|
|
378
|
-
font-size: inherit;
|
|
379
|
-
font-weight: inherit;
|
|
380
|
-
margin: initial;
|
|
381
|
-
padding: initial;
|
|
382
|
-
line-height: inherit;
|
|
383
|
-
letter-spacing: normal;
|
|
384
|
-
color: inherit;
|
|
385
|
-
border-bottom: none;
|
|
386
|
-
text-transform: none;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
.clearify-openapi-container p {
|
|
390
|
-
margin: initial;
|
|
391
|
-
color: inherit;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
.clearify-openapi-container ul,
|
|
395
|
-
.clearify-openapi-container ol {
|
|
396
|
-
margin: initial;
|
|
397
|
-
padding: initial;
|
|
398
|
-
color: inherit;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
.clearify-openapi-container li {
|
|
402
|
-
margin: initial;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
.clearify-openapi-container img {
|
|
406
|
-
max-width: initial;
|
|
407
|
-
border-radius: initial;
|
|
408
|
-
border: initial;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
.clearify-openapi-container code {
|
|
412
|
-
background-color: initial;
|
|
413
|
-
padding: initial;
|
|
414
|
-
border-radius: initial;
|
|
415
|
-
font-size: inherit;
|
|
416
|
-
font-family: inherit;
|
|
417
|
-
font-weight: inherit;
|
|
418
|
-
color: inherit;
|
|
419
|
-
border: initial;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
.clearify-openapi-container pre {
|
|
423
|
-
background-color: initial;
|
|
424
|
-
border: initial;
|
|
425
|
-
border-radius: initial;
|
|
426
|
-
padding: initial;
|
|
427
|
-
overflow-x: initial;
|
|
428
|
-
margin: initial;
|
|
429
|
-
font-size: inherit;
|
|
430
|
-
line-height: inherit;
|
|
431
|
-
font-family: inherit;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
.clearify-openapi-container table {
|
|
435
|
-
width: initial;
|
|
436
|
-
border-collapse: initial;
|
|
437
|
-
border-spacing: initial;
|
|
438
|
-
margin: initial;
|
|
439
|
-
font-size: inherit;
|
|
440
|
-
border-radius: initial;
|
|
441
|
-
overflow: initial;
|
|
442
|
-
border: initial;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
.clearify-openapi-container th,
|
|
446
|
-
.clearify-openapi-container td {
|
|
447
|
-
padding: initial;
|
|
448
|
-
text-align: initial;
|
|
449
|
-
border-bottom: initial;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
.clearify-openapi-container th {
|
|
453
|
-
background-color: initial;
|
|
454
|
-
font-weight: inherit;
|
|
455
|
-
font-size: inherit;
|
|
456
|
-
text-transform: initial;
|
|
457
|
-
letter-spacing: initial;
|
|
458
|
-
color: inherit;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
.clearify-openapi-container strong {
|
|
462
|
-
font-weight: inherit;
|
|
463
|
-
color: inherit;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
.clearify-openapi-container blockquote {
|
|
467
|
-
border-left: initial;
|
|
468
|
-
padding: initial;
|
|
469
|
-
color: inherit;
|
|
470
|
-
margin: initial;
|
|
471
|
-
background: initial;
|
|
472
|
-
border-radius: initial;
|
|
473
|
-
font-style: initial;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
.clearify-openapi-container hr {
|
|
477
|
-
border: initial;
|
|
478
|
-
border-top: initial;
|
|
479
|
-
margin: initial;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
.clearify-openapi-container a {
|
|
483
|
-
color: inherit;
|
|
484
|
-
text-decoration: initial;
|
|
485
|
-
transition: initial;
|
|
365
|
+
/* ─── OpenAPI page layout ─── */
|
|
366
|
+
.clearify-openapi-page {
|
|
367
|
+
max-width: none;
|
|
486
368
|
}
|
|
487
369
|
|
|
488
|
-
.clearify-openapi-
|
|
489
|
-
|
|
490
|
-
|
|
370
|
+
.clearify-prose:has(.clearify-openapi-page) {
|
|
371
|
+
max-width: none !important;
|
|
372
|
+
padding-left: 1.5rem !important;
|
|
373
|
+
padding-right: 1.5rem !important;
|
|
491
374
|
}
|