Skip to content

Commit d8ce87b

Browse files
feat(deps): upgrade zod from v3 to v4 (#3153)
- Replace z.record(z.unknown()) with z.record(z.string(), z.unknown()) (breaking change v4) - Replace z.ZodIssueCode.custom string enum with plain 'custom' string literal - Replace invalid_type_error param with error param in z.string() - Remove .strip() (now default behavior in v4) - Add input field to ctx.addIssue() calls per v4 API Closes #3149
1 parent b3e3788 commit d8ce87b

5 files changed

Lines changed: 13 additions & 14 deletions

File tree

lib/helpers/zod.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
*/
44
import zxcvbn from 'zxcvbn';
55
import config from '../../config/index.js';
6-
import { z } from 'zod';
76

87
/**
98
* @desc Zod superRefine for zxcvbn password strength
109
*/
1110
const passwordRefinement = (val, ctx) => {
1211
if (config.zxcvbn.forbiddenPasswords.includes(val)) {
13-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'password is too common' });
12+
ctx.addIssue({ code: 'custom', message: 'password is too common', input: val });
1413
} else if (zxcvbn(val).score < config.zxcvbn.minimumScore) {
15-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: `password must have a strength of at least ${config.zxcvbn.minimumScore}` });
14+
ctx.addIssue({ code: 'custom', message: `password must have a strength of at least ${config.zxcvbn.minimumScore}`, input: val });
1615
}
1716
};
1817

modules/tasks/models/tasks.schema.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import { z } from 'zod';
77
* Data Schema
88
*/
99
const Task = z.object({
10-
title: z.string({ invalid_type_error: 'title must be a string' }).trim().min(1),
10+
title: z.string({ error: 'title must be a string' }).trim().min(1),
1111
description: z.string().default(''),
1212
user: z.string().trim().default(''),
13-
}).strip();
13+
});
1414

1515
const TaskUpdate = Task.partial();
1616

modules/users/models/user.schema.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const User = z.object({
2121
roles: z.array(z.enum(config.whitelists.users.roles)).min(1).default(['user']),
2222
/* Provider */
2323
provider: z.string().optional(),
24-
providerData: z.record(z.unknown()).optional(),
24+
providerData: z.record(z.string(), z.unknown()).optional(),
2525
/* Password */
2626
password: z.string()
2727
.max(config.zxcvbn.maxSize)
@@ -30,16 +30,16 @@ const User = z.object({
3030
if (val === '') return; // allow empty (OAuth users / no password set)
3131
zodHelpers.passwordRefinement(val, ctx);
3232
if (val.length < config.zxcvbn.minSize) {
33-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Password length must be at least ${config.zxcvbn.minSize} characters long` });
33+
ctx.addIssue({ code: 'custom', message: `Password length must be at least ${config.zxcvbn.minSize} characters long`, input: val });
3434
}
3535
}),
3636
resetPasswordToken: z.string().nullable().optional(),
3737
resetPasswordExpires: z.coerce.date().nullable().optional(),
3838
// startup requirement
3939
terms: z.coerce.date().nullable().optional(),
4040
// others
41-
complementary: z.record(z.unknown()).nullable().optional(),
42-
}).strip();
41+
complementary: z.record(z.string(), z.unknown()).nullable().optional(),
42+
});
4343

4444
const UserUpdate = User.partial();
4545

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
"swagger-ui-express": "^5.0.1",
9090
"ts-jest": "^29.4.6",
9191
"winston": "^3.19.0",
92-
"zod": "^3.25.76",
92+
"zod": "^4.3.6",
9393
"zxcvbn": "^4.4.2"
9494
},
9595
"devDependencies": {

0 commit comments

Comments
 (0)