fumadocs-openapi 5.11.8 → 6.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/dist/index.d.ts +20 -71
- package/dist/index.js +21 -18
- package/dist/scalar/client-client-DgnHaOQ3.js +93 -0
- package/dist/scalar/index.d.ts +176 -0
- package/dist/scalar/index.js +13 -0
- package/dist/server/index.d.ts +24 -71
- package/dist/server/index.js +218 -212
- package/dist/ui/client-client-CpwKrzlY.js +107 -0
- package/dist/ui/{fetcher-Cc3BieIx.js → fetcher-Cey1qI8X.js} +1 -1
- package/dist/ui/{index-client-DPqAL2w9.js → index-client-CehDtJk-.js} +582 -434
- package/dist/ui/index.d.ts +32 -15
- package/dist/ui/index.js +33 -82
- package/dist/ui/server-select-client-CbFencmM.js +86 -0
- package/package.json +24 -11
- package/dist/ui/client-client-B06fJG48.js +0 -359
- package/dist/ui/server-select-client-CtG30byb.js +0 -101
package/dist/server/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
|
|
|
14
14
|
import { Accordions, Accordion } from 'fumadocs-ui/components/accordion';
|
|
15
15
|
import * as Base from 'fumadocs-ui/components/codeblock';
|
|
16
16
|
import { highlight } from 'fumadocs-core/server';
|
|
17
|
-
import { Root, API, APIInfo, APIExample as APIExample$1, Property, ObjectCollapsible
|
|
17
|
+
import { APIPlayground, Root, API, APIInfo, APIExample as APIExample$1, Property, ObjectCollapsible } from '../ui/index.js';
|
|
18
18
|
import { load, upgrade, dereference } from '@scalar/openapi-parser';
|
|
19
19
|
import { fetchUrls } from '@scalar/openapi-parser/plugins/fetch-urls';
|
|
20
20
|
import { readFiles } from '@scalar/openapi-parser/plugins/read-files';
|
|
@@ -54,7 +54,7 @@ function getSecurityPrefix(security) {
|
|
|
54
54
|
if (security.type === 'oauth2') return 'Bearer';
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function generateSample(path, method, { baseUrl, document }) {
|
|
57
|
+
function generateSample(path, method, { baseUrl, schema: { document } }) {
|
|
58
58
|
const params = [];
|
|
59
59
|
const responses = {};
|
|
60
60
|
for (const param of method.parameters ?? []){
|
|
@@ -328,173 +328,6 @@ async function getTypescriptSchema(endpoint, code, dereferenceMap) {
|
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
-
function Playground({ path, method, ctx }) {
|
|
332
|
-
let currentId = 0;
|
|
333
|
-
const bodyContent = method.requestBody?.content;
|
|
334
|
-
const mediaType = bodyContent ? getPreferredType(bodyContent) : undefined;
|
|
335
|
-
const context = {
|
|
336
|
-
allowFile: mediaType === 'multipart/form-data',
|
|
337
|
-
references: {},
|
|
338
|
-
nextId () {
|
|
339
|
-
return String(currentId++);
|
|
340
|
-
},
|
|
341
|
-
registered: new WeakMap(),
|
|
342
|
-
render: ctx
|
|
343
|
-
};
|
|
344
|
-
const bodySchema = bodyContent && mediaType && bodyContent[mediaType].schema ? toSchema(bodyContent[mediaType].schema, true, context) : undefined;
|
|
345
|
-
const props = {
|
|
346
|
-
authorization: getAuthorizationField(method, ctx),
|
|
347
|
-
method: method.method,
|
|
348
|
-
route: path,
|
|
349
|
-
path: method.parameters?.filter((v)=>v.in === 'path').map((v)=>parameterToField(v, context)),
|
|
350
|
-
query: method.parameters?.filter((v)=>v.in === 'query').map((v)=>parameterToField(v, context)),
|
|
351
|
-
header: method.parameters?.filter((v)=>v.in === 'header').map((v)=>parameterToField(v, context)),
|
|
352
|
-
body: bodySchema && mediaType ? {
|
|
353
|
-
...bodySchema,
|
|
354
|
-
mediaType: mediaType
|
|
355
|
-
} : undefined,
|
|
356
|
-
schemas: context.references,
|
|
357
|
-
proxyUrl: ctx.proxyUrl
|
|
358
|
-
};
|
|
359
|
-
return /*#__PURE__*/ jsx(ctx.renderer.APIPlayground, {
|
|
360
|
-
...props
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
function getAuthorizationField(method, ctx) {
|
|
364
|
-
const security = method.security ?? ctx.document.security ?? [];
|
|
365
|
-
if (security.length === 0) return;
|
|
366
|
-
const singular = security.find((requirements)=>Object.keys(requirements).length === 1);
|
|
367
|
-
if (!singular) return;
|
|
368
|
-
const scheme = getSecurities(singular, ctx.document)[0];
|
|
369
|
-
return {
|
|
370
|
-
type: 'string',
|
|
371
|
-
name: scheme.type === 'apiKey' ? scheme.name : 'Authorization',
|
|
372
|
-
authType: scheme.type,
|
|
373
|
-
defaultValue: scheme.type === 'oauth2' || scheme.type === 'http' && scheme.scheme === 'bearer' ? 'Bearer' : 'Basic',
|
|
374
|
-
isRequired: security.every((requirements)=>Object.keys(requirements).length > 0),
|
|
375
|
-
description: 'The Authorization access token'
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
function getIdFromSchema(schema, required, ctx) {
|
|
379
|
-
const registered = ctx.registered.get(schema);
|
|
380
|
-
if (registered === undefined) {
|
|
381
|
-
const id = ctx.nextId();
|
|
382
|
-
ctx.registered.set(schema, id);
|
|
383
|
-
ctx.references[id] = toSchema(schema, required, ctx);
|
|
384
|
-
return id;
|
|
385
|
-
}
|
|
386
|
-
return registered;
|
|
387
|
-
}
|
|
388
|
-
function parameterToField(v, ctx) {
|
|
389
|
-
return {
|
|
390
|
-
name: v.name,
|
|
391
|
-
...toSchema(v.schema ?? {
|
|
392
|
-
type: 'string'
|
|
393
|
-
}, v.required ?? false, ctx)
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
function toReference(schema, required, ctx) {
|
|
397
|
-
return {
|
|
398
|
-
type: 'ref',
|
|
399
|
-
isRequired: required,
|
|
400
|
-
schema: getIdFromSchema(schema, false, ctx)
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
function toSchema(schema, required, ctx) {
|
|
404
|
-
if (schema.type === 'array') {
|
|
405
|
-
return {
|
|
406
|
-
type: 'array',
|
|
407
|
-
description: schema.description ?? schema.title,
|
|
408
|
-
isRequired: required,
|
|
409
|
-
items: getIdFromSchema(schema.items, false, ctx)
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
if (schema.type === 'object' || schema.properties !== undefined || schema.allOf !== undefined) {
|
|
413
|
-
const properties = {};
|
|
414
|
-
Object.entries(schema.properties ?? {}).forEach(([key, prop])=>{
|
|
415
|
-
properties[key] = toReference(prop, schema.required?.includes(key) ?? false, ctx);
|
|
416
|
-
});
|
|
417
|
-
schema.allOf?.forEach((c)=>{
|
|
418
|
-
const field = toSchema(c, true, ctx);
|
|
419
|
-
if (field.type === 'object') Object.assign(properties, field.properties);
|
|
420
|
-
});
|
|
421
|
-
const additional = schema.additionalProperties;
|
|
422
|
-
let additionalProperties;
|
|
423
|
-
if (additional && typeof additional === 'object') {
|
|
424
|
-
if ((!additional.type || additional.type.length === 0) && !additional.anyOf && !additional.allOf && !additional.oneOf) {
|
|
425
|
-
additionalProperties = true;
|
|
426
|
-
} else {
|
|
427
|
-
additionalProperties = getIdFromSchema(additional, false, ctx);
|
|
428
|
-
}
|
|
429
|
-
} else {
|
|
430
|
-
additionalProperties = additional;
|
|
431
|
-
}
|
|
432
|
-
return {
|
|
433
|
-
type: 'object',
|
|
434
|
-
isRequired: required,
|
|
435
|
-
description: schema.description ?? schema.title,
|
|
436
|
-
properties,
|
|
437
|
-
additionalProperties
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
if (schema.type === undefined) {
|
|
441
|
-
const combine = schema.anyOf ?? schema.oneOf;
|
|
442
|
-
if (combine) {
|
|
443
|
-
return {
|
|
444
|
-
type: 'switcher',
|
|
445
|
-
description: schema.description ?? schema.title,
|
|
446
|
-
items: Object.fromEntries(combine.map((item, idx)=>{
|
|
447
|
-
return [
|
|
448
|
-
item.title ?? item.type ?? `Item ${idx.toString()}`,
|
|
449
|
-
toReference(item, true, ctx)
|
|
450
|
-
];
|
|
451
|
-
})),
|
|
452
|
-
isRequired: required
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
return {
|
|
456
|
-
type: 'null',
|
|
457
|
-
isRequired: false
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
if (ctx.allowFile && schema.type === 'string' && schema.format === 'binary') {
|
|
461
|
-
return {
|
|
462
|
-
type: 'file',
|
|
463
|
-
isRequired: required,
|
|
464
|
-
description: schema.description ?? schema.title
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
if (Array.isArray(schema.type)) {
|
|
468
|
-
const items = {};
|
|
469
|
-
for (const type of schema.type){
|
|
470
|
-
if (type === 'array') {
|
|
471
|
-
items[type] = {
|
|
472
|
-
type,
|
|
473
|
-
items: 'items' in schema && schema.items ? toSchema(schema.items, false, ctx) : toSchema({}, required, ctx),
|
|
474
|
-
isRequired: required
|
|
475
|
-
};
|
|
476
|
-
} else {
|
|
477
|
-
items[type] = toSchema({
|
|
478
|
-
...schema,
|
|
479
|
-
type
|
|
480
|
-
}, true, ctx);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
return {
|
|
484
|
-
type: 'switcher',
|
|
485
|
-
description: schema.description ?? schema.title,
|
|
486
|
-
items,
|
|
487
|
-
isRequired: required
|
|
488
|
-
};
|
|
489
|
-
}
|
|
490
|
-
return {
|
|
491
|
-
type: schema.type === 'integer' ? 'number' : schema.type,
|
|
492
|
-
defaultValue: schema.example ?? '',
|
|
493
|
-
isRequired: required,
|
|
494
|
-
description: schema.description ?? schema.title
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
|
|
498
331
|
function idToTitle(id) {
|
|
499
332
|
let result = [];
|
|
500
333
|
for (const c of id){
|
|
@@ -606,17 +439,18 @@ function Schema({ name, schema, ctx }) {
|
|
|
606
439
|
const parseObject = ctx.parseObject ?? true;
|
|
607
440
|
const stack = ctx.stack ?? [];
|
|
608
441
|
const { renderer } = ctx.render;
|
|
609
|
-
const child = [];
|
|
610
442
|
// object type
|
|
611
443
|
if (isObject(schema) && parseObject && (schema.additionalProperties || schema.properties)) {
|
|
444
|
+
let body = null;
|
|
445
|
+
let footer = null;
|
|
612
446
|
const { additionalProperties, properties } = schema;
|
|
613
447
|
if (additionalProperties === true) {
|
|
614
|
-
|
|
448
|
+
footer = /*#__PURE__*/ jsx(renderer.Property, {
|
|
615
449
|
name: "[key: string]",
|
|
616
450
|
type: "any"
|
|
617
|
-
}
|
|
451
|
+
});
|
|
618
452
|
} else if (additionalProperties) {
|
|
619
|
-
|
|
453
|
+
footer = /*#__PURE__*/ jsx(Schema, {
|
|
620
454
|
name: "[key: string]",
|
|
621
455
|
schema: additionalProperties,
|
|
622
456
|
ctx: {
|
|
@@ -624,10 +458,10 @@ function Schema({ name, schema, ctx }) {
|
|
|
624
458
|
required: false,
|
|
625
459
|
parseObject: false
|
|
626
460
|
}
|
|
627
|
-
}
|
|
461
|
+
});
|
|
628
462
|
}
|
|
629
463
|
if (properties) {
|
|
630
|
-
|
|
464
|
+
body = Object.entries(properties).map(([key, value])=>{
|
|
631
465
|
return /*#__PURE__*/ jsx(Schema, {
|
|
632
466
|
name: key,
|
|
633
467
|
schema: value,
|
|
@@ -638,9 +472,14 @@ function Schema({ name, schema, ctx }) {
|
|
|
638
472
|
}
|
|
639
473
|
}, key);
|
|
640
474
|
});
|
|
641
|
-
child.push(...rendered);
|
|
642
475
|
}
|
|
643
|
-
return
|
|
476
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
477
|
+
className: "flex flex-col gap-4",
|
|
478
|
+
children: [
|
|
479
|
+
body,
|
|
480
|
+
footer
|
|
481
|
+
]
|
|
482
|
+
});
|
|
644
483
|
}
|
|
645
484
|
if (schema.allOf && parseObject) {
|
|
646
485
|
return /*#__PURE__*/ jsx(Schema, {
|
|
@@ -649,9 +488,7 @@ function Schema({ name, schema, ctx }) {
|
|
|
649
488
|
ctx: ctx
|
|
650
489
|
});
|
|
651
490
|
}
|
|
652
|
-
|
|
653
|
-
text: schema.description
|
|
654
|
-
}, "description"));
|
|
491
|
+
let footer = null;
|
|
655
492
|
const fields = [];
|
|
656
493
|
for (const [key, value] of Object.entries(keys$1)){
|
|
657
494
|
if (key in schema) {
|
|
@@ -667,21 +504,9 @@ function Schema({ name, schema, ctx }) {
|
|
|
667
504
|
value: schema.enum.map((value)=>JSON.stringify(value)).join(' | ')
|
|
668
505
|
});
|
|
669
506
|
}
|
|
670
|
-
if (fields.length > 0) child.push(/*#__PURE__*/ jsx("div", {
|
|
671
|
-
className: "flex flex-col gap-2",
|
|
672
|
-
children: fields.map((field)=>/*#__PURE__*/ jsxs("span", {
|
|
673
|
-
children: [
|
|
674
|
-
field.key,
|
|
675
|
-
": ",
|
|
676
|
-
/*#__PURE__*/ jsx("code", {
|
|
677
|
-
children: field.value
|
|
678
|
-
})
|
|
679
|
-
]
|
|
680
|
-
}, field.key))
|
|
681
|
-
}, "fields"));
|
|
682
507
|
if (isObject(schema) && !parseObject && !stack.includes(schema)) {
|
|
683
|
-
|
|
684
|
-
name: "Attributes",
|
|
508
|
+
footer = /*#__PURE__*/ jsx(renderer.ObjectCollapsible, {
|
|
509
|
+
name: "Show Attributes",
|
|
685
510
|
children: /*#__PURE__*/ jsx(Schema, {
|
|
686
511
|
name: name,
|
|
687
512
|
schema: schema,
|
|
@@ -695,7 +520,7 @@ function Schema({ name, schema, ctx }) {
|
|
|
695
520
|
]
|
|
696
521
|
}
|
|
697
522
|
})
|
|
698
|
-
}
|
|
523
|
+
});
|
|
699
524
|
} else {
|
|
700
525
|
const mentionedObjectTypes = [
|
|
701
526
|
...schema.anyOf ?? schema.oneOf ?? [],
|
|
@@ -706,9 +531,9 @@ function Schema({ name, schema, ctx }) {
|
|
|
706
531
|
schema.items
|
|
707
532
|
] : []
|
|
708
533
|
].filter((s)=>isComplexType(s) && !stack.includes(s));
|
|
709
|
-
|
|
534
|
+
footer = mentionedObjectTypes.map((s, idx)=>{
|
|
710
535
|
return /*#__PURE__*/ jsx(renderer.ObjectCollapsible, {
|
|
711
|
-
name: s.title ?? `Object ${
|
|
536
|
+
name: s.title ?? (mentionedObjectTypes.length === 1 ? 'Show Attributes' : `Object ${idx + 1}`),
|
|
712
537
|
children: /*#__PURE__*/ jsx(Schema, {
|
|
713
538
|
name: "element",
|
|
714
539
|
schema: s,
|
|
@@ -722,16 +547,32 @@ function Schema({ name, schema, ctx }) {
|
|
|
722
547
|
required: false
|
|
723
548
|
}
|
|
724
549
|
})
|
|
725
|
-
},
|
|
550
|
+
}, idx);
|
|
726
551
|
});
|
|
727
|
-
child.push(...renderedMentionedTypes);
|
|
728
552
|
}
|
|
729
|
-
return /*#__PURE__*/
|
|
553
|
+
return /*#__PURE__*/ jsxs(renderer.Property, {
|
|
730
554
|
name: name,
|
|
731
555
|
type: getSchemaType(schema, ctx),
|
|
732
556
|
required: ctx.required,
|
|
733
557
|
deprecated: schema.deprecated,
|
|
734
|
-
children:
|
|
558
|
+
children: [
|
|
559
|
+
schema.description ? /*#__PURE__*/ jsx(Markdown, {
|
|
560
|
+
text: schema.description
|
|
561
|
+
}) : null,
|
|
562
|
+
fields.length > 0 ? /*#__PURE__*/ jsx("div", {
|
|
563
|
+
className: "flex flex-col gap-2",
|
|
564
|
+
children: fields.map((field)=>/*#__PURE__*/ jsxs("span", {
|
|
565
|
+
children: [
|
|
566
|
+
field.key,
|
|
567
|
+
": ",
|
|
568
|
+
/*#__PURE__*/ jsx("code", {
|
|
569
|
+
children: field.value
|
|
570
|
+
})
|
|
571
|
+
]
|
|
572
|
+
}, field.key))
|
|
573
|
+
}) : null,
|
|
574
|
+
footer
|
|
575
|
+
]
|
|
735
576
|
});
|
|
736
577
|
}
|
|
737
578
|
/**
|
|
@@ -793,7 +634,7 @@ const methodKeys = [
|
|
|
793
634
|
|
|
794
635
|
function Operation({ type = 'operation', path, method, ctx, hasHead, headingLevel = 2 }) {
|
|
795
636
|
const body = method.requestBody;
|
|
796
|
-
const security = method.security ?? ctx.document.security;
|
|
637
|
+
const security = method.security ?? ctx.schema.document.security;
|
|
797
638
|
let headNode = null;
|
|
798
639
|
let bodyNode = null;
|
|
799
640
|
let responseNode = null;
|
|
@@ -923,7 +764,7 @@ function Operation({ type = 'operation', path, method, ctx, hasHead, headingLeve
|
|
|
923
764
|
method: method.method,
|
|
924
765
|
route: path,
|
|
925
766
|
children: [
|
|
926
|
-
type === 'operation' ? /*#__PURE__*/ jsx(
|
|
767
|
+
type === 'operation' ? /*#__PURE__*/ jsx(ctx.renderer.APIPlayground, {
|
|
927
768
|
path: path,
|
|
928
769
|
method: method,
|
|
929
770
|
ctx: ctx
|
|
@@ -1053,7 +894,7 @@ function WebhookCallback({ callback, ctx, headingLevel }) {
|
|
|
1053
894
|
}
|
|
1054
895
|
return out;
|
|
1055
896
|
}
|
|
1056
|
-
function AuthSection({ ctx: { document, renderer }, requirements }) {
|
|
897
|
+
function AuthSection({ ctx: { schema: { document }, renderer }, requirements }) {
|
|
1057
898
|
let id = 0;
|
|
1058
899
|
const info = [];
|
|
1059
900
|
for (const requirement of requirements){
|
|
@@ -1125,7 +966,7 @@ function AuthSection({ ctx: { document, renderer }, requirements }) {
|
|
|
1125
966
|
}
|
|
1126
967
|
return info;
|
|
1127
968
|
}
|
|
1128
|
-
async function ResponseTabs({ endpoint, operation, ctx: { renderer, generateTypeScriptSchema,
|
|
969
|
+
async function ResponseTabs({ endpoint, operation, ctx: { renderer, generateTypeScriptSchema, schema } }) {
|
|
1129
970
|
const items = [];
|
|
1130
971
|
const children = [];
|
|
1131
972
|
if (!operation.responses) return null;
|
|
@@ -1144,7 +985,7 @@ async function ResponseTabs({ endpoint, operation, ctx: { renderer, generateType
|
|
|
1144
985
|
if (generateTypeScriptSchema) {
|
|
1145
986
|
ts = await generateTypeScriptSchema(endpoint, code);
|
|
1146
987
|
} else if (generateTypeScriptSchema === undefined) {
|
|
1147
|
-
ts = await getTypescriptSchema(endpoint, code, dereferenceMap);
|
|
988
|
+
ts = await getTypescriptSchema(endpoint, code, schema.dereferenceMap);
|
|
1148
989
|
}
|
|
1149
990
|
if (ts) {
|
|
1150
991
|
types.push({
|
|
@@ -1192,6 +1033,165 @@ async function CodeBlock({ code, lang, options, ...rest }) {
|
|
|
1192
1033
|
});
|
|
1193
1034
|
}
|
|
1194
1035
|
|
|
1036
|
+
function Playground({ path, method, ctx }) {
|
|
1037
|
+
let currentId = 0;
|
|
1038
|
+
const bodyContent = method.requestBody?.content;
|
|
1039
|
+
const mediaType = bodyContent ? getPreferredType(bodyContent) : undefined;
|
|
1040
|
+
const context = {
|
|
1041
|
+
allowFile: mediaType === 'multipart/form-data',
|
|
1042
|
+
references: {},
|
|
1043
|
+
nextId () {
|
|
1044
|
+
return String(currentId++);
|
|
1045
|
+
},
|
|
1046
|
+
registered: new WeakMap(),
|
|
1047
|
+
render: ctx
|
|
1048
|
+
};
|
|
1049
|
+
const bodySchema = bodyContent && mediaType && bodyContent[mediaType].schema ? toSchema(bodyContent[mediaType].schema, true, context) : undefined;
|
|
1050
|
+
const props = {
|
|
1051
|
+
authorization: getAuthorizationField(method, ctx),
|
|
1052
|
+
method: method.method,
|
|
1053
|
+
route: path,
|
|
1054
|
+
path: method.parameters?.filter((v)=>v.in === 'path').map((v)=>parameterToField(v, context)),
|
|
1055
|
+
query: method.parameters?.filter((v)=>v.in === 'query').map((v)=>parameterToField(v, context)),
|
|
1056
|
+
header: method.parameters?.filter((v)=>v.in === 'header').map((v)=>parameterToField(v, context)),
|
|
1057
|
+
body: bodySchema && mediaType ? {
|
|
1058
|
+
...bodySchema,
|
|
1059
|
+
mediaType: mediaType
|
|
1060
|
+
} : undefined,
|
|
1061
|
+
schemas: context.references,
|
|
1062
|
+
proxyUrl: ctx.proxyUrl
|
|
1063
|
+
};
|
|
1064
|
+
return /*#__PURE__*/ jsx(APIPlayground, {
|
|
1065
|
+
...props
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
function getAuthorizationField(method, { schema: { document } }) {
|
|
1069
|
+
const security = method.security ?? document.security ?? [];
|
|
1070
|
+
if (security.length === 0) return;
|
|
1071
|
+
const singular = security.find((requirements)=>Object.keys(requirements).length === 1);
|
|
1072
|
+
if (!singular) return;
|
|
1073
|
+
return getSecurities(singular, document)[0];
|
|
1074
|
+
}
|
|
1075
|
+
function getIdFromSchema(schema, required, ctx) {
|
|
1076
|
+
const registered = ctx.registered.get(schema);
|
|
1077
|
+
if (registered === undefined) {
|
|
1078
|
+
const id = ctx.nextId();
|
|
1079
|
+
ctx.registered.set(schema, id);
|
|
1080
|
+
ctx.references[id] = toSchema(schema, required, ctx);
|
|
1081
|
+
return id;
|
|
1082
|
+
}
|
|
1083
|
+
return registered;
|
|
1084
|
+
}
|
|
1085
|
+
function parameterToField(v, ctx) {
|
|
1086
|
+
return {
|
|
1087
|
+
name: v.name,
|
|
1088
|
+
...toSchema(v.schema ?? {
|
|
1089
|
+
type: 'string'
|
|
1090
|
+
}, v.required ?? false, ctx)
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
function toReference(schema, required, ctx) {
|
|
1094
|
+
return {
|
|
1095
|
+
type: 'ref',
|
|
1096
|
+
isRequired: required,
|
|
1097
|
+
schema: getIdFromSchema(schema, false, ctx)
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
function toSchema(schema, required, ctx) {
|
|
1101
|
+
if (schema.type === 'array') {
|
|
1102
|
+
return {
|
|
1103
|
+
type: 'array',
|
|
1104
|
+
description: schema.description ?? schema.title,
|
|
1105
|
+
isRequired: required,
|
|
1106
|
+
items: getIdFromSchema(schema.items, false, ctx)
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
if (schema.type === 'object' || schema.properties !== undefined || schema.allOf !== undefined) {
|
|
1110
|
+
const properties = {};
|
|
1111
|
+
Object.entries(schema.properties ?? {}).forEach(([key, prop])=>{
|
|
1112
|
+
properties[key] = toReference(prop, schema.required?.includes(key) ?? false, ctx);
|
|
1113
|
+
});
|
|
1114
|
+
schema.allOf?.forEach((c)=>{
|
|
1115
|
+
const field = toSchema(c, true, ctx);
|
|
1116
|
+
if (field.type === 'object') Object.assign(properties, field.properties);
|
|
1117
|
+
});
|
|
1118
|
+
const additional = schema.additionalProperties;
|
|
1119
|
+
let additionalProperties;
|
|
1120
|
+
if (additional && typeof additional === 'object') {
|
|
1121
|
+
if ((!additional.type || additional.type.length === 0) && !additional.anyOf && !additional.allOf && !additional.oneOf) {
|
|
1122
|
+
additionalProperties = true;
|
|
1123
|
+
} else {
|
|
1124
|
+
additionalProperties = getIdFromSchema(additional, false, ctx);
|
|
1125
|
+
}
|
|
1126
|
+
} else {
|
|
1127
|
+
additionalProperties = additional;
|
|
1128
|
+
}
|
|
1129
|
+
return {
|
|
1130
|
+
type: 'object',
|
|
1131
|
+
isRequired: required,
|
|
1132
|
+
description: schema.description ?? schema.title,
|
|
1133
|
+
properties,
|
|
1134
|
+
additionalProperties
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
if (schema.type === undefined) {
|
|
1138
|
+
const combine = schema.anyOf ?? schema.oneOf;
|
|
1139
|
+
if (combine) {
|
|
1140
|
+
return {
|
|
1141
|
+
type: 'switcher',
|
|
1142
|
+
description: schema.description ?? schema.title,
|
|
1143
|
+
items: Object.fromEntries(combine.map((item, idx)=>{
|
|
1144
|
+
return [
|
|
1145
|
+
item.title ?? item.type ?? `Item ${idx.toString()}`,
|
|
1146
|
+
toReference(item, true, ctx)
|
|
1147
|
+
];
|
|
1148
|
+
})),
|
|
1149
|
+
isRequired: required
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
return {
|
|
1153
|
+
type: 'null',
|
|
1154
|
+
isRequired: false
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
if (ctx.allowFile && schema.type === 'string' && schema.format === 'binary') {
|
|
1158
|
+
return {
|
|
1159
|
+
type: 'file',
|
|
1160
|
+
isRequired: required,
|
|
1161
|
+
description: schema.description ?? schema.title
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
if (Array.isArray(schema.type)) {
|
|
1165
|
+
const items = {};
|
|
1166
|
+
for (const type of schema.type){
|
|
1167
|
+
if (type === 'array') {
|
|
1168
|
+
items[type] = {
|
|
1169
|
+
type,
|
|
1170
|
+
items: 'items' in schema && schema.items ? toSchema(schema.items, false, ctx) : toSchema({}, required, ctx),
|
|
1171
|
+
isRequired: required
|
|
1172
|
+
};
|
|
1173
|
+
} else {
|
|
1174
|
+
items[type] = toSchema({
|
|
1175
|
+
...schema,
|
|
1176
|
+
type
|
|
1177
|
+
}, required, ctx);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
return {
|
|
1181
|
+
type: 'switcher',
|
|
1182
|
+
description: schema.description ?? schema.title,
|
|
1183
|
+
items,
|
|
1184
|
+
isRequired: required
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
return {
|
|
1188
|
+
type: schema.type === 'integer' ? 'number' : schema.type,
|
|
1189
|
+
defaultValue: schema.example ?? '',
|
|
1190
|
+
isRequired: required,
|
|
1191
|
+
description: schema.description ?? schema.title
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
1195
|
function createRenders(shikiOptions) {
|
|
1196
1196
|
return {
|
|
1197
1197
|
Root: (props)=>/*#__PURE__*/ jsx(Root, {
|
|
@@ -1200,7 +1200,12 @@ function createRenders(shikiOptions) {
|
|
|
1200
1200
|
children: props.children
|
|
1201
1201
|
}),
|
|
1202
1202
|
API,
|
|
1203
|
-
APIInfo,
|
|
1203
|
+
APIInfo: ({ children, head })=>/*#__PURE__*/ jsxs(APIInfo, {
|
|
1204
|
+
children: [
|
|
1205
|
+
head,
|
|
1206
|
+
children
|
|
1207
|
+
]
|
|
1208
|
+
}),
|
|
1204
1209
|
APIExample: APIExample$1,
|
|
1205
1210
|
Responses: Tabs,
|
|
1206
1211
|
Response: Tab,
|
|
@@ -1232,7 +1237,7 @@ function createRenders(shikiOptions) {
|
|
|
1232
1237
|
options: shikiOptions
|
|
1233
1238
|
})
|
|
1234
1239
|
}),
|
|
1235
|
-
APIPlayground
|
|
1240
|
+
APIPlayground: Playground
|
|
1236
1241
|
};
|
|
1237
1242
|
}
|
|
1238
1243
|
|
|
@@ -1258,7 +1263,8 @@ const cache = new Map();
|
|
|
1258
1263
|
});
|
|
1259
1264
|
const processed = {
|
|
1260
1265
|
document: dereferenced,
|
|
1261
|
-
dereferenceMap
|
|
1266
|
+
dereferenceMap,
|
|
1267
|
+
downloaded: loaded.specification
|
|
1262
1268
|
};
|
|
1263
1269
|
if (!disableCache && typeof document === 'string') {
|
|
1264
1270
|
cache.set(document, processed);
|
|
@@ -1316,7 +1322,8 @@ async function APIPage(props) {
|
|
|
1316
1322
|
]
|
|
1317
1323
|
});
|
|
1318
1324
|
}
|
|
1319
|
-
async function getContext(
|
|
1325
|
+
async function getContext(schema, options = {}) {
|
|
1326
|
+
const document = schema.document;
|
|
1320
1327
|
const servers = document.servers && document.servers.length > 0 ? document.servers : [
|
|
1321
1328
|
{
|
|
1322
1329
|
url: 'https://example.com'
|
|
@@ -1324,8 +1331,7 @@ async function getContext({ document, dereferenceMap }, options = {}) {
|
|
|
1324
1331
|
];
|
|
1325
1332
|
const server = servers[0];
|
|
1326
1333
|
return {
|
|
1327
|
-
|
|
1328
|
-
dereferenceMap,
|
|
1334
|
+
schema,
|
|
1329
1335
|
proxyUrl: options.proxyUrl,
|
|
1330
1336
|
showResponseSchema: options.showResponseSchema,
|
|
1331
1337
|
renderer: {
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useContext, createContext, useState, useRef, useEffect, useMemo } from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { cn } from 'fumadocs-ui/components/api';
|
|
5
|
+
import dynamic from 'next/dynamic';
|
|
6
|
+
|
|
7
|
+
const ApiContext = /*#__PURE__*/ createContext(undefined);
|
|
8
|
+
const ServerSelectContext = /*#__PURE__*/ createContext(undefined);
|
|
9
|
+
function useApiContext() {
|
|
10
|
+
const ctx = useContext(ApiContext);
|
|
11
|
+
if (!ctx) throw new Error('Component must be used under <ApiProvider />');
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
function useServerSelectContext() {
|
|
15
|
+
const ctx = useContext(ServerSelectContext);
|
|
16
|
+
if (!ctx) throw new Error('Component must be used under <ApiProvider />');
|
|
17
|
+
return ctx;
|
|
18
|
+
}
|
|
19
|
+
function ApiProvider({ defaultBaseUrl, children, ...props }) {
|
|
20
|
+
const [server, setServer] = useState(()=>{
|
|
21
|
+
const defaultItem = defaultBaseUrl ? props.servers.find((item)=>item.url === defaultBaseUrl) : undefined;
|
|
22
|
+
return defaultItem ? {
|
|
23
|
+
url: defaultItem.url,
|
|
24
|
+
variables: getDefaultValues(defaultItem)
|
|
25
|
+
} : null;
|
|
26
|
+
});
|
|
27
|
+
const serverRef = useRef(server);
|
|
28
|
+
serverRef.current = server;
|
|
29
|
+
useEffect(()=>{
|
|
30
|
+
const cached = localStorage.getItem('apiBaseUrl');
|
|
31
|
+
if (!cached) return;
|
|
32
|
+
try {
|
|
33
|
+
const obj = JSON.parse(cached);
|
|
34
|
+
if (!obj || typeof obj !== 'object') return;
|
|
35
|
+
setServer(obj);
|
|
36
|
+
} catch {
|
|
37
|
+
// ignore
|
|
38
|
+
}
|
|
39
|
+
}, []);
|
|
40
|
+
return /*#__PURE__*/ jsx(ApiContext.Provider, {
|
|
41
|
+
value: useMemo(()=>({
|
|
42
|
+
...props,
|
|
43
|
+
serverRef
|
|
44
|
+
}), [
|
|
45
|
+
props
|
|
46
|
+
]),
|
|
47
|
+
children: /*#__PURE__*/ jsx(ServerSelectContext.Provider, {
|
|
48
|
+
value: useMemo(()=>({
|
|
49
|
+
server,
|
|
50
|
+
setServerVariables (variables) {
|
|
51
|
+
setServer((prev)=>{
|
|
52
|
+
if (!prev) return null;
|
|
53
|
+
const updated = {
|
|
54
|
+
...prev,
|
|
55
|
+
variables
|
|
56
|
+
};
|
|
57
|
+
localStorage.setItem('apiBaseUrl', JSON.stringify(updated));
|
|
58
|
+
return updated;
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
setServer (value) {
|
|
62
|
+
const obj = props.servers.find((item)=>item.url === value);
|
|
63
|
+
if (!obj) return;
|
|
64
|
+
const result = {
|
|
65
|
+
url: value,
|
|
66
|
+
variables: getDefaultValues(obj)
|
|
67
|
+
};
|
|
68
|
+
localStorage.setItem('apiBaseUrl', JSON.stringify(result));
|
|
69
|
+
setServer(result);
|
|
70
|
+
}
|
|
71
|
+
}), [
|
|
72
|
+
server,
|
|
73
|
+
props.servers
|
|
74
|
+
]),
|
|
75
|
+
children: children
|
|
76
|
+
})
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function getDefaultValues(server) {
|
|
80
|
+
return Object.fromEntries(Object.entries(server.variables ?? {}).map(([k, v])=>[
|
|
81
|
+
k,
|
|
82
|
+
v.default
|
|
83
|
+
]));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const SchemaContext = /*#__PURE__*/ createContext(undefined);
|
|
87
|
+
function useSchemaContext() {
|
|
88
|
+
const ctx = useContext(SchemaContext);
|
|
89
|
+
if (!ctx) throw new Error('Missing provider');
|
|
90
|
+
return ctx;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const APIPlayground = dynamic(()=>import('./index-client-CehDtJk-.js').then(function (n) { return n.i; }).then((mod)=>mod.APIPlayground));
|
|
94
|
+
function Root({ children, baseUrl, className, shikiOptions, servers, ...props }) {
|
|
95
|
+
return /*#__PURE__*/ jsx("div", {
|
|
96
|
+
className: cn('flex flex-col gap-24 text-sm text-fd-muted-foreground', className),
|
|
97
|
+
...props,
|
|
98
|
+
children: /*#__PURE__*/ jsx(ApiProvider, {
|
|
99
|
+
servers: servers,
|
|
100
|
+
shikiOptions: shikiOptions,
|
|
101
|
+
defaultBaseUrl: baseUrl,
|
|
102
|
+
children: children
|
|
103
|
+
})
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export { APIPlayground as A, Root as R, SchemaContext as S, useApiContext as a, useServerSelectContext as b, useSchemaContext as u };
|