fumadocs-openapi 10.2.4 → 10.2.5

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 (50) hide show
  1. package/dist/generate-file.js.map +1 -1
  2. package/dist/playground/client.d.ts +11 -12
  3. package/dist/playground/client.d.ts.map +1 -1
  4. package/dist/playground/client.js +70 -74
  5. package/dist/playground/client.js.map +1 -1
  6. package/dist/playground/components/inputs.js +198 -187
  7. package/dist/playground/components/inputs.js.map +1 -1
  8. package/dist/playground/components/oauth-dialog.js +2 -2
  9. package/dist/playground/components/server-select.js +24 -25
  10. package/dist/playground/components/server-select.js.map +1 -1
  11. package/dist/playground/fetcher.js.map +1 -1
  12. package/dist/playground/index.js.map +1 -1
  13. package/dist/playground/schema.d.ts +1 -0
  14. package/dist/playground/schema.d.ts.map +1 -1
  15. package/dist/playground/schema.js +10 -12
  16. package/dist/playground/schema.js.map +1 -1
  17. package/dist/playground/status-info.js.map +1 -1
  18. package/dist/requests/generators/csharp.js.map +1 -1
  19. package/dist/requests/generators/curl.js.map +1 -1
  20. package/dist/requests/generators/go.js.map +1 -1
  21. package/dist/requests/generators/index.js.map +1 -1
  22. package/dist/requests/generators/java.js.map +1 -1
  23. package/dist/requests/generators/javascript.js.map +1 -1
  24. package/dist/requests/generators/python.js.map +1 -1
  25. package/dist/requests/media/adapter.js.map +1 -1
  26. package/dist/requests/media/encode.js.map +1 -1
  27. package/dist/requests/media/resolve-adapter.js +4 -0
  28. package/dist/requests/media/resolve-adapter.js.map +1 -1
  29. package/dist/server/create.js.map +1 -1
  30. package/dist/server/proxy.js.map +1 -1
  31. package/dist/server/source-api.js.map +1 -1
  32. package/dist/ui/api-page.js.map +1 -1
  33. package/dist/ui/contexts/api.js.map +1 -1
  34. package/dist/ui/operation/index.js.map +1 -1
  35. package/dist/ui/operation/request-tabs.js.map +1 -1
  36. package/dist/ui/operation/response-tabs.js.map +1 -1
  37. package/dist/ui/operation/usage-tabs/client.js.map +1 -1
  38. package/dist/ui/operation/usage-tabs/index.js.map +1 -1
  39. package/dist/ui/schema/client.d.ts.map +1 -1
  40. package/dist/ui/schema/client.js +120 -114
  41. package/dist/ui/schema/client.js.map +1 -1
  42. package/dist/ui/schema/index.js +1 -1
  43. package/dist/ui/schema/index.js.map +1 -1
  44. package/dist/utils/id-to-title.js.map +1 -1
  45. package/dist/utils/merge-schema.js.map +1 -1
  46. package/dist/utils/pages/builder.js.map +1 -1
  47. package/dist/utils/pages/preset-auto.js.map +1 -1
  48. package/dist/utils/pages/to-static-data.js.map +1 -1
  49. package/dist/utils/pages/to-text.js.map +1 -1
  50. package/package.json +13 -12
@@ -1,16 +1,17 @@
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
6
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/components/select.js";
5
7
  import { Input, labelVariants } from "../../ui/components/input.js";
6
- import { getDefaultValue } from "../get-default-values.js";
7
8
  import { FormatFlags, schemaToString } from "../../utils/schema-to-string.js";
8
- import { anyFields, useFieldInfo, useResolvedSchema, useSchemaScope } from "../schema.js";
9
9
  import { useState } from "react";
10
- import { useController, useFieldArray, useFormContext } from "react-hook-form";
11
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
12
- import { ChevronDown, Plus, Trash2, X } from "lucide-react";
11
+ import { ChevronRight, Plus, Trash2, X } from "lucide-react";
13
12
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
13
+ import { useArray, useDataEngine, useFieldValue, useObject } from "@fumari/stf";
14
+ import { stringifyFieldKey } from "@fumari/stf/lib/utils";
14
15
 
15
16
  //#region src/playground/components/inputs.tsx
16
17
  function FieldLabel(props) {
@@ -39,39 +40,79 @@ function FieldLabelType(props) {
39
40
  }
40
41
  function ObjectInput({ field: _field, fieldName, ...props }) {
41
42
  const field = useResolvedSchema(_field);
43
+ const [nextName, setNextName] = useState("");
44
+ const { properties, onAppend, onDelete } = useObject(fieldName, {
45
+ defaultValue: () => getDefaultValue(field),
46
+ properties: field.properties ?? {},
47
+ fallback: field.additionalProperties,
48
+ patternProperties: field.patternProperties
49
+ });
50
+ const isDynamic = field.patternProperties ?? field.additionalProperties;
42
51
  return /* @__PURE__ */ jsxs("div", {
43
52
  ...props,
44
53
  className: cn("grid grid-cols-1 gap-4 @md:grid-cols-2", props.className),
45
- children: [Object.entries(field.properties ?? {}).map(([key, child]) => /* @__PURE__ */ jsx(FieldSet, {
46
- name: key,
47
- field: child,
48
- fieldName: `${fieldName}.${key}`,
49
- isRequired: field.required?.includes(key)
50
- }, key)), (field.additionalProperties || field.patternProperties) && /* @__PURE__ */ jsx(DynamicProperties, {
51
- fieldName,
52
- filterKey: (v) => !field.properties || !Object.keys(field.properties).includes(v),
53
- getType: (key) => {
54
- for (const pattern in field.patternProperties) if (key.match(RegExp(pattern))) return field.patternProperties[pattern];
55
- if (field.additionalProperties) return field.additionalProperties;
56
- return anyFields;
57
- }
54
+ children: [properties.map((child) => {
55
+ let toolbar = null;
56
+ if (child.kind === "pattern" || child.kind === "fallback") toolbar = /* @__PURE__ */ jsx("button", {
57
+ type: "button",
58
+ "aria-label": "Remove Item",
59
+ className: cn(buttonVariants({
60
+ color: "outline",
61
+ size: "icon-xs"
62
+ })),
63
+ onClick: () => {
64
+ onDelete(child.key);
65
+ },
66
+ children: /* @__PURE__ */ jsx(Trash2, {})
67
+ });
68
+ return /* @__PURE__ */ jsx(FieldSet, {
69
+ name: child.key,
70
+ field: child.info,
71
+ fieldName: child.field,
72
+ isRequired: field.required?.includes(child.key),
73
+ toolbar
74
+ }, child.key);
75
+ }), isDynamic && /* @__PURE__ */ jsxs("div", {
76
+ className: "flex gap-2 col-span-full",
77
+ children: [/* @__PURE__ */ jsx(Input, {
78
+ value: nextName,
79
+ placeholder: "Enter Property Name",
80
+ onChange: (e) => setNextName(e.target.value),
81
+ onKeyDown: (e) => {
82
+ if (e.key === "Enter") {
83
+ setNextName("");
84
+ onAppend(nextName);
85
+ e.preventDefault();
86
+ }
87
+ }
88
+ }), /* @__PURE__ */ jsx("button", {
89
+ type: "button",
90
+ className: cn(buttonVariants({
91
+ color: "secondary",
92
+ size: "sm"
93
+ }), "px-4"),
94
+ onClick: () => {
95
+ onAppend(nextName);
96
+ setNextName("");
97
+ },
98
+ children: "New"
99
+ })]
58
100
  })]
59
101
  });
60
102
  }
61
103
  function JsonInput({ fieldName }) {
62
- const controller = useController({ name: fieldName });
104
+ const engine = useDataEngine();
63
105
  const [error, setError] = useState(null);
64
- const [value, setValue] = useState(() => JSON.stringify(controller.field.value, null, 2));
106
+ const [value, setValue] = useState(() => JSON.stringify(engine.init(fieldName, {}), null, 2));
65
107
  return /* @__PURE__ */ jsxs("div", {
66
108
  className: "flex flex-col bg-fd-secondary text-fd-secondary-foreground overflow-hidden border rounded-lg",
67
109
  children: [/* @__PURE__ */ jsx("textarea", {
68
- ...controller.field,
69
110
  value,
70
111
  className: "p-2 h-[240px] text-sm font-mono resize-none focus-visible:outline-none",
71
112
  onChange: (v) => {
72
113
  setValue(v.target.value);
73
114
  try {
74
- controller.field.onChange(JSON.parse(v.target.value));
115
+ engine.update(fieldName, JSON.parse(v.target.value));
75
116
  setError(null);
76
117
  } catch (e) {
77
118
  if (e instanceof Error) setError(e.message);
@@ -83,112 +124,73 @@ function JsonInput({ fieldName }) {
83
124
  })]
84
125
  });
85
126
  }
86
- function DynamicProperties({ fieldName, filterKey = () => true, getType = () => anyFields }) {
87
- const { control, setValue, getValues } = useFormContext();
88
- const [nextName, setNextName] = useState("");
89
- const [properties, setProperties] = useState(() => {
90
- const value = getValues(fieldName);
91
- if (value) return Object.keys(value).filter(filterKey);
92
- return [];
93
- });
94
- const onAppend = () => {
95
- const name = nextName.trim();
96
- if (name.length === 0) return;
97
- setProperties((p) => {
98
- if (p.includes(name) || !filterKey(name)) return p;
99
- const type = getType(name);
100
- setValue(`${fieldName}.${name}`, getDefaultValue(type));
101
- setNextName("");
102
- return [...p, name];
103
- });
104
- };
105
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [properties.map((item) => {
106
- return /* @__PURE__ */ jsx(FieldSet, {
107
- name: item,
108
- field: getType(item),
109
- fieldName: `${fieldName}.${item}`,
110
- toolbar: /* @__PURE__ */ jsx("button", {
111
- type: "button",
112
- "aria-label": "Remove Item",
113
- className: cn(buttonVariants({
114
- color: "outline",
115
- size: "icon-xs"
116
- })),
117
- onClick: () => {
118
- setProperties((p) => p.filter((prop) => prop !== item));
119
- control.unregister(`${fieldName}.${item}`);
120
- },
121
- children: /* @__PURE__ */ jsx(Trash2, {})
122
- })
123
- }, item);
124
- }), /* @__PURE__ */ jsxs("div", {
125
- className: "flex gap-2 col-span-full",
126
- children: [/* @__PURE__ */ jsx(Input, {
127
- value: nextName,
128
- placeholder: "Enter Property Name",
129
- onChange: (e) => setNextName(e.target.value),
130
- onKeyDown: (e) => {
131
- if (e.key === "Enter") {
132
- onAppend();
133
- e.preventDefault();
134
- }
135
- }
136
- }), /* @__PURE__ */ jsx("button", {
137
- type: "button",
138
- className: cn(buttonVariants({
139
- color: "secondary",
140
- size: "sm"
141
- }), "px-4"),
142
- onClick: onAppend,
143
- children: "New"
144
- })]
145
- })] });
146
- }
147
127
  function FieldInput({ field, fieldName, isRequired, ...props }) {
148
- const form = useFormContext();
149
- const { field: { value, onChange, ...restField }, fieldState } = useController({
150
- control: form.control,
151
- name: fieldName
152
- });
128
+ const engine = useDataEngine();
129
+ const [value, setValue] = useFieldValue(fieldName);
130
+ const id = stringifyFieldKey(fieldName);
153
131
  if (field.type === "null") return;
154
- if (field.type === "string" && field.format === "binary") return /* @__PURE__ */ jsxs("div", {
155
- ...props,
156
- children: [/* @__PURE__ */ jsx("label", {
157
- htmlFor: fieldName,
158
- className: cn(buttonVariants({
159
- color: "secondary",
160
- className: "w-full h-9 gap-2 truncate"
161
- })),
162
- children: value instanceof File ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
163
- className: "text-fd-muted-foreground text-xs",
164
- children: "Selected"
165
- }), /* @__PURE__ */ jsx("span", {
166
- className: "truncate w-0 flex-1 text-end",
167
- children: value.name
168
- })] }) : /* @__PURE__ */ jsx("span", {
132
+ function renderUnset(children) {
133
+ return /* @__PURE__ */ jsxs("div", {
134
+ ...props,
135
+ className: cn("flex flex-row gap-2", props.className),
136
+ children: [children, value !== void 0 && !isRequired && /* @__PURE__ */ jsx("button", {
137
+ type: "button",
138
+ onClick: () => engine.delete(fieldName),
169
139
  className: "text-fd-muted-foreground",
170
- children: "Upload"
171
- })
172
- }), /* @__PURE__ */ jsx("input", {
173
- id: fieldName,
174
- type: "file",
175
- multiple: false,
176
- onChange: (e) => {
177
- if (!e.target.files) return;
178
- onChange(e.target.files.item(0));
179
- },
180
- hidden: true,
181
- ...restField
182
- })]
183
- });
140
+ children: /* @__PURE__ */ jsx(X, { className: "size-4" })
141
+ })]
142
+ });
143
+ }
144
+ if (field.type === "string" && field.format === "binary") return renderUnset(/* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("label", {
145
+ htmlFor: id,
146
+ className: cn(buttonVariants({
147
+ color: "secondary",
148
+ className: "w-full h-9 gap-2 truncate"
149
+ })),
150
+ children: value instanceof File ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
151
+ className: "text-fd-muted-foreground text-xs",
152
+ children: "Selected"
153
+ }), /* @__PURE__ */ jsx("span", {
154
+ className: "truncate w-0 flex-1 text-end",
155
+ children: value.name
156
+ })] }) : /* @__PURE__ */ jsx("span", {
157
+ className: "text-fd-muted-foreground",
158
+ children: "Upload"
159
+ })
160
+ }), /* @__PURE__ */ jsx("input", {
161
+ id,
162
+ type: "file",
163
+ multiple: false,
164
+ onChange: (e) => {
165
+ if (!e.target.files || e.target.files.length === 0) return;
166
+ setValue(e.target.files.item(0));
167
+ },
168
+ hidden: true
169
+ })] }));
170
+ if (field.enum && field.enum.length > 0) {
171
+ const idx = field.enum.indexOf(value);
172
+ return /* @__PURE__ */ jsxs(Select, {
173
+ value: String(idx),
174
+ onValueChange: (v) => setValue(field.enum[Number(v)]),
175
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
176
+ id,
177
+ ...props,
178
+ children: /* @__PURE__ */ jsx(SelectValue, {})
179
+ }), /* @__PURE__ */ jsxs(SelectContent, { children: [field.enum.map((item, i) => /* @__PURE__ */ jsx(SelectItem, {
180
+ value: String(i),
181
+ children: typeof item === "string" ? item : JSON.stringify(item, null, 2)
182
+ }, i)), !isRequired && /* @__PURE__ */ jsx(SelectItem, {
183
+ value: "-1",
184
+ children: "Unset"
185
+ })] })]
186
+ });
187
+ }
184
188
  if (field.type === "boolean") return /* @__PURE__ */ jsxs(Select, {
185
189
  value: String(value),
186
- onValueChange: (value$1) => onChange(value$1 === "undefined" ? void 0 : value$1 === "true"),
187
- disabled: restField.disabled,
190
+ onValueChange: (value$1) => setValue(value$1 === "undefined" ? void 0 : value$1 === "true"),
188
191
  children: [/* @__PURE__ */ jsx(SelectTrigger, {
189
- id: fieldName,
190
- className: props.className,
191
- ...restField,
192
+ id,
193
+ ...props,
192
194
  children: /* @__PURE__ */ jsx(SelectValue, {})
193
195
  }), /* @__PURE__ */ jsxs(SelectContent, { children: [
194
196
  /* @__PURE__ */ jsx(SelectItem, {
@@ -206,37 +208,29 @@ function FieldInput({ field, fieldName, isRequired, ...props }) {
206
208
  ] })]
207
209
  });
208
210
  const isNumber = field.type === "integer" || field.type === "number";
209
- return /* @__PURE__ */ jsxs("div", {
210
- ...props,
211
- className: cn("flex flex-row gap-2", props.className),
212
- children: [/* @__PURE__ */ jsx(Input, {
213
- id: fieldName,
214
- placeholder: "Enter value",
215
- type: isNumber ? "number" : "text",
216
- step: field.type === "integer" ? 1 : void 0,
217
- value: value ?? "",
218
- onChange: (e) => {
219
- if (isNumber && !Number.isNaN(e.target.valueAsNumber)) onChange(e.target.valueAsNumber);
220
- else if (!isNumber) onChange(e.target.value);
221
- },
222
- ...restField
223
- }), fieldState.isDirty && /* @__PURE__ */ jsx("button", {
224
- type: "button",
225
- onClick: () => form.resetField(fieldName),
226
- className: "text-fd-muted-foreground",
227
- children: /* @__PURE__ */ jsx(X, { className: "size-4" })
228
- })]
229
- });
211
+ return renderUnset(/* @__PURE__ */ jsx(Input, {
212
+ id,
213
+ placeholder: "Enter value",
214
+ type: isNumber ? "number" : "text",
215
+ step: field.type === "integer" ? 1 : void 0,
216
+ value: String(value ?? ""),
217
+ onChange: (e) => {
218
+ if (isNumber) setValue(Number.isNaN(e.target.valueAsNumber) ? void 0 : e.target.valueAsNumber);
219
+ else if (!isNumber) setValue(e.target.value);
220
+ }
221
+ }));
230
222
  }
231
223
  function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth = 0, slotType, collapsible = true, ...props }) {
232
224
  const { readOnly, writeOnly } = useSchemaScope();
233
225
  const field = useResolvedSchema(_field);
234
226
  const [show, setShow] = useState(!collapsible);
235
- const { info, updateInfo } = useFieldInfo(fieldName, field, depth);
227
+ const { info, updateInfo } = useFieldInfo(fieldName, field);
228
+ const id = stringifyFieldKey(fieldName);
229
+ const dataEngine = useDataEngine();
236
230
  if (_field === false) return;
237
231
  if (field.readOnly && !readOnly) return;
238
232
  if (field.writeOnly && !writeOnly) return;
239
- if (info.unionField) {
233
+ if (info.unionField && field[info.unionField]) {
240
234
  const union = field[info.unionField];
241
235
  const showSelect = union.length > 1;
242
236
  return /* @__PURE__ */ jsx(FieldSet, {
@@ -288,44 +282,61 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
288
282
  }), toolbar] })
289
283
  });
290
284
  }
291
- const showBn = collapsible && /* @__PURE__ */ jsx("button", {
292
- type: "button",
293
- onClick: () => setShow((prev) => !prev),
294
- className: cn(buttonVariants({
295
- size: "icon-xs",
296
- color: "ghost",
297
- className: "text-fd-muted-foreground -ms-1"
298
- })),
299
- children: /* @__PURE__ */ jsx(ChevronDown, { className: cn(show && "rotate-180") })
300
- });
301
- if (field.type === "object" || info.intersection) return /* @__PURE__ */ jsxs("fieldset", {
302
- ...props,
303
- className: cn("flex flex-col gap-1.5 col-span-full @container", props.className),
304
- children: [/* @__PURE__ */ jsxs(FieldLabel, {
305
- htmlFor: fieldName,
306
- children: [
307
- showBn,
308
- /* @__PURE__ */ jsx(FieldLabelName, {
309
- required: isRequired,
310
- children: name
311
- }),
312
- slotType ?? /* @__PURE__ */ jsx(FieldLabelType, { children: schemaToString(field) }),
313
- toolbar
314
- ]
315
- }), show && /* @__PURE__ */ jsx(ObjectInput, {
316
- field: info.intersection?.merged ?? field,
317
- fieldName,
285
+ if (field.type === "object" || info.intersection) {
286
+ const schema = info.intersection?.merged ?? field;
287
+ return /* @__PURE__ */ jsxs("fieldset", {
318
288
  ...props,
319
- className: cn("rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm", props.className)
320
- })]
321
- });
289
+ className: cn("flex flex-col gap-1.5 col-span-full @container", props.className),
290
+ children: [/* @__PURE__ */ jsxs(FieldLabel, {
291
+ htmlFor: id,
292
+ children: [
293
+ collapsible && /* @__PURE__ */ jsx("button", {
294
+ type: "button",
295
+ onClick: () => {
296
+ dataEngine.init(fieldName, getDefaultValue(schema));
297
+ setShow((prev) => !prev);
298
+ },
299
+ className: cn(buttonVariants({
300
+ size: "icon-xs",
301
+ color: "ghost",
302
+ className: "text-fd-muted-foreground -ms-1"
303
+ })),
304
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: cn(show && "rotate-90") })
305
+ }),
306
+ /* @__PURE__ */ jsx(FieldLabelName, {
307
+ required: isRequired,
308
+ children: name
309
+ }),
310
+ slotType ?? /* @__PURE__ */ jsx(FieldLabelType, { children: schemaToString(field) }),
311
+ toolbar
312
+ ]
313
+ }), show && /* @__PURE__ */ jsx(ObjectInput, {
314
+ field: schema,
315
+ fieldName,
316
+ ...props,
317
+ className: cn("rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm", props.className)
318
+ })]
319
+ });
320
+ }
322
321
  if (field.type === "array") return /* @__PURE__ */ jsxs("fieldset", {
323
322
  ...props,
324
323
  className: cn("flex flex-col gap-1.5 col-span-full", props.className),
325
324
  children: [/* @__PURE__ */ jsxs(FieldLabel, {
326
- htmlFor: fieldName,
325
+ htmlFor: id,
327
326
  children: [
328
- showBn,
327
+ collapsible && /* @__PURE__ */ jsx("button", {
328
+ type: "button",
329
+ onClick: () => {
330
+ dataEngine.init(fieldName, getDefaultValue(field));
331
+ setShow((prev) => !prev);
332
+ },
333
+ className: cn(buttonVariants({
334
+ size: "icon-xs",
335
+ color: "ghost",
336
+ className: "text-fd-muted-foreground -ms-1"
337
+ })),
338
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: cn(show && "rotate-90") })
339
+ }),
329
340
  /* @__PURE__ */ jsx(FieldLabelName, {
330
341
  required: isRequired,
331
342
  children: name
@@ -344,7 +355,7 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
344
355
  ...props,
345
356
  className: cn("flex flex-col gap-1.5", props.className),
346
357
  children: [/* @__PURE__ */ jsxs(FieldLabel, {
347
- htmlFor: fieldName,
358
+ htmlFor: id,
348
359
  children: [
349
360
  /* @__PURE__ */ jsx(FieldLabelName, {
350
361
  required: isRequired,
@@ -360,25 +371,25 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
360
371
  })]
361
372
  });
362
373
  }
363
- function ArrayInput({ fieldName, items, ...props }) {
364
- const name = fieldName.split(".").at(-1) ?? "";
365
- const { fields, append, remove } = useFieldArray({ name: fieldName });
374
+ function ArrayInput({ fieldName, items: itemSchema, ...props }) {
375
+ const name = fieldName.at(-1) ?? "";
376
+ const { items, insertItem, removeItem } = useArray(fieldName, { defaultValue: [] });
366
377
  return /* @__PURE__ */ jsxs("div", {
367
378
  ...props,
368
379
  className: cn("flex flex-col gap-2", props.className),
369
- children: [fields.map((item, index) => /* @__PURE__ */ jsx(FieldSet, {
380
+ children: [items.map((item) => /* @__PURE__ */ jsx(FieldSet, {
370
381
  name: /* @__PURE__ */ jsxs("span", {
371
382
  className: "text-fd-muted-foreground",
372
383
  children: [
373
384
  name,
374
385
  "[",
375
- index,
386
+ item.index,
376
387
  "]"
377
388
  ]
378
389
  }),
379
- field: items,
390
+ field: itemSchema,
380
391
  isRequired: true,
381
- fieldName: `${fieldName}.${index}`,
392
+ fieldName: item.field,
382
393
  toolbar: /* @__PURE__ */ jsx("button", {
383
394
  type: "button",
384
395
  "aria-label": "Remove Item",
@@ -386,10 +397,10 @@ function ArrayInput({ fieldName, items, ...props }) {
386
397
  color: "outline",
387
398
  size: "icon-xs"
388
399
  })),
389
- onClick: () => remove(index),
400
+ onClick: () => removeItem(item.index),
390
401
  children: /* @__PURE__ */ jsx(Trash2, {})
391
402
  })
392
- }, item.id)), /* @__PURE__ */ jsxs("button", {
403
+ }, item.index)), /* @__PURE__ */ jsxs("button", {
393
404
  type: "button",
394
405
  className: cn(buttonVariants({
395
406
  color: "secondary",
@@ -397,7 +408,7 @@ function ArrayInput({ fieldName, items, ...props }) {
397
408
  size: "sm"
398
409
  })),
399
410
  onClick: () => {
400
- append(getDefaultValue(items));
411
+ insertItem(getDefaultValue(itemSchema));
401
412
  },
402
413
  children: [/* @__PURE__ */ jsx(Plus, { className: "size-4" }), "New Item"]
403
414
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"inputs.js","names":["value"],"sources":["../../../src/playground/components/inputs.tsx"],"sourcesContent":["'use client';\nimport { type ComponentProps, type HTMLAttributes, type ReactNode, useState } from 'react';\nimport { ChevronDown, Plus, Trash2, X } from 'lucide-react';\nimport { useController, useFieldArray, useFormContext } from 'react-hook-form';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/ui/components/select';\nimport { Input, labelVariants } from '@/ui/components/input';\nimport { getDefaultValue } from '../get-default-values';\nimport { cn } from '@/utils/cn';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { FormatFlags, schemaToString } from '@/utils/schema-to-string';\nimport { anyFields, useFieldInfo, useResolvedSchema, useSchemaScope } from '@/playground/schema';\nimport type { ParsedSchema } from '@/utils/schema';\n\nfunction FieldLabel(props: ComponentProps<'label'>) {\n return (\n <label {...props} className={cn('w-full inline-flex items-center gap-0.5', props.className)}>\n {props.children}\n </label>\n );\n}\n\nfunction FieldLabelName({\n required = false,\n ...props\n}: ComponentProps<'span'> & { required?: boolean }) {\n return (\n <span {...props} className={cn(labelVariants(), 'font-mono me-auto', props.className)}>\n {props.children}\n {required && <span className=\"text-red-400/80 mx-1\">*</span>}\n </span>\n );\n}\n\nfunction FieldLabelType(props: ComponentProps<'code'>) {\n return (\n <code {...props} className={cn('text-xs text-fd-muted-foreground', props.className)}>\n {props.children}\n </code>\n );\n}\n\nexport function ObjectInput({\n field: _field,\n fieldName,\n ...props\n}: {\n field: Exclude<ParsedSchema, boolean>;\n fieldName: string;\n} & ComponentProps<'div'>) {\n const field = useResolvedSchema(_field);\n\n return (\n <div {...props} className={cn('grid grid-cols-1 gap-4 @md:grid-cols-2', props.className)}>\n {Object.entries(field.properties ?? {}).map(([key, child]) => (\n <FieldSet\n key={key}\n name={key}\n field={child}\n fieldName={`${fieldName}.${key}`}\n isRequired={field.required?.includes(key)}\n />\n ))}\n {(field.additionalProperties || field.patternProperties) && (\n <DynamicProperties\n fieldName={fieldName}\n filterKey={(v) => !field.properties || !Object.keys(field.properties).includes(v)}\n getType={(key) => {\n for (const pattern in field.patternProperties) {\n if (key.match(RegExp(pattern))) {\n return field.patternProperties[pattern];\n }\n }\n\n if (field.additionalProperties) return field.additionalProperties;\n\n return anyFields;\n }}\n />\n )}\n </div>\n );\n}\n\nexport function JsonInput({ fieldName }: { fieldName: string }) {\n const controller = useController({\n name: fieldName,\n });\n const [error, setError] = useState<string | null>(null);\n const [value, setValue] = useState(() => JSON.stringify(controller.field.value, null, 2));\n\n return (\n <div className=\"flex flex-col bg-fd-secondary text-fd-secondary-foreground overflow-hidden border rounded-lg\">\n <textarea\n {...controller.field}\n value={value}\n className=\"p-2 h-[240px] text-sm font-mono resize-none focus-visible:outline-none\"\n onChange={(v) => {\n setValue(v.target.value);\n try {\n controller.field.onChange(JSON.parse(v.target.value));\n setError(null);\n } catch (e) {\n if (e instanceof Error) setError(e.message);\n }\n }}\n />\n <p className=\"p-2 text-xs font-mono border-t text-red-400 empty:hidden\">{error}</p>\n </div>\n );\n}\n\nfunction DynamicProperties({\n fieldName,\n filterKey = () => true,\n getType = () => anyFields,\n}: {\n fieldName: string;\n filterKey?: (key: string) => boolean;\n getType: (key: string) => ParsedSchema;\n}) {\n const { control, setValue, getValues } = useFormContext();\n const [nextName, setNextName] = useState('');\n const [properties, setProperties] = useState<string[]>(() => {\n const value = getValues(fieldName);\n if (value) return Object.keys(value).filter(filterKey);\n\n return [];\n });\n\n const onAppend = () => {\n const name = nextName.trim();\n if (name.length === 0) return;\n\n setProperties((p) => {\n if (p.includes(name) || !filterKey(name)) return p;\n const type = getType(name);\n\n setValue(`${fieldName}.${name}`, getDefaultValue(type));\n setNextName('');\n return [...p, name];\n });\n };\n\n return (\n <>\n {properties.map((item) => {\n const type = getType(item);\n\n return (\n <FieldSet\n key={item}\n name={item}\n field={type}\n fieldName={`${fieldName}.${item}`}\n toolbar={\n <button\n type=\"button\"\n aria-label=\"Remove Item\"\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'icon-xs',\n }),\n )}\n onClick={() => {\n setProperties((p) => p.filter((prop) => prop !== item));\n control.unregister(`${fieldName}.${item}`);\n }}\n >\n <Trash2 />\n </button>\n }\n />\n );\n })}\n <div className=\"flex gap-2 col-span-full\">\n <Input\n value={nextName}\n placeholder=\"Enter Property Name\"\n onChange={(e) => setNextName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n onAppend();\n e.preventDefault();\n }\n }}\n />\n <button\n type=\"button\"\n className={cn(buttonVariants({ color: 'secondary', size: 'sm' }), 'px-4')}\n onClick={onAppend}\n >\n New\n </button>\n </div>\n </>\n );\n}\n\nexport function FieldInput({\n field,\n fieldName,\n isRequired,\n ...props\n}: HTMLAttributes<HTMLElement> & {\n field: Exclude<ParsedSchema, boolean>;\n isRequired?: boolean;\n fieldName: string;\n}) {\n const form = useFormContext();\n const {\n field: { value, onChange, ...restField },\n fieldState,\n } = useController({\n control: form.control,\n name: fieldName,\n });\n\n if (field.type === 'null') return;\n\n if (field.type === 'string' && field.format === 'binary') {\n return (\n <div {...props}>\n <label\n htmlFor={fieldName}\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'w-full h-9 gap-2 truncate',\n }),\n )}\n >\n {value instanceof File ? (\n <>\n <span className=\"text-fd-muted-foreground text-xs\">Selected</span>\n <span className=\"truncate w-0 flex-1 text-end\">{value.name}</span>\n </>\n ) : (\n <span className=\"text-fd-muted-foreground\">Upload</span>\n )}\n </label>\n <input\n id={fieldName}\n type=\"file\"\n multiple={false}\n onChange={(e) => {\n if (!e.target.files) return;\n onChange(e.target.files.item(0));\n }}\n hidden\n {...restField}\n />\n </div>\n );\n }\n\n if (field.type === 'boolean') {\n return (\n <Select\n value={String(value)}\n onValueChange={(value) => onChange(value === 'undefined' ? undefined : value === 'true')}\n disabled={restField.disabled}\n >\n <SelectTrigger id={fieldName} className={props.className} {...restField}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">True</SelectItem>\n <SelectItem value=\"false\">False</SelectItem>\n {!isRequired && <SelectItem value=\"undefined\">Unset</SelectItem>}\n </SelectContent>\n </Select>\n );\n }\n\n const isNumber = field.type === 'integer' || field.type === 'number';\n\n return (\n <div {...props} className={cn('flex flex-row gap-2', props.className)}>\n <Input\n id={fieldName}\n placeholder=\"Enter value\"\n type={isNumber ? 'number' : 'text'}\n step={field.type === 'integer' ? 1 : undefined}\n value={value ?? ''}\n onChange={(e) => {\n if (isNumber && !Number.isNaN(e.target.valueAsNumber)) {\n onChange(e.target.valueAsNumber);\n } else if (!isNumber) {\n onChange(e.target.value);\n }\n }}\n {...restField}\n />\n {fieldState.isDirty && (\n <button\n type=\"button\"\n // TODO: `react-hook-form` doesn't support setting a value to `undefined` (aka remove the value), if there's a default value defined.\n // the default value is kept by `react-hook-form` internally, we cannot manipulate it.\n // hence, we can only support resetting to the default value.\n // perhaps when we migrate to Tanstack Form, we can reconsider this.\n onClick={() => form.resetField(fieldName)}\n className=\"text-fd-muted-foreground\"\n >\n <X className=\"size-4\" />\n </button>\n )}\n </div>\n );\n}\n\nexport function FieldSet({\n field: _field,\n fieldName,\n toolbar,\n name,\n isRequired,\n depth = 0,\n slotType,\n collapsible = true,\n ...props\n}: HTMLAttributes<HTMLElement> & {\n isRequired?: boolean;\n name?: ReactNode;\n field: ParsedSchema;\n fieldName: string;\n depth?: number;\n\n slotType?: ReactNode;\n toolbar?: ReactNode;\n collapsible?: boolean;\n}) {\n const { readOnly, writeOnly } = useSchemaScope();\n const field = useResolvedSchema(_field);\n const [show, setShow] = useState(!collapsible);\n const { info, updateInfo } = useFieldInfo(fieldName, field, depth);\n\n if (_field === false) return;\n if (field.readOnly && !readOnly) return;\n if (field.writeOnly && !writeOnly) return;\n\n if (info.unionField) {\n const union = field[info.unionField]!;\n const showSelect = union.length > 1;\n\n return (\n <FieldSet\n {...props}\n name={name}\n fieldName={fieldName}\n isRequired={isRequired}\n field={union[info.oneOf]}\n depth={depth + 1}\n slotType={showSelect ? false : slotType}\n toolbar={\n <>\n {showSelect && (\n <select\n className=\"text-xs font-mono\"\n value={info.oneOf}\n onChange={(e) => {\n updateInfo({\n oneOf: Number(e.target.value),\n });\n }}\n >\n {union.map((item, i) => (\n <option key={i} value={i} className=\"bg-fd-popover text-fd-popover-foreground\">\n {schemaToString(item, undefined, FormatFlags.UseAlias)}\n </option>\n ))}\n </select>\n )}\n {toolbar}\n </>\n }\n />\n );\n }\n\n if (Array.isArray(field.type)) {\n const showSelect = field.type.length > 1;\n\n return (\n <FieldSet\n {...props}\n name={name}\n fieldName={fieldName}\n isRequired={isRequired}\n field={{\n ...field,\n type: info.selectedType,\n }}\n depth={depth + 1}\n slotType={showSelect ? false : slotType}\n toolbar={\n <>\n {showSelect && (\n <select\n className=\"text-xs font-mono\"\n value={info.selectedType}\n onChange={(e) => {\n updateInfo({\n selectedType: e.target.value,\n });\n }}\n >\n {field.type.map((item) => (\n <option\n key={item}\n value={item}\n className=\"bg-fd-popover text-fd-popover-foreground\"\n >\n {item}\n </option>\n ))}\n </select>\n )}\n {toolbar}\n </>\n }\n />\n );\n }\n\n const showBn = collapsible && (\n <button\n type=\"button\"\n onClick={() => setShow((prev) => !prev)}\n className={cn(\n buttonVariants({\n size: 'icon-xs',\n color: 'ghost',\n className: 'text-fd-muted-foreground -ms-1',\n }),\n )}\n >\n <ChevronDown className={cn(show && 'rotate-180')} />\n </button>\n );\n\n if (field.type === 'object' || info.intersection) {\n return (\n <fieldset\n {...props}\n className={cn('flex flex-col gap-1.5 col-span-full @container', props.className)}\n >\n <FieldLabel htmlFor={fieldName}>\n {showBn}\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n {show && (\n <ObjectInput\n field={info.intersection?.merged ?? field}\n fieldName={fieldName}\n {...props}\n className={cn(\n 'rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm',\n props.className,\n )}\n />\n )}\n </fieldset>\n );\n }\n\n if (field.type === 'array') {\n return (\n <fieldset {...props} className={cn('flex flex-col gap-1.5 col-span-full', props.className)}>\n <FieldLabel htmlFor={fieldName}>\n {showBn}\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n {show && (\n <ArrayInput\n fieldName={fieldName}\n items={field.items ?? anyFields}\n {...props}\n className={cn(\n 'rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm',\n props.className,\n )}\n />\n )}\n </fieldset>\n );\n }\n return (\n <fieldset {...props} className={cn('flex flex-col gap-1.5', props.className)}>\n <FieldLabel htmlFor={fieldName}>\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n <FieldInput field={field} fieldName={fieldName} isRequired={isRequired} />\n </fieldset>\n );\n}\n\nfunction ArrayInput({\n fieldName,\n items,\n ...props\n}: {\n fieldName: string;\n items: ParsedSchema;\n} & ComponentProps<'div'>) {\n const name = fieldName.split('.').at(-1) ?? '';\n const { fields, append, remove } = useFieldArray({\n name: fieldName,\n });\n\n return (\n <div {...props} className={cn('flex flex-col gap-2', props.className)}>\n {fields.map((item, index) => (\n <FieldSet\n key={item.id}\n name={\n <span className=\"text-fd-muted-foreground\">\n {name}[{index}]\n </span>\n }\n field={items}\n isRequired\n fieldName={`${fieldName}.${index}`}\n toolbar={\n <button\n type=\"button\"\n aria-label=\"Remove Item\"\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'icon-xs',\n }),\n )}\n onClick={() => remove(index)}\n >\n <Trash2 />\n </button>\n }\n />\n ))}\n <button\n type=\"button\"\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'gap-1.5 py-2',\n size: 'sm',\n }),\n )}\n onClick={() => {\n append(getDefaultValue(items));\n }}\n >\n <Plus className=\"size-4\" />\n New Item\n </button>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"inputs.js","names":["value"],"sources":["../../../src/playground/components/inputs.tsx"],"sourcesContent":["'use client';\nimport { type ComponentProps, type HTMLAttributes, type ReactNode, useState } from 'react';\nimport { ChevronRight, Plus, Trash2, X } from 'lucide-react';\nimport { FieldKey, useArray, useDataEngine, useFieldValue, useObject } from '@fumari/stf';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/ui/components/select';\nimport { Input, labelVariants } from '@/ui/components/input';\nimport { getDefaultValue } from '../get-default-values';\nimport { cn } from '@/utils/cn';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { FormatFlags, schemaToString } from '@/utils/schema-to-string';\nimport { anyFields, useFieldInfo, useResolvedSchema, useSchemaScope } from '@/playground/schema';\nimport type { ParsedSchema } from '@/utils/schema';\nimport { stringifyFieldKey } from '@fumari/stf/lib/utils';\n\nfunction FieldLabel(props: ComponentProps<'label'>) {\n return (\n <label {...props} className={cn('w-full inline-flex items-center gap-0.5', props.className)}>\n {props.children}\n </label>\n );\n}\n\nfunction FieldLabelName({\n required = false,\n ...props\n}: ComponentProps<'span'> & { required?: boolean }) {\n return (\n <span {...props} className={cn(labelVariants(), 'font-mono me-auto', props.className)}>\n {props.children}\n {required && <span className=\"text-red-400/80 mx-1\">*</span>}\n </span>\n );\n}\n\nfunction FieldLabelType(props: ComponentProps<'code'>) {\n return (\n <code {...props} className={cn('text-xs text-fd-muted-foreground', props.className)}>\n {props.children}\n </code>\n );\n}\n\nexport function ObjectInput({\n field: _field,\n fieldName,\n ...props\n}: {\n field: Exclude<ParsedSchema, boolean>;\n fieldName: FieldKey;\n} & ComponentProps<'div'>) {\n const field = useResolvedSchema(_field);\n const [nextName, setNextName] = useState('');\n const { properties, onAppend, onDelete } = useObject(fieldName, {\n defaultValue: () => getDefaultValue(field) as object,\n properties: field.properties ?? {},\n fallback: field.additionalProperties,\n patternProperties: field.patternProperties,\n });\n\n const isDynamic = field.patternProperties ?? field.additionalProperties;\n return (\n <div {...props} className={cn('grid grid-cols-1 gap-4 @md:grid-cols-2', props.className)}>\n {properties.map((child) => {\n let toolbar: ReactNode = null;\n if (child.kind === 'pattern' || child.kind === 'fallback') {\n toolbar = (\n <button\n type=\"button\"\n aria-label=\"Remove Item\"\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'icon-xs',\n }),\n )}\n onClick={() => {\n onDelete(child.key);\n }}\n >\n <Trash2 />\n </button>\n );\n }\n\n return (\n <FieldSet\n key={child.key}\n name={child.key}\n field={child.info}\n fieldName={child.field}\n isRequired={field.required?.includes(child.key)}\n toolbar={toolbar}\n />\n );\n })}\n {isDynamic && (\n <div className=\"flex gap-2 col-span-full\">\n <Input\n value={nextName}\n placeholder=\"Enter Property Name\"\n onChange={(e) => setNextName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n setNextName('');\n onAppend(nextName);\n e.preventDefault();\n }\n }}\n />\n <button\n type=\"button\"\n className={cn(buttonVariants({ color: 'secondary', size: 'sm' }), 'px-4')}\n onClick={() => {\n onAppend(nextName);\n setNextName('');\n }}\n >\n New\n </button>\n </div>\n )}\n </div>\n );\n}\n\nexport function JsonInput({ fieldName }: { fieldName: FieldKey }) {\n const engine = useDataEngine();\n const [error, setError] = useState<string | null>(null);\n const [value, setValue] = useState(() => JSON.stringify(engine.init(fieldName, {}), null, 2));\n\n return (\n <div className=\"flex flex-col bg-fd-secondary text-fd-secondary-foreground overflow-hidden border rounded-lg\">\n <textarea\n value={value}\n className=\"p-2 h-[240px] text-sm font-mono resize-none focus-visible:outline-none\"\n onChange={(v) => {\n setValue(v.target.value);\n try {\n engine.update(fieldName, JSON.parse(v.target.value));\n setError(null);\n } catch (e) {\n if (e instanceof Error) setError(e.message);\n }\n }}\n />\n <p className=\"p-2 text-xs font-mono border-t text-red-400 empty:hidden\">{error}</p>\n </div>\n );\n}\n\nexport function FieldInput({\n field,\n fieldName,\n isRequired,\n ...props\n}: HTMLAttributes<HTMLElement> & {\n field: Exclude<ParsedSchema, boolean>;\n isRequired?: boolean;\n fieldName: FieldKey;\n}) {\n const engine = useDataEngine();\n const [value, setValue] = useFieldValue(fieldName);\n const id = stringifyFieldKey(fieldName);\n if (field.type === 'null') return;\n\n function renderUnset(children: ReactNode) {\n return (\n <div {...props} className={cn('flex flex-row gap-2', props.className)}>\n {children}\n {value !== undefined && !isRequired && (\n <button\n type=\"button\"\n onClick={() => engine.delete(fieldName)}\n className=\"text-fd-muted-foreground\"\n >\n <X className=\"size-4\" />\n </button>\n )}\n </div>\n );\n }\n\n if (field.type === 'string' && field.format === 'binary') {\n return renderUnset(\n <>\n <label\n htmlFor={id}\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'w-full h-9 gap-2 truncate',\n }),\n )}\n >\n {value instanceof File ? (\n <>\n <span className=\"text-fd-muted-foreground text-xs\">Selected</span>\n <span className=\"truncate w-0 flex-1 text-end\">{value.name}</span>\n </>\n ) : (\n <span className=\"text-fd-muted-foreground\">Upload</span>\n )}\n </label>\n <input\n id={id}\n type=\"file\"\n multiple={false}\n onChange={(e) => {\n if (!e.target.files || e.target.files.length === 0) return;\n setValue(e.target.files.item(0));\n }}\n hidden\n />\n </>,\n );\n }\n\n if (field.enum && field.enum.length > 0) {\n const idx = field.enum.indexOf(value);\n\n return (\n <Select value={String(idx)} onValueChange={(v) => setValue(field.enum![Number(v)])}>\n <SelectTrigger id={id} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {field.enum.map((item, i) => (\n <SelectItem key={i} value={String(i)}>\n {typeof item === 'string' ? item : JSON.stringify(item, null, 2)}\n </SelectItem>\n ))}\n {!isRequired && <SelectItem value=\"-1\">Unset</SelectItem>}\n </SelectContent>\n </Select>\n );\n }\n\n if (field.type === 'boolean') {\n return (\n <Select\n value={String(value)}\n onValueChange={(value) => setValue(value === 'undefined' ? undefined : value === 'true')}\n >\n <SelectTrigger id={id} {...props}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">True</SelectItem>\n <SelectItem value=\"false\">False</SelectItem>\n {!isRequired && <SelectItem value=\"undefined\">Unset</SelectItem>}\n </SelectContent>\n </Select>\n );\n }\n\n const isNumber = field.type === 'integer' || field.type === 'number';\n return renderUnset(\n <Input\n id={id}\n placeholder=\"Enter value\"\n type={isNumber ? 'number' : 'text'}\n step={field.type === 'integer' ? 1 : undefined}\n value={String(value ?? '')}\n onChange={(e) => {\n if (isNumber) {\n setValue(Number.isNaN(e.target.valueAsNumber) ? undefined : e.target.valueAsNumber);\n } else if (!isNumber) {\n setValue(e.target.value);\n }\n }}\n />,\n );\n}\n\nexport function FieldSet({\n field: _field,\n fieldName,\n toolbar,\n name,\n isRequired,\n depth = 0,\n slotType,\n collapsible = true,\n ...props\n}: HTMLAttributes<HTMLElement> & {\n isRequired?: boolean;\n name?: ReactNode;\n field: ParsedSchema;\n fieldName: FieldKey;\n depth?: number;\n\n slotType?: ReactNode;\n toolbar?: ReactNode;\n collapsible?: boolean;\n}) {\n const { readOnly, writeOnly } = useSchemaScope();\n const field = useResolvedSchema(_field);\n const [show, setShow] = useState(!collapsible);\n const { info, updateInfo } = useFieldInfo(fieldName, field);\n const id = stringifyFieldKey(fieldName);\n const dataEngine = useDataEngine();\n\n if (_field === false) return;\n if (field.readOnly && !readOnly) return;\n if (field.writeOnly && !writeOnly) return;\n\n if (info.unionField && field[info.unionField]) {\n const union = field[info.unionField]!;\n const showSelect = union.length > 1;\n\n return (\n <FieldSet\n {...props}\n name={name}\n fieldName={fieldName}\n isRequired={isRequired}\n field={union[info.oneOf]}\n depth={depth + 1}\n slotType={showSelect ? false : slotType}\n toolbar={\n <>\n {showSelect && (\n <select\n className=\"text-xs font-mono\"\n value={info.oneOf}\n onChange={(e) => {\n updateInfo({\n oneOf: Number(e.target.value),\n });\n }}\n >\n {union.map((item, i) => (\n <option key={i} value={i} className=\"bg-fd-popover text-fd-popover-foreground\">\n {schemaToString(item, undefined, FormatFlags.UseAlias)}\n </option>\n ))}\n </select>\n )}\n {toolbar}\n </>\n }\n />\n );\n }\n\n if (Array.isArray(field.type)) {\n const showSelect = field.type.length > 1;\n\n return (\n <FieldSet\n {...props}\n name={name}\n fieldName={fieldName}\n isRequired={isRequired}\n field={{\n ...field,\n type: info.selectedType,\n }}\n depth={depth + 1}\n slotType={showSelect ? false : slotType}\n toolbar={\n <>\n {showSelect && (\n <select\n className=\"text-xs font-mono\"\n value={info.selectedType}\n onChange={(e) => {\n updateInfo({\n selectedType: e.target.value,\n });\n }}\n >\n {field.type.map((item) => (\n <option\n key={item}\n value={item}\n className=\"bg-fd-popover text-fd-popover-foreground\"\n >\n {item}\n </option>\n ))}\n </select>\n )}\n {toolbar}\n </>\n }\n />\n );\n }\n\n if (field.type === 'object' || info.intersection) {\n const schema = info.intersection?.merged ?? field;\n return (\n <fieldset\n {...props}\n className={cn('flex flex-col gap-1.5 col-span-full @container', props.className)}\n >\n <FieldLabel htmlFor={id}>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n dataEngine.init(fieldName, getDefaultValue(schema));\n setShow((prev) => !prev);\n }}\n className={cn(\n buttonVariants({\n size: 'icon-xs',\n color: 'ghost',\n className: 'text-fd-muted-foreground -ms-1',\n }),\n )}\n >\n <ChevronRight className={cn(show && 'rotate-90')} />\n </button>\n )}\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n {show && (\n <ObjectInput\n field={schema}\n fieldName={fieldName}\n {...props}\n className={cn(\n 'rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm',\n props.className,\n )}\n />\n )}\n </fieldset>\n );\n }\n\n if (field.type === 'array') {\n return (\n <fieldset {...props} className={cn('flex flex-col gap-1.5 col-span-full', props.className)}>\n <FieldLabel htmlFor={id}>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => {\n dataEngine.init(fieldName, getDefaultValue(field));\n setShow((prev) => !prev);\n }}\n className={cn(\n buttonVariants({\n size: 'icon-xs',\n color: 'ghost',\n className: 'text-fd-muted-foreground -ms-1',\n }),\n )}\n >\n <ChevronRight className={cn(show && 'rotate-90')} />\n </button>\n )}\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n {show && (\n <ArrayInput\n fieldName={fieldName}\n items={field.items ?? anyFields}\n {...props}\n className={cn(\n 'rounded-lg border border-fd-primary/20 bg-fd-background/50 p-2 shadow-sm',\n props.className,\n )}\n />\n )}\n </fieldset>\n );\n }\n return (\n <fieldset {...props} className={cn('flex flex-col gap-1.5', props.className)}>\n <FieldLabel htmlFor={id}>\n <FieldLabelName required={isRequired}>{name}</FieldLabelName>\n {slotType ?? <FieldLabelType>{schemaToString(field)}</FieldLabelType>}\n {toolbar}\n </FieldLabel>\n <FieldInput field={field} fieldName={fieldName} isRequired={isRequired} />\n </fieldset>\n );\n}\n\nfunction ArrayInput({\n fieldName,\n items: itemSchema,\n ...props\n}: {\n fieldName: FieldKey;\n items: ParsedSchema;\n} & ComponentProps<'div'>) {\n const name = fieldName.at(-1) ?? '';\n const { items, insertItem, removeItem } = useArray(fieldName, {\n defaultValue: [],\n });\n\n return (\n <div {...props} className={cn('flex flex-col gap-2', props.className)}>\n {items.map((item) => (\n <FieldSet\n key={item.index}\n name={\n <span className=\"text-fd-muted-foreground\">\n {name}[{item.index}]\n </span>\n }\n field={itemSchema}\n isRequired\n fieldName={item.field}\n toolbar={\n <button\n type=\"button\"\n aria-label=\"Remove Item\"\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'icon-xs',\n }),\n )}\n onClick={() => removeItem(item.index)}\n >\n <Trash2 />\n </button>\n }\n />\n ))}\n <button\n type=\"button\"\n className={cn(\n buttonVariants({\n color: 'secondary',\n className: 'gap-1.5 py-2',\n size: 'sm',\n }),\n )}\n onClick={() => {\n insertItem(getDefaultValue(itemSchema));\n }}\n >\n <Plus className=\"size-4\" />\n New Item\n </button>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { cn } from "../../utils/cn.js";
2
+ import { useQuery } from "../../utils/use-query.js";
2
3
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/components/select.js";
3
4
  import { Input, labelVariants } from "../../ui/components/input.js";
4
- import { useQuery } from "../../utils/use-query.js";
5
5
  import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "../../ui/components/dialog.js";
6
6
  import { useEffect, useState } from "react";
7
- import { useForm } from "react-hook-form";
8
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
8
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
9
+ import { useForm } from "react-hook-form";
10
10
 
11
11
  //#region src/playground/components/oauth-dialog.tsx
12
12
  const FlowTypes = {