Skip to content

Commit e79675c

Browse files
committed
chore: update to zod v4
1 parent 911945a commit e79675c

22 files changed

+986
-996
lines changed

apps/api/package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,39 @@
1616
},
1717
"dependencies": {
1818
"@fastify/cookie": "^11.0.2",
19-
"@fastify/cors": "^10.0.2",
19+
"@fastify/cors": "^11.1.0",
2020
"@fastify/env": "^5.0.2",
21-
"@fastify/jwt": "^9.0.4",
21+
"@fastify/jwt": "^10.0.0",
2222
"@fastify/sensible": "^6.0.2",
2323
"@fastify/swagger": "^9.4.2",
2424
"@fastify/swagger-ui": "^5.2.1",
2525
"@orama/cuid2": "^2.2.3",
2626
"@taskcord/database": "workspace:*",
27-
"dotenv": "^16.4.7",
28-
"drizzle-orm": "^0.39.3",
29-
"fastify": "^5.2.1",
27+
"dotenv": "^17.2.3",
28+
"drizzle-orm": "^0.44.7",
29+
"fastify": "^5.6.1",
3030
"fastify-plugin": "^5.0.1",
3131
"fastify-zod": "^1.4.0",
3232
"ioredis": "^5.5.0",
3333
"jsonwebtoken": "^9.0.2",
3434
"pg": "^8.13.2",
3535
"uuidv7": "^1.0.2",
36-
"zod": "^3.24.1"
36+
"zod": "^4.1.12"
3737
},
3838
"devDependencies": {
39-
"@faker-js/faker": "^9.8.0",
39+
"@faker-js/faker": "^10.1.0",
4040
"@repo/eslint-config": "workspace:*",
4141
"@repo/typescript-config": "workspace:*",
4242
"@types/jsonwebtoken": "^9.0.8",
4343
"@types/node": "^20.11.24",
4444
"@types/pg": "^8.11.11",
4545
"@types/supertest": "^6.0.2",
46-
"drizzle-kit": "^0.30.4",
46+
"drizzle-kit": "^0.31.5",
4747
"pino-pretty": "^13.0.0",
4848
"supertest": "^7.0.0",
4949
"tsdown": "^0.15.6",
5050
"tsup": "^8.2.4",
51-
"typescript": "5.5.4",
52-
"vitest": "^3.0.5"
51+
"typescript": "5.9.3",
52+
"vitest": "^4.0.2"
5353
}
5454
}
Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,34 @@
1-
import type { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
1+
import type { FastifyInstance } from "fastify";
22
import AuthController from "./auth.controller";
33
import AuthService from "./auth.service";
4-
import { authSchemaRef, authSchemas } from "./auth.schema";
54

65
export default function AuthRoute(fastify: FastifyInstance) {
7-
// Register schemas
8-
for (const schema of authSchemas) {
9-
fastify.addSchema(schema);
10-
}
6+
const authController = new AuthController(new AuthService());
117

12-
const authController = new AuthController(new AuthService());
13-
14-
fastify.get(
15-
"/discord/init",
16-
{
17-
schema: {
18-
tags: ["Auth"],
19-
querystring: authSchemaRef("authInitQueryParams"),
20-
description: "Initialize the Discord auth flow",
21-
},
22-
},
23-
authController.initializeDiscordAuthFlowHandler.bind(authController),
24-
);
8+
fastify.get(
9+
"/discord/init",
10+
{
11+
schema: {
12+
tags: ["Auth"],
13+
querystring: { $ref: "authInitQueryParams" },
14+
description: "Initialize the Discord auth flow",
15+
},
16+
},
17+
authController.initializeDiscordAuthFlowHandler.bind(authController)
18+
);
2519

26-
fastify.get(
27-
"/discord/oauth-callback",
28-
{
29-
schema: {
30-
tags: ["Auth"],
31-
description: "Callback for the Discord auth flow",
32-
querystring: authSchemaRef("queryParams"),
33-
response: {
34-
200: authSchemaRef("200"),
20+
fastify.get(
21+
"/discord/oauth-callback",
22+
{
23+
schema: {
24+
tags: ["Auth"],
25+
description: "Callback for the Discord auth flow",
26+
querystring: { $ref: "queryParams" },
27+
response: {
28+
200: { $ref: "200" },
29+
},
30+
},
3531
},
36-
},
37-
},
38-
authController.handleDiscordOAuthCallback.bind(authController),
39-
);
32+
authController.handleDiscordOAuthCallback.bind(authController)
33+
);
4034
}
Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
1-
import { z } from "zod";
2-
import { buildJsonSchemas } from "fastify-zod";
1+
import { zodSchemasToJSONSchema } from "@/utils/schemaHelper";
2+
import { z } from "zod/v4";
33

4-
export const DiscordAuthCallbackSchema = {
5-
request: {
6-
queryParams: z.object({
7-
code: z.string().nonempty(),
8-
state: z.string().min(5),
9-
}),
10-
},
11-
response: {
12-
200: z.object({
13-
access_token: z.string(),
14-
token_type: z.string(),
15-
expires_in: z.number(),
16-
refresh_token: z.string(),
17-
scope: z.string(),
18-
}),
19-
},
20-
};
4+
const queryParamsSchema = z
5+
.object({
6+
code: z.string().nonempty(),
7+
state: z.string().min(5),
8+
})
9+
.meta({ $id: "queryParams" });
2110

22-
const DiscordAuthInitRequestSchema = {
23-
request: z.object({
24-
redirect_url: z.enum(["http://localhost:5173", "https://p005.netlify.app"]),
25-
}),
26-
};
11+
const auth200ResponseSchema = z
12+
.object({
13+
access_token: z.string(),
14+
token_type: z.string(),
15+
expires_in: z.number(),
16+
refresh_token: z.string(),
17+
scope: z.string(),
18+
})
19+
.meta({ $id: "200" });
2720

28-
export const { schemas: authSchemas, $ref: authSchemaRef } = buildJsonSchemas(
29-
{
30-
...DiscordAuthCallbackSchema.request,
31-
...DiscordAuthCallbackSchema.response,
32-
authInitQueryParams: DiscordAuthInitRequestSchema.request,
33-
} as const,
34-
{ $id: "authSchema" },
35-
);
21+
const authInitQueryParamsSchema = z
22+
.object({
23+
redirect_url: z.enum([
24+
"http://localhost:5173",
25+
"https://p005.netlify.app",
26+
]),
27+
})
28+
.meta({ $id: "authInitQueryParams" });
29+
30+
export type QueryParams = z.infer<typeof queryParamsSchema>;
31+
export type Auth200Response = z.infer<typeof auth200ResponseSchema>;
32+
export type AuthInitQueryParams = z.infer<typeof authInitQueryParamsSchema>;
33+
34+
export const zodAuthSchemas = zodSchemasToJSONSchema([
35+
queryParamsSchema,
36+
auth200ResponseSchema,
37+
authInitQueryParamsSchema,
38+
]);

apps/api/src/modules/auth/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import type { FastifyInstance, FastifyPluginOptions } from "fastify";
22
import { fastifyPlugin } from "fastify-plugin";
33
import AuthRoute from "./auth.route";
4+
import { zodAuthSchemas } from "./auth.schema";
45

56
export default fastifyPlugin(
6-
async (fastify: FastifyInstance, options: FastifyPluginOptions) => {
7-
await fastify.register(AuthRoute, options);
8-
},
7+
async (fastify: FastifyInstance, options: FastifyPluginOptions) => {
8+
zodAuthSchemas.map((schema) => {
9+
fastify.addSchema(schema);
10+
});
11+
12+
await fastify.register(AuthRoute, options);
13+
}
914
);
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import type { FastifyInstance, FastifyPluginOptions } from "fastify";
22
import { fastifyPlugin } from "fastify-plugin";
33
import LabelRoute from "./label.route";
4+
import { zodLabelSchemas } from "./label.schema";
45

56
export default fastifyPlugin(
6-
async (fastify: FastifyInstance, options: FastifyPluginOptions) => {
7-
await fastify.register(LabelRoute, options);
8-
},
7+
async (fastify: FastifyInstance, options: FastifyPluginOptions) => {
8+
zodLabelSchemas.map((schema) => {
9+
fastify.addSchema(schema);
10+
});
11+
12+
await fastify.register(LabelRoute, options);
13+
}
914
);
Lines changed: 62 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,76 @@
11
import type { FastifyInstance } from "fastify";
22
import LabelController from "./label.controller";
33
import LabelService from "./label.service";
4-
import { labelSchemas, labelSchemaRef } from "./label.schema";
54

65
export default function LabelsRoute(fastify: FastifyInstance) {
7-
// Register schemas
8-
for (const schema of labelSchemas) {
9-
fastify.addSchema(schema);
10-
}
6+
const labelController = new LabelController(new LabelService());
117

12-
const labelController = new LabelController(new LabelService());
13-
14-
// Create a new task label
15-
fastify.post(
16-
"/",
17-
{
18-
onRequest: [fastify.jwtAuth],
19-
schema: {
20-
tags: ["Task Labels"],
21-
description: "Create a new task label",
22-
body: labelSchemaRef("createLabelSchema"),
23-
response: {
24-
201: labelSchemaRef("labelResponse"),
25-
400: labelSchemaRef("errorResponse"),
8+
// Create a new task label
9+
fastify.post(
10+
"/",
11+
{
12+
onRequest: [fastify.jwtAuth],
13+
schema: {
14+
tags: ["Task Labels"],
15+
description: "Create a new task label",
16+
body: { $ref: "createLabelSchema" },
17+
response: {
18+
201: { $ref: "labelResponse" },
19+
400: { $ref: "labelErrorResponse" },
20+
},
21+
},
2622
},
27-
},
28-
},
29-
// @ts-expect-error - this is a bug in fastify-zod
30-
labelController.createLabel.bind(labelController),
31-
);
23+
labelController.createLabel.bind(labelController)
24+
);
3225

33-
// Get all task labels of a project
34-
fastify.get(
35-
"/",
36-
{
37-
onRequest: [fastify.jwtAuth],
38-
schema: {
39-
tags: ["Task Labels"],
40-
description: "Get all task labels of a project",
41-
response: {
42-
200: labelSchemaRef("labelsResponse"),
26+
// Get all task labels of a project
27+
fastify.get(
28+
"/",
29+
{
30+
onRequest: [fastify.jwtAuth],
31+
schema: {
32+
tags: ["Task Labels"],
33+
description: "Get all task labels of a project",
34+
response: {
35+
200: { $ref: "labelsResponse" },
36+
},
37+
},
4338
},
44-
},
45-
},
46-
// @ts-expect-error - this is a bug in fastify-zod
47-
labelController.getAllProjectLabels.bind(labelController),
48-
);
39+
labelController.getAllProjectLabels.bind(labelController)
40+
);
4941

50-
// Update a task label
51-
fastify.put(
52-
"/:labelId",
53-
{
54-
onRequest: [fastify.jwtAuth],
55-
schema: {
56-
tags: ["Task Labels"],
57-
description: "Update a task label",
58-
body: labelSchemaRef("updateLabelSchema"),
59-
response: {
60-
200: labelSchemaRef("labelResponse"),
61-
400: labelSchemaRef("errorResponse"),
42+
// Update a task label
43+
fastify.put(
44+
"/:labelId",
45+
{
46+
onRequest: [fastify.jwtAuth],
47+
schema: {
48+
tags: ["Task Labels"],
49+
description: "Update a task label",
50+
body: { $ref: "updateLabelSchema" },
51+
response: {
52+
200: { $ref: "labelResponse" },
53+
400: { $ref: "labelErrorResponse" },
54+
},
55+
},
6256
},
63-
},
64-
},
65-
// @ts-expect-error - this is a bug in fastify-zod
66-
labelController.updateLabel.bind(labelController),
67-
);
57+
labelController.updateLabel.bind(labelController)
58+
);
6859

69-
// Delete a task label
70-
fastify.delete(
71-
"/:labelId",
72-
{
73-
onRequest: [fastify.jwtAuth],
74-
schema: {
75-
tags: ["Task Labels"],
76-
description: "Delete a task label",
77-
response: {
78-
200: labelSchemaRef("labelResponse"),
79-
400: labelSchemaRef("errorResponse"),
60+
// Delete a task label
61+
fastify.delete(
62+
"/:labelId",
63+
{
64+
onRequest: [fastify.jwtAuth],
65+
schema: {
66+
tags: ["Task Labels"],
67+
description: "Delete a task label",
68+
response: {
69+
200: { $ref: "labelResponse" },
70+
400: { $ref: "labelErrorResponse" },
71+
},
72+
},
8073
},
81-
},
82-
},
83-
// @ts-expect-error - this is a bug in fastify-zod
84-
labelController.deleteLabel.bind(labelController),
85-
);
74+
labelController.deleteLabel.bind(labelController)
75+
);
8676
}

0 commit comments

Comments
 (0)