moahmedwafy commited on
Commit
e9affa5
Β·
1 Parent(s): 4cade40
.vscode/settings.json CHANGED
@@ -1,5 +1,6 @@
1
  {
2
  "cSpell.words": [
 
3
  "Routable",
4
  "tlds"
5
  ]
 
1
  {
2
  "cSpell.words": [
3
+ "IJSON",
4
  "Routable",
5
  "tlds"
6
  ]
src/common/serializers/{user.serializtion.ts β†’ user.serialization.ts} RENAMED
File without changes
src/helpers/serialize.ts CHANGED
@@ -1,14 +1,33 @@
1
  import { plainToClass } from "class-transformer";
 
2
 
 
 
 
 
 
 
 
 
3
  export const serialize = <T>(
4
- serializable: Record<string, any> | Record<string, any>[],
 
 
 
 
5
  serializer: new () => T
6
  ): T | T[] => {
 
 
 
 
 
7
  if (Array.isArray(serializable)) {
8
  return serializable.map((item) => serialize(item, serializer)) as T[];
9
  }
10
 
 
11
  return plainToClass(serializer, serializable, {
12
  excludeExtraneousValues: true,
13
  }) as T;
14
- };
 
1
  import { plainToClass } from "class-transformer";
2
+ import { Document } from "mongoose";
3
 
4
+ /**
5
+ * Serializes the given object or array of objects into the specified class type.
6
+ *
7
+ * @template T - The class type to serialize the object(s) into.
8
+ * @param serializable - The object or array of objects to be serialized.
9
+ * @param serializer - The class constructor function for the target serialization type.
10
+ * @returns The serialized object(s) of type T or an array of serialized objects of type T.
11
+ */
12
  export const serialize = <T>(
13
+ serializable:
14
+ | Record<string, any>
15
+ | Record<string, any>[]
16
+ | Document
17
+ | Document[],
18
  serializer: new () => T
19
  ): T | T[] => {
20
+ // If the serializable object is a Document, convert it to a JSON object.
21
+ if (serializable.hasOwnProperty("toJSON"))
22
+ serializable = (serializable as Document).toJSON();
23
+
24
+ // If the serializable object is an array, serialize each item in the array.
25
  if (Array.isArray(serializable)) {
26
  return serializable.map((item) => serialize(item, serializer)) as T[];
27
  }
28
 
29
+ // Serialize the object and return it.
30
  return plainToClass(serializer, serializable, {
31
  excludeExtraneousValues: true,
32
  }) as T;
33
+ };
src/helpers/validation.helper.ts CHANGED
@@ -1,3 +1,4 @@
 
1
  import { NextFunction, Request, Response } from "express";
2
  import { createValidator } from "express-joi-validation";
3
  import Joi from "joi";
@@ -21,11 +22,12 @@ export const validationErrorHandler = (
21
  console.log(`err`, err.error);
22
 
23
  const errors = err.error.details.map((detail) => detail.message);
24
- return res.status(422).json({
25
- success: false,
26
- errors: errors,
27
- code: 422,
28
- });
 
29
  } else {
30
  // pass on to another error handler
31
  next(err);
 
1
+ import { JsonResponse } from "@lib/responses/json-response";
2
  import { NextFunction, Request, Response } from "express";
3
  import { createValidator } from "express-joi-validation";
4
  import Joi from "joi";
 
22
  console.log(`err`, err.error);
23
 
24
  const errors = err.error.details.map((detail) => detail.message);
25
+ return JsonResponse.validationError(
26
+ {
27
+ errors,
28
+ },
29
+ res
30
+ );
31
  } else {
32
  // pass on to another error handler
33
  next(err);
src/lib/responses/json-response.ts CHANGED
@@ -1,24 +1,94 @@
1
- interface JsonResponseProps {
2
- status?: number;
3
- message?: string;
4
- data?: Record<string, any> | Record<string, any>[];
5
- meta?: {
6
- total: number;
7
- page: number;
8
- perPage: number;
9
- };
10
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
- export class JsonResponse {
13
- public status: JsonResponseProps["status"];
14
- public message: JsonResponseProps["message"];
15
- public data: JsonResponseProps["data"];
16
- public meta?: JsonResponseProps["meta"];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- constructor(props: JsonResponseProps) {
19
- this.status = props.status || 200;
20
- this.message = props.message || "Success";
21
- this.data = props.data || {};
22
- this.meta = props.meta;
23
  }
24
  }
 
1
+ import { Response } from "express";
2
+ import {
3
+ IJSONSuccessResponse,
4
+ IJSONErrorResponse,
5
+ IJSONValidationErrorResponse,
6
+ } from "./json-responses";
7
+ import {
8
+ IJSONSuccessResponseProps,
9
+ IJSONErrorResponseProps,
10
+ IJSONValidationErrorResponseProps,
11
+ } from "./json-responses-params";
12
+
13
+ /**
14
+ * Represents a base class for JSON responses.
15
+ */
16
+ export abstract class JsonResponse {
17
+ private constructor() {}
18
+
19
+ /**
20
+ * Generates a success response object.
21
+ *
22
+ * @param props - The properties for the success response.
23
+ * @param res - Optional Express response object to send the response.
24
+ * @returns The success response object or the Express response object if provided.
25
+ */
26
+ static success(props: IJSONSuccessResponseProps): IJSONSuccessResponse;
27
+ static success(
28
+ props: IJSONSuccessResponseProps,
29
+ res: Response<IJSONSuccessResponse>
30
+ ): Response<IJSONSuccessResponse>;
31
+ static success(
32
+ props: IJSONSuccessResponseProps,
33
+ res?: Response<IJSONSuccessResponse>
34
+ ): IJSONSuccessResponse | Response<IJSONSuccessResponse> {
35
+ const data = {
36
+ status: props.status || 200,
37
+ message: props.message || "Success",
38
+ data: props.data,
39
+ meta: props.meta,
40
+ } satisfies IJSONSuccessResponse;
41
+
42
+ return (res && res.status(data.status).json(data)) || data;
43
+ }
44
+
45
+ /**
46
+ * Creates a JSON error response.
47
+ * @param props - The properties for the error response.
48
+ * @param res - Optional response object to send the error response.
49
+ * @returns The JSON error response object or the response object if provided.
50
+ */
51
+ static error(props: IJSONErrorResponseProps): IJSONErrorResponse;
52
+ static error(
53
+ props: IJSONErrorResponseProps,
54
+ res: Response<IJSONErrorResponse>
55
+ ): Response<IJSONErrorResponse>;
56
+ static error(
57
+ props: IJSONErrorResponseProps,
58
+ res?: Response<IJSONErrorResponse>
59
+ ): IJSONErrorResponse | Response<IJSONErrorResponse> {
60
+ const data = {
61
+ status: props.status || 500,
62
+ message: props.message || "Something Went Wrong",
63
+ error: props.error,
64
+ } satisfies IJSONErrorResponse;
65
+
66
+ return (res && res.status(data.status).json(data)) || data;
67
+ }
68
 
69
+ /**
70
+ * Represents a validation error response.
71
+ * @param props - The properties of the validation error response.
72
+ * @param res - Optional response object to send the JSON response.
73
+ * @returns The validation error response object or the response object if provided.
74
+ */
75
+ static validationError(
76
+ props: IJSONValidationErrorResponseProps
77
+ ): IJSONValidationErrorResponse;
78
+ static validationError(
79
+ props: IJSONValidationErrorResponseProps,
80
+ res: Response<IJSONValidationErrorResponse>
81
+ ): Response<IJSONValidationErrorResponse>;
82
+ static validationError(
83
+ props: IJSONValidationErrorResponseProps,
84
+ res?: Response<IJSONValidationErrorResponse>
85
+ ): IJSONValidationErrorResponse | Response<IJSONValidationErrorResponse> {
86
+ const data = {
87
+ status: 422,
88
+ message: "Validation Error",
89
+ errors: props.errors,
90
+ } satisfies IJSONValidationErrorResponse;
91
 
92
+ return (res && res.status(data.status).json(data)) || data;
 
 
 
 
93
  }
94
  }
src/lib/responses/json-responses-params.d.ts ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface IJSONSuccessResponseProps {
2
+ status?: number;
3
+ message?: string;
4
+ data: Record<string, any> | Record<string, any>[];
5
+ meta?: {
6
+ total: number;
7
+ page: number;
8
+ perPage: number;
9
+ };
10
+ }
11
+
12
+ export interface IJSONErrorResponseProps {
13
+ status?: number;
14
+ message?: string;
15
+ error: string;
16
+ }
17
+
18
+ export interface IJSONValidationErrorResponseProps {
19
+ errors: Record<string, any>[];
20
+ }
src/lib/responses/json-responses.d.ts ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interface IJSONResponse {
2
+ status: number;
3
+ message: string;
4
+ }
5
+
6
+ export interface IJSONSuccessResponse extends IJSONResponse {
7
+ data: Record<string, any> | Record<string, any>[];
8
+ meta?: {
9
+ total: number;
10
+ page: number;
11
+ perPage: number;
12
+ };
13
+ }
14
+
15
+ export interface IJSONErrorResponse extends IJSONResponse {
16
+ error: string;
17
+ }
18
+
19
+ export interface IJSONValidationErrorResponse extends IJSONResponse {
20
+ status: 422;
21
+ message: "Validation Error";
22
+ errors: Record<string, any>[];
23
+ }
src/modules/console/common/serializers/{admin.serializtion.ts β†’ admin.serialization.ts} RENAMED
File without changes
src/modules/console/modules/admins/controllers/admins.controller.ts CHANGED
@@ -11,7 +11,7 @@ import { ControllerMiddleware } from "@lib/decorators/controller-middleware.deco
11
  import { AdminGuardMiddleware } from "modules/console/common/guards/admins.guard";
12
  import { Role } from "@common/enums/role.enum";
13
  import { serialize } from "@helpers/serialize";
14
- import { AdminSerialization } from "modules/console/common/serializers/admin.serializtion";
15
 
16
  @Prefix("/console/admins")
17
  @ControllerMiddleware(AdminGuardMiddleware({ roles: [Role.SUPER_ADMIN] }))
@@ -39,39 +39,48 @@ export class AdminsController extends BaseController {
39
  );
40
  }
41
 
42
- list = async (req: Request, res: Response) => {
43
  const paginationQuery = parsePaginationQuery(req.query);
44
  const { docs, paginationData } = await this.adminsService.list(
45
  {},
46
  paginationQuery
47
  );
48
 
49
- const response = new JsonResponse({
50
- data: serialize(docs, AdminSerialization),
51
- meta: paginationData,
52
- });
53
- return res.json(response);
 
 
54
  };
55
 
56
- get = async (req: Request, res: Response) => {
57
  const data = await this.adminsService.findOneOrFail({
58
  _id: req.params.id,
59
  });
60
- const response = new JsonResponse({
61
- data: serialize(data.toJSON(), AdminSerialization),
62
- });
63
- res.json(response);
 
 
 
64
  };
65
 
66
- create = async (req: Request, res: Response) => {
67
  const admin = await this.adminsService.create(req.body);
68
- const response = new JsonResponse({
69
- data: serialize(admin.toJSON(), AdminSerialization),
70
- });
71
- res.json(response);
 
 
 
 
72
  };
73
 
74
- update = async (req: Request, res: Response) => {
75
  const admin = await this.adminsService.update(
76
  {
77
  _id: req.params.id,
@@ -79,22 +88,24 @@ export class AdminsController extends BaseController {
79
  req.body
80
  );
81
 
82
- const response = new JsonResponse({
83
- data: serialize(admin.toJSON(), AdminSerialization),
84
- });
85
-
86
- res.json(response);
 
87
  };
88
 
89
- delete = async (req: Request, res: Response) => {
90
  const admin = await this.adminsService.delete({
91
  _id: req.params.id,
92
  });
93
 
94
- const response = new JsonResponse({
95
- data: serialize(admin.toJSON(), AdminSerialization),
96
- });
97
-
98
- res.json(response);
 
99
  };
100
  }
 
11
  import { AdminGuardMiddleware } from "modules/console/common/guards/admins.guard";
12
  import { Role } from "@common/enums/role.enum";
13
  import { serialize } from "@helpers/serialize";
14
+ import { AdminSerialization } from "modules/console/common/serializers/admin.serialization";
15
 
16
  @Prefix("/console/admins")
17
  @ControllerMiddleware(AdminGuardMiddleware({ roles: [Role.SUPER_ADMIN] }))
 
39
  );
40
  }
41
 
42
+ list = async (req: Request, res: Response): Promise<Response> => {
43
  const paginationQuery = parsePaginationQuery(req.query);
44
  const { docs, paginationData } = await this.adminsService.list(
45
  {},
46
  paginationQuery
47
  );
48
 
49
+ return JsonResponse.success(
50
+ {
51
+ data: serialize(docs, AdminSerialization),
52
+ meta: paginationData,
53
+ },
54
+ res
55
+ );
56
  };
57
 
58
+ get = async (req: Request, res: Response): Promise<Response> => {
59
  const data = await this.adminsService.findOneOrFail({
60
  _id: req.params.id,
61
  });
62
+
63
+ return JsonResponse.success(
64
+ {
65
+ data: serialize(data, AdminSerialization),
66
+ },
67
+ res
68
+ );
69
  };
70
 
71
+ create = async (req: Request, res: Response): Promise<Response> => {
72
  const admin = await this.adminsService.create(req.body);
73
+
74
+ return JsonResponse.success(
75
+ {
76
+ status: 201,
77
+ data: serialize(admin, AdminSerialization),
78
+ },
79
+ res
80
+ );
81
  };
82
 
83
+ update = async (req: Request, res: Response): Promise<Response> => {
84
  const admin = await this.adminsService.update(
85
  {
86
  _id: req.params.id,
 
88
  req.body
89
  );
90
 
91
+ return JsonResponse.success(
92
+ {
93
+ data: serialize(admin, AdminSerialization),
94
+ },
95
+ res
96
+ );
97
  };
98
 
99
+ delete = async (req: Request, res: Response): Promise<Response> => {
100
  const admin = await this.adminsService.delete({
101
  _id: req.params.id,
102
  });
103
 
104
+ return JsonResponse.success(
105
+ {
106
+ data: serialize(admin, AdminSerialization),
107
+ },
108
+ res
109
+ );
110
  };
111
  }
src/modules/console/modules/users/controllers/users.controller.ts CHANGED
@@ -1,31 +1,29 @@
1
- import { userRegisterSchema } from "@common/validations/user-register.validation";
2
  import { UsersService } from "../services/users.service";
3
  import { JsonResponse } from "@lib/responses/json-response";
4
  import { Request, Response } from "express";
5
  import { asyncHandler } from "@helpers/async-handler";
6
- import { bodyValidator } from "@helpers/validation.helper";
7
  import { BaseController } from "@lib/controllers/controller.base";
8
  import { Prefix } from "@lib/decorators/prefix.decorator";
9
  import { serialize } from "@helpers/serialize";
10
- import { UserSerialization } from "@common/serializers/user.serializtion";
11
-
12
 
13
  @Prefix("/console/users")
14
  export class AdminUsersController extends BaseController {
15
  private usersService: UsersService = new UsersService();
16
 
17
  setRoutes() {
18
- this.router.post(
19
- "/create",
20
- asyncHandler(this.create)
21
- );
22
  }
23
 
24
- create = async (req: Request, res: Response) => {
25
  let user = await this.usersService.create(req.body);
26
- const response = new JsonResponse({
27
- data: serialize(user.toJSON(), UserSerialization),
28
- });
29
- return res.json(response);
 
 
 
 
30
  };
31
  }
 
 
1
  import { UsersService } from "../services/users.service";
2
  import { JsonResponse } from "@lib/responses/json-response";
3
  import { Request, Response } from "express";
4
  import { asyncHandler } from "@helpers/async-handler";
 
5
  import { BaseController } from "@lib/controllers/controller.base";
6
  import { Prefix } from "@lib/decorators/prefix.decorator";
7
  import { serialize } from "@helpers/serialize";
8
+ import { UserSerialization } from "@common/serializers/user.serialization";
 
9
 
10
  @Prefix("/console/users")
11
  export class AdminUsersController extends BaseController {
12
  private usersService: UsersService = new UsersService();
13
 
14
  setRoutes() {
15
+ this.router.post("/create", asyncHandler(this.create));
 
 
 
16
  }
17
 
18
+ create = async (req: Request, res: Response): Promise<Response> => {
19
  let user = await this.usersService.create(req.body);
20
+
21
+ return JsonResponse.success(
22
+ {
23
+ status: 201,
24
+ data: serialize(user, UserSerialization),
25
+ },
26
+ res
27
+ );
28
  };
29
  }
src/modules/users/{auth β†’ modules/auth}/controllers/auth.controller.ts RENAMED
@@ -2,13 +2,16 @@ import { UsersAuthService } from "../services/users.service";
2
  import { loginValidationSchema } from "../validation/login.validation";
3
  import { Request, Response } from "express";
4
  import { JsonResponse } from "@lib/responses/json-response";
5
- import { userRegisterSchema, IUserRegister } from "@common/validations/user-register.validation";
 
 
 
6
  import { asyncHandler } from "@helpers/async-handler";
7
  import { bodyValidator } from "@helpers/validation.helper";
8
  import { BaseController } from "@lib/controllers/controller.base";
9
  import { Prefix } from "@lib/decorators/prefix.decorator";
10
  import { serialize } from "@helpers/serialize";
11
- import { UserSerialization } from "@common/serializers/user.serializtion";
12
 
13
  @Prefix("/users/auth")
14
  export class UsersAuthController extends BaseController {
@@ -30,17 +33,22 @@ export class UsersAuthController extends BaseController {
30
  register = async (req: Request, res: Response) => {
31
  const user = await this.authService.register(req.body as IUserRegister);
32
 
33
- const response = new JsonResponse({
34
- data: serialize(user.toJSON(), UserSerialization),
35
- });
36
- return res.json(response);
 
 
37
  };
38
 
39
- login = async (req: Request, res: Response) => {
40
  const { user, token } = await this.authService.login(req.body);
41
- const response = new JsonResponse({
42
- data: { user: serialize(user.toJSON(), UserSerialization), token },
43
- });
44
- return res.json(response);
 
 
 
45
  };
46
  }
 
2
  import { loginValidationSchema } from "../validation/login.validation";
3
  import { Request, Response } from "express";
4
  import { JsonResponse } from "@lib/responses/json-response";
5
+ import {
6
+ userRegisterSchema,
7
+ IUserRegister,
8
+ } from "@common/validations/user-register.validation";
9
  import { asyncHandler } from "@helpers/async-handler";
10
  import { bodyValidator } from "@helpers/validation.helper";
11
  import { BaseController } from "@lib/controllers/controller.base";
12
  import { Prefix } from "@lib/decorators/prefix.decorator";
13
  import { serialize } from "@helpers/serialize";
14
+ import { UserSerialization } from "@common/serializers/user.serialization";
15
 
16
  @Prefix("/users/auth")
17
  export class UsersAuthController extends BaseController {
 
33
  register = async (req: Request, res: Response) => {
34
  const user = await this.authService.register(req.body as IUserRegister);
35
 
36
+ return JsonResponse.success(
37
+ {
38
+ data: serialize(user, UserSerialization),
39
+ },
40
+ res
41
+ );
42
  };
43
 
44
+ login = async (req: Request, res: Response): Promise<Response> => {
45
  const { user, token } = await this.authService.login(req.body);
46
+
47
+ return JsonResponse.success(
48
+ {
49
+ data: { user: serialize(user, UserSerialization), token },
50
+ },
51
+ res
52
+ );
53
  };
54
  }
src/modules/users/{auth β†’ modules/auth}/services/users-auth.service.ts RENAMED
File without changes
src/modules/users/{auth β†’ modules/auth}/services/users.service.ts RENAMED
File without changes
src/modules/users/{auth β†’ modules/auth}/validation/login.validation.ts RENAMED
File without changes
src/modules/users/{exercises β†’ modules/exercises}/controllers/exercises.controller.ts RENAMED
@@ -11,7 +11,6 @@ import { ExerciseSerialization } from "@common/serializers/exercise.serializtion
11
  import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
12
  import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
13
 
14
-
15
  @Prefix("/users/exercises")
16
  @ControllerMiddleware(UsersGuardMiddleware())
17
  export class ExerciseController extends BaseController {
@@ -22,27 +21,32 @@ export class ExerciseController extends BaseController {
22
  this.router.get("/:id", paramsValidator("id"), asyncHandler(this.get));
23
  }
24
 
25
- list = async (req: Request, res: Response) => {
26
  const paginationQuery = parsePaginationQuery(req.query);
27
  const { docs, paginationData } = await this.exercisesService.list(
28
  {},
29
  paginationQuery
30
  );
31
 
32
- const response = new JsonResponse({
33
- data: serialize(docs, ExerciseSerialization),
34
- meta: paginationData,
35
- });
36
- return res.json(response);
 
 
37
  };
38
 
39
- get = async (req: Request, res: Response) => {
40
  const data = await this.exercisesService.findOneOrFail({
41
  _id: req.params.id,
42
  });
43
- const response = new JsonResponse({
44
- data: serialize(data.toJSON(), ExerciseSerialization),
45
- });
46
- res.json(response);
 
 
 
47
  };
48
  }
 
11
  import { ControllerMiddleware } from "@lib/decorators/controller-middleware.decorator";
12
  import { UsersGuardMiddleware } from "modules/users/common/guards/users.guard";
13
 
 
14
  @Prefix("/users/exercises")
15
  @ControllerMiddleware(UsersGuardMiddleware())
16
  export class ExerciseController extends BaseController {
 
21
  this.router.get("/:id", paramsValidator("id"), asyncHandler(this.get));
22
  }
23
 
24
+ list = async (req: Request, res: Response): Promise<Response> => {
25
  const paginationQuery = parsePaginationQuery(req.query);
26
  const { docs, paginationData } = await this.exercisesService.list(
27
  {},
28
  paginationQuery
29
  );
30
 
31
+ return JsonResponse.success(
32
+ {
33
+ data: serialize(docs, ExerciseSerialization),
34
+ meta: paginationData,
35
+ },
36
+ res
37
+ );
38
  };
39
 
40
+ get = async (req: Request, res: Response): Promise<Response> => {
41
  const data = await this.exercisesService.findOneOrFail({
42
  _id: req.params.id,
43
  });
44
+
45
+ return JsonResponse.success(
46
+ {
47
+ data: serialize(data, ExerciseSerialization),
48
+ },
49
+ res
50
+ );
51
  };
52
  }
src/modules/users/{exercises β†’ modules/exercises}/services/exercises.service.ts RENAMED
File without changes
src/modules/users/{workouts β†’ modules/workouts}/controllers/workouts.controller.ts RENAMED
@@ -21,27 +21,32 @@ export class WorkoutController extends BaseController {
21
  this.router.get("/:id", paramsValidator("id"), asyncHandler(this.get));
22
  }
23
 
24
- list = async (req: Request, res: Response) => {
25
  const paginationQuery = parsePaginationQuery(req.query);
26
  const { docs, paginationData } = await this.workoutsService.list(
27
  {},
28
  paginationQuery
29
  );
30
 
31
- const response = new JsonResponse({
32
- data: serialize(docs, WorkoutSerialization),
33
- meta: paginationData,
34
- });
35
- return res.json(response);
 
 
36
  };
37
 
38
- get = async (req: Request, res: Response) => {
39
  const data = await this.workoutsService.findOneOrFail({
40
  _id: req.params.id,
41
  });
42
- const response = new JsonResponse({
43
- data: serialize(data.toJSON(), WorkoutSerialization),
44
- });
45
- res.json(response);
 
 
 
46
  };
47
  }
 
21
  this.router.get("/:id", paramsValidator("id"), asyncHandler(this.get));
22
  }
23
 
24
+ list = async (req: Request, res: Response): Promise<Response> => {
25
  const paginationQuery = parsePaginationQuery(req.query);
26
  const { docs, paginationData } = await this.workoutsService.list(
27
  {},
28
  paginationQuery
29
  );
30
 
31
+ return JsonResponse.success(
32
+ {
33
+ data: serialize(docs, WorkoutSerialization),
34
+ meta: paginationData,
35
+ },
36
+ res
37
+ );
38
  };
39
 
40
+ get = async (req: Request, res: Response): Promise<Response> => {
41
  const data = await this.workoutsService.findOneOrFail({
42
  _id: req.params.id,
43
  });
44
+
45
+ return JsonResponse.success(
46
+ {
47
+ data: serialize(data, WorkoutSerialization),
48
+ },
49
+ res
50
+ );
51
  };
52
  }
src/modules/users/{workouts β†’ modules/workouts}/services/workouts.service.ts RENAMED
File without changes
src/routes.ts CHANGED
@@ -4,7 +4,13 @@ import * as glob from "glob";
4
  import path from "path";
5
  import { BaseController } from "./lib/controllers/controller.base";
6
  import { validationErrorHandler } from "./helpers/validation.helper";
 
7
 
 
 
 
 
 
8
  export const setAppRoutes = async (app: Express) => {
9
  const mainRouter = Router();
10
 
@@ -16,46 +22,77 @@ export const setAppRoutes = async (app: Express) => {
16
 
17
  /* custom routes */
18
 
 
 
 
 
 
19
  const setCustomRoutes = (router: Router) => {
 
20
  router.get("/health", (_req: any, res: any) => {
21
- res
22
- .status(200)
23
- .json({ success: true, message: "Server is up!", code: 200 });
 
 
 
 
24
  });
25
 
 
26
  router.use(validationErrorHandler);
27
 
 
28
  router.all("*", (_req: any, res: any) => {
29
- res
30
- .status(404)
31
- .json({ success: false, message: "Invalid URL!", code: 404 });
 
 
 
 
32
  });
 
 
33
  router.use((err, req, res, next) => {
34
  try {
35
  err.message = JSON.parse(err.message);
36
- } catch (error) { }
37
 
38
- res.status(err.status || 500).json({
39
- status: err.status || 500,
40
- message: err.message || "Internal Server Error",
41
- });
 
 
 
42
 
43
  console.error(err.message, err.stack);
44
  });
45
-
46
  };
47
 
48
  /* importing all controllers */
49
 
 
 
 
 
50
  const findControllerFiles = (): string[] => {
51
- const controllersPath = path.relative(process.cwd(), path.join(__dirname, "**/*.controller.{ts,js}")).replace(/\\/g, "/")
 
 
52
 
53
  return glob.sync(controllersPath, {}).map((file) => {
54
  return path.resolve(file);
55
  });
56
  };
57
 
58
-
 
 
 
 
 
59
  const importControllers = async (router: Router) => {
60
  const files = findControllerFiles();
61
 
@@ -71,6 +108,11 @@ const importControllers = async (router: Router) => {
71
  );
72
  };
73
 
 
 
 
 
 
74
  const importController = async (file: string) => {
75
  const controllers = Object.values(await import(file));
76
  return controllers.find(
 
4
  import path from "path";
5
  import { BaseController } from "./lib/controllers/controller.base";
6
  import { validationErrorHandler } from "./helpers/validation.helper";
7
+ import { JsonResponse } from "@lib/responses/json-response";
8
 
9
+ /**
10
+ * Sets the routes for the Express app.
11
+ *
12
+ * @param app - The Express app.
13
+ */
14
  export const setAppRoutes = async (app: Express) => {
15
  const mainRouter = Router();
16
 
 
22
 
23
  /* custom routes */
24
 
25
+ /**
26
+ * Sets custom routes for the router.
27
+ *
28
+ * @param router - The router object to set the routes on.
29
+ */
30
  const setCustomRoutes = (router: Router) => {
31
+ // Health check route
32
  router.get("/health", (_req: any, res: any) => {
33
+ JsonResponse.success(
34
+ {
35
+ message: "Server is up!",
36
+ data: { success: true },
37
+ },
38
+ res
39
+ );
40
  });
41
 
42
+ // Validation error handler
43
  router.use(validationErrorHandler);
44
 
45
+ // Invalid URL handler
46
  router.all("*", (_req: any, res: any) => {
47
+ JsonResponse.error(
48
+ {
49
+ error: "Invalid URL!",
50
+ status: 404,
51
+ },
52
+ res
53
+ );
54
  });
55
+
56
+ // Error handler
57
  router.use((err, req, res, next) => {
58
  try {
59
  err.message = JSON.parse(err.message);
60
+ } catch (error) {}
61
 
62
+ JsonResponse.error(
63
+ {
64
+ error: err.message || "Internal Server Error",
65
+ status: err.status || 500,
66
+ },
67
+ res
68
+ );
69
 
70
  console.error(err.message, err.stack);
71
  });
 
72
  };
73
 
74
  /* importing all controllers */
75
 
76
+ /**
77
+ * Finds all controller files in the project.
78
+ * @returns An array of strings representing the absolute paths of the controller files.
79
+ */
80
  const findControllerFiles = (): string[] => {
81
+ const controllersPath = path
82
+ .relative(process.cwd(), path.join(__dirname, "**/*.controller.{ts,js}"))
83
+ .replace(/\\/g, "/");
84
 
85
  return glob.sync(controllersPath, {}).map((file) => {
86
  return path.resolve(file);
87
  });
88
  };
89
 
90
+ /**
91
+ * Imports controller classes from files, sets up routes for each controller,
92
+ * and adds them to the provided router.
93
+ *
94
+ * @param router - The router to add the routes to.
95
+ */
96
  const importControllers = async (router: Router) => {
97
  const files = findControllerFiles();
98
 
 
108
  );
109
  };
110
 
111
+ /**
112
+ * Imports a module from a file and returns the first controller that extends BaseController.
113
+ * @param file - The path to the file containing the module.
114
+ * @returns The first controller that extends BaseController.
115
+ */
116
  const importController = async (file: string) => {
117
  const controllers = Object.values(await import(file));
118
  return controllers.find(