Skip to content

Commit f6ca716

Browse files
committed
refactor: add base global errors for zod
1 parent cdc90cd commit f6ca716

File tree

9 files changed

+58
-31
lines changed

9 files changed

+58
-31
lines changed

app/app.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ import express from 'express'
22
import cors from 'cors'
33
import helmet from 'helmet'
44
import logger from 'morgan'
5+
import z from 'zod'
56

6-
import { env } from './config'
7+
import { env, zodConfig } from './config'
78
import { globalErrorHandler, notFoundHandler } from './middlewares'
89
import { apiRouter } from './routes'
910

1011
export const app = express()
1112

13+
z.config(zodConfig)
14+
1215
app.use(helmet())
1316
app.use(cors({ origin: env.ALLOWED_ORIGINS }))
1417
app.use(logger(app.get('env') === 'development' ? 'dev' : 'combined'))

app/config/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export { transport } from './mailer.config'
22
export { default } from './cloudinary.config'
33
export { env } from './env.config'
44
export { redisClient } from './redis.config'
5+
export { zodConfig } from './zod.config'
56
export { defaultUserAvatars } from './default-user-avatars.config'

app/config/zod.config.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type z from 'zod'
2+
3+
export const zodConfig: z.core.$ZodConfig = {
4+
customError: ({
5+
input,
6+
code,
7+
minimum,
8+
maximum,
9+
expected,
10+
format,
11+
values
12+
}) => {
13+
if (!input) return 'The field is required'
14+
15+
if (code === 'too_small') {
16+
return `The field must be at least ${minimum} characters`
17+
}
18+
19+
if (code === 'too_big') {
20+
return `The field must be at most ${maximum} characters`
21+
}
22+
23+
if (code === 'invalid_value') {
24+
return `The field must be one of the following values: ${values.join(', ')}`
25+
}
26+
27+
if (code === 'invalid_format') {
28+
return `The field must have a valid ${format} format`
29+
}
30+
31+
if (code === 'invalid_type') return `The field must be of type ${expected}`
32+
33+
return undefined
34+
}
35+
}

app/schemas/auth.schema.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
import * as z from 'zod'
22

33
export const SigninSchema = z.object({
4-
email: z.email('Email is required'),
5-
password: z
6-
.string()
7-
.min(8, 'Password must be at least 8 characters')
8-
.max(64, 'Password must be at most 64 characters')
4+
email: z.email(),
5+
password: z.string().min(8).max(64)
96
})
107

118
export const SignupSchema = z.object({
129
...SigninSchema.shape,
13-
name: z.string().min(2, 'Name must be at least 2 characters')
10+
name: z.string().min(2)
1411
})
1512

1613
export const RefreshTokenSchema = z.object({
17-
refreshToken: z.string().min(1, 'Refresh token is required')
14+
refreshToken: z.string().min(1)
1815
})
1916

2017
export const GoogleCodeSchema = z.object({
21-
code: z.string().min(1, 'Code is required'),
18+
code: z.string().min(1),
2219
state: z.optional(z.string())
2320
})

app/schemas/board.schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const zObjectKeys = <T extends Record<string, unknown>>(obj: T) => {
1414
}
1515

1616
export const AddBoardSchema = z.object({
17-
title: z.string().min(3, 'Title must be at least 3 characters'),
17+
title: z.string().min(3),
1818
icon: z.enum(Icon),
1919
background: zObjectKeys(boardImages)
2020
})

app/schemas/card.schema.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@ import * as z from 'zod'
44
import { objectIdSchema } from './object-id.schema'
55

66
export const AddCardSchema = z.object({
7-
title: z.string().min(3, 'Title must be at least 3 characters'),
8-
description: z.string().min(3, 'Description must be at least 3 characters'),
9-
priority: z.enum(
10-
Priority,
11-
`Priority must be one of the following: ${Object.values(Priority).join(',')}`
12-
),
13-
deadline: z.iso.datetime('Deadline must be a valid datetime')
7+
title: z.string().min(3),
8+
description: z.string().min(3),
9+
priority: z.enum(Priority),
10+
deadline: z.iso.datetime()
1411
})
1512

1613
export const EditCardSchema = z

app/schemas/column.schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as z from 'zod'
33
import { objectIdSchema } from './object-id.schema'
44

55
export const AddColumnSchema = z.object({
6-
title: z.string().min(3, 'Title must be at least 3 characters')
6+
title: z.string().min(3)
77
})
88

99
export const EditColumnSchema = AddColumnSchema.partial()

app/schemas/object-id.schema.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
import * as z from 'zod'
22

3-
export const objectIdSchema = () =>
4-
z.string().regex(/^[0-9a-f]{24}$/, 'Id must be a valid ObjectId')
3+
export const objectIdSchema = () => z.string().regex(/^[0-9a-f]{24}$/)

app/schemas/user.schema.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@ import { Theme } from '@prisma/client'
22
import * as z from 'zod'
33

44
export const NeedHelpSchema = z.object({
5-
email: z.email('Email is invalid'),
6-
comment: z.string().min(5, 'Comment must be at least 5 characters')
5+
email: z.email(),
6+
comment: z.string().min(5)
77
})
88

99
export const EditUserSchema = z
1010
.object({
11-
name: z.string().min(2, 'Name must be at least 2 characters'),
12-
email: z.email('Email is invalid'),
13-
password: z
14-
.string()
15-
.min(8, 'Password must be at least 8 characters')
16-
.max(64, 'Password must be at most 64 characters'),
17-
theme: z.enum(Theme, {
18-
message: `Theme must be one of the following: ${Object.values(Theme).join(',')}`
19-
})
11+
name: z.string().min(2),
12+
email: z.email(),
13+
password: z.string().min(8).max(64),
14+
theme: z.enum(Theme)
2015
})
2116
.partial()

0 commit comments

Comments
 (0)