Skip to content

Commit b60627c

Browse files
authored
fix(zod): add coercion call when generating schema for DateTime field (#1068)
1 parent a01065c commit b60627c

File tree

4 files changed

+135
-2
lines changed

4 files changed

+135
-2
lines changed

packages/schema/src/plugins/zod/utils/schema-gen.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ function makeZodSchema(field: DataModelField) {
174174
schema = 'z.boolean()';
175175
break;
176176
case 'DateTime':
177-
schema = 'z.date()';
177+
schema = 'z.coerce.date()';
178178
break;
179179
case 'Bytes':
180180
schema = 'z.union([z.string(), z.instanceof(Uint8Array)])';

packages/server/tests/api/rest.test.ts

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ describe('REST server tests', () => {
4040
id Int @id @default(autoincrement())
4141
createdAt DateTime @default (now())
4242
updatedAt DateTime @updatedAt
43-
title String
43+
title String @length(1, 10)
4444
author User? @relation(fields: [authorId], references: [myId])
4545
authorId String?
4646
published Boolean @default(false)
47+
publishedAt DateTime?
4748
viewCount Int @default(0)
4849
comments Comment[]
4950
setting Setting?
@@ -1293,6 +1294,49 @@ describe('REST server tests', () => {
12931294
});
12941295
});
12951296

1297+
it('creates an item with date coercion', async () => {
1298+
const r = await handler({
1299+
method: 'post',
1300+
path: '/post',
1301+
query: {},
1302+
requestBody: {
1303+
data: {
1304+
type: 'post',
1305+
attributes: {
1306+
id: 1,
1307+
title: 'Post1',
1308+
published: true,
1309+
publishedAt: '2024-03-02T05:00:00.000Z',
1310+
},
1311+
},
1312+
},
1313+
prisma,
1314+
});
1315+
1316+
expect(r.status).toBe(201);
1317+
});
1318+
1319+
it('creates an item with zod violation', async () => {
1320+
const r = await handler({
1321+
method: 'post',
1322+
path: '/post',
1323+
query: {},
1324+
requestBody: {
1325+
data: {
1326+
type: 'post',
1327+
attributes: {
1328+
id: 1,
1329+
title: 'a very very long long title',
1330+
},
1331+
},
1332+
},
1333+
prisma,
1334+
});
1335+
1336+
expect(r.status).toBe(400);
1337+
expect(r.body.errors[0].code).toBe('invalid-payload');
1338+
});
1339+
12961340
it('creates an item with collection relations', async () => {
12971341
await prisma.post.create({
12981342
data: { id: 1, title: 'Post1' },
@@ -1586,6 +1630,50 @@ describe('REST server tests', () => {
15861630
});
15871631
});
15881632

1633+
it('update an item with date coercion', async () => {
1634+
await prisma.post.create({ data: { id: 1, title: 'Post1' } });
1635+
1636+
const r = await handler({
1637+
method: 'put',
1638+
path: '/post/1',
1639+
query: {},
1640+
requestBody: {
1641+
data: {
1642+
type: 'post',
1643+
attributes: {
1644+
published: true,
1645+
publishedAt: '2024-03-02T05:00:00.000Z',
1646+
},
1647+
},
1648+
},
1649+
prisma,
1650+
});
1651+
1652+
expect(r.status).toBe(200);
1653+
});
1654+
1655+
it('update an item with zod violation', async () => {
1656+
await prisma.post.create({ data: { id: 1, title: 'Post1' } });
1657+
1658+
const r = await handler({
1659+
method: 'put',
1660+
path: '/post/1',
1661+
query: {},
1662+
requestBody: {
1663+
data: {
1664+
type: 'post',
1665+
attributes: {
1666+
publishedAt: '2024-13-01',
1667+
},
1668+
},
1669+
},
1670+
prisma,
1671+
});
1672+
1673+
expect(r.status).toBe(400);
1674+
expect(r.body.errors[0].code).toBe('invalid-payload');
1675+
});
1676+
15891677
it('update a single relation', async () => {
15901678
await prisma.user.create({ data: { myId: 'user1', email: 'user1@abc.com' } });
15911679
await prisma.post.create({

packages/server/tests/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ model Post {
2020
author User? @relation(fields: [authorId], references: [id])
2121
authorId String?
2222
published Boolean @default(false)
23+
publishedAt DateTime?
2324
viewCount Int @default(0)
2425
2526
@@allow('all', author == auth())

tests/integration/tests/plugins/zod.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,50 @@ describe('Zod plugin tests', () => {
503503
).toBeFalsy();
504504
});
505505

506+
it('does date coercion', async () => {
507+
const { zodSchemas } = await loadSchema(
508+
`
509+
datasource db {
510+
provider = 'postgresql'
511+
url = env('DATABASE_URL')
512+
}
513+
514+
generator js {
515+
provider = 'prisma-client-js'
516+
}
517+
518+
plugin zod {
519+
provider = "@core/zod"
520+
}
521+
522+
model Model {
523+
id Int @id @default(autoincrement())
524+
dt DateTime
525+
}
526+
`,
527+
{ addPrelude: false, pushDb: false }
528+
);
529+
const schemas = zodSchemas.models;
530+
531+
expect(
532+
schemas.ModelCreateSchema.safeParse({
533+
dt: new Date(),
534+
}).success
535+
).toBeTruthy();
536+
537+
expect(
538+
schemas.ModelCreateSchema.safeParse({
539+
dt: '2023-01-01T00:00:00.000Z',
540+
}).success
541+
).toBeTruthy();
542+
543+
expect(
544+
schemas.ModelCreateSchema.safeParse({
545+
dt: '2023-13-01',
546+
}).success
547+
).toBeFalsy();
548+
});
549+
506550
it('generate for selected models full', async () => {
507551
const { projectDir } = await loadSchema(
508552
`

0 commit comments

Comments
 (0)