Refactor action and route handlers to use async schema validation (#361)

- Removed the `zodParseFactory` utility and replaced it with direct async schema validation using `safeParseAsync` in both `enhanceAction` and `enhanceRouteHandler`.
- Improved error handling to return meaningful messages for invalid request bodies.
- Streamlined the codebase by deleting the now-unnecessary `utils/index.ts` file.
This commit is contained in:
Giancarlo Buomprisco
2025-09-25 22:16:31 +08:00
committed by GitHub
parent 2b8572baaa
commit 3c13b5ec1e
4 changed files with 25 additions and 23 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "next-supabase-saas-kit-turbo", "name": "next-supabase-saas-kit-turbo",
"version": "2.15.0", "version": "2.15.1",
"private": true, "private": true,
"sideEffects": false, "sideEffects": false,
"engines": { "engines": {

View File

@@ -9,8 +9,6 @@ import { requireUser } from '@kit/supabase/require-user';
import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { JWTUserData } from '@kit/supabase/types'; import { JWTUserData } from '@kit/supabase/types';
import { zodParseFactory } from '../utils';
/** /**
* @name enhanceAction * @name enhanceAction
* @description Enhance an action with captcha, schema and auth checks * @description Enhance an action with captcha, schema and auth checks
@@ -42,9 +40,21 @@ export function enhanceAction<
let user: UserParam = undefined as UserParam; let user: UserParam = undefined as UserParam;
// validate the schema passed in the config if it exists // validate the schema passed in the config if it exists
const data = config.schema const validateData = async () => {
? zodParseFactory(config.schema)(params) if (config.schema) {
: params; const parsed = await config.schema.safeParseAsync(params);
if (parsed.success) {
return parsed.data;
}
throw new Error(parsed.error.message || 'Invalid request body');
}
return params;
};
const data = await validateData();
// by default, the CAPTCHA token is not required // by default, the CAPTCHA token is not required
const verifyCaptcha = config.captcha ?? false; const verifyCaptcha = config.captcha ?? false;

View File

@@ -10,8 +10,6 @@ import { requireUser } from '@kit/supabase/require-user';
import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { JWTUserData } from '@kit/supabase/types'; import { JWTUserData } from '@kit/supabase/types';
import { zodParseFactory } from '../utils';
interface Config<Schema> { interface Config<Schema> {
auth?: boolean; auth?: boolean;
captcha?: boolean; captcha?: boolean;
@@ -117,8 +115,16 @@ export const enhanceRouteHandler = <
// clone the request to read the body // clone the request to read the body
// so that we can pass it to the handler safely // so that we can pass it to the handler safely
const json = await request.clone().json(); const json = await request.clone().json();
const parsedBody = await params.schema.safeParseAsync(json);
body = zodParseFactory(params.schema)(json); if (parsedBody.success) {
body = parsedBody.data;
} else {
return NextResponse.json(
{ error: parsedBody.error.message || 'Invalid request body' },
{ status: 400 },
);
}
} }
return handler({ return handler({

View File

@@ -1,14 +0,0 @@
import { z } from 'zod';
export const zodParseFactory =
<T extends z.ZodTypeAny>(schema: T) =>
(data: unknown): z.infer<T> => {
try {
return schema.parse(data) as unknown;
} catch (err) {
console.error(err);
// handle error
throw new Error(`Invalid data: ${err as string}`);
}
};