Skip to content

migrate from joi to zod for schema validation and update related test… - #71

Merged
janishar merged 1 commit into
mainfrom
zod
Jun 7, 2026
Merged

janishar merged 1 commit into
mainfrom
zod

Conversation

@janishar

@janishar janishar commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

…s and documentation accordingly

Copilot AI review requested due to automatic review settings June 7, 2026 18:08
@janishar
janishar merged commit 44b739c into main Jun 7, 2026
2 checks passed
@janishar
janishar deleted the zod branch June 7, 2026 18:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates request schema validation from Joi to Zod across route/auth schemas, and updates TypeScript build configuration, tests, and docs to reflect the new validation behavior and build output structure.

Changes:

  • Replace Joi-based schemas with Zod schemas and update the shared validation middleware to use safeParse.
  • Split TypeScript configuration into tsconfig.build.json (emit) and tsconfig.json (typecheck/noEmit), and update build/start/debug scripts accordingly.
  • Update unit/integration tests and README to reflect Zod validation messages and the new validator behavior.

Reviewed changes

Copilot reviewed 17 out of 19 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tsconfig.json Switch to extending build config; set noEmit for typecheck-only config.
tsconfig.build.json New build-focused TS config defining emit/rootDir/outDir.
package.json Update build/check scripts to use build tsconfig; adjust runtime entrypoint path; swap Joi for Zod dependency.
package-lock.json Remove Joi dependency tree; add Zod dependency tree.
src/helpers/validator.ts Replace Joi validation middleware with Zod safeParse; add Zod helper schemas.
src/routes/access/schema.ts Migrate access route schemas from Joi to Zod.
src/auth/schema.ts Migrate auth header schemas from Joi to Zod.
src/routes/blog/schema.ts Migrate blog create/update/url/id schemas from Joi to Zod.
src/routes/blogs/schema.ts Migrate blogs route schemas (pagination/tag/id) from Joi to Zod.
src/routes/profile/schema.ts Migrate profile route schemas from Joi to Zod.
tests/routes/blog/writer/unit.test.ts Update writer blog create route tests to match Zod validation messaging.
tests/routes/blog/index/unit.test.ts Update blog detail-by-url tests to match Zod validation messaging.
tests/routes/access/signup/unit.test.ts Update signup validation tests to match Zod validation messaging.
tests/routes/access/login/unit.test.ts Update login validation tests to match Zod validation messaging.
tests/routes/access/login/integration.test.ts Update login integration validation tests to match Zod validation messaging.
tests/auth/authentication/unit.test.ts Update auth validation test to match new bearer-token validation messaging.
README.md Replace Joi mention with Zod.
.vscode/launch.json Update preLaunch task to build using tsconfig.build.json.
.templates/route/schema.ts Update route schema template from Joi to Zod.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to +5
import z from 'zod';
import { zAuthBearer } from '../../helpers/validator';

export default {
credential: Joi.object().keys({
email: Joi.string().required().email(),
password: Joi.string().required().min(6),
credential: z.object({
Comment thread src/auth/schema.ts
Comment on lines +1 to +8
import z from 'zod';
import { Header } from '../core/utils';
import { JoiAuthBearer } from '../helpers/validator';
import { zAuthBearer } from '../helpers/validator';

export default {
apiKey: Joi.object()
.keys({
[Header.API_KEY]: Joi.string().required(),
})
.unknown(true),
auth: Joi.object()
.keys({
authorization: JoiAuthBearer().required(),
})
.unknown(true),
apiKey: z.looseObject({ [Header.API_KEY]: z.string() }),
auth: z.looseObject({
authorization: zAuthBearer(),
Comment thread src/routes/blog/schema.ts
@@ -1,29 +1,29 @@
import Joi from 'joi';
import { JoiObjectId, JoiUrlEndpoint } from '../../helpers/validator';
import z from 'zod';
Comment thread src/routes/blog/schema.ts
Comment on lines +15 to +18
blogUrl: zUrlEndpoint(200),
imgUrl: z.url().max(200).optional(),
score: z.number().min(0).max(1).optional(),
tags: z.array(z.string().toUpperCase()).min(1).optional(),
Comment thread src/routes/blog/schema.ts
Comment on lines +24 to +27
blogUrl: zUrlEndpoint(200).optional(),
imgUrl: z.url().max(200).optional(),
score: z.number().min(0).max(1).optional(),
tags: z.array(z.string().toUpperCase()).min(1).optional(),
Comment on lines +1 to +10
import z from 'zod';
import { zObjectId } from '../../helpers/validator';

export default {
userId: Joi.object().keys({
id: JoiObjectId().required(),
userId: z.object({
id: zObjectId(),
}),
profile: Joi.object().keys({
name: Joi.string().min(1).max(200).optional(),
profilePicUrl: Joi.string().uri().optional(),
profile: z.object({
name: z.string().min(1).max(200).optional(),
profilePicUrl: z.url().optional(),
@@ -1,18 +1,18 @@
import Joi from 'joi';
import { JoiObjectId } from '../../helpers/validator';
import z from 'zod';
Comment thread src/helpers/validator.ts
Comment on lines +25 to 32
/**
*
* @param schema Any z.ZodType (z.object, z.email, z.string, etc.)
* @param source Part of the request to validate (default: 'body')
*/
export default (
schema: Joi.AnySchema,
schema: z.ZodType,
source: ValidationSource = ValidationSource.BODY,
Comment on lines 132 to 134
expect(response.body.message).toMatch(/imgUrl/i);
expect(response.body.message).toMatch(/valid uri/i);
expect(response.body.message).toMatch(/valid url/i);
expect(mockBlogFindUrlIfExists).not.toHaveBeenCalled();
Comment thread src/helpers/validator.ts
Comment on lines +16 to +18
/** Validates an "Authorization: Bearer <token>" header value */
export const zAuthBearer = () =>
z.string().regex(/^Bearer\s.+$/, 'invalid bearer token');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants