Skip to content

Commit ddd6a2f

Browse files
committed
fix: add applyDefault to enum branches in jsonSchemaToZod
1 parent 2199455 commit ddd6a2f

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

src/integrations/xcode-tools-bridge/__tests__/jsonschema-to-zod.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,27 @@ describe('jsonSchemaToZod', () => {
105105
const intSchema = { type: 'integer', default: 7 };
106106
expect(jsonSchemaToZod(intSchema).parse(undefined)).toBe(7);
107107
});
108+
109+
it('applies default values on enum types', () => {
110+
// String enum with default
111+
const stringEnumSchema = {
112+
enum: ['project-relative', 'absolute'],
113+
default: 'project-relative',
114+
};
115+
expect(jsonSchemaToZod(stringEnumSchema).parse(undefined)).toBe('project-relative');
116+
expect(jsonSchemaToZod(stringEnumSchema).parse('absolute')).toBe('absolute');
117+
118+
// Single-value string enum (literal) with default
119+
const singleEnumSchema = { enum: ['only'], default: 'only' };
120+
expect(jsonSchemaToZod(singleEnumSchema).parse(undefined)).toBe('only');
121+
122+
// Mixed-type enum with default
123+
const mixedEnumSchema = { enum: ['a', 1, true], default: 1 };
124+
expect(jsonSchemaToZod(mixedEnumSchema).parse(undefined)).toBe(1);
125+
expect(jsonSchemaToZod(mixedEnumSchema).parse('a')).toBe('a');
126+
127+
// Single mixed literal with default
128+
const singleMixedSchema = { enum: [42], default: 42 };
129+
expect(jsonSchemaToZod(singleMixedSchema).parse(undefined)).toBe(42);
130+
});
108131
});

src/integrations/xcode-tools-bridge/jsonschema-to-zod.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,31 +47,37 @@ export function jsonSchemaToZod(schema: JsonSchema | unknown): z.ZodTypeAny {
4747
if (Array.isArray(s.enum)) {
4848
const enumValues = s.enum.filter(isEnumValue);
4949
if (enumValues.length === 0) {
50-
return applyDescription(z.any(), s.description);
50+
return applyDefault(applyDescription(z.any(), s.description), s.default);
5151
}
5252
const allStrings = enumValues.every((v) => typeof v === 'string');
5353
if (allStrings) {
5454
const stringValues = enumValues as string[];
5555
if (stringValues.length === 1) {
56-
return applyDescription(z.literal(stringValues[0]), s.description);
56+
return applyDefault(applyDescription(z.literal(stringValues[0]), s.description), s.default);
5757
}
58-
return applyDescription(z.enum(stringValues as [string, ...string[]]), s.description);
58+
return applyDefault(
59+
applyDescription(z.enum(stringValues as [string, ...string[]]), s.description),
60+
s.default,
61+
);
5962
}
6063

6164
// z.enum only supports string unions; use z.literal union for mixed enums.
6265
const literals = enumValues.map((v) => z.literal(v)) as z.ZodLiteral<JsonSchemaEnumValue>[];
6366
if (literals.length === 1) {
64-
return applyDescription(literals[0], s.description);
67+
return applyDefault(applyDescription(literals[0], s.description), s.default);
6568
}
66-
return applyDescription(
67-
z.union(
68-
literals as [
69-
z.ZodLiteral<JsonSchemaEnumValue>,
70-
z.ZodLiteral<JsonSchemaEnumValue>,
71-
...z.ZodLiteral<JsonSchemaEnumValue>[],
72-
],
69+
return applyDefault(
70+
applyDescription(
71+
z.union(
72+
literals as [
73+
z.ZodLiteral<JsonSchemaEnumValue>,
74+
z.ZodLiteral<JsonSchemaEnumValue>,
75+
...z.ZodLiteral<JsonSchemaEnumValue>[],
76+
],
77+
),
78+
s.description,
7379
),
74-
s.description,
80+
s.default,
7581
);
7682
}
7783

0 commit comments

Comments
 (0)