zudoku 0.0.0-z7b86faab → 0.0.0-z9d382b4a
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.
- package/dist/lib/oas/graphql/circular.d.ts +1 -1
- package/dist/lib/oas/graphql/circular.js +18 -35
- package/dist/lib/oas/graphql/circular.js.map +1 -1
- package/dist/lib/oas/graphql/circular.test.js +33 -2
- package/dist/lib/oas/graphql/circular.test.js.map +1 -1
- package/dist/lib/util/readFrontmatter.js +2 -1
- package/dist/lib/util/readFrontmatter.js.map +1 -1
- package/dist/vite/build.js +91 -73
- package/dist/vite/build.js.map +1 -1
- package/dist/vite/mdx/remark-inject-filepath.js +5 -1
- package/dist/vite/mdx/remark-inject-filepath.js.map +1 -1
- package/dist/vite/mdx/remark-link-rewrite.js +3 -2
- package/dist/vite/mdx/remark-link-rewrite.js.map +1 -1
- package/dist/vite/plugin-docs.js +9 -7
- package/dist/vite/plugin-docs.js.map +1 -1
- package/dist/vite/plugin-markdown-export.js +4 -2
- package/dist/vite/plugin-markdown-export.js.map +1 -1
- package/lib/{OasProvider-CS_ASmBB.js → OasProvider-B2KxIBsI.js} +2 -2
- package/lib/{OasProvider-CS_ASmBB.js.map → OasProvider-B2KxIBsI.js.map} +1 -1
- package/lib/{OperationList-Dq_AB4W9.js → OperationList-C2tAfThO.js} +3 -3
- package/lib/{OperationList-Dq_AB4W9.js.map → OperationList-C2tAfThO.js.map} +1 -1
- package/lib/{SchemaList-BJZJv1gD.js → SchemaList-Ep8DleP_.js} +3 -3
- package/lib/{SchemaList-BJZJv1gD.js.map → SchemaList-Ep8DleP_.js.map} +1 -1
- package/lib/{SchemaView-U4JMYB3N.js → SchemaView-BpaEKRYx.js} +2 -2
- package/lib/{SchemaView-U4JMYB3N.js.map → SchemaView-BpaEKRYx.js.map} +1 -1
- package/lib/{circular-BmMJjG1v.js → circular-CG3e0_Uz.js} +1327 -1346
- package/lib/{circular-BmMJjG1v.js.map → circular-CG3e0_Uz.js.map} +1 -1
- package/lib/{createServer-CLSZ7hWJ.js → createServer-CNeRqj98.js} +3 -3
- package/lib/{createServer-CLSZ7hWJ.js.map → createServer-CNeRqj98.js.map} +1 -1
- package/lib/{index-O9RHI87z.js → index-I3kmZ7tG.js} +6 -6
- package/lib/{index-O9RHI87z.js.map → index-I3kmZ7tG.js.map} +1 -1
- package/lib/zudoku.plugin-openapi.js +1 -1
- package/package.json +2 -2
- package/src/lib/oas/graphql/circular.test.ts +37 -2
- package/src/lib/oas/graphql/circular.ts +25 -51
- package/src/lib/util/readFrontmatter.ts +2 -1
|
@@ -3,7 +3,7 @@ import "lucide-react";
|
|
|
3
3
|
import "./chunk-EPOLDU6W-C6C8jAwd.js";
|
|
4
4
|
import "./ui/Button.js";
|
|
5
5
|
import "./ZudokuContext-BZB1TWdT.js";
|
|
6
|
-
import { y as e, U as n, z as s } from "./index-
|
|
6
|
+
import { y as e, U as n, z as s } from "./index-I3kmZ7tG.js";
|
|
7
7
|
export {
|
|
8
8
|
e as GetNavigationOperationsQuery,
|
|
9
9
|
n as UNTAGGED_PATH,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zudoku",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-z9d382b4a",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://zudoku.dev",
|
|
6
6
|
"repository": {
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
"pagefind": "1.5.0-beta.1",
|
|
234
234
|
"picocolors": "1.1.1",
|
|
235
235
|
"piscina": "5.1.4",
|
|
236
|
-
"posthog-node": "5.
|
|
236
|
+
"posthog-node": "5.21.2",
|
|
237
237
|
"react-error-boundary": "6.0.0",
|
|
238
238
|
"react-hook-form": "7.66.0",
|
|
239
239
|
"react-is": "19.2.3",
|
|
@@ -156,16 +156,20 @@ describe("handleCircularRefs", () => {
|
|
|
156
156
|
});
|
|
157
157
|
});
|
|
158
158
|
|
|
159
|
-
it("should
|
|
159
|
+
it("should handle shared object instances with __$ref without marking circular", () => {
|
|
160
160
|
const shared = { __$ref: "#/components/schemas/Foo", type: "string" };
|
|
161
161
|
const obj = { a: shared, b: shared };
|
|
162
162
|
const result = handleCircularRefs(obj);
|
|
163
163
|
|
|
164
|
+
// Both should return the cached result, not mark as circular
|
|
164
165
|
expect(result.a).toEqual({
|
|
165
166
|
__$ref: "#/components/schemas/Foo",
|
|
166
167
|
type: "string",
|
|
167
168
|
});
|
|
168
|
-
expect(result.b).
|
|
169
|
+
expect(result.b).toEqual({
|
|
170
|
+
__$ref: "#/components/schemas/Foo",
|
|
171
|
+
type: "string",
|
|
172
|
+
});
|
|
169
173
|
});
|
|
170
174
|
|
|
171
175
|
it("should mark circular ref with property name from path", () => {
|
|
@@ -183,4 +187,35 @@ describe("handleCircularRefs", () => {
|
|
|
183
187
|
|
|
184
188
|
expect(result.properties.child.properties.back).toContain(CIRCULAR_REF);
|
|
185
189
|
});
|
|
190
|
+
|
|
191
|
+
// Exact reproduction of #1869 - shared object instances with __$ref
|
|
192
|
+
it("should NOT mark shared object instances with __$ref as circular (issue #1869)", () => {
|
|
193
|
+
// When dereferencing, the SAME object instance is returned for all refs to the same schema
|
|
194
|
+
const timestampSchema = {
|
|
195
|
+
__$ref: "#/components/schemas/timestamp",
|
|
196
|
+
type: "string",
|
|
197
|
+
format: "date-time",
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// Both created_at and updated_at point to the SAME object instance
|
|
201
|
+
const obj = {
|
|
202
|
+
type: "object",
|
|
203
|
+
properties: {
|
|
204
|
+
created_at: timestampSchema,
|
|
205
|
+
updated_at: timestampSchema,
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const result = handleCircularRefs(obj);
|
|
210
|
+
|
|
211
|
+
// The first one should be fully expanded
|
|
212
|
+
expect(result.properties.created_at).toEqual({
|
|
213
|
+
__$ref: "#/components/schemas/timestamp",
|
|
214
|
+
type: "string",
|
|
215
|
+
format: "date-time",
|
|
216
|
+
});
|
|
217
|
+
// The second one should ALSO be fully expanded (not marked as circular)
|
|
218
|
+
expect(typeof result.properties.updated_at).toBe("object");
|
|
219
|
+
expect(result.properties.updated_at).not.toContain(CIRCULAR_REF);
|
|
220
|
+
});
|
|
186
221
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GraphQLScalarType } from "graphql/index.js";
|
|
2
2
|
import { GraphQLJSON } from "graphql-type-json";
|
|
3
|
-
import type { RecordAny } from "../../util/traverse.js";
|
|
4
3
|
|
|
5
4
|
export const CIRCULAR_REF = "$[Circular Reference]";
|
|
6
5
|
export const SCHEMA_REF_PREFIX = "$ref:";
|
|
@@ -17,73 +16,48 @@ const OPENAPI_PROPS = new Set([
|
|
|
17
16
|
export const handleCircularRefs = (
|
|
18
17
|
// biome-ignore lint/suspicious/noExplicitAny: Allow any type
|
|
19
18
|
obj: any,
|
|
20
|
-
|
|
19
|
+
currentPath = new WeakSet(),
|
|
21
20
|
refs = new WeakMap(),
|
|
22
21
|
path: string[] = [],
|
|
23
|
-
|
|
22
|
+
currentRefPaths = new Set<string>(),
|
|
24
23
|
// biome-ignore lint/suspicious/noExplicitAny: Allow any type
|
|
25
24
|
): any => {
|
|
26
25
|
if (obj === null || typeof obj !== "object") return obj;
|
|
27
26
|
|
|
28
27
|
const refPath = obj.__$ref;
|
|
28
|
+
const isCircular =
|
|
29
|
+
currentPath.has(obj) ||
|
|
30
|
+
(typeof refPath === "string" && currentRefPaths.has(refPath));
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// instead of the full data to avoid JSON.stringify serializing duplicates
|
|
33
|
-
if (typeof refPath === "string" && seenRefPaths.has(refPath)) {
|
|
34
|
-
return SCHEMA_REF_PREFIX + refPath;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (visited.has(obj)) {
|
|
38
|
-
const cached = refs.get(obj);
|
|
39
|
-
if (cached) {
|
|
40
|
-
return typeof refPath === "string"
|
|
41
|
-
? // If already processed, return ref marker to avoid duplicate serialization
|
|
42
|
-
SCHEMA_REF_PREFIX + refPath
|
|
43
|
-
: cached;
|
|
44
|
-
}
|
|
32
|
+
if (isCircular) {
|
|
33
|
+
if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
|
|
45
34
|
const circularProp = path.find((p) => !OPENAPI_PROPS.has(p)) || path[0];
|
|
46
|
-
|
|
47
35
|
return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
|
|
48
36
|
}
|
|
49
37
|
|
|
50
|
-
|
|
38
|
+
if (refs.has(obj)) return refs.get(obj);
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (typeof refPath === "string") {
|
|
55
|
-
seenRefPaths.add(refPath);
|
|
56
|
-
}
|
|
40
|
+
currentPath.add(obj);
|
|
41
|
+
if (typeof refPath === "string") currentRefPaths.add(refPath);
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
[...path, index.toString()],
|
|
66
|
-
seenRefPaths,
|
|
67
|
-
),
|
|
43
|
+
const recurse = (value: unknown, key: string) =>
|
|
44
|
+
handleCircularRefs(
|
|
45
|
+
value,
|
|
46
|
+
currentPath,
|
|
47
|
+
refs,
|
|
48
|
+
[...path, key],
|
|
49
|
+
currentRefPaths,
|
|
68
50
|
);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
visited,
|
|
75
|
-
refs,
|
|
76
|
-
[...path, key],
|
|
77
|
-
seenRefPaths,
|
|
51
|
+
|
|
52
|
+
const result = Array.isArray(obj)
|
|
53
|
+
? obj.map((item, i) => recurse(item, i.toString()))
|
|
54
|
+
: Object.fromEntries(
|
|
55
|
+
Object.entries(obj).map(([k, v]) => [k, recurse(v, k)]),
|
|
78
56
|
);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
refs.set(obj, result);
|
|
82
57
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
58
|
+
refs.set(obj, result);
|
|
59
|
+
currentPath.delete(obj);
|
|
60
|
+
if (typeof refPath === "string") currentRefPaths.delete(refPath);
|
|
87
61
|
|
|
88
62
|
return result;
|
|
89
63
|
};
|
|
@@ -9,5 +9,6 @@ export const yaml = {
|
|
|
9
9
|
|
|
10
10
|
export const readFrontmatter = async (filePath: string) => {
|
|
11
11
|
const content = await readFile(filePath, "utf-8");
|
|
12
|
-
|
|
12
|
+
const normalizedContent = content.replace(/\r\n/g, "\n");
|
|
13
|
+
return matter(normalizedContent, { engines: { yaml } });
|
|
13
14
|
};
|