fumadocs-openapi 10.3.13 → 10.3.14

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.
@@ -19,6 +19,7 @@
19
19
  @source inline("@default");
20
20
  @source inline("@defaultValue");
21
21
  @source inline("@deprecated");
22
+ @source inline("@fumari/json-schema-ts");
22
23
  @source inline("@fumari/stf");
23
24
  @source inline("@md:grid-cols-2");
24
25
  @source inline("@param");
@@ -141,6 +142,7 @@
141
142
  @source inline("col-span-full");
142
143
  @source inline("collapsible");
143
144
  @source inline("color");
145
+ @source inline("compile");
144
146
  @source inline("compiler");
145
147
  @source inline("components");
146
148
  @source inline("conditions");
@@ -158,6 +160,7 @@
158
160
  @source inline("cookies");
159
161
  @source inline("core");
160
162
  @source inline("could");
163
+ @source inline("count");
161
164
  @source inline("createAutoPreset");
162
165
  @source inline("createContext");
163
166
  @source inline("createMethod");
@@ -165,7 +168,6 @@
165
168
  @source inline("css");
166
169
  @source inline("ctx");
167
170
  @source inline("current");
168
- @source inline("currentId");
169
171
  @source inline("currentRef");
170
172
  @source inline("currentValue");
171
173
  @source inline("customisation");
@@ -331,8 +333,8 @@
331
333
  @source inline("generators");
332
334
  @source inline("getAPIPageProps");
333
335
  @source inline("getSchema");
336
+ @source inline("getSchemaId");
334
337
  @source inline("getStatusInfo");
335
- @source inline("getTypescriptSchema");
336
338
  @source inline("ghost");
337
339
  @source inline("github-slugger");
338
340
  @source inline("given");
@@ -397,6 +399,7 @@
397
399
  @source inline("interface");
398
400
  @source inline("internal_legacy");
399
401
  @source inline("intersection");
402
+ @source inline("invalid");
400
403
  @source inline("is");
401
404
  @source inline("isDefined");
402
405
  @source inline("isDuplicated");
@@ -498,7 +501,6 @@
498
501
  @source inline("new");
499
502
  @source inline("newKey");
500
503
  @source inline("next-themes");
501
- @source inline("nextId");
502
504
  @source inline("no-cache");
503
505
  @source inline("node");
504
506
  @source inline("not");
@@ -581,6 +583,7 @@
581
583
  @source inline("paths");
582
584
  @source inline("pattern");
583
585
  @source inline("patternProperties");
586
+ @source inline("pb-0");
584
587
  @source inline("pb-2");
585
588
  @source inline("pe-2");
586
589
  @source inline("peer-disabled:cursor-not-allowed");
@@ -634,6 +637,7 @@
634
637
  @source inline("py-4");
635
638
  @source inline("query");
636
639
  @source inline("quiet");
640
+ @source inline("r");
637
641
  @source inline("race");
638
642
  @source inline("range");
639
643
  @source inline("raw");
@@ -660,6 +664,7 @@
660
664
  @source inline("remark-rehype");
661
665
  @source inline("remarkGfm");
662
666
  @source inline("remarkRehype");
667
+ @source inline("remove");
663
668
  @source inline("removeItem");
664
669
  @source inline("removeListener");
665
670
  @source inline("render");
@@ -835,6 +840,7 @@
835
840
  @source inline("tab");
836
841
  @source inline("tabs");
837
842
  @source inline("tag");
843
+ @source inline("takenIds");
838
844
  @source inline("targetServer");
839
845
  @source inline("testQuery");
840
846
  @source inline("text");
@@ -902,6 +908,7 @@
902
908
  @source inline("typeVariants");
903
909
  @source inline("typeof");
904
910
  @source inline("types");
911
+ @source inline("typescript");
905
912
  @source inline("unchanged");
906
913
  @source inline("undefined");
907
914
  @source inline("under");
@@ -0,0 +1,5 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
3
+
4
+ //#endregion
5
+ export { __commonJSMin };
@@ -0,0 +1,42 @@
1
+ import { __commonJSMin } from "../../../../../_virtual/_rolldown/runtime.js";
2
+ import { require_klona } from "./klona.js";
3
+ import { require_resolveRef } from "./resolveRef.js";
4
+
5
+ //#region ../../node_modules/.pnpm/dereference-json-schema@0.2.1/node_modules/dereference-json-schema/dereference.js
6
+ var require_dereference = /* @__PURE__ */ __commonJSMin(((exports) => {
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ Object.defineProperty(exports, "dereferenceSync", {
9
+ enumerable: true,
10
+ get: function() {
11
+ return dereferenceSync;
12
+ }
13
+ });
14
+ var _klona = require_klona();
15
+ var _resolveRef = require_resolveRef();
16
+ var cache = /* @__PURE__ */ new Map();
17
+ var dereferenceSync = function(schema) {
18
+ if (cache.has(schema)) return cache.get(schema);
19
+ var visitedNodes = /* @__PURE__ */ new Set();
20
+ var cloned = (0, _klona.klona)(schema);
21
+ var resolve = function(current, path) {
22
+ if (typeof current === "object" && current !== null) {
23
+ if (visitedNodes.has(current)) return current;
24
+ visitedNodes.add(current);
25
+ if (Array.isArray(current)) for (var index = 0; index < current.length; index++) current[index] = resolve(current[index], "".concat(path, "/").concat(index));
26
+ else {
27
+ if ("$ref" in current && typeof current["$ref"] === "string") return (0, _resolveRef.resolveRefSync)(cloned, current["$ref"]);
28
+ for (var key in current) current[key] = resolve(current[key], "".concat(path, "/").concat(key));
29
+ }
30
+ }
31
+ return current;
32
+ };
33
+ var result = resolve(cloned, "#");
34
+ cache.set(schema, result);
35
+ return result;
36
+ };
37
+ }));
38
+
39
+ //#endregion
40
+ export default require_dereference();
41
+
42
+ export { require_dereference };
@@ -0,0 +1,28 @@
1
+ import { __commonJSMin } from "../../../../../_virtual/_rolldown/runtime.js";
2
+ import { require_types } from "./types.js";
3
+ import { require_resolveRef } from "./resolveRef.js";
4
+ import { require_dereference } from "./dereference.js";
5
+
6
+ //#region ../../node_modules/.pnpm/dereference-json-schema@0.2.1/node_modules/dereference-json-schema/index.js
7
+ var require_dereference_json_schema = /* @__PURE__ */ __commonJSMin(((exports) => {
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ _exportStar(require_types(), exports);
10
+ _exportStar(require_dereference(), exports);
11
+ _exportStar(require_resolveRef(), exports);
12
+ function _exportStar(from, to) {
13
+ Object.keys(from).forEach(function(k) {
14
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) Object.defineProperty(to, k, {
15
+ enumerable: true,
16
+ get: function() {
17
+ return from[k];
18
+ }
19
+ });
20
+ });
21
+ return from;
22
+ }
23
+ }));
24
+
25
+ //#endregion
26
+ export default require_dereference_json_schema();
27
+
28
+ export { require_dereference_json_schema };
@@ -0,0 +1,41 @@
1
+ import { __commonJSMin } from "../../../../../_virtual/_rolldown/runtime.js";
2
+
3
+ //#region ../../node_modules/.pnpm/dereference-json-schema@0.2.1/node_modules/dereference-json-schema/klona.js
4
+ /**
5
+ * klona/json - MIT License
6
+ *
7
+ * https://github.com/lukeed/klona/blob/master/license
8
+ */ var require_klona = /* @__PURE__ */ __commonJSMin(((exports) => {
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ Object.defineProperty(exports, "klona", {
11
+ enumerable: true,
12
+ get: function() {
13
+ return klona;
14
+ }
15
+ });
16
+ function klona(val) {
17
+ var index, out, tmp;
18
+ if (Array.isArray(val)) {
19
+ out = Array(index = val.length);
20
+ while (index--) out[index] = (tmp = val[index]) && typeof tmp === "object" ? klona(tmp) : tmp;
21
+ return out;
22
+ }
23
+ if (Object.prototype.toString.call(val) === "[object Object]") {
24
+ out = {};
25
+ for (index in val) if (index === "__proto__") Object.defineProperty(out, index, {
26
+ value: klona(val[index]),
27
+ configurable: true,
28
+ enumerable: true,
29
+ writable: true
30
+ });
31
+ else out[index] = (tmp = val[index]) && typeof tmp === "object" ? klona(tmp) : tmp;
32
+ return out;
33
+ }
34
+ return val;
35
+ }
36
+ }));
37
+
38
+ //#endregion
39
+ export default require_klona();
40
+
41
+ export { require_klona };
@@ -0,0 +1,45 @@
1
+ import { __commonJSMin } from "../../../../../_virtual/_rolldown/runtime.js";
2
+
3
+ //#region ../../node_modules/.pnpm/dereference-json-schema@0.2.1/node_modules/dereference-json-schema/resolveRef.js
4
+ var require_resolveRef = /* @__PURE__ */ __commonJSMin(((exports) => {
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ Object.defineProperty(exports, "resolveRefSync", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return resolveRefSync;
10
+ }
11
+ });
12
+ var cache = /* @__PURE__ */ new Map();
13
+ var resolveRefSync = function(schema, ref) {
14
+ if (!cache.has(schema)) cache.set(schema, /* @__PURE__ */ new Map());
15
+ var schemaCache = cache.get(schema);
16
+ if (schemaCache.has(ref)) return schemaCache.get(ref);
17
+ var path = ref.split("/").slice(1);
18
+ var current = schema;
19
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
20
+ try {
21
+ for (var _iterator = path[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
22
+ var segment = _step.value;
23
+ if (!current || typeof current !== "object") current = null;
24
+ var _current_segment;
25
+ current = (_current_segment = current[segment]) !== null && _current_segment !== void 0 ? _current_segment : null;
26
+ }
27
+ } catch (err) {
28
+ _didIteratorError = true;
29
+ _iteratorError = err;
30
+ } finally {
31
+ try {
32
+ if (!_iteratorNormalCompletion && _iterator.return != null) _iterator.return();
33
+ } finally {
34
+ if (_didIteratorError) throw _iteratorError;
35
+ }
36
+ }
37
+ schemaCache.set(ref, current);
38
+ return current;
39
+ };
40
+ }));
41
+
42
+ //#endregion
43
+ export default require_resolveRef();
44
+
45
+ export { require_resolveRef };
@@ -0,0 +1,11 @@
1
+ import { __commonJSMin } from "../../../../../_virtual/_rolldown/runtime.js";
2
+
3
+ //#region ../../node_modules/.pnpm/dereference-json-schema@0.2.1/node_modules/dereference-json-schema/types.js
4
+ var require_types = /* @__PURE__ */ __commonJSMin(((exports) => {
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ }));
7
+
8
+ //#endregion
9
+ export default require_types();
10
+
11
+ export { require_types };
@@ -9,13 +9,20 @@ async function APIPlayground({ path, method, ctx }) {
9
9
  method,
10
10
  ctx
11
11
  });
12
- let currentId = 0;
13
12
  const bodyContent = method.requestBody?.content;
14
13
  const mediaType = bodyContent ? getPreferredType(bodyContent) : void 0;
14
+ const takenIds = /* @__PURE__ */ new Map();
15
15
  const context = {
16
16
  references: {},
17
- nextId() {
18
- return String(currentId++);
17
+ id(schema) {
18
+ let name = "r";
19
+ if (schema) {
20
+ const ref = ctx.schema.getRawRef(schema)?.split("/");
21
+ if (ref && ref.length > 0) name = ref[ref.length - 1];
22
+ }
23
+ const count = takenIds.get(name) ?? 0;
24
+ takenIds.set(name, count + 1);
25
+ return count === 0 ? name : `${name}${count}`;
19
26
  },
20
27
  registered: /* @__PURE__ */ new WeakMap()
21
28
  };
@@ -38,7 +45,7 @@ function writeReferences(schema, ctx, stack = /* @__PURE__ */ new WeakMap()) {
38
45
  if (typeof schema !== "object" || !schema) return schema;
39
46
  if (stack.has(schema)) {
40
47
  const out = stack.get(schema);
41
- const id = ctx.nextId();
48
+ const id = ctx.id(schema);
42
49
  ctx.references[id] = out;
43
50
  return { $ref: `#/${id}` };
44
51
  }
@@ -24,9 +24,8 @@ function SchemaProvider({ references, readOnly, writeOnly, children }) {
24
24
  const ajv = useMemo(() => new Ajv2020({
25
25
  strict: false,
26
26
  validateSchema: false,
27
- validateFormats: false,
28
- schemas: references
29
- }), [references]);
27
+ validateFormats: false
28
+ }), []);
30
29
  return /* @__PURE__ */ jsx(SchemaContext.Provider, {
31
30
  value: useMemo(() => ({
32
31
  references,
@@ -53,7 +52,7 @@ function useSchemaScope() {
53
52
  * @param depth - The depth to avoid duplicated field name with same schema (e.g. nested `oneOf`).
54
53
  */
55
54
  function useFieldInfo(fieldName, schema, depth = 0) {
56
- const { ajv } = use(SchemaContext);
55
+ const { ajv, references } = use(SchemaContext);
57
56
  const engine = useDataEngine();
58
57
  const { generateDefault } = useSchemaUtils();
59
58
  const [info, setInfo] = useFieldValue([], { stf: useNamespace({
@@ -64,7 +63,10 @@ function useFieldInfo(fieldName, schema, depth = 0) {
64
63
  const union = getUnion(schema);
65
64
  if (union) {
66
65
  const [members, field] = union;
67
- out.oneOf = members.findIndex((item) => ajv.validate(item, value));
66
+ out.oneOf = members.findIndex((item) => ajv.validate(typeof item === "object" ? {
67
+ ...item,
68
+ ...references
69
+ } : item, value));
68
70
  if (out.oneOf === -1) out.oneOf = 0;
69
71
  out.unionField = field;
70
72
  }
@@ -73,12 +75,15 @@ function useFieldInfo(fieldName, schema, depth = 0) {
73
75
  out.selectedType = types.find((type) => {
74
76
  return ajv.validate({
75
77
  ...schema,
78
+ ...references,
76
79
  type
77
80
  }, value);
78
81
  }) ?? types[0];
79
82
  }
80
83
  if (schema.allOf) {
81
- const merged = mergeAllOf(schema);
84
+ const merged = mergeAllOf(schema, { dereference(schema) {
85
+ return dereference(schema, references);
86
+ } });
82
87
  if (typeof merged !== "boolean") out.intersection = { merged };
83
88
  }
84
89
  return out;
@@ -97,7 +102,8 @@ function useFieldInfo(fieldName, schema, depth = 0) {
97
102
  if (updated.unionField) valueSchema = schema[updated.unionField][updated.oneOf];
98
103
  else if (updated.selectedType) valueSchema = {
99
104
  ...schema,
100
- type: updated.selectedType
105
+ type: updated.selectedType,
106
+ examples: void 0
101
107
  };
102
108
  engine.update(fieldName, generateDefault(valueSchema));
103
109
  }
@@ -105,15 +111,6 @@ function useFieldInfo(fieldName, schema, depth = 0) {
105
111
  }
106
112
  function useSchemaUtils() {
107
113
  const { references } = use(SchemaContext);
108
- function resolve(schema) {
109
- if (typeof schema === "boolean") return anyFields;
110
- let ref = schema.$ref;
111
- if (ref) {
112
- if (ref.startsWith("#/")) ref = ref.slice(2);
113
- if (ref in references) return fallbackAny(references[ref]);
114
- }
115
- return schema;
116
- }
117
114
  return {
118
115
  generateDefault(schema) {
119
116
  return sample(schema, {
@@ -122,15 +119,26 @@ function useSchemaUtils() {
122
119
  quiet: true
123
120
  }, references);
124
121
  },
125
- resolve,
122
+ resolve(schema) {
123
+ return fallbackAny(dereference(schema, references));
124
+ },
126
125
  schemaToString(value, flags) {
127
126
  return schemaToString(value, (s) => ({
128
- dereferenced: resolve(s),
127
+ dereferenced: dereference(s, references),
129
128
  raw: s
130
129
  }), flags);
131
130
  }
132
131
  };
133
132
  }
133
+ function dereference(schema, references) {
134
+ if (typeof schema === "boolean") return schema;
135
+ let ref = schema.$ref;
136
+ if (ref) {
137
+ if (ref.startsWith("#/")) ref = ref.slice(2);
138
+ if (ref in references) return references[ref];
139
+ }
140
+ return schema;
141
+ }
134
142
  function fallbackAny(schema) {
135
143
  return typeof schema === "boolean" ? anyFields : schema;
136
144
  }
package/dist/ui/base.d.ts CHANGED
@@ -15,6 +15,16 @@ import { ResolvedShikiConfig } from "fumadocs-core/highlight/config";
15
15
  import { JSONSchema } from "json-schema-typed";
16
16
 
17
17
  //#region src/ui/base.d.ts
18
+ interface GenerateTypeScriptDefinitionsContext extends RenderContext {
19
+ operation: NoReference<MethodInformation>;
20
+ readOnly: boolean;
21
+ writeOnly: boolean;
22
+ /** @deprecated */
23
+ _internal_legacy?: {
24
+ statusCode: string;
25
+ contentType: string;
26
+ };
27
+ }
18
28
  interface CreateAPIPageOptions {
19
29
  /**
20
30
  * Generate TypeScript definitions from response schema.
@@ -31,13 +41,7 @@ interface CreateAPIPageOptions {
31
41
  *
32
42
  * Pass `false` to disable it.
33
43
  */
34
- generateTypeScriptDefinitions?: (schema: JSONSchema, ctx: RenderContext & {
35
- operation: NoReference<MethodInformation>; /** @deprecated */
36
- _internal_legacy?: {
37
- statusCode: string;
38
- contentType: string;
39
- };
40
- }) => Awaitable<string | undefined>;
44
+ generateTypeScriptDefinitions?: (schema: JSONSchema, ctx: GenerateTypeScriptDefinitionsContext) => Awaitable<string | undefined>;
41
45
  /**
42
46
  * Generate example code usage for endpoints.
43
47
  */
@@ -145,4 +149,4 @@ interface CreateAPIPageOptions {
145
149
  }
146
150
  declare function createAPIPage(server: OpenAPIServer, options: CreateAPIPageOptions): FC<ApiPageProps>;
147
151
  //#endregion
148
- export { CreateAPIPageOptions, createAPIPage };
152
+ export { CreateAPIPageOptions, GenerateTypeScriptDefinitionsContext, createAPIPage };
package/dist/ui/full.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { createAPIPage as createAPIPage$1 } from "./base.js";
2
- import { getTypescriptSchema } from "../utils/get-typescript-schema.js";
3
2
  import { ShikiConfigProvider } from "./full.client.js";
4
3
  import { jsx } from "react/jsx-runtime";
5
4
  import { configDefault } from "fumadocs-core/highlight";
@@ -7,12 +6,22 @@ import { configDefault } from "fumadocs-core/highlight";
7
6
  //#region src/ui/full.tsx
8
7
  function createAPIPage(server, options = {}) {
9
8
  const APIPage = createAPIPage$1(server, {
10
- ...options,
11
9
  shiki: configDefault,
12
- generateTypeScriptDefinitions(schema, ctx) {
10
+ async generateTypeScriptDefinitions(schema, ctx) {
13
11
  if (typeof schema !== "object") return;
14
- return getTypescriptSchema(schema, ctx);
15
- }
12
+ const { compile } = await import("@fumari/json-schema-ts");
13
+ try {
14
+ return compile(schema, {
15
+ name: "Response",
16
+ readOnly: ctx.readOnly,
17
+ writeOnly: ctx.writeOnly,
18
+ getSchemaId: ctx.schema.getRawRef
19
+ });
20
+ } catch (e) {
21
+ console.warn("Failed to generate typescript schema:", e);
22
+ }
23
+ },
24
+ ...options
16
25
  });
17
26
  return function APIPageFull(props) {
18
27
  return /* @__PURE__ */ jsx(ShikiConfigProvider, { children: /* @__PURE__ */ jsx(APIPage, { ...props }) });
@@ -63,6 +63,8 @@ async function Operation({ type = "operation", path, method, ctx, showTitle, sho
63
63
  if (!isMediaTypeSupported(type, ctx.mediaAdapters)) throw new Error(`Media type ${type} is not supported (in ${path})`);
64
64
  const ts = content.schema ? await ctx.generateTypeScriptDefinitions(content.schema, {
65
65
  operation: method,
66
+ readOnly: false,
67
+ writeOnly: true,
66
68
  ...ctx
67
69
  }) : void 0;
68
70
  return /* @__PURE__ */ jsxs(SelectTab, {
@@ -328,6 +330,8 @@ async function ResponseAccordion({ status, operation, ctx }) {
328
330
  }), contentTypes.map(async ([type, resType]) => {
329
331
  const schema = resType.schema;
330
332
  const ts = schema ? await ctx.generateTypeScriptDefinitions(schema, {
333
+ readOnly: true,
334
+ writeOnly: false,
331
335
  operation,
332
336
  _internal_legacy: {
333
337
  statusCode: status,
@@ -46,7 +46,7 @@ function SchemaUIProperty({ name, $type, variant = "default", overrides, objectS
46
46
  }, item.$type)) }), schema.items.map((item) => /* @__PURE__ */ jsx(TabsContent, {
47
47
  value: item.$type,
48
48
  forceMount: void 0,
49
- className: "py-0",
49
+ className: "pt-2 pb-0",
50
50
  children: /* @__PURE__ */ jsx(SchemaUIProperty, {
51
51
  ...item,
52
52
  variant: "expand"
@@ -4,16 +4,19 @@ import { deepEqual } from "./deep-equal.js";
4
4
  /**
5
5
  * Merge `allOf` object schema
6
6
  */
7
- function mergeAllOf(schema) {
7
+ function mergeAllOf(schema, options = {}) {
8
+ if (typeof schema === "boolean") return schema;
9
+ const { dereference } = options;
10
+ if (dereference && "$ref" in schema && typeof schema.$ref === "string") schema = dereference(schema) ?? schema;
8
11
  if (typeof schema === "boolean" || !schema.allOf) return schema;
9
12
  const { allOf, ...rest } = schema;
10
13
  let result = rest;
11
- for (const item of allOf) result = intersection(result, item);
14
+ for (const item of allOf) result = intersection(result, item, options);
12
15
  return result;
13
16
  }
14
- function intersection(a, b) {
15
- a = mergeAllOf(a);
16
- b = mergeAllOf(b);
17
+ function intersection(a, b, options) {
18
+ a = mergeAllOf(a, options);
19
+ b = mergeAllOf(b, options);
17
20
  if (typeof a === "boolean" && typeof b === "boolean") return a && b;
18
21
  if (typeof a === "boolean") return a;
19
22
  if (typeof b === "boolean") return b;
@@ -98,7 +101,7 @@ function intersection(a, b) {
98
101
  const bProp = value[prop];
99
102
  if (aProp === void 0) out[prop] = bProp;
100
103
  else if (bProp === void 0) out[prop] = aProp;
101
- else out[prop] = intersection(aProp, bProp);
104
+ else out[prop] = intersection(aProp, bProp, options);
102
105
  }
103
106
  result[key] = out;
104
107
  break;
@@ -108,7 +111,7 @@ function intersection(a, b) {
108
111
  case "items": {
109
112
  const value = b[key];
110
113
  if (value === void 0) break;
111
- result[key] = result[key] === void 0 ? value : intersection(result[key], value);
114
+ result[key] = result[key] === void 0 ? value : intersection(result[key], value, options);
112
115
  break;
113
116
  }
114
117
  case "not": {
@@ -7,7 +7,6 @@ interface ProcessedDocument {
7
7
  * dereferenced document
8
8
  */
9
9
  dereferenced: NoReference<Document>;
10
- _internal_idToSchema: () => Map<string, object>;
11
10
  /**
12
11
  * Get raw object from dereferenced object
13
12
  */
@@ -1,14 +1,15 @@
1
- import { dereference } from "@scalar/openapi-parser";
1
+ import { require_dereference_json_schema } from "../node_modules/.pnpm/dereference-json-schema@0.2.1/node_modules/dereference-json-schema/index.js";
2
2
  import { bundle } from "@scalar/json-magic/bundle";
3
3
  import { upgrade } from "@scalar/openapi-upgrader";
4
4
  import { fetchUrls, readFiles } from "@scalar/json-magic/bundle/plugins/node";
5
5
 
6
6
  //#region src/utils/process-document.ts
7
+ var import_dereference_json_schema = require_dereference_json_schema();
7
8
  /**
8
9
  * process & reference input document to a Fumadocs OpenAPI compatible format
9
10
  */
10
11
  async function processDocument(input) {
11
- const document = await bundle(input, {
12
+ const bundled = await bundle(input, {
12
13
  plugins: [fetchUrls(), readFiles()],
13
14
  treeShake: true,
14
15
  hooks: { onResolveError(node) {
@@ -21,24 +22,43 @@ async function processDocument(input) {
21
22
  * Dereferenced value and its original `$ref` value
22
23
  */
23
24
  const dereferenceMap = /* @__PURE__ */ new WeakMap();
24
- const serializable = /* @__PURE__ */ new Map();
25
25
  return {
26
- dereferenced: dereference(document, {
27
- throwOnError: true,
28
- onDereference({ schema, ref }) {
29
- serializable.set(ref, schema);
30
- dereferenceMap.set(schema, ref);
31
- }
32
- }).schema,
26
+ dereferenced: dereferenceSync(bundled, (ref, schema) => {
27
+ dereferenceMap.set(schema, ref);
28
+ }),
33
29
  getRawRef(obj) {
34
30
  return dereferenceMap.get(obj);
35
31
  },
36
- _internal_idToSchema() {
37
- return serializable;
38
- },
39
- bundled: document
32
+ bundled
40
33
  };
41
34
  }
35
+ /**
36
+ * Resolves all $ref pointers in a schema and returns a new schema without any $ref pointers.
37
+ */
38
+ function dereferenceSync(schema, onDereference) {
39
+ if (typeof schema === "boolean") return schema;
40
+ const visitedNodes = /* @__PURE__ */ new Set();
41
+ const cloned = structuredClone(schema);
42
+ function resolve(current, path) {
43
+ if (typeof current === "object" && current !== null) {
44
+ if (visitedNodes.has(current)) return current;
45
+ visitedNodes.add(current);
46
+ if (Array.isArray(current)) for (let index = 0; index < current.length; index++) current[index] = resolve(current[index], `${path}/${index}`);
47
+ else {
48
+ if ("$ref" in current && typeof current["$ref"] === "string") {
49
+ const ref = current["$ref"];
50
+ const out = (0, import_dereference_json_schema.resolveRefSync)(cloned, ref);
51
+ onDereference(ref, out);
52
+ return out;
53
+ }
54
+ const obj = current;
55
+ for (const key in current) obj[key] = resolve(obj[key], `${path}/${key}`);
56
+ }
57
+ }
58
+ return current;
59
+ }
60
+ return resolve(cloned, "#");
61
+ }
42
62
 
43
63
  //#endregion
44
64
  export { processDocument };
@@ -6,7 +6,7 @@ let FormatFlags = /* @__PURE__ */ function(FormatFlags) {
6
6
  }({});
7
7
  function schemaToString(value, _resolver, flags = FormatFlags.None) {
8
8
  const resolver = typeof _resolver === "function" ? _resolver : (schema) => {
9
- const ref = _resolver?.getRawRef(schema);
9
+ const ref = _resolver && typeof schema === "object" ? _resolver.getRawRef(schema) : void 0;
10
10
  return {
11
11
  dereferenced: schema,
12
12
  raw: ref ? { $ref: ref } : void 0
@@ -30,8 +30,10 @@ function schemaToString(value, _resolver, flags = FormatFlags.None) {
30
30
  else if (schema === false) return "never";
31
31
  if ((flags & FormatFlags.UseAlias) === FormatFlags.UseAlias) {
32
32
  if (schema.title) return schema.title;
33
- const ref = resolved.raw?.$ref?.split("/");
34
- if (ref && ref.length > 0) return ref[ref.length - 1];
33
+ if (typeof resolved.raw === "object" && resolved.raw.$ref) {
34
+ const ref = resolved.raw.$ref.split("/");
35
+ if (ref.length > 0) return ref[ref.length - 1];
36
+ }
35
37
  }
36
38
  if (Array.isArray(schema.type)) return union(schema.type.map((type) => ({
37
39
  ...schema,
@@ -6,9 +6,9 @@ type NoReference<T> = T extends (infer I)[] ? NoReference<I>[] : T extends Refer
6
6
  type NoReferenceJSONSchema<T> = T extends (infer I)[] ? NoReference<I>[] : T extends {
7
7
  $ref?: string;
8
8
  } ? Omit<T, '$ref'> : T;
9
- type ParsedSchema = JSONSchema & {
9
+ type ParsedSchema = (JSONSchema & {
10
10
  'x-playground-lazy'?: boolean;
11
- };
11
+ }) | boolean;
12
12
  type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;
13
13
  //#endregion
14
14
  export { NoReference, ParsedSchema, ResolvedSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-openapi",
3
- "version": "10.3.13",
3
+ "version": "10.3.14",
4
4
  "description": "Generate MDX docs for your OpenAPI spec",
5
5
  "keywords": [
6
6
  "Docs",
@@ -42,14 +42,13 @@
42
42
  "access": "public"
43
43
  },
44
44
  "dependencies": {
45
- "@fumari/json-schema-to-typescript": "^2.0.0",
45
+ "@fumari/json-schema-ts": "^0.0.2",
46
46
  "@radix-ui/react-accordion": "^1.2.12",
47
47
  "@radix-ui/react-dialog": "^1.1.15",
48
48
  "@radix-ui/react-select": "^2.2.6",
49
49
  "@radix-ui/react-slot": "^1.2.4",
50
50
  "@scalar/json-magic": "^0.11.5",
51
- "@scalar/openapi-parser": "0.24.14",
52
- "@scalar/openapi-upgrader": "^0.1.8",
51
+ "@scalar/openapi-upgrader": "^0.1.9",
53
52
  "ajv": "^8.18.0",
54
53
  "class-variance-authority": "^0.7.1",
55
54
  "github-slugger": "^2.0.0",
@@ -63,21 +62,22 @@
63
62
  "remark-rehype": "^11.1.2",
64
63
  "tailwind-merge": "^3.5.0",
65
64
  "xml-js": "^1.6.11",
66
- "@fumari/stf": "1.0.2"
65
+ "@fumari/stf": "1.0.3"
67
66
  },
68
67
  "devDependencies": {
69
- "@scalar/api-client-react": "^1.3.101",
68
+ "@scalar/api-client-react": "^1.3.104",
70
69
  "@types/js-yaml": "^4.0.9",
71
- "@types/node": "25.3.1",
70
+ "@types/node": "25.3.3",
72
71
  "@types/openapi-sampler": "^1.0.3",
73
72
  "@types/react": "^19.2.14",
73
+ "dereference-json-schema": "^0.2.1",
74
74
  "json-schema-typed": "^8.0.2",
75
75
  "tailwindcss": "^4.2.1",
76
76
  "tsdown": "0.20.3",
77
- "@fumadocs/tailwind": "0.0.2",
77
+ "@fumadocs/tailwind": "0.0.3",
78
78
  "eslint-config-custom": "0.0.0",
79
- "fumadocs-core": "16.6.7",
80
- "fumadocs-ui": "16.6.7",
79
+ "fumadocs-core": "16.6.8",
80
+ "fumadocs-ui": "16.6.8",
81
81
  "tsconfig": "0.0.0"
82
82
  },
83
83
  "peerDependencies": {
@@ -1,21 +0,0 @@
1
- //#region src/utils/get-typescript-schema.ts
2
- async function getTypescriptSchema(schema, ctx) {
3
- const { compile } = await import("@fumari/json-schema-to-typescript");
4
- try {
5
- const input = structuredClone({
6
- schema,
7
- idToSchema: ctx.schema._internal_idToSchema()
8
- });
9
- const schemaToId = /* @__PURE__ */ new WeakMap();
10
- for (const [k, v] of input.idToSchema) schemaToId.set(v, k);
11
- return await compile(input.schema, "Response", {
12
- enableConstEnums: false,
13
- schemaToId
14
- });
15
- } catch (e) {
16
- console.warn("Failed to generate typescript schema:", e);
17
- }
18
- }
19
-
20
- //#endregion
21
- export { getTypescriptSchema };