@gabrielbryk/json-schema-to-zod 2.11.0 → 2.11.1
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/CHANGELOG.md +10 -0
- package/dist/core/emitZod.js +4 -4
- package/dist/parsers/parseObject.js +34 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @gabrielbryk/json-schema-to-zod
|
|
2
2
|
|
|
3
|
+
## 2.11.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 466d672: Fix TS7056 error when generating declarations for schemas referencing recursive types
|
|
8
|
+
|
|
9
|
+
- Add explicit type annotations to any schema that references recursive schemas (not just unions)
|
|
10
|
+
- This prevents TypeScript from trying to serialize extremely large expanded types when generating .d.ts files
|
|
11
|
+
- Fix type narrowing in parseObject for allOf required array handling
|
|
12
|
+
|
|
3
13
|
## 2.11.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/dist/core/emitZod.js
CHANGED
|
@@ -196,14 +196,14 @@ export const emitZod = (analysis) => {
|
|
|
196
196
|
: undefined;
|
|
197
197
|
const hasLazy = expression.includes("z.lazy(");
|
|
198
198
|
const hasGetter = expression.includes("get ");
|
|
199
|
-
|
|
200
|
-
//
|
|
201
|
-
const referencesRecursiveSchema =
|
|
199
|
+
// Check if this schema references any cycle members (recursive schemas)
|
|
200
|
+
// This can cause TS7056 when TypeScript tries to serialize the expanded type
|
|
201
|
+
const referencesRecursiveSchema = Array.from(cycleRefNames).some(cycleName => new RegExp(`\\b${cycleName}\\b`).test(expression));
|
|
202
202
|
// Per Zod v4 docs: type annotations should be on GETTERS for recursive types, not on const declarations.
|
|
203
203
|
// TypeScript can infer the type of const declarations.
|
|
204
204
|
// Exceptions that need explicit type annotation:
|
|
205
205
|
// 1. z.lazy() without getters
|
|
206
|
-
// 2.
|
|
206
|
+
// 2. Any schema that references recursive schemas (to prevent TS7056)
|
|
207
207
|
const needsTypeAnnotation = (hasLazy && !hasGetter) || referencesRecursiveSchema;
|
|
208
208
|
const storedType = needsTypeAnnotation ? (hintedType ?? inferTypeFromExpression(expression)) : undefined;
|
|
209
209
|
// Rule 2 from Zod v4: Don't chain methods on recursive types
|
|
@@ -13,6 +13,16 @@ export function parseObject(objectSchema, refs) {
|
|
|
13
13
|
const hasAdditionalProperties = objectSchema.additionalProperties !== undefined;
|
|
14
14
|
const hasPatternProperties = objectSchema.patternProperties !== undefined;
|
|
15
15
|
const hasNoDirectSchema = !hasDirectProperties && !hasAdditionalProperties && !hasPatternProperties;
|
|
16
|
+
const parentRequired = Array.isArray(objectSchema.required) ? objectSchema.required : [];
|
|
17
|
+
const allOfRequired = its.an.allOf(objectSchema)
|
|
18
|
+
? objectSchema.allOf.flatMap((member) => {
|
|
19
|
+
if (typeof member !== "object" || member === null)
|
|
20
|
+
return [];
|
|
21
|
+
const req = member.required;
|
|
22
|
+
return Array.isArray(req) ? req : [];
|
|
23
|
+
})
|
|
24
|
+
: [];
|
|
25
|
+
const combinedAllOfRequired = [...new Set([...parentRequired, ...allOfRequired])];
|
|
16
26
|
// Helper to add type: "object" to composition members that have properties but no explicit type
|
|
17
27
|
const addObjectType = (members) => members.map((x) => typeof x === "object" &&
|
|
18
28
|
x !== null &&
|
|
@@ -20,9 +30,31 @@ export function parseObject(objectSchema, refs) {
|
|
|
20
30
|
(x.properties || x.additionalProperties || x.patternProperties)
|
|
21
31
|
? { ...x, type: "object" }
|
|
22
32
|
: x);
|
|
33
|
+
const addObjectTypeAndMergeRequired = (members) => members.map((x) => {
|
|
34
|
+
if (typeof x !== "object" || x === null)
|
|
35
|
+
return x;
|
|
36
|
+
let normalized = x;
|
|
37
|
+
const hasShape = normalized.properties || normalized.additionalProperties || normalized.patternProperties;
|
|
38
|
+
if (hasShape && !normalized.type) {
|
|
39
|
+
normalized = { ...normalized, type: "object" };
|
|
40
|
+
}
|
|
41
|
+
if (combinedAllOfRequired.length &&
|
|
42
|
+
normalized.properties &&
|
|
43
|
+
Object.keys(normalized.properties).length) {
|
|
44
|
+
const memberRequired = Array.isArray(normalized.required) ? normalized.required : [];
|
|
45
|
+
const mergedRequired = Array.from(new Set([
|
|
46
|
+
...memberRequired,
|
|
47
|
+
...combinedAllOfRequired.filter((key) => Object.prototype.hasOwnProperty.call(normalized.properties, key)),
|
|
48
|
+
]));
|
|
49
|
+
if (mergedRequired.length) {
|
|
50
|
+
normalized = { ...normalized, required: mergedRequired };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return normalized;
|
|
54
|
+
});
|
|
23
55
|
// If only allOf, delegate to parseAllOf
|
|
24
56
|
if (hasNoDirectSchema && its.an.allOf(objectSchema) && !its.an.anyOf(objectSchema) && !its.a.oneOf(objectSchema) && !its.a.conditional(objectSchema)) {
|
|
25
|
-
return parseAllOf({ ...objectSchema, allOf:
|
|
57
|
+
return parseAllOf({ ...objectSchema, allOf: addObjectTypeAndMergeRequired(objectSchema.allOf) }, refs);
|
|
26
58
|
}
|
|
27
59
|
// If only anyOf, delegate to parseAnyOf
|
|
28
60
|
if (hasNoDirectSchema && its.an.anyOf(objectSchema) && !its.an.allOf(objectSchema) && !its.a.oneOf(objectSchema) && !its.a.conditional(objectSchema)) {
|
|
@@ -285,12 +317,7 @@ export function parseObject(objectSchema, refs) {
|
|
|
285
317
|
if (its.an.allOf(objectSchema)) {
|
|
286
318
|
const allOfResult = parseAllOf({
|
|
287
319
|
...objectSchema,
|
|
288
|
-
allOf: objectSchema.allOf
|
|
289
|
-
x !== null &&
|
|
290
|
-
!x.type &&
|
|
291
|
-
(x.properties || x.additionalProperties || x.patternProperties)
|
|
292
|
-
? { ...x, type: "object" }
|
|
293
|
-
: x),
|
|
320
|
+
allOf: addObjectTypeAndMergeRequired(objectSchema.allOf),
|
|
294
321
|
}, refs);
|
|
295
322
|
output += `.and(${allOfResult.expression})`;
|
|
296
323
|
intersectionTypes.push(allOfResult.type);
|