Skip to content

Commit 0fce97b

Browse files
author
chenzewang
committed
Fix jsonSchemaObjectToZodRawShape to respect required fields
Fixes #11: jsonSchemaObjectToZodRawShape now correctly handles the required field from JSON Schema, making only non-required properties optional. - Required fields remain as their base Zod types (ZodString, ZodNumber, etc.) - Non-required fields are wrapped with .optional() - When no required array is present, all fields are optional by default - Updated tests to reflect correct behavior
1 parent 254d67e commit 0fce97b

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

src/index.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,10 +714,11 @@ describe("jsonSchemaObjectToZodRawShape", () => {
714714
expect(rawShape).toHaveProperty("age");
715715
expect(rawShape).toHaveProperty("isActive");
716716

717-
// Verify types are correct
717+
// Verify types are correct - required fields should be their base types
718718
expect(rawShape.name instanceof z.ZodString).toBe(true);
719719
expect(rawShape.age instanceof z.ZodNumber).toBe(true);
720-
expect(rawShape.isActive instanceof z.ZodBoolean).toBe(true);
720+
// Non-required fields should be optional
721+
expect(rawShape.isActive instanceof z.ZodOptional).toBe(true);
721722
});
722723

723724
it("should handle empty properties", () => {
@@ -759,7 +760,10 @@ describe("jsonSchemaObjectToZodRawShape", () => {
759760
const rawShape = jsonSchemaObjectToZodRawShape(jsonSchema);
760761

761762
expect(rawShape).toHaveProperty("user");
762-
expect(rawShape.user instanceof z.ZodObject).toBe(true);
763+
// Since user is not in the required array at the top level, it should be optional
764+
expect(rawShape.user instanceof z.ZodOptional).toBe(true);
765+
// The inner type should be a ZodObject
766+
expect((rawShape.user as z.ZodOptional<any>)._def.innerType instanceof z.ZodObject).toBe(true);
763767

764768
// Create a schema with the raw shape to test validation
765769
const schema = z.object(rawShape);

src/index.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,28 @@ export function convertJsonSchemaToZod(schema: JSONSchema): z.ZodTypeAny {
319319
*/
320320
export function jsonSchemaObjectToZodRawShape(schema: JSONSchema): z.ZodRawShape {
321321
let raw: z.ZodRawShape = {};
322-
for (const [key, value] of Object.entries(schema.properties ?? {})) {
323-
raw[key] = convertJsonSchemaToZod(value);
322+
323+
// Get the required fields set for efficient lookup
324+
const requiredArray = Array.isArray(schema.required) ? schema.required : [];
325+
const requiredFields = new Set<string>(requiredArray);
326+
327+
// Process each property
328+
for (const [key, propSchema] of Object.entries(schema.properties ?? {})) {
329+
let zodSchema = convertJsonSchemaToZod(propSchema);
330+
331+
// If there's a required array and the field is not in it, make it optional
332+
// If there's no required array, all fields are optional by default in JSON Schema
333+
if (requiredArray.length > 0) {
334+
if (!requiredFields.has(key)) {
335+
zodSchema = zodSchema.optional();
336+
}
337+
} else {
338+
// No required array means all fields are optional
339+
zodSchema = zodSchema.optional();
340+
}
341+
342+
raw[key] = zodSchema;
324343
}
344+
325345
return raw;
326346
}

0 commit comments

Comments
 (0)