Spaces:
Running
Running
Commit
Β·
e9affa5
1
Parent(s):
4cade40
refactors
Browse files- .vscode/settings.json +1 -0
- src/common/serializers/{user.serializtion.ts β user.serialization.ts} +0 -0
- src/helpers/serialize.ts +21 -2
- src/helpers/validation.helper.ts +7 -5
- src/lib/responses/json-response.ts +90 -20
- src/lib/responses/json-responses-params.d.ts +20 -0
- src/lib/responses/json-responses.d.ts +23 -0
- src/modules/console/common/serializers/{admin.serializtion.ts β admin.serialization.ts} +0 -0
- src/modules/console/modules/admins/controllers/admins.controller.ts +40 -29
- src/modules/console/modules/users/controllers/users.controller.ts +11 -13
- src/modules/users/{auth β modules/auth}/controllers/auth.controller.ts +19 -11
- src/modules/users/{auth β modules/auth}/services/users-auth.service.ts +0 -0
- src/modules/users/{auth β modules/auth}/services/users.service.ts +0 -0
- src/modules/users/{auth β modules/auth}/validation/login.validation.ts +0 -0
- src/modules/users/{exercises β modules/exercises}/controllers/exercises.controller.ts +16 -12
- src/modules/users/{exercises β modules/exercises}/services/exercises.service.ts +0 -0
- src/modules/users/{workouts β modules/workouts}/controllers/workouts.controller.ts +16 -11
- src/modules/users/{workouts β modules/workouts}/services/workouts.service.ts +0 -0
- src/routes.ts +56 -14
.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:
|
|
|
|
|
|
|
|
|
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
|
25 |
-
|
26 |
-
|
27 |
-
|
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 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
|
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.
|
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 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
54 |
};
|
55 |
|
56 |
-
get = async (req: Request, res: Response) => {
|
57 |
const data = await this.adminsService.findOneOrFail({
|
58 |
_id: req.params.id,
|
59 |
});
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
64 |
};
|
65 |
|
66 |
-
create = async (req: Request, res: Response) => {
|
67 |
const admin = await this.adminsService.create(req.body);
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
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 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
|
|
87 |
};
|
88 |
|
89 |
-
delete = async (req: Request, res: Response) => {
|
90 |
const admin = await this.adminsService.delete({
|
91 |
_id: req.params.id,
|
92 |
});
|
93 |
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
|
|
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.
|
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 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
|
|
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.
|
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 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
37 |
};
|
38 |
|
39 |
-
login = async (req: Request, res: Response) => {
|
40 |
const { user, token } = await this.authService.login(req.body);
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
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 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
37 |
};
|
38 |
|
39 |
-
get = async (req: Request, res: Response) => {
|
40 |
const data = await this.exercisesService.findOneOrFail({
|
41 |
_id: req.params.id,
|
42 |
});
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
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 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
36 |
};
|
37 |
|
38 |
-
get = async (req: Request, res: Response) => {
|
39 |
const data = await this.workoutsService.findOneOrFail({
|
40 |
_id: req.params.id,
|
41 |
});
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
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 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
24 |
});
|
25 |
|
|
|
26 |
router.use(validationErrorHandler);
|
27 |
|
|
|
28 |
router.all("*", (_req: any, res: any) => {
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
32 |
});
|
|
|
|
|
33 |
router.use((err, req, res, next) => {
|
34 |
try {
|
35 |
err.message = JSON.parse(err.message);
|
36 |
-
} catch (error) {
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
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
|
|
|
|
|
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(
|