fumadocs-openapi 10.3.10 → 10.3.12

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.
@@ -1,4 +1,6 @@
1
1
  @source inline("!isDefined");
2
+ @source inline("!last");
3
+ @source inline("*:data-[collapsible=true]:order-last");
2
4
  @source inline("*:min-w-0");
3
5
  @source inline("--fd-docs-row-1");
4
6
  @source inline("--initial-height");
@@ -25,7 +27,6 @@
25
27
  @source inline("@scalar/api-client-react");
26
28
  @source inline("@see");
27
29
  @source inline("@typescript-eslint/no-explicit-any");
28
- @source inline("[&_svg]:size-3.5");
29
30
  @source inline("a");
30
31
  @source inline("absolute");
31
32
  @source inline("access");
@@ -99,6 +100,7 @@
99
100
  @source inline("border-fd-primary/20");
100
101
  @source inline("border-t");
101
102
  @source inline("border-x");
103
+ @source inline("border-y");
102
104
  @source inline("both");
103
105
  @source inline("but");
104
106
  @source inline("button");
@@ -123,6 +125,7 @@
123
125
  @source inline("client");
124
126
  @source inline("client-side");
125
127
  @source inline("clientCredentials");
128
+ @source inline("clientHeight");
126
129
  @source inline("clientId");
127
130
  @source inline("clientSecret");
128
131
  @source inline("client_credentials");
@@ -158,6 +161,7 @@
158
161
  @source inline("ctx");
159
162
  @source inline("current");
160
163
  @source inline("currentId");
164
+ @source inline("currentRef");
161
165
  @source inline("currentValue");
162
166
  @source inline("customisation");
163
167
  @source inline("cva");
@@ -177,6 +181,8 @@
177
181
  @source inline("data-[state=open]:animate-fd-fade-in");
178
182
  @source inline("data-[state=open]:rounded-b-none");
179
183
  @source inline("data-[state=open]:text-fd-accent-foreground");
184
+ @source inline("data-collapsible");
185
+ @source inline("data-placeholder:text-fd-muted-foreground");
180
186
  @source inline("dataEngine");
181
187
  @source inline("declare");
182
188
  @source inline("default");
@@ -187,6 +193,7 @@
187
193
  @source inline("defaultSamples");
188
194
  @source inline("defaultValue");
189
195
  @source inline("defaultValues");
196
+ @source inline("deferredValue");
190
197
  @source inline("definitions");
191
198
  @source inline("deprecated");
192
199
  @source inline("depth");
@@ -252,6 +259,7 @@
252
259
  @source inline("file");
253
260
  @source inline("filePath");
254
261
  @source inline("files");
262
+ @source inline("filtered");
255
263
  @source inline("find");
256
264
  @source inline("fine");
257
265
  @source inline("first");
@@ -268,6 +276,8 @@
268
276
  @source inline("focus-visible:outline-none");
269
277
  @source inline("focus-visible:ring-1");
270
278
  @source inline("focus-visible:ring-fd-ring");
279
+ @source inline("focus-within:ring-2");
280
+ @source inline("focus-within:ring-fd-ring");
271
281
  @source inline("focus:bg-fd-accent");
272
282
  @source inline("focus:outline-none");
273
283
  @source inline("focus:ring");
@@ -306,12 +316,12 @@
306
316
  @source inline("gap-x-6");
307
317
  @source inline("gap-y-4");
308
318
  @source inline("generate");
319
+ @source inline("generateDefault");
309
320
  @source inline("generated");
310
321
  @source inline("generated/defined");
311
322
  @source inline("generator");
312
323
  @source inline("generators");
313
324
  @source inline("getAPIPageProps");
314
- @source inline("getDefaultValue");
315
325
  @source inline("getSchema");
316
326
  @source inline("getStatusInfo");
317
327
  @source inline("getTypescriptSchema");
@@ -339,6 +349,7 @@
339
349
  @source inline("headers");
340
350
  @source inline("headingLevel");
341
351
  @source inline("hidden");
352
+ @source inline("hiddenProperties");
342
353
  @source inline("hook");
343
354
  @source inline("hover:bg-fd-accent");
344
355
  @source inline("hover:text-fd-accent-foreground");
@@ -381,6 +392,7 @@
381
392
  @source inline("isDefined");
382
393
  @source inline("isDuplicated");
383
394
  @source inline("isDynamic");
395
+ @source inline("isLazy");
384
396
  @source inline("isLoading");
385
397
  @source inline("isMediaTypeSupported");
386
398
  @source inline("isNumber");
@@ -426,7 +438,6 @@
426
438
  @source inline("lucide-react");
427
439
  @source inline("map");
428
440
  @source inline("mapInputs");
429
- @source inline("match");
430
441
  @source inline("max");
431
442
  @source inline("max-age");
432
443
  @source inline("max-h-[460px]");
@@ -453,6 +464,7 @@
453
464
  @source inline("module");
454
465
  @source inline("moon");
455
466
  @source inline("mounted");
467
+ @source inline("ms-2");
456
468
  @source inline("ms-auto");
457
469
  @source inline("mt-10");
458
470
  @source inline("mt-2");
@@ -467,6 +479,7 @@
467
479
  @source inline("my-4");
468
480
  @source inline("name");
469
481
  @source inline("name!");
482
+ @source inline("namespace");
470
483
  @source inline("necessary");
471
484
  @source inline("need");
472
485
  @source inline("nested");
@@ -492,7 +505,6 @@
492
505
  @source inline("onChange");
493
506
  @source inline("onClick");
494
507
  @source inline("onCopy");
495
- @source inline("onDelete");
496
508
  @source inline("onKeyDown");
497
509
  @source inline("onOpenChange");
498
510
  @source inline("onSubmit");
@@ -512,6 +524,7 @@
512
524
  @source inline("options");
513
525
  @source inline("or");
514
526
  @source inline("orange");
527
+ @source inline("order-last");
515
528
  @source inline("origin");
516
529
  @source inline("original");
517
530
  @source inline("other");
@@ -567,12 +580,14 @@
567
580
  @source inline("placeholder");
568
581
  @source inline("placeholder:text-fd-muted-foreground");
569
582
  @source inline("playground");
583
+ @source inline("playground/index.tsx");
570
584
  @source inline("playgroundEnabled");
571
585
  @source inline("playgrounds");
572
586
  @source inline("plugins");
573
587
  @source inline("position");
574
588
  @source inline("pre");
575
589
  @source inline("prefix");
590
+ @source inline("preprocessed");
576
591
  @source inline("prev");
577
592
  @source inline("prevent");
578
593
  @source inline("primary");
@@ -586,6 +601,7 @@
586
601
  @source inline("props");
587
602
  @source inline("prose-no-margin");
588
603
  @source inline("proxyUrl");
604
+ @source inline("ps-2");
589
605
  @source inline("ps-4.5");
590
606
  @source inline("ps-6");
591
607
  @source inline("pt-1");
@@ -603,6 +619,7 @@
603
619
  @source inline("py-2");
604
620
  @source inline("py-4");
605
621
  @source inline("query");
622
+ @source inline("quiet");
606
623
  @source inline("race");
607
624
  @source inline("range");
608
625
  @source inline("raw");
@@ -612,6 +629,7 @@
612
629
  @source inline("react/jsx-runtime");
613
630
  @source inline("read");
614
631
  @source inline("readOnly");
632
+ @source inline("recover");
615
633
  @source inline("red");
616
634
  @source inline("redirect_uri");
617
635
  @source inline("ref");
@@ -653,6 +671,7 @@
653
671
  @source inline("resType");
654
672
  @source inline("reset");
655
673
  @source inline("resize-none");
674
+ @source inline("resolution");
656
675
  @source inline("resolveMediaAdapter");
657
676
  @source inline("resolveRequestData");
658
677
  @source inline("resolvedTheme");
@@ -679,6 +698,7 @@
679
698
  @source inline("samples");
680
699
  @source inline("satisfies");
681
700
  @source inline("schema");
701
+ @source inline("schemaPropKeys");
682
702
  @source inline("schemaToString");
683
703
  @source inline("schemaUI");
684
704
  @source inline("schemas");
@@ -724,6 +744,7 @@
724
744
  @source inline("setNextName");
725
745
  @source inline("setOpen");
726
746
  @source inline("setPath");
747
+ @source inline("setSearch");
727
748
  @source inline("setSecurityId");
728
749
  @source inline("setServer");
729
750
  @source inline("setServerVariables");
@@ -790,6 +811,7 @@
790
811
  @source inline("such");
791
812
  @source inline("summary");
792
813
  @source inline("supported");
814
+ @source inline("swallow");
793
815
  @source inline("switch");
794
816
  @source inline("tab");
795
817
  @source inline("tabs");
@@ -882,11 +904,12 @@
882
904
  @source inline("useFieldValue");
883
905
  @source inline("useForm");
884
906
  @source inline("useMemo");
907
+ @source inline("useNamespace");
885
908
  @source inline("useObject");
886
909
  @source inline("useQuery");
887
910
  @source inline("useRef");
888
- @source inline("useResolvedSchema");
889
911
  @source inline("useSchemaScope");
912
+ @source inline("useSchemaUtils");
890
913
  @source inline("useServerContext");
891
914
  @source inline("useServerSelectContext");
892
915
  @source inline("useState");
@@ -933,6 +956,7 @@
933
956
  @source inline("writeOnly");
934
957
  @source inline("x-codeSamples");
935
958
  @source inline("x-exclusiveCodeSample");
959
+ @source inline("x-playground-lazy");
936
960
  @source inline("x-selectedCodeSample");
937
961
  @source inline("yellow");
938
962
  @source inline("you");
@@ -8,7 +8,7 @@ import { cn } from "../utils/cn.js";
8
8
  import { MethodLabel } from "../ui/components/method-label.js";
9
9
  import { useQuery } from "../utils/use-query.js";
10
10
  import { encodeRequestData } from "../requests/media/encode.js";
11
- import { SchemaProvider, useResolvedSchema } from "./schema.js";
11
+ import { SchemaProvider, useSchemaUtils } from "./schema.js";
12
12
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/components/select.js";
13
13
  import { labelVariants } from "../ui/components/input.js";
14
14
  import ServerSelect from "./components/server-select.js";
@@ -16,7 +16,7 @@ import { useExampleRequests } from "../ui/operation/usage-tabs/client.js";
16
16
  import { FieldInput, FieldSet, JsonInput, ObjectInput } from "./components/inputs.js";
17
17
  import { Fragment, lazy, useEffect, useMemo, useRef, useState } from "react";
18
18
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
19
- import { ChevronDown, LoaderCircle, X } from "lucide-react";
19
+ import { ChevronDown, LoaderCircle } from "lucide-react";
20
20
  import { DynamicCodeBlock } from "fumadocs-ui/components/dynamic-codeblock.core";
21
21
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "fumadocs-ui/components/ui/collapsible";
22
22
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
@@ -121,6 +121,10 @@ function PlaygroundClient({ route, method = "GET", securities, parameters = [],
121
121
  })
122
122
  ]
123
123
  }),
124
+ testQuery.data ? /* @__PURE__ */ jsx(ResultDisplay, {
125
+ data: testQuery.data,
126
+ reset: testQuery.reset
127
+ }) : null,
124
128
  securities.length > 0 && /* @__PURE__ */ jsx(SecurityTabs, {
125
129
  securities,
126
130
  securityId,
@@ -130,11 +134,7 @@ function PlaygroundClient({ route, method = "GET", securities, parameters = [],
130
134
  /* @__PURE__ */ jsx(FormBody, {
131
135
  body,
132
136
  parameters
133
- }),
134
- testQuery.data ? /* @__PURE__ */ jsx(ResultDisplay, {
135
- data: testQuery.data,
136
- reset: testQuery.reset
137
- }) : null
137
+ })
138
138
  ]
139
139
  })
140
140
  })
@@ -206,7 +206,8 @@ function FormBody({ parameters = [], body }) {
206
206
  return /* @__PURE__ */ jsx(FieldSet, {
207
207
  name: field.name,
208
208
  fieldName,
209
- field: schema
209
+ field: schema,
210
+ isRequired: field.required
210
211
  }, stringifyFieldKey(fieldName));
211
212
  })
212
213
  }, type);
@@ -217,11 +218,12 @@ function FormBody({ parameters = [], body }) {
217
218
  })] });
218
219
  }
219
220
  function BodyInput({ field: _field }) {
220
- const field = useResolvedSchema(_field);
221
+ const field = useSchemaUtils().resolve(_field);
221
222
  const [isJson, setIsJson] = useState(false);
222
223
  if (field.format === "binary") return /* @__PURE__ */ jsx(FieldSet, {
223
224
  field,
224
- fieldName: ["body"]
225
+ fieldName: ["body"],
226
+ isRequired: true
225
227
  });
226
228
  if (isJson) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
227
229
  className: cn(buttonVariants({
@@ -237,6 +239,7 @@ function BodyInput({ field: _field }) {
237
239
  field,
238
240
  fieldName: ["body"],
239
241
  collapsible: false,
242
+ isRequired: true,
240
243
  name: /* @__PURE__ */ jsx("button", {
241
244
  type: "button",
242
245
  className: cn(buttonVariants({
@@ -405,19 +408,21 @@ function DefaultResultDisplay({ data, reset }) {
405
408
  const statusInfo = useMemo(() => getStatusInfo(data.status), [data.status]);
406
409
  const { shikiOptions } = useApiContext();
407
410
  return /* @__PURE__ */ jsxs("div", {
408
- className: "flex flex-col gap-3 p-3",
411
+ className: "flex flex-col gap-3 mt-2 px-3 py-2 border-y bg-fd-secondary text-fd-secondary-foreground",
409
412
  children: [
410
413
  /* @__PURE__ */ jsxs("div", {
411
414
  className: "flex justify-between items-center",
412
415
  children: [/* @__PURE__ */ jsxs("div", {
413
- className: "inline-flex items-center gap-1.5 text-sm font-medium text-fd-foreground",
416
+ className: "inline-flex items-center gap-1.5 text-sm font-medium",
414
417
  children: [/* @__PURE__ */ jsx(statusInfo.icon, { className: cn("size-4", statusInfo.color) }), statusInfo.description]
415
418
  }), /* @__PURE__ */ jsx("button", {
416
419
  type: "button",
417
- className: cn(buttonVariants({ size: "icon-xs" }), "p-0 text-fd-muted-foreground hover:text-fd-accent-foreground [&_svg]:size-3.5"),
420
+ className: cn(buttonVariants({
421
+ size: "sm",
422
+ variant: "outline"
423
+ })),
418
424
  onClick: () => reset(),
419
- "aria-label": "Dismiss response",
420
- children: /* @__PURE__ */ jsx(X, {})
425
+ children: "Close"
421
426
  })]
422
427
  }),
423
428
  /* @__PURE__ */ jsx("p", {
@@ -1,11 +1,10 @@
1
1
  'use client';
2
2
 
3
3
  import { cn } from "../../utils/cn.js";
4
- import { getDefaultValue } from "../get-default-values.js";
5
- import { anyFields, useFieldInfo, useResolvedSchema, useSchemaScope } from "../schema.js";
4
+ import { FormatFlags } from "../../utils/schema-to-string.js";
5
+ import { anyFields, useFieldInfo, useSchemaScope, useSchemaUtils } from "../schema.js";
6
6
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/components/select.js";
7
7
  import { Input, labelVariants } from "../../ui/components/input.js";
8
- import { FormatFlags, schemaToString } from "../../utils/schema-to-string.js";
9
8
  import { useState } from "react";
10
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
10
  import { ChevronRight, Plus, Trash2, X } from "lucide-react";
@@ -24,65 +23,84 @@ function FieldLabelType(props) {
24
23
  });
25
24
  }
26
25
  function ObjectInput({ field: _field, fieldName, ...props }) {
27
- const field = useResolvedSchema(_field);
26
+ const { resolve, generateDefault } = useSchemaUtils();
27
+ const field = resolve(_field);
28
+ const schemaPropKeys = field.properties ? Object.keys(field.properties) : [];
29
+ const { patternProperties = {}, additionalProperties, "x-playground-lazy": isLazy = schemaPropKeys.length > 100 } = field;
30
+ const isDynamic = Object.keys(patternProperties).length > 0 || additionalProperties;
28
31
  const [nextName, setNextName] = useState("");
29
- const { properties, onAppend, onDelete } = useObject(fieldName, {
30
- defaultValue: () => getDefaultValue(field),
32
+ const { properties, onAppend, onDelete, _objectKeys } = useObject(fieldName, {
33
+ lazy: isLazy,
34
+ defaultValue: () => generateDefault(field),
31
35
  properties: field.properties ?? {},
32
- fallback: field.additionalProperties,
33
- patternProperties: field.patternProperties
36
+ fallback: additionalProperties,
37
+ patternProperties
34
38
  });
35
- const isDynamic = field.patternProperties ?? field.additionalProperties;
39
+ const hiddenProperties = isLazy ? schemaPropKeys.filter((key) => !_objectKeys.includes(key)) : [];
36
40
  return /* @__PURE__ */ jsxs("div", {
37
41
  ...props,
38
- className: cn("grid grid-cols-1 gap-4 @md:grid-cols-2", props.className),
39
- children: [properties.map((child) => {
40
- let toolbar = null;
41
- if (child.kind === "pattern" || child.kind === "fallback") toolbar = /* @__PURE__ */ jsx("button", {
42
- type: "button",
43
- "aria-label": "Remove Item",
44
- className: cn(buttonVariants({
45
- color: "outline",
46
- size: "icon-xs"
47
- })),
48
- onClick: () => {
49
- onDelete(child.key);
50
- },
51
- children: /* @__PURE__ */ jsx(Trash2, {})
52
- });
53
- return /* @__PURE__ */ jsx(FieldSet, {
54
- name: child.key,
55
- field: child.info,
56
- fieldName: child.field,
57
- isRequired: field.required?.includes(child.key),
58
- toolbar
59
- }, child.key);
60
- }), isDynamic && /* @__PURE__ */ jsxs("div", {
61
- className: "flex gap-2 col-span-full",
62
- children: [/* @__PURE__ */ jsx(Input, {
63
- value: nextName,
64
- placeholder: "Enter Property Name",
65
- onChange: (e) => setNextName(e.target.value),
66
- onKeyDown: (e) => {
67
- if (e.key === "Enter") {
68
- setNextName("");
69
- onAppend(nextName);
70
- e.preventDefault();
42
+ className: cn("grid grid-cols-1 gap-4 @md:grid-cols-2 *:data-[collapsible=true]:order-last", props.className),
43
+ children: [
44
+ isLazy && hiddenProperties.length > 0 && /* @__PURE__ */ jsxs(Select, {
45
+ value: "",
46
+ onValueChange: onAppend,
47
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
48
+ className: "col-span-full",
49
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Show Property" })
50
+ }), /* @__PURE__ */ jsx(SelectContent, { children: hiddenProperties.map((key) => /* @__PURE__ */ jsx(SelectItem, {
51
+ value: key,
52
+ children: key
53
+ }, key)) })]
54
+ }),
55
+ properties.map((child) => {
56
+ let toolbar = null;
57
+ if (child.kind === "pattern" || child.kind === "fallback") toolbar = /* @__PURE__ */ jsx("button", {
58
+ type: "button",
59
+ "aria-label": "Remove Item",
60
+ className: cn(buttonVariants({
61
+ color: "outline",
62
+ size: "icon-xs"
63
+ })),
64
+ onClick: () => {
65
+ onDelete(child.key);
66
+ },
67
+ children: /* @__PURE__ */ jsx(Trash2, {})
68
+ });
69
+ return /* @__PURE__ */ jsx(FieldSet, {
70
+ name: child.key,
71
+ field: child.info,
72
+ fieldName: child.field,
73
+ isRequired: field.required?.includes(child.key),
74
+ toolbar
75
+ }, child.key);
76
+ }),
77
+ isDynamic && /* @__PURE__ */ jsxs("div", {
78
+ className: "flex gap-2 order-last col-span-full",
79
+ children: [/* @__PURE__ */ jsx(Input, {
80
+ value: nextName,
81
+ placeholder: "Enter Property Name",
82
+ onChange: (e) => setNextName(e.target.value),
83
+ onKeyDown: (e) => {
84
+ if (e.key === "Enter") {
85
+ setNextName("");
86
+ onAppend(nextName);
87
+ e.preventDefault();
88
+ }
71
89
  }
72
- }
73
- }), /* @__PURE__ */ jsx("button", {
74
- type: "button",
75
- className: cn(buttonVariants({
76
- color: "secondary",
77
- size: "sm"
78
- }), "px-4"),
79
- onClick: () => {
80
- onAppend(nextName);
81
- setNextName("");
82
- },
83
- children: "New"
84
- })]
85
- })]
90
+ }), /* @__PURE__ */ jsx("button", {
91
+ type: "button",
92
+ className: cn(buttonVariants({
93
+ color: "secondary",
94
+ size: "sm"
95
+ }), "px-4"),
96
+ onClick: () => {
97
+ onAppend(nextName);
98
+ setNextName("");
99
+ },
100
+ children: "New"
101
+ })]
102
+ })
103
+ ]
86
104
  });
87
105
  }
88
106
  function JsonInput({ fieldName }) {
@@ -142,12 +160,12 @@ function FieldInput({ field, fieldName, isRequired, ...props }) {
142
160
  if (field.enum && field.enum.length > 0) {
143
161
  const idx = field.enum.indexOf(value);
144
162
  return /* @__PURE__ */ jsxs(Select, {
145
- value: String(idx),
163
+ value: idx === -1 && isRequired ? "" : String(idx),
146
164
  onValueChange: (v) => setValue(field.enum[Number(v)]),
147
165
  children: [/* @__PURE__ */ jsx(SelectTrigger, {
148
166
  id,
149
167
  ...props,
150
- children: /* @__PURE__ */ jsx(SelectValue, {})
168
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select" })
151
169
  }), /* @__PURE__ */ jsxs(SelectContent, { children: [field.enum.map((item, i) => /* @__PURE__ */ jsx(SelectItem, {
152
170
  value: String(i),
153
171
  children: typeof item === "string" ? item : JSON.stringify(item, null, 2)
@@ -194,9 +212,10 @@ function FieldInput({ field, fieldName, isRequired, ...props }) {
194
212
  }
195
213
  function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth = 0, slotType, collapsible = true, ...props }) {
196
214
  const { readOnly, writeOnly } = useSchemaScope();
197
- const field = useResolvedSchema(_field);
215
+ const { resolve, generateDefault, schemaToString } = useSchemaUtils();
216
+ const field = resolve(_field);
198
217
  const [show, setShow] = useState(!collapsible);
199
- const { info, updateInfo } = useFieldInfo(fieldName, field);
218
+ const { info, updateInfo } = useFieldInfo(fieldName, field, depth);
200
219
  const id = stringifyFieldKey(fieldName);
201
220
  const dataEngine = useDataEngine();
202
221
  const [isDefined] = useFieldValue(fieldName, { compute(currentValue) {
@@ -212,7 +231,7 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
212
231
  type: "button",
213
232
  className: cn(labelVariants(), "inline-flex items-center gap-1 font-mono me-auto"),
214
233
  onClick: () => {
215
- dataEngine.init(fieldName, getDefaultValue(schema));
234
+ dataEngine.init(fieldName, generateDefault(schema));
216
235
  setShow((prev) => !prev);
217
236
  },
218
237
  children: [
@@ -253,6 +272,7 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
253
272
  field: union[info.oneOf],
254
273
  depth: depth + 1,
255
274
  slotType: showSelect ? false : slotType,
275
+ collapsible,
256
276
  toolbar: /* @__PURE__ */ jsxs(Fragment$1, { children: [showSelect && /* @__PURE__ */ jsx("select", {
257
277
  className: "text-xs font-mono",
258
278
  value: info.oneOf,
@@ -262,7 +282,7 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
262
282
  children: union.map((item, i) => /* @__PURE__ */ jsx("option", {
263
283
  value: i,
264
284
  className: "bg-fd-popover text-fd-popover-foreground",
265
- children: schemaToString(item, void 0, FormatFlags.UseAlias)
285
+ children: schemaToString(item, FormatFlags.UseAlias)
266
286
  }, i))
267
287
  }), toolbar] })
268
288
  });
@@ -278,6 +298,7 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
278
298
  ...field,
279
299
  type: info.selectedType
280
300
  },
301
+ collapsible,
281
302
  depth: depth + 1,
282
303
  slotType: showSelect ? false : slotType,
283
304
  toolbar: /* @__PURE__ */ jsxs(Fragment$1, { children: [showSelect && /* @__PURE__ */ jsx("select", {
@@ -298,6 +319,7 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
298
319
  const schema = info.intersection?.merged ?? field;
299
320
  return /* @__PURE__ */ jsxs("fieldset", {
300
321
  ...props,
322
+ "data-collapsible": collapsible,
301
323
  className: cn("flex flex-col gap-1.5 col-span-full @container", props.className),
302
324
  children: [/* @__PURE__ */ jsxs("div", {
303
325
  className: fieldLabelVariants(),
@@ -316,6 +338,7 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
316
338
  }
317
339
  if (field.type === "array") return /* @__PURE__ */ jsxs("fieldset", {
318
340
  ...props,
341
+ "data-collapsible": collapsible,
319
342
  className: cn("flex flex-col gap-1.5 col-span-full", props.className),
320
343
  children: [/* @__PURE__ */ jsxs("div", {
321
344
  className: fieldLabelVariants(),
@@ -352,7 +375,8 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
352
375
  }
353
376
  function ArrayInput({ fieldName, items: itemSchema, ...props }) {
354
377
  const name = fieldName.at(-1) ?? "";
355
- const { items, insertItem, removeItem } = useArray(fieldName, { defaultValue: [] });
378
+ const { generateDefault } = useSchemaUtils();
379
+ const { items, insertItem, removeItem } = useArray(fieldName);
356
380
  return /* @__PURE__ */ jsxs("div", {
357
381
  ...props,
358
382
  className: cn("flex flex-col gap-2", props.className),
@@ -387,7 +411,7 @@ function ArrayInput({ fieldName, items: itemSchema, ...props }) {
387
411
  size: "sm"
388
412
  })),
389
413
  onClick: () => {
390
- insertItem(getDefaultValue(itemSchema));
414
+ insertItem(generateDefault(itemSchema));
391
415
  },
392
416
  children: [/* @__PURE__ */ jsx(Plus, { className: "size-4" }), "New Item"]
393
417
  })]
@@ -21,6 +21,6 @@ declare function APIPlayground({
21
21
  path,
22
22
  method,
23
23
  ctx
24
- }: APIPlaygroundProps): Promise<string | number | bigint | boolean | Iterable<react.ReactNode> | react_jsx_runtime0.JSX.Element | null | undefined>;
24
+ }: APIPlaygroundProps): Promise<string | number | bigint | boolean | react_jsx_runtime0.JSX.Element | Iterable<react.ReactNode> | null | undefined>;
25
25
  //#endregion
26
26
  export { APIPlayground, APIPlaygroundProps, ParameterField, SecurityEntry };
@@ -40,7 +40,7 @@ function writeReferences(schema, ctx, stack = /* @__PURE__ */ new WeakMap()) {
40
40
  const out = stack.get(schema);
41
41
  const id = ctx.nextId();
42
42
  ctx.references[id] = out;
43
- return { $ref: id };
43
+ return { $ref: `#/${id}` };
44
44
  }
45
45
  const output = { ...schema };
46
46
  stack.set(schema, output);
@@ -1,4 +1,5 @@
1
1
  import "../utils/schema.js";
2
+ import "../utils/schema-to-string.js";
2
3
  import { ReactNode } from "react";
3
4
  import "react/jsx-runtime";
4
5
  import { Ajv2020 } from "ajv/dist/2020";
@@ -1,10 +1,11 @@
1
- import { getDefaultValue } from "./get-default-values.js";
2
1
  import { mergeAllOf } from "../utils/merge-schema.js";
2
+ import { schemaToString } from "../utils/schema-to-string.js";
3
3
  import { createContext, use, useMemo } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { Ajv2020 } from "ajv/dist/2020";
6
- import { useDataEngine, useFieldValue } from "@fumari/stf";
6
+ import { useDataEngine, useFieldValue, useNamespace } from "@fumari/stf";
7
7
  import { stringifyFieldKey } from "@fumari/stf/lib/utils";
8
+ import { sample } from "openapi-sampler";
8
9
 
9
10
  //#region src/playground/schema.tsx
10
11
  const SchemaContext = createContext(void 0);
@@ -51,33 +52,37 @@ function useSchemaScope() {
51
52
  * @param schema - The JSON Schema to generate initial values.
52
53
  * @param depth - The depth to avoid duplicated field name with same schema (e.g. nested `oneOf`).
53
54
  */
54
- function useFieldInfo(fieldName, schema) {
55
+ function useFieldInfo(fieldName, schema, depth = 0) {
55
56
  const { ajv } = use(SchemaContext);
56
57
  const engine = useDataEngine();
57
- const [info, setInfo] = useFieldValue([], { stf: engine.namespace(`field-info:${stringifyFieldKey(fieldName)}`, () => {
58
- const value = engine.get(fieldName);
59
- const out = { oneOf: -1 };
60
- const union = getUnion(schema);
61
- if (union) {
62
- const [members, field] = union;
63
- out.oneOf = members.findIndex((item) => ajv.validate(item, value));
64
- if (out.oneOf === -1) out.oneOf = 0;
65
- out.unionField = field;
58
+ const { generateDefault } = useSchemaUtils();
59
+ const [info, setInfo] = useFieldValue([], { stf: useNamespace({
60
+ namespace: `field-info:${depth}:${stringifyFieldKey(fieldName)}`,
61
+ initial() {
62
+ const value = engine.get(fieldName);
63
+ const out = { oneOf: -1 };
64
+ const union = getUnion(schema);
65
+ if (union) {
66
+ const [members, field] = union;
67
+ out.oneOf = members.findIndex((item) => ajv.validate(item, value));
68
+ if (out.oneOf === -1) out.oneOf = 0;
69
+ out.unionField = field;
70
+ }
71
+ if (Array.isArray(schema.type)) {
72
+ const types = schema.type;
73
+ out.selectedType = types.find((type) => {
74
+ return ajv.validate({
75
+ ...schema,
76
+ type
77
+ }, value);
78
+ }) ?? types[0];
79
+ }
80
+ if (schema.allOf) {
81
+ const merged = mergeAllOf(schema);
82
+ if (typeof merged !== "boolean") out.intersection = { merged };
83
+ }
84
+ return out;
66
85
  }
67
- if (Array.isArray(schema.type)) {
68
- const types = schema.type;
69
- out.selectedType = types.find((type) => {
70
- schema.type = type;
71
- const match = ajv.validate(schema, value);
72
- schema.type = types;
73
- return match;
74
- }) ?? types.at(0);
75
- }
76
- if (schema.allOf) {
77
- const merged = mergeAllOf(schema);
78
- if (typeof merged !== "boolean") out.intersection = { merged };
79
- }
80
- return out;
81
86
  }) });
82
87
  return {
83
88
  info,
@@ -94,20 +99,37 @@ function useFieldInfo(fieldName, schema) {
94
99
  ...schema,
95
100
  type: updated.selectedType
96
101
  };
97
- engine.update(fieldName, getDefaultValue(valueSchema));
102
+ engine.update(fieldName, generateDefault(valueSchema));
98
103
  }
99
104
  };
100
105
  }
101
- /**
102
- * Resolve `$ref` in the schema, **not recursive**.
103
- */
104
- function useResolvedSchema(schema) {
106
+ function useSchemaUtils() {
105
107
  const { references } = use(SchemaContext);
106
- return useMemo(() => {
108
+ function resolve(schema) {
107
109
  if (typeof schema === "boolean") return anyFields;
108
- if (schema.$ref) return fallbackAny(references[schema.$ref]);
110
+ let ref = schema.$ref;
111
+ if (ref) {
112
+ if (ref.startsWith("#/")) ref = ref.slice(2);
113
+ if (ref in references) return fallbackAny(references[ref]);
114
+ }
109
115
  return schema;
110
- }, [references, schema]);
116
+ }
117
+ return {
118
+ generateDefault(schema) {
119
+ return sample(schema, {
120
+ skipNonRequired: true,
121
+ skipReadOnly: true,
122
+ quiet: true
123
+ }, references);
124
+ },
125
+ resolve,
126
+ schemaToString(value, flags) {
127
+ return schemaToString(value, (s) => ({
128
+ dereferenced: resolve(s),
129
+ raw: s
130
+ }), flags);
131
+ }
132
+ };
111
133
  }
112
134
  function fallbackAny(schema) {
113
135
  return typeof schema === "boolean" ? anyFields : schema;
@@ -118,4 +140,4 @@ function getUnion(schema) {
118
140
  }
119
141
 
120
142
  //#endregion
121
- export { SchemaProvider, anyFields, useFieldInfo, useResolvedSchema, useSchemaScope };
143
+ export { SchemaProvider, anyFields, useFieldInfo, useSchemaScope, useSchemaUtils };
@@ -10,7 +10,7 @@ const SelectGroup = SelectPrimitive.Group;
10
10
  const SelectValue = SelectPrimitive.Value;
11
11
  const SelectTrigger = forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
12
12
  ref,
13
- className: cn("flex items-center w-full rounded-md border p-2 gap-2 text-start text-sm text-fd-secondary-foreground bg-fd-secondary hover:bg-fd-accent focus:outline-none focus:ring focus:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50", className),
13
+ className: cn("flex items-center w-full rounded-md border p-2 gap-2 text-start text-sm text-fd-secondary-foreground bg-fd-secondary hover:bg-fd-accent focus:outline-none focus:ring focus:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50 data-placeholder:text-fd-muted-foreground", className),
14
14
  ...props,
15
15
  children: [children, /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
16
16
  asChild: true,
package/dist/ui/full.js CHANGED
@@ -10,8 +10,8 @@ function createAPIPage(server, options = {}) {
10
10
  ...options,
11
11
  shiki: configDefault,
12
12
  generateTypeScriptSchema(method, statusCode, contentType, ctx) {
13
- const schema = method.responses?.[statusCode]?.content?.[contentType];
14
- if (!schema) return;
13
+ const schema = method.responses?.[statusCode]?.content?.[contentType].schema;
14
+ if (!schema || typeof schema !== "object") return;
15
15
  return getTypescriptSchema(schema, ctx);
16
16
  }
17
17
  });
@@ -4,8 +4,8 @@ import { MethodLabel } from "../components/method-label.js";
4
4
  import { encodeRequestData } from "../../requests/media/encode.js";
5
5
  import { AccordionContent, AccordionHeader, AccordionItem, AccordionTrigger, Accordions } from "../components/accordion.js";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
- import { Tabs, TabsContent, TabsList, TabsTrigger } from "fumadocs-ui/components/tabs";
8
7
  import { sample } from "openapi-sampler";
8
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "fumadocs-ui/components/tabs";
9
9
 
10
10
  //#region src/ui/operation/request-tabs.tsx
11
11
  function getExampleRequests(path, operation, ctx) {
@@ -1,8 +1,8 @@
1
1
  import { getPreferredType } from "../../utils/schema.js";
2
2
  import { AccordionContent, AccordionHeader, AccordionItem, AccordionTrigger, Accordions } from "../components/accordion.js";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
- import { Tab, Tabs } from "fumadocs-ui/components/tabs";
5
4
  import { sample } from "openapi-sampler";
5
+ import { Tab, Tabs } from "fumadocs-ui/components/tabs";
6
6
 
7
7
  //#region src/ui/operation/response-tabs.tsx
8
8
  function ResponseTabs({ operation, ctx }) {
@@ -2,9 +2,9 @@
2
2
 
3
3
  import { cn } from "../../utils/cn.js";
4
4
  import { Badge } from "../components/method-label.js";
5
- import { Fragment, createContext, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import { Fragment, Suspense, createContext, use, useCallback, useDeferredValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
6
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
- import { ChevronDown } from "lucide-react";
7
+ import { ChevronDown, FilterIcon } from "lucide-react";
8
8
  import { cva } from "class-variance-authority";
9
9
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "fumadocs-ui/components/ui/collapsible";
10
10
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
@@ -58,11 +58,7 @@ function SchemaUIProperty({ name, $type, variant = "default", overrides }) {
58
58
  $ref: $type
59
59
  });
60
60
  } else if (schema.type === "object" && schema.props.length > 0) {
61
- if (variant === "expand") return schema.props.map((prop) => /* @__PURE__ */ jsx(SchemaUIProperty, {
62
- name: prop.name,
63
- $type: prop.$type,
64
- overrides: { required: prop.required }
65
- }, prop.name));
61
+ if (variant === "expand") return /* @__PURE__ */ jsx(SearchProps, { props: schema.props });
66
62
  type = renderRef({
67
63
  pathName: name,
68
64
  $ref: $type
@@ -103,6 +99,30 @@ function SchemaUIProperty({ name, $type, variant = "default", overrides }) {
103
99
  children: child
104
100
  });
105
101
  }
102
+ function SearchProps({ props }) {
103
+ const [search, setSearch] = useState("");
104
+ const deferredValue = useDeferredValue(search);
105
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
106
+ className: "flex items-center border my-2 rounded-md bg-fd-secondary text-fd-secondary-foreground transition-colors shadow-sm focus-within:ring-2 focus-within:ring-fd-ring",
107
+ children: [/* @__PURE__ */ jsx(FilterIcon, { className: "text-fd-muted-foreground ms-2 size-3.5" }), /* @__PURE__ */ jsx("input", {
108
+ value: search,
109
+ onChange: (e) => setSearch(e.target.value),
110
+ placeholder: "Filter Properties",
111
+ className: "text-sm ps-2 py-2 flex-1 outline-none placeholder:text-fd-muted-foreground"
112
+ })]
113
+ }), /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(SearchPropsContent, {
114
+ search: deferredValue,
115
+ props
116
+ }) })] });
117
+ }
118
+ function SearchPropsContent({ search, props }) {
119
+ search = search.trim().toLowerCase();
120
+ return (search.length > 0 ? props.filter((prop) => prop.name.toLowerCase().includes(search)) : props).map((prop) => /* @__PURE__ */ jsx(SchemaUIProperty, {
121
+ name: prop.name,
122
+ $type: prop.$type,
123
+ overrides: { required: prop.required }
124
+ }, prop.name));
125
+ }
106
126
  function InfoTag({ tag }) {
107
127
  const ref = useRef(null);
108
128
  const [isTruncated, setTruncated] = useState(false);
@@ -138,12 +158,15 @@ function InfoTag({ tag }) {
138
158
  function SchemaUIPopover({ initialPath }) {
139
159
  const [path, setPath] = useState(initialPath);
140
160
  const ref = useRef(null);
141
- const last = path.findLast((item) => item.$ref !== void 0);
142
- useEffect(() => {
161
+ useLayoutEffect(() => {
162
+ const last = path[0];
143
163
  const element = ref.current;
144
- if (!element || !element.parentElement) return;
145
- element.parentElement.scrollTop = 0;
146
- }, [last?.$ref]);
164
+ if (!element || !last || !element.parentElement) return;
165
+ element.parentElement.scrollTop = last?.scrollTop ?? 0;
166
+ return () => {
167
+ last.scrollTop = element.parentElement.scrollTop;
168
+ };
169
+ }, [path]);
147
170
  const context = useMemo(() => ({ renderTrigger: ({ $ref, pathName, children }) => /* @__PURE__ */ jsx("button", {
148
171
  className: cn(typeVariants({ variant: "trigger" })),
149
172
  onClick: () => setPath((path) => [...path, {
@@ -152,9 +175,9 @@ function SchemaUIPopover({ initialPath }) {
152
175
  }]),
153
176
  children
154
177
  }) }), []);
155
- if (!last) return;
178
+ const currentRef = path.findLast((item) => item.$ref !== void 0);
156
179
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
157
- className: "sticky top-0 flex flex-row flex-wrap items-center text-sm font-medium font-mono bg-fd-muted p-2",
180
+ className: "sticky top-0 flex flex-row flex-wrap items-center text-sm font-medium font-mono bg-fd-popover px-2 py-1.5 border-b",
158
181
  children: path.map((item, i) => {
159
182
  const className = cn(path.some((other, j) => j < i && other.$ref === item.$ref) && "text-orange-400", item.$ref && "hover:underline hover:text-fd-accent-foreground");
160
183
  const node = item.$ref ? /* @__PURE__ */ jsx("button", {
@@ -169,12 +192,12 @@ function SchemaUIPopover({ initialPath }) {
169
192
  })
170
193
  }), /* @__PURE__ */ jsx(PopoverContext, {
171
194
  value: context,
172
- children: /* @__PURE__ */ jsx("div", {
195
+ children: currentRef?.$ref && /* @__PURE__ */ jsx("div", {
173
196
  ref,
174
197
  className: "px-2",
175
198
  children: /* @__PURE__ */ jsx(SchemaUIProperty, {
176
199
  name: "",
177
- $type: last.$ref,
200
+ $type: currentRef.$ref,
178
201
  variant: "expand"
179
202
  })
180
203
  })
@@ -217,7 +240,7 @@ function useRenderRef() {
217
240
  function RootPopoverTrigger({ $ref, pathName, children }) {
218
241
  const ref = useCallback((element) => {
219
242
  if (!element || element.style.getPropertyValue("--initial-height")) return;
220
- element.style.setProperty("--initial-height", `${element.clientHeight}px`);
243
+ element.style.setProperty("--initial-height", `${element.clientHeight + 2}px`);
221
244
  }, []);
222
245
  return /* @__PURE__ */ jsxs(Popover, { children: [/* @__PURE__ */ jsx(PopoverTrigger, {
223
246
  className: cn(typeVariants({ variant: "trigger" })),
@@ -16,15 +16,16 @@ interface InfoTag {
16
16
  label: string;
17
17
  value: string;
18
18
  }
19
+ interface SchemaDataObjectProperty {
20
+ name: string;
21
+ $type: string;
22
+ required: boolean;
23
+ }
19
24
  type SchemaData = FieldBase & ({
20
25
  type: 'primitive';
21
26
  } | {
22
27
  type: 'object';
23
- props: {
24
- name: string;
25
- $type: string;
26
- required: boolean;
27
- }[];
28
+ props: SchemaDataObjectProperty[];
28
29
  } | {
29
30
  type: 'array';
30
31
  item: {
@@ -198,7 +198,7 @@ function generateSchemaUI({ root, readOnly, writeOnly }, ctx) {
198
198
  required: schema.required?.includes(key) ?? false
199
199
  });
200
200
  }
201
- if (additionalProperties !== void 0 && isVisible(additionalProperties)) {
201
+ if (additionalProperties && isVisible(additionalProperties)) {
202
202
  const $type = getSchemaId(additionalProperties);
203
203
  scanRefs($type, additionalProperties);
204
204
  out.props.push({
@@ -0,0 +1,2 @@
1
+ import "./schema.js";
2
+ import "./process-document.js";
@@ -4,7 +4,14 @@ let FormatFlags = /* @__PURE__ */ function(FormatFlags) {
4
4
  FormatFlags[FormatFlags["UseAlias"] = 1] = "UseAlias";
5
5
  return FormatFlags;
6
6
  }({});
7
- function schemaToString(value, ctx, flags = FormatFlags.None) {
7
+ function schemaToString(value, _resolver, flags = FormatFlags.None) {
8
+ const resolver = typeof _resolver === "function" ? _resolver : (schema) => {
9
+ const ref = _resolver?.getRawRef(schema);
10
+ return {
11
+ dereferenced: schema,
12
+ raw: ref ? { $ref: ref } : void 0
13
+ };
14
+ };
8
15
  function union(union, sep, flags) {
9
16
  const members = /* @__PURE__ */ new Set();
10
17
  let nullable = false;
@@ -17,11 +24,13 @@ function schemaToString(value, ctx, flags = FormatFlags.None) {
17
24
  return nullable ? `${result} | null` : result;
18
25
  }
19
26
  function run(schema, flags) {
27
+ const resolved = resolver(schema);
28
+ schema = resolved.dereferenced;
20
29
  if (schema === true) return "any";
21
30
  else if (schema === false) return "never";
22
31
  if ((flags & FormatFlags.UseAlias) === FormatFlags.UseAlias) {
23
32
  if (schema.title) return schema.title;
24
- const ref = ctx?.getRawRef(schema)?.split("/");
33
+ const ref = resolved.raw?.$ref?.split("/");
25
34
  if (ref && ref.length > 0) return ref[ref.length - 1];
26
35
  }
27
36
  if (Array.isArray(schema.type)) return union(schema.type.map((type) => ({
@@ -6,7 +6,9 @@ type NoReference<T> = T extends (infer I)[] ? NoReference<I>[] : T extends Refer
6
6
  type NoReferenceJSONSchema<T> = T extends (infer I)[] ? NoReference<I>[] : T extends {
7
7
  $ref?: string;
8
8
  } ? Omit<T, '$ref'> : T;
9
- type ParsedSchema = JSONSchema;
9
+ type ParsedSchema = JSONSchema & {
10
+ 'x-playground-lazy'?: boolean;
11
+ };
10
12
  type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;
11
13
  //#endregion
12
14
  export { NoReference, ParsedSchema, ResolvedSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-openapi",
3
- "version": "10.3.10",
3
+ "version": "10.3.12",
4
4
  "description": "Generate MDX docs for your OpenAPI spec",
5
5
  "keywords": [
6
6
  "Docs",
@@ -77,7 +77,7 @@
77
77
  "remark-rehype": "^11.1.2",
78
78
  "tailwind-merge": "^3.4.1",
79
79
  "xml-js": "^1.6.11",
80
- "@fumari/stf": "1.0.0"
80
+ "@fumari/stf": "1.0.2"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@scalar/api-client-react": "^1.3.96",
@@ -90,8 +90,8 @@
90
90
  "tsdown": "^0.20.3",
91
91
  "@fumadocs/tailwind": "0.0.2",
92
92
  "eslint-config-custom": "0.0.0",
93
- "fumadocs-core": "16.6.5",
94
- "fumadocs-ui": "16.6.5",
93
+ "fumadocs-core": "16.6.6",
94
+ "fumadocs-ui": "16.6.6",
95
95
  "tsconfig": "0.0.0"
96
96
  },
97
97
  "peerDependencies": {
@@ -1,23 +0,0 @@
1
- //#region src/playground/get-default-values.ts
2
- function getDefaultValue(schema) {
3
- if (typeof schema === "boolean") return null;
4
- const type = schema.type;
5
- if (Array.isArray(type)) return getDefaultValue({
6
- ...schema,
7
- type: type[0]
8
- });
9
- if (type === "object" && typeof schema === "object") return Object.fromEntries(Object.entries(schema.properties ?? {}).map(([key, prop]) => {
10
- return [key, getDefaultValue(prop)];
11
- }));
12
- if (type === "array") return [];
13
- if (type === "null") return null;
14
- if (type === "string") {
15
- if (typeof schema === "object" && schema.format === "binary") return void 0;
16
- return "";
17
- }
18
- if (type === "number" || type === "integer") return 0;
19
- if (type === "boolean") return false;
20
- }
21
-
22
- //#endregion
23
- export { getDefaultValue };