add register route

This commit is contained in:
sianida26 2024-02-28 21:21:55 +07:00
parent 2d25e0d9dd
commit cfefeb625e
8 changed files with 69 additions and 16 deletions

View File

@ -1,4 +1,4 @@
import BaseError from "@/core/error/BaseError";
import applicationJsonOnly from "@/core/utils/applicationJsonOnly";
import handleCatchApi from "@/core/utils/handleCatchApi";
import AuthError from "@/modules/auth/error/AuthError";
import signInSchema from "@/modules/auth/formSchemas/signInSchema";
@ -9,13 +9,7 @@ export const dynamic = "force-dynamic";
export async function POST(request: NextRequest) {
try {
if (request.headers.get("Content-Type") !== "application/json")
throw new BaseError({
errorCode: "UNSUPPORTED_CONTENT_TYPE",
message:
"This content type is not supported. Please use application/json instead",
statusCode: 400
});
applicationJsonOnly(request.headers)
const data = signInSchema.safeParse(await request.json());
if (!data.success){

View File

@ -0,0 +1,38 @@
import BaseError from "@/core/error/BaseError";
import applicationJsonOnly from "@/core/utils/applicationJsonOnly";
import handleCatchApi from "@/core/utils/handleCatchApi";
import { createUserSchema } from "@/modules/auth/formSchemas/CreateUserFormSchema";
import createUser from "@/modules/auth/services/createUser";
import mapObjectToFirstValue from "@/utils/mapObjectToFirstValue";
import { NextRequest, NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function POST(request: NextRequest) {
try {
applicationJsonOnly(request.headers);
const data = createUserSchema.safeParse(await request.json());
if (!data.success) {
throw new BaseError({
errorCode: "INVALID_FORM_DATA",
message: "",
formErrors: mapObjectToFirstValue(
data.error.flatten().fieldErrors
),
statusCode: 422,
});
}
const result = await createUser({
email: data.data.email,
name: data.data.name,
password: data.data.password,
passwordConfirmation: data.data.passwordConfirmation ?? "",
});
return NextResponse.json(result);
} catch (e) {
return handleCatchApi(e);
}
}

View File

@ -1,21 +1,24 @@
import logger from "../logger/Logger";
export const BaseErrorCodes = ["UNKNOWN_ERROR", "UNSUPPORTED_CONTENT_TYPE"] as const;
export const BaseErrorCodes = ["UNKNOWN_ERROR", "UNSUPPORTED_CONTENT_TYPE", "INVALID_FORM_DATA"] as const;
interface ErrorOptions {
message?: string;
errorCode: (typeof BaseErrorCodes)[number] | (string & {});
statusCode?: number
statusCode?: number,
formErrors?: Record<string, string>
}
class BaseError extends Error {
public readonly errorCode: (typeof BaseErrorCodes)[number] | (string & {});
public readonly statusCode: number;
public readonly formErrors?: ErrorOptions['formErrors'];
constructor(options: ErrorOptions) {
super(options.message ?? "Undetermined Error");
this.errorCode = options.errorCode ?? "UNKNOWN_ERROR";
this.statusCode = options.statusCode ?? 500;
this.formErrors = options.formErrors;
Object.setPrototypeOf(this, new.target.prototype);

View File

@ -11,7 +11,7 @@ interface ErrorOptions {
class ClientError extends Error {
public readonly errorCode: ErrorOptions['errorCode'];
public readonly statusCode: ErrorOptions['statusCode'];
public readonly formErrors?: ErrorOptions['formErrors']
public readonly formErrors?: ErrorOptions['formErrors'];
constructor(options: ErrorOptions) {
super(options.message ?? "Undetermined Error");

View File

@ -0,0 +1,11 @@
import BaseError from "../error/BaseError";
export default function applicationJsonOnly(headers: Headers) {
if (headers.get("Content-Type") !== "application/json")
throw new BaseError({
errorCode: "UNSUPPORTED_CONTENT_TYPE",
message:
"This content type is not supported. Please use application/json instead",
statusCode: 400,
});
}

View File

@ -6,6 +6,7 @@ export default function handleCatchApi(e: unknown): NextResponse {
return NextResponse.json({
code: e.errorCode,
message: e.message,
formErrors: e.formErrors
}, {status: e.statusCode});
}
if (e instanceof Error) {

View File

@ -6,8 +6,8 @@ import {z} from "zod"
export interface CreateUserSchema {
name: string;
email: string;
plainPassword: string;
plainPasswordConfirmation: string;
password: string;
passwordConfirmation: string;
}
export const createUserSchema = z

View File

@ -1,4 +1,3 @@
import DashboardError from "@/modules/dashboard/errors/DashboardError";
import {
CreateUserSchema,
createUserSchema,
@ -8,7 +7,7 @@ import db from "@/core/db";
import AuthError from "../error/AuthError";
import hashPassword from "../utils/hashPassword";
import { createJwtToken } from "../utils/createJwtToken";
import { cookies } from "next/headers";
import BaseError from "@/core/error/BaseError";
/**
* Creates a new user in the database after validating the input data.
@ -25,11 +24,12 @@ export default async function createUser(userData: CreateUserSchema) {
//Validate form input
if (!validatedFields.success) {
throw new DashboardError({
throw new BaseError({
errorCode: "INVALID_FORM_DATA",
formErrors: mapObjectToFirstValue(
validatedFields.error.flatten().fieldErrors
),
statusCode: 422,
});
}
@ -42,6 +42,7 @@ export default async function createUser(userData: CreateUserSchema) {
throw new AuthError({
errorCode: "USER_ALREADY_EXISTS",
message: "This email already exists",
statusCode: 422,
});
}
@ -59,5 +60,10 @@ export default async function createUser(userData: CreateUserSchema) {
return {
token,
user: {
name: user.name,
email: user.email,
profilePhotoUrl: user.photoProfile,
},
};
}