fumadocs-openapi 10.3.8 → 10.3.10

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,4 @@
1
- @source inline("!isRequired");
1
+ @source inline("!isDefined");
2
2
  @source inline("*:min-w-0");
3
3
  @source inline("--fd-docs-row-1");
4
4
  @source inline("--initial-height");
@@ -59,7 +59,6 @@
59
59
  @source inline("assume");
60
60
  @source inline("async");
61
61
  @source inline("at");
62
- @source inline("attachedData");
63
62
  @source inline("auth-specific");
64
63
  @source inline("authCodeCallback");
65
64
  @source inline("authNode");
@@ -246,7 +245,8 @@
246
245
  @source inline("fetch");
247
246
  @source inline("fetcher");
248
247
  @source inline("field");
249
- @source inline("field-info");
248
+ @source inline("fieldData");
249
+ @source inline("fieldLabelVariants");
250
250
  @source inline("fieldName");
251
251
  @source inline("fields");
252
252
  @source inline("file");
@@ -366,7 +366,6 @@
366
366
  @source inline("infoTags");
367
367
  @source inline("initAuthValues");
368
368
  @source inline("initial");
369
- @source inline("initialInfo");
370
369
  @source inline("initialPath");
371
370
  @source inline("inline-flex");
372
371
  @source inline("input");
@@ -379,6 +378,7 @@
379
378
  @source inline("interface");
380
379
  @source inline("intersection");
381
380
  @source inline("is");
381
+ @source inline("isDefined");
382
382
  @source inline("isDuplicated");
383
383
  @source inline("isDynamic");
384
384
  @source inline("isLoading");
@@ -878,8 +878,8 @@
878
878
  @source inline("useApiClientModal");
879
879
  @source inline("useApiContext");
880
880
  @source inline("useCopyButton");
881
- @source inline("useDataEngine");
882
881
  @source inline("useExampleRequests");
882
+ @source inline("useFieldValue");
883
883
  @source inline("useForm");
884
884
  @source inline("useMemo");
885
885
  @source inline("useObject");
@@ -9,18 +9,13 @@ import { FormatFlags, schemaToString } from "../../utils/schema-to-string.js";
9
9
  import { useState } from "react";
10
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { ChevronRight, Plus, Trash2, X } from "lucide-react";
12
+ import { cva } from "class-variance-authority";
12
13
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
13
14
  import { useArray, useDataEngine, useFieldValue, useObject } from "@fumari/stf";
14
15
  import { stringifyFieldKey } from "@fumari/stf/lib/utils";
15
16
 
16
17
  //#region src/playground/components/inputs.tsx
17
- function FieldLabel(props) {
18
- return /* @__PURE__ */ jsx("label", {
19
- ...props,
20
- className: cn("w-full inline-flex items-center gap-0.5", props.className),
21
- children: props.children
22
- });
23
- }
18
+ const fieldLabelVariants = cva("w-full inline-flex items-center gap-0.5");
24
19
  function FieldLabelType(props) {
25
20
  return /* @__PURE__ */ jsx("code", {
26
21
  ...props,
@@ -115,23 +110,10 @@ function JsonInput({ fieldName }) {
115
110
  });
116
111
  }
117
112
  function FieldInput({ field, fieldName, isRequired, ...props }) {
118
- const engine = useDataEngine();
119
113
  const [value, setValue] = useFieldValue(fieldName);
120
114
  const id = stringifyFieldKey(fieldName);
121
115
  if (field.type === "null") return;
122
- function renderUnset(children) {
123
- return /* @__PURE__ */ jsxs("div", {
124
- ...props,
125
- className: cn("flex flex-row gap-2", props.className),
126
- children: [children, value !== void 0 && !isRequired && /* @__PURE__ */ jsx("button", {
127
- type: "button",
128
- onClick: () => engine.delete(fieldName),
129
- className: "text-fd-muted-foreground",
130
- children: /* @__PURE__ */ jsx(X, { className: "size-4" })
131
- })]
132
- });
133
- }
134
- if (field.type === "string" && field.format === "binary") return renderUnset(/* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("label", {
116
+ if (field.type === "string" && field.format === "binary") return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("label", {
135
117
  htmlFor: id,
136
118
  className: cn(buttonVariants({
137
119
  color: "secondary",
@@ -156,7 +138,7 @@ function FieldInput({ field, fieldName, isRequired, ...props }) {
156
138
  setValue(e.target.files.item(0));
157
139
  },
158
140
  hidden: true
159
- })] }));
141
+ })] });
160
142
  if (field.enum && field.enum.length > 0) {
161
143
  const idx = field.enum.indexOf(value);
162
144
  return /* @__PURE__ */ jsxs(Select, {
@@ -198,7 +180,7 @@ function FieldInput({ field, fieldName, isRequired, ...props }) {
198
180
  ] })]
199
181
  });
200
182
  const isNumber = field.type === "integer" || field.type === "number";
201
- return renderUnset(/* @__PURE__ */ jsx(Input, {
183
+ return /* @__PURE__ */ jsx(Input, {
202
184
  id,
203
185
  placeholder: "Enter value",
204
186
  type: isNumber ? "number" : "text",
@@ -208,7 +190,7 @@ function FieldInput({ field, fieldName, isRequired, ...props }) {
208
190
  if (isNumber) setValue(Number.isNaN(e.target.valueAsNumber) ? void 0 : e.target.valueAsNumber);
209
191
  else if (!isNumber) setValue(e.target.value);
210
192
  }
211
- }));
193
+ });
212
194
  }
213
195
  function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth = 0, slotType, collapsible = true, ...props }) {
214
196
  const { readOnly, writeOnly } = useSchemaScope();
@@ -217,9 +199,13 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
217
199
  const { info, updateInfo } = useFieldInfo(fieldName, field);
218
200
  const id = stringifyFieldKey(fieldName);
219
201
  const dataEngine = useDataEngine();
202
+ const [isDefined] = useFieldValue(fieldName, { compute(currentValue) {
203
+ return currentValue !== void 0;
204
+ } });
220
205
  if (_field === false) return;
221
206
  if (field.readOnly && !readOnly) return;
222
207
  if (field.writeOnly && !writeOnly) return;
208
+ if (collapsible && !isDefined && show) setShow(false);
223
209
  function renderLabelTrigger(schema = field) {
224
210
  if (!collapsible) return renderLabelName();
225
211
  return /* @__PURE__ */ jsxs("button", {
@@ -248,6 +234,14 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
248
234
  })]
249
235
  });
250
236
  }
237
+ function renderUnsetButton() {
238
+ return /* @__PURE__ */ jsx("button", {
239
+ type: "button",
240
+ onClick: () => dataEngine.delete(fieldName),
241
+ className: "text-fd-muted-foreground hover:text-fd-accent-foreground",
242
+ children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
243
+ });
244
+ }
251
245
  if (info.unionField && field[info.unionField]) {
252
246
  const union = field[info.unionField];
253
247
  const showSelect = union.length > 1;
@@ -305,12 +299,13 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
305
299
  return /* @__PURE__ */ jsxs("fieldset", {
306
300
  ...props,
307
301
  className: cn("flex flex-col gap-1.5 col-span-full @container", props.className),
308
- children: [/* @__PURE__ */ jsxs(FieldLabel, {
309
- htmlFor: id,
302
+ children: [/* @__PURE__ */ jsxs("div", {
303
+ className: fieldLabelVariants(),
310
304
  children: [
311
305
  renderLabelTrigger(schema),
312
306
  slotType ?? /* @__PURE__ */ jsx(FieldLabelType, { children: schemaToString(field) }),
313
- toolbar
307
+ toolbar,
308
+ !isRequired && isDefined && renderUnsetButton()
314
309
  ]
315
310
  }), show && /* @__PURE__ */ jsx(ObjectInput, {
316
311
  field: schema,
@@ -322,12 +317,13 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
322
317
  if (field.type === "array") return /* @__PURE__ */ jsxs("fieldset", {
323
318
  ...props,
324
319
  className: cn("flex flex-col gap-1.5 col-span-full", props.className),
325
- children: [/* @__PURE__ */ jsxs(FieldLabel, {
326
- htmlFor: id,
320
+ children: [/* @__PURE__ */ jsxs("div", {
321
+ className: fieldLabelVariants(),
327
322
  children: [
328
323
  renderLabelTrigger(),
329
324
  slotType ?? /* @__PURE__ */ jsx(FieldLabelType, { children: schemaToString(field) }),
330
- toolbar
325
+ toolbar,
326
+ !isRequired && isDefined && renderUnsetButton()
331
327
  ]
332
328
  }), show && /* @__PURE__ */ jsx(ArrayInput, {
333
329
  fieldName,
@@ -338,12 +334,14 @@ function FieldSet({ field: _field, fieldName, toolbar, name, isRequired, depth =
338
334
  return /* @__PURE__ */ jsxs("fieldset", {
339
335
  ...props,
340
336
  className: cn("flex flex-col gap-1.5", props.className),
341
- children: [/* @__PURE__ */ jsxs(FieldLabel, {
337
+ children: [/* @__PURE__ */ jsxs("label", {
338
+ className: fieldLabelVariants(),
342
339
  htmlFor: id,
343
340
  children: [
344
341
  renderLabelName(),
345
342
  slotType ?? /* @__PURE__ */ jsx(FieldLabelType, { children: schemaToString(field) }),
346
- toolbar
343
+ toolbar,
344
+ !isRequired && isDefined && renderUnsetButton()
347
345
  ]
348
346
  }), /* @__PURE__ */ jsx(FieldInput, {
349
347
  field,
@@ -118,7 +118,8 @@ function Field({ fieldName, variable }) {
118
118
  return /* @__PURE__ */ jsx(Input, {
119
119
  id: fieldName,
120
120
  value,
121
- onChange: (e) => setValue(e.target.value)
121
+ onChange: (e) => setValue(e.target.value),
122
+ placeholder: "Enter Value"
122
123
  });
123
124
  }
124
125
 
@@ -21,6 +21,6 @@ declare function APIPlayground({
21
21
  path,
22
22
  method,
23
23
  ctx
24
- }: APIPlaygroundProps): Promise<string | number | bigint | boolean | react_jsx_runtime0.JSX.Element | Iterable<react.ReactNode> | null | undefined>;
24
+ }: APIPlaygroundProps): Promise<string | number | bigint | boolean | Iterable<react.ReactNode> | react_jsx_runtime0.JSX.Element | null | undefined>;
25
25
  //#endregion
26
26
  export { APIPlayground, APIPlaygroundProps, ParameterField, SecurityEntry };
@@ -1,9 +1,10 @@
1
1
  import { getDefaultValue } from "./get-default-values.js";
2
2
  import { mergeAllOf } from "../utils/merge-schema.js";
3
- import { createContext, use, useMemo, useState } from "react";
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 } from "@fumari/stf";
6
+ import { useDataEngine, useFieldValue } from "@fumari/stf";
7
+ import { stringifyFieldKey } from "@fumari/stf/lib/utils";
7
8
 
8
9
  //#region src/playground/schema.tsx
9
10
  const SchemaContext = createContext(void 0);
@@ -53,11 +54,8 @@ function useSchemaScope() {
53
54
  function useFieldInfo(fieldName, schema) {
54
55
  const { ajv } = use(SchemaContext);
55
56
  const engine = useDataEngine();
56
- const attachedData = engine.attachedData("field-info");
57
- const [info, setInfo] = useState(() => {
57
+ const [info, setInfo] = useFieldValue([], { stf: engine.namespace(`field-info:${stringifyFieldKey(fieldName)}`, () => {
58
58
  const value = engine.get(fieldName);
59
- const initialInfo = attachedData.get(fieldName);
60
- if (initialInfo) return initialInfo;
61
59
  const out = { oneOf: -1 };
62
60
  const union = getUnion(schema);
63
61
  if (union) {
@@ -80,11 +78,10 @@ function useFieldInfo(fieldName, schema) {
80
78
  if (typeof merged !== "boolean") out.intersection = { merged };
81
79
  }
82
80
  return out;
83
- });
84
- attachedData.set(fieldName, info);
81
+ }) });
85
82
  return {
86
83
  info,
87
- updateInfo: (value) => {
84
+ updateInfo(value) {
88
85
  const updated = {
89
86
  ...info,
90
87
  ...value
@@ -95,7 +95,7 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
95
95
  if (!params || params.length === 0) return;
96
96
  return /* @__PURE__ */ jsxs(Fragment, { children: [ctx.renderHeading(headingLevel, title), /* @__PURE__ */ jsx("div", {
97
97
  className: "flex flex-col",
98
- children: params.map((param) => /* @__PURE__ */ jsx(Schema, {
98
+ children: params.map((param) => param.schema != null && /* @__PURE__ */ jsx(Schema, {
99
99
  client: {
100
100
  name: param.name,
101
101
  required: param.required
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-openapi",
3
- "version": "10.3.8",
3
+ "version": "10.3.10",
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": "^0.0.3"
80
+ "@fumari/stf": "1.0.0"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@scalar/api-client-react": "^1.3.96",