-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8ee7b7b
commit 19707bb
Showing
22 changed files
with
865 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Utils } from "../lib/helpers/utils"; | ||
import { Env } from "../lib/types/factory.type"; | ||
import { Hono } from "hono"; | ||
import { Schema } from "zod"; | ||
|
||
export interface IController { | ||
setupHandlers(): unknown; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { ApiResponse } from "../lib/helpers/api-response"; | ||
import { Utils } from "../lib/helpers/utils"; | ||
import { CreateFactoryType } from "../lib/types/factory.type"; | ||
import { HttpStatus } from "../lib/types/http.type"; | ||
import { UserValidation } from "../lib/validations/schema.validation"; | ||
import { Validator } from "../lib/validations/validator"; | ||
import { IUserService, UserService } from "../services/user.service"; | ||
import { zValidator } from "@hono/zod-validator"; | ||
import { z } from "zod"; | ||
|
||
import { IController } from "./types.controller"; | ||
|
||
export interface IUserController extends IController { | ||
setupHandlers(): Utils.MethodReturnType<UserController, "setupHandlers">; | ||
} | ||
|
||
export class UserController { | ||
private factory: CreateFactoryType; | ||
private userService: IUserService; | ||
constructor(factory: CreateFactoryType) { | ||
this.factory = factory; | ||
this.userService = new UserService(); | ||
} | ||
setupHandlers() { | ||
return this.factory | ||
.createApp() | ||
.patch("/:id", ...this.updateUserHandler()); | ||
} | ||
private updateUserHandler() { | ||
const params = z.object({ | ||
id: z.string().uuid(), | ||
}); | ||
const response = UserValidation.selectSchema.omit({ | ||
hasedPassword: true, | ||
}); | ||
return this.factory.createHandlers( | ||
zValidator( | ||
"json", | ||
UserValidation.updateSchema, | ||
Validator.handleParseError, | ||
), | ||
zValidator("param", params, Validator.handleParseError), | ||
async (c) => { | ||
const jsonData = c.req.valid("json"); | ||
const { id } = c.req.valid("param"); | ||
const updatedUser = await this.userService.updateUser( | ||
id, | ||
jsonData, | ||
); | ||
const resp = response.safeParse(updatedUser); | ||
if (!resp.success) { | ||
return ApiResponse.WriteJSON({ | ||
c, | ||
msg: "Failed to parse", | ||
status: HttpStatus.BadGateway, | ||
}); | ||
} | ||
return ApiResponse.WriteJSON({ | ||
c, | ||
data: resp.data, | ||
status: HttpStatus.OK, | ||
}); | ||
}, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,30 @@ | ||
import { HttpStatus } from "../types/http.type"; | ||
import { hash, verify } from "@node-rs/argon2"; | ||
import { Context } from "hono"; | ||
import { ZodError } from "zod"; | ||
|
||
import { ApiResponse } from "./api-response"; | ||
export namespace Utils { | ||
export type MethodReturnType<T, K extends keyof T> = T[K] extends ( | ||
...args: any[] | ||
) => any | ||
? ReturnType<T[K]> | ||
: never; | ||
|
||
export type MethodReturnType<T, K extends keyof T> = T[K] extends ( | ||
...args: any[] | ||
) => any | ||
? ReturnType<T[K]> | ||
: never; | ||
|
||
export class PasswordUtils { | ||
public static async verifyHash(hash: string, password: string) { | ||
const success = await verify(hash, password, { | ||
memoryCost: 19456, | ||
timeCost: 2, | ||
outputLen: 32, | ||
parallelism: 1, | ||
}); | ||
return success; | ||
} | ||
public static async hashPassword(password: string) { | ||
const passwordHash = await hash(password, { | ||
memoryCost: 19456, | ||
timeCost: 2, | ||
outputLen: 32, | ||
parallelism: 1, | ||
}); | ||
return passwordHash; | ||
} | ||
} | ||
|
||
type ResultType<T> = { | ||
success: boolean; | ||
data: T; | ||
error?: ZodError; | ||
}; | ||
|
||
export class Validator { | ||
public static validatorHandler<T>(result: ResultType<T>, c: Context) { | ||
if (!result.success) { | ||
const zodErr = result.error | ||
? result?.error.flatten().fieldErrors | ||
: "Something went wrong"; | ||
return ApiResponse.WriteJSON({ | ||
c, | ||
status: HttpStatus.BadRequest, | ||
errors: zodErr, | ||
export class PasswordUtils { | ||
public static async verifyHash(hash: string, password: string) { | ||
const success = await verify(hash, password, { | ||
memoryCost: 19456, | ||
timeCost: 2, | ||
outputLen: 32, | ||
parallelism: 1, | ||
}); | ||
return success; | ||
} | ||
public static async hashPassword(password: string) { | ||
const passwordHash = await hash(password, { | ||
memoryCost: 19456, | ||
timeCost: 2, | ||
outputLen: 32, | ||
parallelism: 1, | ||
}); | ||
return passwordHash; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { ApiResponse } from "../helpers/api-response"; | ||
import { MyError } from "../helpers/errors"; | ||
import { HttpStatus } from "../types/http.type"; | ||
import { Context } from "hono"; | ||
import { HTTPResponseError } from "hono/types"; | ||
import { ZodError } from "zod"; | ||
|
||
type ResultType<T> = { | ||
success: boolean; | ||
data: T; | ||
error?: ZodError; | ||
}; | ||
|
||
export class Validator { | ||
public static handleParseError<T>(result: ResultType<T>, c: Context) { | ||
if (!result.success) { | ||
const zodErr = result.error | ||
? result?.error.flatten().fieldErrors | ||
: "Something went wrong"; | ||
return ApiResponse.WriteJSON({ | ||
c, | ||
status: HttpStatus.BadRequest, | ||
errors: zodErr, | ||
}); | ||
} | ||
} | ||
public static handleErrorException( | ||
err: Error | HTTPResponseError, | ||
c: Context, | ||
) { | ||
switch (true) { | ||
case err instanceof MyError.UnauthenticatedError: | ||
case err instanceof MyError.UnauthorizedError: | ||
case err instanceof MyError.NotFoundError: | ||
case err instanceof MyError.ValidationError: | ||
case err instanceof MyError.ConflictError: | ||
case err instanceof MyError.BadGatewayError: | ||
case err instanceof MyError.InternalServerError: | ||
case err instanceof MyError.TooManyRequestsError: | ||
case err instanceof MyError.ServiceUnavailableError: | ||
case err instanceof MyError.GatewayTimeoutError: | ||
return ApiResponse.WriteJSON({ | ||
c, | ||
status: err.statusCode, | ||
errors: err.message, | ||
}); | ||
default: | ||
console.error("Failed to handle error: ", err); | ||
return ApiResponse.WriteJSON({ | ||
c, | ||
status: HttpStatus.InternalServerError, | ||
errors: err.message, | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export interface IWriter<Insert, Update, Select, ID = string> { | ||
create(data: Insert): Promise<Select | undefined>; | ||
update(id: ID, data: Update): Promise<Select | undefined>; | ||
delete(id: ID): Promise<boolean | undefined>; | ||
} | ||
export interface IReader<Select, ID = string> { | ||
findById(id: ID): Promise<Select | undefined>; | ||
findAll(): Promise<Select[]>; | ||
} |
Oops, something went wrong.