Skip to content

Commit

Permalink
Add support for ZodCatch
Browse files Browse the repository at this point in the history
  • Loading branch information
matejchalk committed Feb 19, 2025
1 parent 483fd8f commit 8ce403f
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 78 deletions.
190 changes: 113 additions & 77 deletions src/converter/convert-schemas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,95 +210,131 @@ describe('convert exported Zod schemas to models', () => {
it('should support the ZodPipeline type', () => {
const PostalCodeSchema = z
.string()
.transform((postalCode: string) => postalCode.toUpperCase().replaceAll(' ', ''))
.transform((postalCode: string) =>
postalCode.toUpperCase().replaceAll(' ', '')
)
.pipe(z.string().regex(/^\d{4}(?:[A-Z]{2}|\d)?$/, 'Invalid postal code'));

expect(convertSchemas([{path: 'postalcode.ts', schema: PostalCodeSchema, name: 'PostalCode'}])).toEqual(<NamedModel[]>[{
name: "PostalCode",
path: "postalcode.ts",
type: "string",
validations: [
[
"regex",
/^\d{4}(?:[A-Z]{2}|\d)?$/,
],
],
}]);
expect(
convertSchemas([
{ path: 'postalcode.ts', schema: PostalCodeSchema, name: 'PostalCode' },
])
).toEqual(<NamedModel[]>[
{
name: 'PostalCode',
path: 'postalcode.ts',
type: 'string',
validations: [['regex', /^\d{4}(?:[A-Z]{2}|\d)?$/]],
},
]);
});

it('should suppot the ZodDiscriminatedUnion type', () => {
const schemaA = z.object({
type: z.literal('first'),
name: z.string()
}).describe('Schema A');
const schemaB = z.object({
type: z.literal('second'),
age: z.number().min(21).max(90)
}).describe('Schema B');
const schemaA = z
.object({
type: z.literal('first'),
name: z.string(),
})
.describe('Schema A');
const schemaB = z
.object({
type: z.literal('second'),
age: z.number().min(21).max(90),
})
.describe('Schema B');
const unionSchema = z.discriminatedUnion('type', [schemaA, schemaB]);

expect(convertSchemas([{path: 'unionschema.ts', name: 'Union', schema: unionSchema}])).toEqual<NamedModel[]>([{
name: "Union",
options: [
{
kind: "model",
model: {
description: "Schema A",
fields: [
{
key: "type",
kind: "model",
model: {
type: "literal",
value: "first",
expect(
convertSchemas([
{ path: 'unionschema.ts', name: 'Union', schema: unionSchema },
])
).toEqual<NamedModel[]>([
{
name: 'Union',
options: [
{
kind: 'model',
model: {
description: 'Schema A',
fields: [
{
key: 'type',
kind: 'model',
model: {
type: 'literal',
value: 'first',
},
required: true,
},
required: true,
},
{
key: "name",
kind: "model",
model: {
type: "string",
{
key: 'name',
kind: 'model',
model: {
type: 'string',
},
required: true,
},
required: true,
},
],
type: "object",
],
type: 'object',
},
},
},
{
kind: "model",
model: {
description: "Schema B",
fields: [
{
key: "type",
kind: "model",
model: {
type: "literal",
value: "second",
{
kind: 'model',
model: {
description: 'Schema B',
fields: [
{
key: 'type',
kind: 'model',
model: {
type: 'literal',
value: 'second',
},
required: true,
},
required: true,
},
{
key: "age",
kind: "model",
model: {
type: "number",
validations: [
["gte", 21],
["lte", 90],
],
{
key: 'age',
kind: 'model',
model: {
type: 'number',
validations: [
['gte', 21],
['lte', 90],
],
},
required: true,
},
required: true,
},
],
type: "object",
],
type: 'object',
},
},
],
path: 'unionschema.ts',
type: 'union',
},
]);
});

it('should support the ZodCatch type', () => {
const permissiveUrlSchema = z.string().url().catch('');

expect(
convertSchemas([
{
path: 'utils.ts',
schema: permissiveUrlSchema,
name: 'URL',
},
],
path: "unionschema.ts",
type: "union",
}])
})
])
).toEqual(<NamedModel[]>[
{
name: 'URL',
path: 'utils.ts',
type: 'string',
validations: ['url'],
nullable: true,
optional: true,
},
]);
});
});
8 changes: 7 additions & 1 deletion src/converter/convert-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ZodBigInt,
ZodBoolean,
ZodBranded,
ZodCatch,
ZodDate,
ZodDefault,
ZodDiscriminatedUnion,
Expand Down Expand Up @@ -169,6 +170,9 @@ function convertSchema(
if (schema instanceof ZodEffects) {
return convertSchema(schema._def.schema, exportedSchemas);
}
if (schema instanceof ZodCatch) {
return convertSchema(schema._def.innerType, exportedSchemas);
}
if (schema instanceof ZodBranded) {
return convertSchema(schema._def.type, exportedSchemas);
}
Expand Down Expand Up @@ -248,7 +252,9 @@ function convertSchema(
if (schema instanceof ZodDiscriminatedUnion) {
return {
type: 'union',
options: schema._def.options.map((option: any) => createModelOrRef(option, exportedSchemas)),
options: schema._def.options.map((option: any) =>
createModelOrRef(option, exportedSchemas)
),
};
}

Expand Down

0 comments on commit 8ce403f

Please sign in to comment.