fumadocs-openapi 10.6.7 → 10.6.8

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.
@@ -337,6 +337,7 @@
337
337
  @source inline("font-semibold");
338
338
  @source inline("for");
339
339
  @source inline("form");
340
+ @source inline("formData");
340
341
  @source inline("format");
341
342
  @source inline("forwardRef");
342
343
  @source inline("found");
@@ -591,7 +592,6 @@
591
592
  @source inline("openApiData");
592
593
  @source inline("openIdConnect");
593
594
  @source inline("openapi");
594
- @source inline("openapi-sampler");
595
595
  @source inline("openapi-types");
596
596
  @source inline("openid");
597
597
  @source inline("operation");
@@ -708,7 +708,6 @@
708
708
  @source inline("raw");
709
709
  @source inline("rawSearch");
710
710
  @source inline("react");
711
- @source inline("react-hook-form");
712
711
  @source inline("react-hooks/exhaustive-deps");
713
712
  @source inline("react/jsx-runtime");
714
713
  @source inline("read");
@@ -1037,12 +1036,11 @@
1037
1036
  @source inline("usageTabs");
1038
1037
  @source inline("usages");
1039
1038
  @source inline("use");
1040
- @source inline("useApiClientModal");
1039
+ @source inline("useApiClient");
1041
1040
  @source inline("useApiContext");
1042
1041
  @source inline("useAuth");
1043
1042
  @source inline("useCopyButton");
1044
1043
  @source inline("useFieldValue");
1045
- @source inline("useForm");
1046
1044
  @source inline("useI18n");
1047
1045
  @source inline("useMemo");
1048
1046
  @source inline("useNamespace");
@@ -1,5 +1,6 @@
1
1
  //#region \0rolldown/runtime.js
2
2
  var __defProp = Object.defineProperty;
3
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
3
4
  var __exportAll = (all, no_symbols) => {
4
5
  let target = {};
5
6
  for (var name in all) __defProp(target, name, {
@@ -10,4 +11,4 @@ var __exportAll = (all, no_symbols) => {
10
11
  return target;
11
12
  };
12
13
  //#endregion
13
- export { __exportAll };
14
+ export { __commonJSMin, __exportAll };
package/dist/i18n.js CHANGED
@@ -1,5 +1,6 @@
1
- import { deepmerge } from "@fastify/deepmerge";
1
+ import { require_deepmerge } from "./node_modules/.pnpm/@fastify_deepmerge@3.2.1/node_modules/@fastify/deepmerge/index.js";
2
2
  //#region src/i18n.ts
3
+ var import_deepmerge = require_deepmerge();
3
4
  const defaultTranslations = {
4
5
  loading: "loading...",
5
6
  empty: "Empty",
@@ -95,7 +96,7 @@ const defaultTranslations = {
95
96
  playgroundInputUnset: "Unset"
96
97
  };
97
98
  function defineI18nOpenAPI(config, translations) {
98
- const dm = deepmerge();
99
+ const dm = (0, import_deepmerge.deepmerge)();
99
100
  return {
100
101
  ...config,
101
102
  provider(locale = config.defaultLanguage) {
@@ -0,0 +1,108 @@
1
+ import { __commonJSMin } from "../../../../../../_virtual/_rolldown/runtime.js";
2
+ //#region ../../node_modules/.pnpm/@fastify+deepmerge@3.2.1/node_modules/@fastify/deepmerge/index.js
3
+ var require_deepmerge = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4
+ const JSON_PROTO = Object.getPrototypeOf({});
5
+ function defaultIsMergeableObjectFactory() {
6
+ return function defaultIsMergeableObject(value) {
7
+ return typeof value === "object" && value !== null && !(value instanceof RegExp) && !(value instanceof Date);
8
+ };
9
+ }
10
+ function deepmergeConstructor(options) {
11
+ function isNotPrototypeKey(value) {
12
+ return value !== "constructor" && value !== "prototype" && value !== "__proto__";
13
+ }
14
+ function cloneArray(value) {
15
+ let i = 0;
16
+ const il = value.length;
17
+ const result = new Array(il);
18
+ for (; i < il; ++i) result[i] = clone(value[i]);
19
+ return result;
20
+ }
21
+ function cloneObject(target) {
22
+ const result = {};
23
+ if (cloneProtoObject && Object.getPrototypeOf(target) !== JSON_PROTO) return cloneProtoObject(target);
24
+ const targetKeys = getKeys(target);
25
+ let i, il, key;
26
+ for (i = 0, il = targetKeys.length; i < il; ++i) isNotPrototypeKey(key = targetKeys[i]) && (result[key] = clone(target[key]));
27
+ return result;
28
+ }
29
+ function concatArrays(target, source) {
30
+ const tl = target.length;
31
+ const sl = source.length;
32
+ let i = 0;
33
+ const result = new Array(tl + sl);
34
+ for (; i < tl; ++i) result[i] = clone(target[i]);
35
+ for (i = 0; i < sl; ++i) result[i + tl] = clone(source[i]);
36
+ return result;
37
+ }
38
+ const propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
39
+ function getSymbolsAndKeys(value) {
40
+ const result = Object.keys(value);
41
+ const keys = Object.getOwnPropertySymbols(value);
42
+ for (let i = 0, il = keys.length; i < il; ++i) propertyIsEnumerable.call(value, keys[i]) && result.push(keys[i]);
43
+ return result;
44
+ }
45
+ const getKeys = options?.symbols ? getSymbolsAndKeys : Object.keys;
46
+ const cloneProtoObject = typeof options?.cloneProtoObject === "function" ? options.cloneProtoObject : void 0;
47
+ const isMergeableObject = typeof options?.isMergeableObject === "function" ? options.isMergeableObject : defaultIsMergeableObjectFactory();
48
+ const onlyDefinedProperties = options?.onlyDefinedProperties === true;
49
+ function isPrimitive(value) {
50
+ return typeof value !== "object" || value === null;
51
+ }
52
+ const mergeArray = options && typeof options.mergeArray === "function" ? options.mergeArray({
53
+ clone,
54
+ deepmerge: _deepmerge,
55
+ getKeys,
56
+ isMergeableObject
57
+ }) : concatArrays;
58
+ function clone(entry) {
59
+ return isMergeableObject(entry) ? Array.isArray(entry) ? cloneArray(entry) : cloneObject(entry) : entry;
60
+ }
61
+ function mergeObject(target, source) {
62
+ const result = {};
63
+ const targetKeys = getKeys(target);
64
+ const sourceKeys = getKeys(source);
65
+ let i, il, key;
66
+ for (i = 0, il = targetKeys.length; i < il; ++i) isNotPrototypeKey(key = targetKeys[i]) && sourceKeys.indexOf(key) === -1 && (result[key] = clone(target[key]));
67
+ for (i = 0, il = sourceKeys.length; i < il; ++i) {
68
+ if (!isNotPrototypeKey(key = sourceKeys[i])) continue;
69
+ if (key in target) {
70
+ if (targetKeys.indexOf(key) !== -1) if (cloneProtoObject && isMergeableObject(source[key]) && Object.getPrototypeOf(source[key]) !== JSON_PROTO) result[key] = cloneProtoObject(source[key]);
71
+ else result[key] = _deepmerge(target[key], source[key]);
72
+ } else {
73
+ if (onlyDefinedProperties && typeof source[key] === "undefined") continue;
74
+ result[key] = clone(source[key]);
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ function _deepmerge(target, source) {
80
+ if (onlyDefinedProperties && typeof source === "undefined") return clone(target);
81
+ const sourceIsArray = Array.isArray(source);
82
+ const targetIsArray = Array.isArray(target);
83
+ if (isPrimitive(source)) return source;
84
+ else if (!isMergeableObject(target)) return clone(source);
85
+ else if (sourceIsArray && targetIsArray) return mergeArray(target, source);
86
+ else if (sourceIsArray !== targetIsArray) return clone(source);
87
+ else return mergeObject(target, source);
88
+ }
89
+ function _deepmergeAll() {
90
+ switch (arguments.length) {
91
+ case 0: return {};
92
+ case 1: return clone(arguments[0]);
93
+ case 2: return _deepmerge(arguments[0], arguments[1]);
94
+ }
95
+ let result;
96
+ for (let i = 0, il = arguments.length; i < il; ++i) result = _deepmerge(result, arguments[i]);
97
+ return result;
98
+ }
99
+ return options?.all ? _deepmergeAll : _deepmerge;
100
+ }
101
+ module.exports = deepmergeConstructor;
102
+ module.exports.default = deepmergeConstructor;
103
+ module.exports.deepmerge = deepmergeConstructor;
104
+ Object.defineProperty(module.exports, "isMergeableObject", { get: defaultIsMergeableObjectFactory });
105
+ }));
106
+ //#endregion
107
+ export default require_deepmerge();
108
+ export { require_deepmerge };
@@ -0,0 +1,115 @@
1
+ import { __commonJSMin } from "../../../../../_virtual/_rolldown/runtime.js";
2
+ //#region ../../node_modules/.pnpm/fast-content-type-parse@3.0.0/node_modules/fast-content-type-parse/index.js
3
+ var require_fast_content_type_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4
+ const NullObject = function NullObject() {};
5
+ NullObject.prototype = Object.create(null);
6
+ /**
7
+ * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1
8
+ *
9
+ * parameter = token "=" ( token / quoted-string )
10
+ * token = 1*tchar
11
+ * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
12
+ * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
13
+ * / DIGIT / ALPHA
14
+ * ; any VCHAR, except delimiters
15
+ * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
16
+ * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
17
+ * obs-text = %x80-FF
18
+ * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
19
+ */
20
+ const paramRE = /; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu;
21
+ /**
22
+ * RegExp to match quoted-pair in RFC 7230 sec 3.2.6
23
+ *
24
+ * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
25
+ * obs-text = %x80-FF
26
+ */
27
+ const quotedPairRE = /\\([\v\u0020-\u00ff])/gu;
28
+ /**
29
+ * RegExp to match type in RFC 7231 sec 3.1.1.1
30
+ *
31
+ * media-type = type "/" subtype
32
+ * type = token
33
+ * subtype = token
34
+ */
35
+ const mediaTypeRE = /^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u;
36
+ const defaultContentType = {
37
+ type: "",
38
+ parameters: new NullObject()
39
+ };
40
+ Object.freeze(defaultContentType.parameters);
41
+ Object.freeze(defaultContentType);
42
+ /**
43
+ * Parse media type to object.
44
+ *
45
+ * @param {string|object} header
46
+ * @return {Object}
47
+ * @public
48
+ */
49
+ function parse(header) {
50
+ if (typeof header !== "string") throw new TypeError("argument header is required and must be a string");
51
+ let index = header.indexOf(";");
52
+ const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
53
+ if (mediaTypeRE.test(type) === false) throw new TypeError("invalid media type");
54
+ const result = {
55
+ type: type.toLowerCase(),
56
+ parameters: new NullObject()
57
+ };
58
+ if (index === -1) return result;
59
+ let key;
60
+ let match;
61
+ let value;
62
+ paramRE.lastIndex = index;
63
+ while (match = paramRE.exec(header)) {
64
+ if (match.index !== index) throw new TypeError("invalid parameter format");
65
+ index += match[0].length;
66
+ key = match[1].toLowerCase();
67
+ value = match[2];
68
+ if (value[0] === "\"") {
69
+ value = value.slice(1, value.length - 1);
70
+ quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
71
+ }
72
+ result.parameters[key] = value;
73
+ }
74
+ if (index !== header.length) throw new TypeError("invalid parameter format");
75
+ return result;
76
+ }
77
+ function safeParse(header) {
78
+ if (typeof header !== "string") return defaultContentType;
79
+ let index = header.indexOf(";");
80
+ const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
81
+ if (mediaTypeRE.test(type) === false) return defaultContentType;
82
+ const result = {
83
+ type: type.toLowerCase(),
84
+ parameters: new NullObject()
85
+ };
86
+ if (index === -1) return result;
87
+ let key;
88
+ let match;
89
+ let value;
90
+ paramRE.lastIndex = index;
91
+ while (match = paramRE.exec(header)) {
92
+ if (match.index !== index) return defaultContentType;
93
+ index += match[0].length;
94
+ key = match[1].toLowerCase();
95
+ value = match[2];
96
+ if (value[0] === "\"") {
97
+ value = value.slice(1, value.length - 1);
98
+ quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
99
+ }
100
+ result.parameters[key] = value;
101
+ }
102
+ if (index !== header.length) return defaultContentType;
103
+ return result;
104
+ }
105
+ module.exports.default = {
106
+ parse,
107
+ safeParse
108
+ };
109
+ module.exports.parse = parse;
110
+ module.exports.safeParse = safeParse;
111
+ module.exports.defaultContentType = defaultContentType;
112
+ }));
113
+ //#endregion
114
+ export default require_fast_content_type_parse();
115
+ export { require_fast_content_type_parse };
@@ -9,7 +9,6 @@ import { useAuth } from "../auth.js";
9
9
  import { useMemo, useState } from "react";
10
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
12
- import { useForm } from "react-hook-form";
13
12
  //#region src/playground/components/oauth-dialog.tsx
14
13
  const OAuthDialog = Dialog;
15
14
  function OAuthDialogContent(props) {
@@ -52,14 +51,14 @@ function Content({ schemeId, scopes, setToken, setOpen }) {
52
51
  supported: false
53
52
  }
54
53
  }), [t]);
55
- const form = useForm({ defaultValues: useMemo(() => {
54
+ const defaultValues = useMemo(() => {
56
55
  return {
57
56
  clientId: tokenInfo?.client_id ?? "",
58
57
  clientSecret: tokenInfo?.type === "authorization_code" ? tokenInfo.client_secret : "",
59
58
  username: "",
60
59
  password: ""
61
60
  };
62
- }, [tokenInfo]) });
61
+ }, [tokenInfo]);
63
62
  const authorize = useQuery(async (values) => {
64
63
  if (type === "implicit") {
65
64
  const value = scheme.flows[type];
@@ -127,13 +126,12 @@ function Content({ schemeId, scopes, setToken, setOpen }) {
127
126
  }
128
127
  });
129
128
  const isLoading = authorize.isLoading;
130
- const onSubmit = form.handleSubmit((values) => {
131
- return authorize.start(values);
132
- });
133
129
  return /* @__PURE__ */ jsxs("form", {
134
130
  className: "flex flex-col gap-6",
135
131
  onSubmit: (e) => {
136
- onSubmit(e);
132
+ const formData = new FormData(e.target);
133
+ authorize.start(Object.fromEntries(formData.entries()));
134
+ e.preventDefault();
137
135
  e.stopPropagation();
138
136
  },
139
137
  children: [
@@ -168,11 +166,13 @@ function Content({ schemeId, scopes, setToken, setOpen }) {
168
166
  }),
169
167
  /* @__PURE__ */ jsx(Input, {
170
168
  id: "client_id",
169
+ name: "clientId",
171
170
  placeholder: t.inputPlaceholder,
172
171
  type: "text",
173
172
  autoComplete: "off",
174
173
  disabled: isLoading,
175
- ...form.register("clientId", { required: true })
174
+ defaultValue: defaultValues.clientId,
175
+ required: true
176
176
  })
177
177
  ]
178
178
  }),
@@ -190,11 +190,13 @@ function Content({ schemeId, scopes, setToken, setOpen }) {
190
190
  }),
191
191
  /* @__PURE__ */ jsx(Input, {
192
192
  id: "client_secret",
193
+ name: "clientSecret",
193
194
  placeholder: t.inputPlaceholder,
194
195
  type: "password",
195
196
  autoComplete: "off",
196
197
  disabled: isLoading,
197
- ...form.register("clientSecret", { required: true })
198
+ defaultValue: defaultValues.clientSecret,
199
+ required: true
198
200
  })
199
201
  ]
200
202
  }),
@@ -206,11 +208,13 @@ function Content({ schemeId, scopes, setToken, setOpen }) {
206
208
  children: t.usernameField
207
209
  }), /* @__PURE__ */ jsx(Input, {
208
210
  id: "username",
211
+ name: "username",
209
212
  placeholder: t.inputPlaceholder,
210
213
  type: "text",
211
214
  autoComplete: "off",
212
215
  disabled: isLoading,
213
- ...form.register("username", { required: true })
216
+ defaultValue: defaultValues.username,
217
+ required: true
214
218
  })]
215
219
  }), /* @__PURE__ */ jsxs("fieldset", {
216
220
  className: "flex flex-col gap-1.5",
@@ -220,11 +224,13 @@ function Content({ schemeId, scopes, setToken, setOpen }) {
220
224
  children: t.clientSecret
221
225
  }), /* @__PURE__ */ jsx(Input, {
222
226
  id: "password",
227
+ name: "password",
223
228
  placeholder: t.inputPlaceholder,
224
229
  type: "password",
225
230
  autoComplete: "off",
226
231
  disabled: isLoading,
227
- ...form.register("password", { required: true })
232
+ defaultValue: defaultValues.password,
233
+ required: true
228
234
  })]
229
235
  })] }),
230
236
  type && allFlows[type].supported ? /* @__PURE__ */ jsxs(Fragment$1, { children: [authorize.error ? /* @__PURE__ */ jsx("p", {
@@ -3,13 +3,14 @@ import { useTranslations, withReplacements } from "../../ui/client/i18n.js";
3
3
  import { useStatusInfo } from "../status-info.js";
4
4
  import { cn } from "../../utils/cn.js";
5
5
  import { ClientCodeBlock } from "../../ui/components/codeblock.js";
6
+ import { require_fast_content_type_parse } from "../../node_modules/.pnpm/fast-content-type-parse@3.0.0/node_modules/fast-content-type-parse/index.js";
6
7
  import { useEffect, useMemo, useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
9
  import { CircleX } from "lucide-react";
9
10
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
10
- import { safeParse } from "fast-content-type-parse";
11
11
  import { cva } from "class-variance-authority";
12
12
  //#region src/playground/components/result-display.tsx
13
+ var import_fast_content_type_parse = require_fast_content_type_parse();
13
14
  const panelVariants = cva("flex flex-col gap-2 mt-2 px-3 py-2 border-y bg-fd-secondary text-fd-secondary-foreground");
14
15
  function DefaultResultDisplay({ data, reset, ...rest }) {
15
16
  const t = useTranslations();
@@ -60,7 +61,7 @@ function getTextFormat(mime) {
60
61
  function ResponseResult({ data, reset, ...rest }) {
61
62
  const t = useTranslations();
62
63
  const statusInfo = useStatusInfo(data.status);
63
- const { parameters, type } = useMemo(() => safeParse(data.headers.get("Content-Type") ?? "text/plain"), [data.headers]);
64
+ const { parameters, type } = useMemo(() => (0, import_fast_content_type_parse.safeParse)(data.headers.get("Content-Type") ?? "text/plain"), [data.headers]);
64
65
  let content;
65
66
  if (type.startsWith("image/")) content = /* @__PURE__ */ jsx(ImageResult, {
66
67
  mime: type,
@@ -1,4 +1,5 @@
1
1
  import { mergeAllOf } from "../utils/schema/merge.js";
2
+ import { sample } from "../utils/schema/sample.js";
2
3
  import { schemaToString } from "../utils/schema/to-string.js";
3
4
  import { dereferenceSwallow } from "../utils/schema/dereference.js";
4
5
  import { createContext, use, useMemo } from "react";
@@ -6,7 +7,6 @@ import { jsx } from "react/jsx-runtime";
6
7
  import { Ajv2020 } from "ajv/dist/2020.js";
7
8
  import { useDataEngine, useFieldValue, useNamespace } from "@fumari/stf";
8
9
  import { stringifyFieldKey } from "@fumari/stf/lib/utils";
9
- import { sample } from "openapi-sampler";
10
10
  //#region src/playground/schema.tsx
11
11
  const SchemaContext = createContext(void 0);
12
12
  const anyFields = {
@@ -4,13 +4,17 @@ import { MethodLabel } from "../ui/components/method-label.js";
4
4
  import { useEffect, useState } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
7
- import { ApiClientModalProvider, useApiClientModal } from "@scalar/api-client-react";
7
+ import { useApiClient } from "@scalar/api-client-react";
8
8
  import { useTheme } from "next-themes";
9
9
  import "@scalar/api-client-react/style.css";
10
10
  //#region src/scalar/client.tsx
11
11
  function ScalarPlayground({ path, method, spec }) {
12
12
  const { resolvedTheme } = useTheme();
13
13
  const [mounted, setMounted] = useState(false);
14
+ const client = useApiClient({ configuration: {
15
+ theme: "moon",
16
+ spec
17
+ } });
14
18
  useEffect(() => {
15
19
  setMounted(true);
16
20
  }, []);
@@ -25,33 +29,20 @@ function ScalarPlayground({ path, method, spec }) {
25
29
  className: "flex-1 overflow-auto text-nowrap text-[0.8125rem] text-fd-muted-foreground",
26
30
  children: path
27
31
  }),
28
- /* @__PURE__ */ jsx(ApiClientModalProvider, {
29
- configuration: {
30
- theme: "moon",
31
- content: spec
32
- },
33
- children: /* @__PURE__ */ jsx(Trigger, {
32
+ /* @__PURE__ */ jsx("button", {
33
+ type: "submit",
34
+ className: cn(buttonVariants({
35
+ color: "primary",
36
+ size: "sm"
37
+ }), "px-3 py-1.5"),
38
+ onClick: () => client?.open({
34
39
  path,
35
40
  method
36
- })
41
+ }),
42
+ children: "Test"
37
43
  })
38
44
  ]
39
45
  });
40
46
  }
41
- function Trigger({ path, method }) {
42
- const client = useApiClientModal();
43
- return /* @__PURE__ */ jsx("button", {
44
- type: "submit",
45
- className: cn(buttonVariants({
46
- color: "primary",
47
- size: "sm"
48
- }), "px-3 py-1.5"),
49
- onClick: () => client?.open({
50
- path,
51
- method
52
- }),
53
- children: "Test"
54
- });
55
- }
56
47
  //#endregion
57
48
  export { ScalarPlayground as default };
@@ -1,6 +1,6 @@
1
1
  import { getPreferredType, pickExample } from "../../utils/schema/index.js";
2
2
  import { encodeRequestData } from "../../requests/media/encode.js";
3
- import { sample } from "openapi-sampler";
3
+ import { sample } from "../../utils/schema/sample.js";
4
4
  //#region src/ui/operation/get-example-requests.ts
5
5
  function getExampleRequests(path, operation, ctx) {
6
6
  const requestBody = operation.requestBody;
@@ -1,9 +1,9 @@
1
1
  import { getPreferredType } from "../../utils/schema/index.js";
2
2
  import { I18nLabel } from "../client/i18n.js";
3
+ import { sample } from "../../utils/schema/sample.js";
3
4
  import { AccordionContent, AccordionHeader, AccordionItem, AccordionTrigger, Accordions } from "../components/accordion.js";
4
5
  import { useMemo } from "react";
5
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
- import { sample } from "openapi-sampler";
7
7
  import { Tab, Tabs } from "fumadocs-ui/components/tabs";
8
8
  //#region src/ui/operation/response-tabs.tsx
9
9
  function ResponseTabs({ operation, ctx }) {
@@ -0,0 +1,442 @@
1
+ import { require_deepmerge } from "../../node_modules/.pnpm/@fastify_deepmerge@3.2.1/node_modules/@fastify/deepmerge/index.js";
2
+ import { isPlainObject } from "../is-plain-object.js";
3
+ import { resolveRefSync } from "./resolve-ref.js";
4
+ const mergeDeep = (0, require_deepmerge().deepmerge)({
5
+ all: true,
6
+ isMergeableObject(value) {
7
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof RegExp) && !(value instanceof Date);
8
+ }
9
+ });
10
+ const SKIP = Symbol("skip");
11
+ const defaultOptions = {
12
+ skipReadOnly: false,
13
+ maxSampleDepth: 15
14
+ };
15
+ let refResolving = {};
16
+ const seenObjectStack = [];
17
+ function clearCaches() {
18
+ refResolving = {};
19
+ seenObjectStack.length = 0;
20
+ }
21
+ function popStack(context) {
22
+ if (context) seenObjectStack.pop();
23
+ }
24
+ function inferType(schema) {
25
+ if (schema.type !== void 0) {
26
+ const t = schema.type;
27
+ return Array.isArray(t) ? t.length === 0 ? null : String(t[0]) : String(t);
28
+ }
29
+ for (const [kw, ty] of Object.entries({
30
+ multipleOf: "number",
31
+ maximum: "number",
32
+ exclusiveMaximum: "number",
33
+ minimum: "number",
34
+ exclusiveMinimum: "number",
35
+ maxLength: "string",
36
+ minLength: "string",
37
+ pattern: "string",
38
+ items: "array",
39
+ maxItems: "array",
40
+ minItems: "array",
41
+ uniqueItems: "array",
42
+ additionalItems: "array",
43
+ maxProperties: "object",
44
+ minProperties: "object",
45
+ required: "object",
46
+ additionalProperties: "object",
47
+ properties: "object",
48
+ patternProperties: "object",
49
+ dependencies: "object"
50
+ })) if (schema[kw] !== void 0) return ty;
51
+ return null;
52
+ }
53
+ function getCircularPlaceholder(type) {
54
+ if (type === "object") return {};
55
+ if (type === "array") return [];
56
+ }
57
+ function hashCode(str) {
58
+ let hash = 0;
59
+ for (let i = 0; i < str.length; i++) {
60
+ hash = (hash << 5) - hash + str.charCodeAt(i);
61
+ hash |= 0;
62
+ }
63
+ return hash;
64
+ }
65
+ function jsf32(a, b, c, d) {
66
+ return () => {
67
+ a |= 0;
68
+ b |= 0;
69
+ c |= 0;
70
+ d |= 0;
71
+ const t = a - (b << 27 | b >>> 5) | 0;
72
+ a = b ^ (c << 17 | c >>> 15);
73
+ b = c + d | 0;
74
+ c = d + t | 0;
75
+ d = a + t | 0;
76
+ return (d >>> 0) / 4294967296;
77
+ };
78
+ }
79
+ function uuidFromSeed(str) {
80
+ const hash = hashCode(str);
81
+ const random = jsf32(hash, hash, hash, hash);
82
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
83
+ const r = random() * 16 | 0;
84
+ return (c === "x" ? r : r & 3 | 8).toString(16);
85
+ });
86
+ }
87
+ function toRFCDateTime(date, omitTime, omitDate, ms) {
88
+ const pad = (n) => n < 10 ? `0${n}` : `${n}`;
89
+ let res = omitDate ? "" : `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}`;
90
+ if (!omitTime) {
91
+ res += `T${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}`;
92
+ if (ms) res += `.${(date.getUTCMilliseconds() / 1e3).toFixed(3).slice(2, 5)}`;
93
+ res += "Z";
94
+ }
95
+ return res;
96
+ }
97
+ function ensureMinLength(sample, min) {
98
+ if (min > sample.length) return sample.repeat(Math.trunc(min / sample.length) + 1).substring(0, min);
99
+ return sample;
100
+ }
101
+ function sampleBoolean() {
102
+ return true;
103
+ }
104
+ function sampleNumber(schema) {
105
+ let res = 0;
106
+ if (schema.type === "number" && (schema.format === "float" || schema.format === "double")) res = .1;
107
+ const exMinB = typeof schema.exclusiveMinimum === "boolean";
108
+ const exMaxB = typeof schema.exclusiveMaximum === "boolean";
109
+ if (exMinB || exMaxB) {
110
+ if (schema.maximum != null && schema.minimum != null) {
111
+ const min = schema.minimum;
112
+ const max = schema.maximum;
113
+ res = schema.exclusiveMinimum ? Math.floor(min) + 1 : min;
114
+ if (schema.exclusiveMaximum && res >= max || !schema.exclusiveMaximum && res > max) res = (max + min) / 2;
115
+ return res;
116
+ }
117
+ if (schema.minimum != null) {
118
+ const min = schema.minimum;
119
+ return schema.exclusiveMinimum ? Math.floor(min) + 1 : min;
120
+ }
121
+ if (schema.maximum != null) {
122
+ const max = schema.maximum;
123
+ if (schema.exclusiveMaximum) return max > 0 ? 0 : Math.floor(max) - 1;
124
+ return max > 0 ? 0 : max;
125
+ }
126
+ } else {
127
+ if (schema.minimum != null) return schema.minimum;
128
+ if (schema.exclusiveMinimum != null) {
129
+ res = Math.floor(schema.exclusiveMinimum) + 1;
130
+ if (res === schema.exclusiveMaximum) res = (res + Math.floor(schema.exclusiveMaximum) - 1) / 2;
131
+ } else if (schema.exclusiveMaximum != null) res = Math.floor(schema.exclusiveMaximum) - 1;
132
+ else if (schema.maximum != null) res = schema.maximum;
133
+ }
134
+ return res;
135
+ }
136
+ function defaultStringSample(min, max, pattern, enablePatterns) {
137
+ if (pattern && enablePatterns) return patternSample(pattern);
138
+ let res = ensureMinLength("string", min);
139
+ if (max != null && res.length > max) res = res.substring(0, max);
140
+ return res;
141
+ }
142
+ /** Minimal pattern sampler for `enablePatterns` (subset of openapi-sampler). */
143
+ function patternSample(pattern) {
144
+ const stripped = pattern.replace(/^\^?/, "").replace(/\$?$/, "");
145
+ const m = stripped.match(/^(.)\{(\d+)\}$/);
146
+ if (m) return m[1].repeat(parseInt(m[2], 10));
147
+ return stripped.length > 0 ? stripped : "x";
148
+ }
149
+ function sampleString(schema, options, _spec, context) {
150
+ const format = schema.format || "default";
151
+ const propertyName = context?.propertyName;
152
+ const min = schema.minLength ?? 0;
153
+ const max = schema.maxLength;
154
+ const pattern = schema.pattern;
155
+ const fixed = /* @__PURE__ */ new Date("2019-08-24T14:15:22.123Z");
156
+ const formats = {
157
+ email: () => "user@example.com",
158
+ "idn-email": () => "пошта@укр.нет",
159
+ password: () => {
160
+ let res = "pa$$word";
161
+ if (min > res.length) {
162
+ res += "_";
163
+ res += ensureMinLength("qwerty!@#$%^123456", min - res.length).substring(0, min - res.length);
164
+ }
165
+ return res;
166
+ },
167
+ "date-time": () => toRFCDateTime(fixed, false, false, false),
168
+ date: () => toRFCDateTime(fixed, true, false, false),
169
+ time: () => toRFCDateTime(fixed, false, true, false).slice(1),
170
+ ipv4: () => "192.168.0.1",
171
+ ipv6: () => "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
172
+ hostname: () => "example.com",
173
+ "idn-hostname": () => "приклад.укр",
174
+ uri: () => "http://example.com",
175
+ "uri-reference": () => "../dictionary",
176
+ "uri-template": () => "http://example.com/{endpoint}",
177
+ iri: () => "http://example.com/entity/1",
178
+ "iri-reference": () => "/entity/1",
179
+ uuid: () => uuidFromSeed(propertyName || "id"),
180
+ "json-pointer": () => "/json/pointer",
181
+ "relative-json-pointer": () => "1/relative/json/pointer",
182
+ regex: () => "/regex/",
183
+ default: () => defaultStringSample(min, max, pattern, options.enablePatterns)
184
+ };
185
+ return (formats[format] ?? formats.default)();
186
+ }
187
+ function sampleArray(schema, options, spec, context) {
188
+ const depth = context?.depth ?? 1;
189
+ let arrayLength = Math.min(schema.maxItems != null ? schema.maxItems : Number.POSITIVE_INFINITY, schema.minItems ?? 1);
190
+ const items = schema.prefixItems ?? schema.items ?? schema.contains;
191
+ if (Array.isArray(items)) arrayLength = Math.max(arrayLength, items.length);
192
+ const itemSchemaGetter = (i) => {
193
+ if (Array.isArray(items)) return items[i] ?? {};
194
+ return items ?? {};
195
+ };
196
+ const res = [];
197
+ if (!items) return res;
198
+ for (let i = 0; i < arrayLength; i++) {
199
+ const { value } = traverse(itemSchemaGetter(i), options, spec, {
200
+ depth: depth + 1,
201
+ propertyName: context?.propertyName
202
+ });
203
+ res.push(value);
204
+ }
205
+ return res;
206
+ }
207
+ function sampleObject(schema, options, spec, context) {
208
+ let res = {};
209
+ const depth = context?.depth ?? 1;
210
+ if (schema.properties && typeof schema.properties === "object") {
211
+ const required = Array.isArray(schema.required) ? schema.required : [];
212
+ const requiredSet = new Set(required);
213
+ for (const propertyName of Object.keys(schema.properties)) {
214
+ if (options.skipNonRequired && !requiredSet.has(propertyName)) continue;
215
+ const propSchema = schema.properties[propertyName];
216
+ const sample = traverse(propSchema, options, spec, {
217
+ propertyName,
218
+ depth: depth + 1
219
+ });
220
+ if (options.skipReadOnly && sample.readOnly) {
221
+ if (context?.isAllOfChild) res[propertyName] = SKIP;
222
+ continue;
223
+ }
224
+ if (options.skipWriteOnly && sample.writeOnly) {
225
+ if (context?.isAllOfChild) res[propertyName] = SKIP;
226
+ continue;
227
+ }
228
+ res[propertyName] = sample.value;
229
+ }
230
+ }
231
+ if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
232
+ const ap = schema.additionalProperties;
233
+ const baseName = ap["x-additionalPropertiesName"] || "property";
234
+ res[`${String(baseName)}1`] = traverse(ap, options, spec, { depth: depth + 1 }).value;
235
+ res[`${String(baseName)}2`] = traverse(ap, options, spec, { depth: depth + 1 }).value;
236
+ }
237
+ if (schema.properties && typeof schema.properties === "object" && typeof schema.maxProperties === "number" && Object.keys(res).length > schema.maxProperties) {
238
+ const filtered = {};
239
+ let added = 0;
240
+ const req = Array.isArray(schema.required) ? schema.required : [];
241
+ for (const name of req) if (res[name] !== void 0) {
242
+ filtered[name] = res[name];
243
+ added++;
244
+ }
245
+ for (const name of Object.keys(res)) if (added < schema.maxProperties && !(name in filtered)) {
246
+ filtered[name] = res[name];
247
+ added++;
248
+ }
249
+ res = filtered;
250
+ }
251
+ return res;
252
+ }
253
+ function inferExample(schema) {
254
+ if (schema.const !== void 0) return schema.const;
255
+ if (Array.isArray(schema.examples) && schema.examples.length > 0) return schema.examples[0];
256
+ if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
257
+ if (schema.default !== void 0) return schema.default;
258
+ }
259
+ function tryInferExample(schema) {
260
+ const example = inferExample(schema);
261
+ if (example !== void 0) return {
262
+ value: example,
263
+ readOnly: schema.readOnly,
264
+ writeOnly: schema.writeOnly,
265
+ type: null
266
+ };
267
+ }
268
+ function allOfSample(into, children, options, spec, context) {
269
+ const res = traverse(into, options, spec);
270
+ const subSamples = [];
271
+ for (const subSchema of children) {
272
+ const { type, readOnly, writeOnly, value } = traverse({
273
+ type: res.type,
274
+ ...subSchema
275
+ }, options, spec, {
276
+ ...context,
277
+ depth: context?.depth ?? 1,
278
+ isAllOfChild: true
279
+ });
280
+ if (res.type && type && type !== res.type) {
281
+ if (!options.quiet) console.warn("allOf: schemas with different types can't be merged");
282
+ res.type = type;
283
+ }
284
+ res.type = res.type ?? type;
285
+ res.readOnly = res.readOnly || readOnly;
286
+ res.writeOnly = res.writeOnly || writeOnly;
287
+ if (value != null) subSamples.push(value);
288
+ }
289
+ if (res.type === "object") {
290
+ const merged = mergeDeep(res.value || {}, ...subSamples.filter((s) => typeof s === "object" && s !== null));
291
+ for (const key of Object.keys(merged)) if (merged[key] === SKIP) delete merged[key];
292
+ return {
293
+ ...res,
294
+ value: merged
295
+ };
296
+ }
297
+ if (res.type === "array") {
298
+ if (!options.quiet) console.warn("OpenAPI Sampler: found allOf with \"array\" type. Result may be incorrect");
299
+ }
300
+ const last = subSamples[subSamples.length - 1];
301
+ return {
302
+ ...res,
303
+ value: last != null ? last : res.value
304
+ };
305
+ }
306
+ const typeSamplers = {
307
+ array: sampleArray,
308
+ boolean: sampleBoolean,
309
+ integer: sampleNumber,
310
+ number: sampleNumber,
311
+ object: sampleObject,
312
+ string: sampleString
313
+ };
314
+ function traverseOneOrAnyOf(parent, selectedSubSchema, options, spec, context) {
315
+ const inferred = tryInferExample(parent);
316
+ if (inferred !== void 0) return inferred;
317
+ const localExample = traverse({
318
+ ...parent,
319
+ oneOf: void 0,
320
+ anyOf: void 0
321
+ }, options, spec, context);
322
+ const subExample = traverse(selectedSubSchema, options, spec, context);
323
+ if (typeof localExample.value === "object" && localExample.value !== null && typeof subExample.value === "object" && subExample.value !== null) {
324
+ const mergedExample = mergeDeep(localExample.value, subExample.value);
325
+ return {
326
+ ...subExample,
327
+ value: mergedExample
328
+ };
329
+ }
330
+ return subExample;
331
+ }
332
+ function traverse(schema, options, spec, context) {
333
+ if (context) {
334
+ if (seenObjectStack.includes(schema)) return {
335
+ value: getCircularPlaceholder(inferType(schema)),
336
+ type: null
337
+ };
338
+ seenObjectStack.push(schema);
339
+ }
340
+ if (context && (context.depth ?? 1) > options.maxSampleDepth) {
341
+ popStack(context);
342
+ return {
343
+ value: getCircularPlaceholder(inferType(schema)),
344
+ type: null
345
+ };
346
+ }
347
+ if (!isPlainObject(schema)) {
348
+ popStack(context);
349
+ return {
350
+ value: schema,
351
+ type: null
352
+ };
353
+ }
354
+ const s = schema;
355
+ if (typeof s.$ref === "string") {
356
+ if (spec == null) throw new Error("Your schema contains $ref. You must provide full specification in the third parameter.");
357
+ const ref = decodeURIComponent(s.$ref);
358
+ if (!ref.startsWith("#")) throw new Error("Your schema contains $ref. Only in-document references (`#/…`) are supported.");
359
+ if (refResolving[ref]) {
360
+ const referencedType = inferType(resolveRefSync(ref, spec) ?? {});
361
+ popStack(context);
362
+ return {
363
+ value: getCircularPlaceholder(referencedType),
364
+ type: null
365
+ };
366
+ }
367
+ refResolving[ref] = true;
368
+ const referenced = resolveRefSync(ref, spec);
369
+ if (referenced === void 0) {
370
+ refResolving[ref] = false;
371
+ popStack(context);
372
+ throw new Error(`Could not resolve $ref: ${s.$ref}`);
373
+ }
374
+ const result = traverse(referenced, options, spec, context);
375
+ refResolving[ref] = false;
376
+ popStack(context);
377
+ return result;
378
+ }
379
+ if (s.example !== void 0) {
380
+ popStack(context);
381
+ return {
382
+ value: s.example,
383
+ readOnly: s.readOnly,
384
+ writeOnly: s.writeOnly,
385
+ type: s.type
386
+ };
387
+ }
388
+ if (s.allOf !== void 0) {
389
+ popStack(context);
390
+ return tryInferExample(s) ?? allOfSample({
391
+ ...s,
392
+ allOf: void 0
393
+ }, s.allOf, options, spec, context);
394
+ }
395
+ if (s.oneOf && Array.isArray(s.oneOf) && s.oneOf.length > 0) {
396
+ if (s.anyOf && !options.quiet) console.warn("oneOf and anyOf are not supported on the same level. Skipping anyOf");
397
+ popStack(context);
398
+ return traverseOneOrAnyOf(s, Object.assign({
399
+ readOnly: s.readOnly,
400
+ writeOnly: s.writeOnly
401
+ }, s.oneOf[0]), options, spec, context);
402
+ }
403
+ if (s.anyOf && Array.isArray(s.anyOf) && s.anyOf.length > 0) {
404
+ popStack(context);
405
+ return traverseOneOrAnyOf(s, Object.assign({
406
+ readOnly: s.readOnly,
407
+ writeOnly: s.writeOnly
408
+ }, s.anyOf[0]), options, spec, context);
409
+ }
410
+ if (s.if && s.then) {
411
+ popStack(context);
412
+ const { if: ifSchema, then, ...rest } = s;
413
+ return traverse(mergeDeep(rest, ifSchema, then), options, spec, context);
414
+ }
415
+ let example = inferExample(s);
416
+ let type = null;
417
+ if (example === void 0) {
418
+ example = null;
419
+ type = s.type;
420
+ if (Array.isArray(type) && type.length > 0) type = type[0];
421
+ if (!type) type = inferType(s);
422
+ const sampler = type ? typeSamplers[type] : void 0;
423
+ if (sampler) example = sampler(s, options, spec, context);
424
+ }
425
+ popStack(context);
426
+ return {
427
+ value: example,
428
+ readOnly: s.readOnly,
429
+ writeOnly: s.writeOnly,
430
+ type
431
+ };
432
+ }
433
+ function sample(schema, options, spec) {
434
+ const opts = {
435
+ ...defaultOptions,
436
+ ...options
437
+ };
438
+ clearCaches();
439
+ return traverse(schema, opts, spec).value;
440
+ }
441
+ //#endregion
442
+ export { sample };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-openapi",
3
- "version": "10.6.7",
3
+ "version": "10.6.8",
4
4
  "description": "Generate MDX docs for your OpenAPI spec",
5
5
  "keywords": [
6
6
  "Docs",
@@ -43,7 +43,6 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "@fastify/deepmerge": "^3.2.1",
47
46
  "@fumari/json-schema-ts": "^0.0.2",
48
47
  "@radix-ui/react-accordion": "^1.2.12",
49
48
  "@radix-ui/react-dialog": "^1.1.15",
@@ -54,37 +53,35 @@
54
53
  "ajv": "^8.18.0",
55
54
  "chokidar": "^5.0.0",
56
55
  "class-variance-authority": "^0.7.1",
57
- "fast-content-type-parse": "^3.0.0",
58
56
  "github-slugger": "^2.0.0",
59
57
  "hast-util-to-jsx-runtime": "^2.3.6",
60
58
  "js-yaml": "^4.1.1",
61
- "lucide-react": "^1.7.0",
59
+ "lucide-react": "^1.8.0",
62
60
  "next-themes": "^0.4.6",
63
- "openapi-sampler": "^1.7.2",
64
- "react-hook-form": "^7.72.1",
65
61
  "remark": "^15.0.1",
66
62
  "remark-rehype": "^11.1.2",
67
63
  "tailwind-merge": "^3.5.0",
68
64
  "xml-js": "^1.6.11",
69
- "@fumari/stf": "1.0.4"
65
+ "@fumari/stf": "1.0.5"
70
66
  },
71
67
  "devDependencies": {
72
- "@scalar/api-client-react": "^1.4.20",
68
+ "@fastify/deepmerge": "^3.2.1",
69
+ "@scalar/api-client-react": "^2.0.1",
73
70
  "@types/js-yaml": "^4.0.9",
74
- "@types/node": "25.5.2",
75
- "@types/openapi-sampler": "^1.0.3",
71
+ "@types/node": "25.6.0",
76
72
  "@types/react": "^19.2.14",
73
+ "fast-content-type-parse": "^3.0.0",
77
74
  "json-schema-typed": "^8.0.2",
78
75
  "shiki": "^4.0.2",
79
76
  "tailwindcss": "^4.2.2",
80
77
  "tsdown": "0.21.7",
81
- "@fumadocs/tailwind": "0.0.3",
82
- "fumadocs-core": "16.7.11",
83
- "fumadocs-ui": "16.7.11",
78
+ "@fumadocs/tailwind": "0.0.4",
79
+ "fumadocs-core": "16.7.13",
80
+ "fumadocs-ui": "16.7.13",
84
81
  "tsconfig": "0.0.0"
85
82
  },
86
83
  "peerDependencies": {
87
- "@scalar/api-client-react": "*",
84
+ "@scalar/api-client-react": "2.x.x",
88
85
  "@types/react": "*",
89
86
  "fumadocs-core": "^16.7.0",
90
87
  "fumadocs-ui": "^16.7.0",
@@ -107,6 +104,10 @@
107
104
  "optional": true
108
105
  }
109
106
  },
107
+ "inlinedDependencies": {
108
+ "@fastify/deepmerge": "3.2.1",
109
+ "fast-content-type-parse": "3.0.0"
110
+ },
110
111
  "scripts": {
111
112
  "build": "tsdown --config-loader unrun",
112
113
  "clean": "rimraf dist",