@ifecodes/backend-template 1.1.9 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +423 -383
- package/bin/cli.js +1276 -964
- package/bin/lib/microservice-config.js +155 -150
- package/bin/lib/prompts.js +277 -241
- package/bin/lib/readme-generator.js +364 -329
- package/bin/lib/service-setup.js +901 -684
- package/package.json +64 -55
- package/template/base/js/.eslintrc.json +10 -13
- package/template/base/js/.prettierrc +7 -7
- package/template/base/js/eslint.config.js +33 -31
- package/template/base/js/package.json +29 -28
- package/template/base/js/src/app.js +20 -18
- package/template/base/js/src/config/db.js +8 -8
- package/template/base/js/src/config/env.js +44 -14
- package/template/base/js/src/config/index.js +7 -7
- package/template/base/js/src/docs/index.js +5 -0
- package/template/base/js/src/docs/route-registry.js +63 -0
- package/template/base/js/src/middlewares/error-handler.middleware.js +22 -19
- package/template/base/js/src/middlewares/index.js +15 -11
- package/template/base/js/src/middlewares/method-not-allowed.middleware.js +19 -13
- package/template/base/js/src/middlewares/not-found.middleware.js +13 -10
- package/template/base/js/src/middlewares/observability.middleware.js +24 -0
- package/template/base/js/src/middlewares/root.middleware.js +18 -16
- package/template/base/js/src/middlewares/validation.middleware.js +39 -0
- package/template/base/js/src/modules/index.js +8 -8
- package/template/base/js/src/modules/v1/health/health.controller.auth.js +29 -0
- package/template/base/js/src/modules/v1/health/health.controller.js +21 -21
- package/template/base/js/src/modules/v1/health/health.route.js +74 -9
- package/template/base/js/src/modules/v1/health/index.js +5 -5
- package/template/base/js/src/modules/v1/index.js +8 -8
- package/template/base/js/src/routes.js +23 -16
- package/template/base/js/src/server.js +18 -18
- package/template/base/js/src/utils/http-error.js +74 -74
- package/template/base/js/src/utils/index.js +28 -28
- package/template/base/js/src/utils/logger.js +57 -67
- package/template/base/ts/.eslintrc.json +13 -17
- package/template/base/ts/.prettierrc +7 -7
- package/template/base/ts/eslint.config.js +33 -33
- package/template/base/ts/package.json +41 -39
- package/template/base/ts/src/app.ts +20 -18
- package/template/base/ts/src/config/db.ts +4 -4
- package/template/base/ts/src/config/env.ts +40 -10
- package/template/base/ts/src/config/index.ts +2 -2
- package/template/base/ts/src/docs/index.ts +3 -0
- package/template/base/ts/src/docs/route-registry.ts +98 -0
- package/template/base/ts/src/middlewares/error-handler.middleware.ts +4 -1
- package/template/base/ts/src/middlewares/index.ts +6 -4
- package/template/base/ts/src/middlewares/method-not-allowed.middleware.ts +23 -18
- package/template/base/ts/src/middlewares/not-found.middleware.ts +10 -8
- package/template/base/ts/src/middlewares/observability.middleware.ts +25 -0
- package/template/base/ts/src/middlewares/root.middleware.ts +16 -14
- package/template/base/ts/src/middlewares/validation.middleware.ts +46 -0
- package/template/base/ts/src/modules/index.ts +8 -8
- package/template/base/ts/src/modules/v1/health/health.controller.auth.ts +26 -0
- package/template/base/ts/src/modules/v1/health/health.controller.ts +18 -18
- package/template/base/ts/src/modules/v1/health/health.route.ts +68 -9
- package/template/base/ts/src/modules/v1/health/index.ts +1 -1
- package/template/base/ts/src/modules/v1/index.ts +8 -8
- package/template/base/ts/src/routes.ts +23 -15
- package/template/base/ts/src/server.ts +19 -19
- package/template/base/ts/src/utils/http-error.ts +63 -63
- package/template/base/ts/src/utils/index.ts +14 -14
- package/template/base/ts/src/utils/logger.ts +58 -68
- package/template/base/ts/tsconfig.json +21 -21
- package/template/features/auth/argon2/inject.js +50 -50
- package/template/features/auth/base/health-openapi.ts +62 -0
- package/template/features/auth/base/inject.js +174 -172
- package/template/features/auth/bcrypt/inject.js +40 -40
- package/template/features/auth/models/index.ts +1 -1
- package/template/features/auth/models/user.model.js +24 -24
- package/template/features/auth/models/user.model.ts +28 -28
- package/template/features/auth/modules/auth.controller.js +21 -21
- package/template/features/auth/modules/auth.controller.ts +28 -20
- package/template/features/auth/modules/auth.routes.js +89 -10
- package/template/features/auth/modules/auth.routes.ts +86 -11
- package/template/features/auth/modules/auth.service.js +29 -29
- package/template/features/auth/modules/auth.service.ts +38 -38
- package/template/features/auth/modules/index.js +1 -1
- package/template/features/auth/modules/index.ts +1 -1
- package/template/features/auth/utils/hash.ts +20 -20
- package/template/features/auth/utils/jwt.js +12 -12
- package/template/features/auth/utils/jwt.ts +15 -15
- package/template/features/cors/inject.js +14 -13
- package/template/features/helmet/inject.js +7 -6
- package/template/features/morgan/inject.js +8 -7
- package/template/features/rate-limit/inject.js +7 -6
- package/template/gateway/js/app.js +42 -42
- package/template/gateway/js/inject.js +33 -33
- package/template/gateway/js/server.js +19 -19
- package/template/gateway/ts/app.ts +43 -43
- package/template/gateway/ts/inject.js +33 -33
- package/template/gateway/ts/server.ts +19 -19
- package/template/microservice/docker/docker-compose.yml +5 -5
- package/template/microservice/nodocker/pm2.config.js +3 -3
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { Request, Response } from "express";
|
|
2
|
-
|
|
3
|
-
export const rootHandler = (_req: Request, res: Response) => {
|
|
4
|
-
res.json({
|
|
5
|
-
name: "/*__PROJECT_NAME__*/",
|
|
6
|
-
type: "/*__PROJECT_TYPE__*/",
|
|
7
|
-
version: "1.0.0",
|
|
8
|
-
status: "running",
|
|
9
|
-
endpoints: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
1
|
+
import { Request, Response } from "express";
|
|
2
|
+
|
|
3
|
+
export const rootHandler = (_req: Request, res: Response) => {
|
|
4
|
+
res.json({
|
|
5
|
+
name: "/*__PROJECT_NAME__*/",
|
|
6
|
+
type: "/*__PROJECT_TYPE__*/",
|
|
7
|
+
version: "1.0.0",
|
|
8
|
+
status: "running",
|
|
9
|
+
endpoints: {
|
|
10
|
+
root: "/",
|
|
11
|
+
health: "/api/v1/health",
|
|
12
|
+
docs: "/api-docs",
|
|
13
|
+
/*__AUTH_ENDPOINT__*/
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { NextFunction, Request, Response } from "express";
|
|
2
|
+
import { BadRequestError } from "@/utils";
|
|
3
|
+
|
|
4
|
+
type RequestSchemas = {
|
|
5
|
+
body?: { parse: (value: unknown) => unknown };
|
|
6
|
+
query?: { parse: (value: unknown) => unknown };
|
|
7
|
+
params?: { parse: (value: unknown) => unknown };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const isValidationError = (error: unknown): error is { issues: Array<{ path?: Array<string | number>; message: string }> } => {
|
|
11
|
+
return (
|
|
12
|
+
typeof error === "object" &&
|
|
13
|
+
error !== null &&
|
|
14
|
+
"issues" in error &&
|
|
15
|
+
Array.isArray((error as { issues?: unknown }).issues)
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const validateRequest = (schemas: RequestSchemas) => {
|
|
20
|
+
return (req: Request, _: Response, next: NextFunction) => {
|
|
21
|
+
try {
|
|
22
|
+
if (schemas.body) {
|
|
23
|
+
req.body = schemas.body.parse(req.body);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (schemas.query) {
|
|
27
|
+
req.query = schemas.query.parse(req.query) as Request["query"];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (schemas.params) {
|
|
31
|
+
req.params = schemas.params.parse(req.params) as Request["params"];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
next();
|
|
35
|
+
} catch (error: unknown) {
|
|
36
|
+
if (isValidationError(error)) {
|
|
37
|
+
const issues = error.issues
|
|
38
|
+
.map((issue) => `${issue.path?.join(".") || "request"}: ${issue.message}`)
|
|
39
|
+
.join("; ");
|
|
40
|
+
return next(new BadRequestError(`Request validation failed - ${issues}`));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return next(error);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
2
|
-
import V1Routes from "./v1";
|
|
3
|
-
|
|
4
|
-
const router = Router();
|
|
5
|
-
|
|
6
|
-
router.use("/v1", V1Routes);
|
|
7
|
-
|
|
8
|
-
export default router;
|
|
1
|
+
import { Router } from "express";
|
|
2
|
+
import V1Routes from "./v1";
|
|
3
|
+
|
|
4
|
+
const router = Router();
|
|
5
|
+
|
|
6
|
+
router.use("/v1", V1Routes);
|
|
7
|
+
|
|
8
|
+
export default router;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Request, Response } from "express";
|
|
2
|
+
import mongoose from "mongoose";
|
|
3
|
+
import { logger } from "@/utils";
|
|
4
|
+
|
|
5
|
+
export const healthCheck = async (_: Request, res: Response) => {
|
|
6
|
+
const mongoState = mongoose.connection.readyState;
|
|
7
|
+
|
|
8
|
+
const healthy = mongoState === 1;
|
|
9
|
+
|
|
10
|
+
const failed: string[] = [];
|
|
11
|
+
if (mongoState !== 1) failed.push("mongodb");
|
|
12
|
+
|
|
13
|
+
return res.status(healthy ? 200 : 503).json({
|
|
14
|
+
status: healthy ? "healthy" : "unhealthy",
|
|
15
|
+
uptime: process.uptime(),
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
services: {
|
|
18
|
+
mongodb: mongoState === 1 ? "connected" : "disconnected",
|
|
19
|
+
memory: {
|
|
20
|
+
rss: process.memoryUsage().rss,
|
|
21
|
+
heapUsed: process.memoryUsage().heapUsed,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
failed,
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { Request, Response } from "express";
|
|
2
|
-
import { logger } from "@/utils";
|
|
3
|
-
|
|
4
|
-
export const healthCheck = async (_: Request, res: Response) => {
|
|
5
|
-
logger.info("Health", "healthy");
|
|
6
|
-
|
|
7
|
-
return res.status(200).json({
|
|
8
|
-
status: "healthy",
|
|
9
|
-
uptime: process.uptime(),
|
|
10
|
-
timestamp: new Date().toISOString(),
|
|
11
|
-
services: {
|
|
12
|
-
memory: {
|
|
13
|
-
rss: process.memoryUsage().rss,
|
|
14
|
-
heapUsed: process.memoryUsage().heapUsed,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
};
|
|
1
|
+
import { Request, Response } from "express";
|
|
2
|
+
import { logger } from "@/utils";
|
|
3
|
+
|
|
4
|
+
export const healthCheck = async (_: Request, res: Response) => {
|
|
5
|
+
logger.info("Health", "healthy");
|
|
6
|
+
|
|
7
|
+
return res.status(200).json({
|
|
8
|
+
status: "healthy",
|
|
9
|
+
uptime: process.uptime(),
|
|
10
|
+
timestamp: new Date().toISOString(),
|
|
11
|
+
services: {
|
|
12
|
+
memory: {
|
|
13
|
+
rss: process.memoryUsage().rss,
|
|
14
|
+
heapUsed: process.memoryUsage().heapUsed,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
};
|
|
@@ -1,9 +1,68 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
2
|
-
import { healthCheck } from "./health.controller";
|
|
3
|
-
import { methodNotAllowedHandler } from "@/middlewares";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
router
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { Router } from "express";
|
|
2
|
+
import { healthCheck } from "./health.controller";
|
|
3
|
+
import { methodNotAllowedHandler, validateRequest } from "@/middlewares";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { routeRegistry } from "@/docs";
|
|
6
|
+
|
|
7
|
+
const router = Router();
|
|
8
|
+
const healthQuerySchema = z
|
|
9
|
+
.object({
|
|
10
|
+
verbose: z.coerce.boolean().optional(),
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
13
|
+
|
|
14
|
+
// Register route schema with auto-generated docs
|
|
15
|
+
routeRegistry.register({
|
|
16
|
+
method: "GET",
|
|
17
|
+
path: "/api/v1/health",
|
|
18
|
+
handler: healthCheck,
|
|
19
|
+
docs: {
|
|
20
|
+
tags: ["Health"],
|
|
21
|
+
summary: "Health check endpoint",
|
|
22
|
+
description:
|
|
23
|
+
"Returns API health status and runtime metrics including uptime and memory usage.",
|
|
24
|
+
parameters: [
|
|
25
|
+
{
|
|
26
|
+
name: "verbose",
|
|
27
|
+
in: "query",
|
|
28
|
+
required: false,
|
|
29
|
+
schema: { type: "boolean" },
|
|
30
|
+
description: "Optional verbose mode for detailed diagnostics.",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
responses: {
|
|
34
|
+
"200": {
|
|
35
|
+
description: "Healthy response with system metrics",
|
|
36
|
+
content: {
|
|
37
|
+
"application/json": {
|
|
38
|
+
schema: {
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
status: { type: "string", example: "healthy" },
|
|
42
|
+
uptime: { type: "number", example: 123.45 },
|
|
43
|
+
timestamp: { type: "string", example: "2024-01-01T00:00:00.000Z" },
|
|
44
|
+
services: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
memory: {
|
|
48
|
+
type: "object",
|
|
49
|
+
properties: {
|
|
50
|
+
rss: { type: "number" },
|
|
51
|
+
heapUsed: { type: "number" },
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
router.use(methodNotAllowedHandler(["GET"]));
|
|
66
|
+
router.get("/", validateRequest({ query: healthQuerySchema }), healthCheck);
|
|
67
|
+
|
|
68
|
+
export default router;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as healthRoutes } from "./health.route";
|
|
1
|
+
export { default as healthRoutes } from "./health.route";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
2
|
-
import { healthRoutes } from "./health";
|
|
3
|
-
|
|
4
|
-
const router = Router();
|
|
5
|
-
|
|
6
|
-
router.use("/health", healthRoutes);
|
|
7
|
-
|
|
8
|
-
export default router;
|
|
1
|
+
import { Router } from "express";
|
|
2
|
+
import { healthRoutes } from "./health";
|
|
3
|
+
|
|
4
|
+
const router = Router();
|
|
5
|
+
|
|
6
|
+
router.use("/health", healthRoutes);
|
|
7
|
+
|
|
8
|
+
export default router;
|
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
2
|
-
import modulesRouter from "./modules";
|
|
3
|
-
import { notFound, rootHandler } from "./middlewares";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
router.
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
router.use(
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import { NextFunction, Request, Response, Router } from "express";
|
|
2
|
+
import modulesRouter from "./modules";
|
|
3
|
+
import { notFound, rootHandler } from "./middlewares";
|
|
4
|
+
import swaggerUi from "swagger-ui-express";
|
|
5
|
+
import { routeRegistry } from "./docs";
|
|
6
|
+
|
|
7
|
+
const router = Router();
|
|
8
|
+
|
|
9
|
+
// Root endpoint
|
|
10
|
+
router.get("/", rootHandler);
|
|
11
|
+
|
|
12
|
+
// Swagger UI with auto-generated spec
|
|
13
|
+
router.use("/api-docs", swaggerUi.serve, (_req: Request, res: Response, next: NextFunction) => {
|
|
14
|
+
const spec = routeRegistry.generateOpenAPI("/*__PROJECT_NAME__*/", "1.0.0");
|
|
15
|
+
swaggerUi.setup(spec)(_req, res, next);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
router.use("/api", modulesRouter);
|
|
19
|
+
|
|
20
|
+
// 404 handler - must be last
|
|
21
|
+
router.use(notFound);
|
|
22
|
+
|
|
23
|
+
export default router;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import app from "./app";
|
|
2
|
-
import { ENV } from "./config";
|
|
3
|
-
import { logger } from "@/utils";
|
|
4
|
-
/*__DB_IMPORT__*/
|
|
5
|
-
|
|
6
|
-
const PORT = ENV.PORT || 3000;
|
|
7
|
-
|
|
8
|
-
const startServer = async () => {
|
|
9
|
-
/*__DB_CONNECT__*/
|
|
10
|
-
|
|
11
|
-
app.listen(PORT, () => {
|
|
12
|
-
logger.info("Server", `Server is running on port ${PORT}`);
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
startServer().catch((error) => {
|
|
17
|
-
logger.error("Server", "Failed to start server", error as Error);
|
|
18
|
-
process.exit(1);
|
|
19
|
-
});
|
|
1
|
+
import app from "./app";
|
|
2
|
+
import { ENV } from "./config";
|
|
3
|
+
import { logger } from "@/utils";
|
|
4
|
+
/*__DB_IMPORT__*/
|
|
5
|
+
|
|
6
|
+
const PORT = ENV.PORT || 3000;
|
|
7
|
+
|
|
8
|
+
const startServer = async () => {
|
|
9
|
+
/*__DB_CONNECT__*/
|
|
10
|
+
|
|
11
|
+
app.listen(PORT, () => {
|
|
12
|
+
logger.info("Server", `Server is running on port ${PORT}`);
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
startServer().catch((error) => {
|
|
17
|
+
logger.error("Server", "Failed to start server", error as Error);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
});
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
export class HttpError extends Error {
|
|
2
|
-
public status: number;
|
|
3
|
-
|
|
4
|
-
constructor(status: number, message: string) {
|
|
5
|
-
super(message);
|
|
6
|
-
this.status = status;
|
|
7
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class BadRequestError extends HttpError {
|
|
12
|
-
constructor(message = "Bad Request") {
|
|
13
|
-
super(400, message);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class UnprocessableEntityError extends HttpError {
|
|
18
|
-
constructor(message = "Unprocessable Entity") {
|
|
19
|
-
super(422, message);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class UnauthorizedError extends HttpError {
|
|
24
|
-
constructor(message = "Unauthorized") {
|
|
25
|
-
super(401, message);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export class ForbiddenError extends HttpError {
|
|
30
|
-
constructor(message = "Forbidden") {
|
|
31
|
-
super(403, message);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class NotFoundError extends HttpError {
|
|
36
|
-
constructor(message = "Not Found") {
|
|
37
|
-
super(404, message);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class ConflictError extends HttpError {
|
|
42
|
-
constructor(message = "Conflict") {
|
|
43
|
-
super(409, message);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export class TooManyRequestsError extends HttpError {
|
|
48
|
-
constructor(message = "Too Many Requests") {
|
|
49
|
-
super(429, message);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export class BadGatewayError extends HttpError {
|
|
54
|
-
constructor(message = "Bad Gateway") {
|
|
55
|
-
super(502, message);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export class InternalServerError extends HttpError {
|
|
60
|
-
constructor(message = "Internal Server Error") {
|
|
61
|
-
super(500, message);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
export class HttpError extends Error {
|
|
2
|
+
public status: number;
|
|
3
|
+
|
|
4
|
+
constructor(status: number, message: string) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.status = status;
|
|
7
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class BadRequestError extends HttpError {
|
|
12
|
+
constructor(message = "Bad Request") {
|
|
13
|
+
super(400, message);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class UnprocessableEntityError extends HttpError {
|
|
18
|
+
constructor(message = "Unprocessable Entity") {
|
|
19
|
+
super(422, message);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class UnauthorizedError extends HttpError {
|
|
24
|
+
constructor(message = "Unauthorized") {
|
|
25
|
+
super(401, message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class ForbiddenError extends HttpError {
|
|
30
|
+
constructor(message = "Forbidden") {
|
|
31
|
+
super(403, message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class NotFoundError extends HttpError {
|
|
36
|
+
constructor(message = "Not Found") {
|
|
37
|
+
super(404, message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class ConflictError extends HttpError {
|
|
42
|
+
constructor(message = "Conflict") {
|
|
43
|
+
super(409, message);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class TooManyRequestsError extends HttpError {
|
|
48
|
+
constructor(message = "Too Many Requests") {
|
|
49
|
+
super(429, message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class BadGatewayError extends HttpError {
|
|
54
|
+
constructor(message = "Bad Gateway") {
|
|
55
|
+
super(502, message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export class InternalServerError extends HttpError {
|
|
60
|
+
constructor(message = "Internal Server Error") {
|
|
61
|
+
super(500, message);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export {
|
|
2
|
-
HttpError,
|
|
3
|
-
BadRequestError,
|
|
4
|
-
UnprocessableEntityError,
|
|
5
|
-
UnauthorizedError,
|
|
6
|
-
ForbiddenError,
|
|
7
|
-
NotFoundError,
|
|
8
|
-
ConflictError,
|
|
9
|
-
TooManyRequestsError,
|
|
10
|
-
BadGatewayError,
|
|
11
|
-
InternalServerError,
|
|
12
|
-
} from "./http-error";
|
|
13
|
-
|
|
14
|
-
export { default as logger } from "./logger";
|
|
1
|
+
export {
|
|
2
|
+
HttpError,
|
|
3
|
+
BadRequestError,
|
|
4
|
+
UnprocessableEntityError,
|
|
5
|
+
UnauthorizedError,
|
|
6
|
+
ForbiddenError,
|
|
7
|
+
NotFoundError,
|
|
8
|
+
ConflictError,
|
|
9
|
+
TooManyRequestsError,
|
|
10
|
+
BadGatewayError,
|
|
11
|
+
InternalServerError,
|
|
12
|
+
} from "./http-error";
|
|
13
|
+
|
|
14
|
+
export { default as logger } from "./logger";
|
|
@@ -1,68 +1,58 @@
|
|
|
1
|
-
import { ENV } from "@/config";
|
|
2
|
-
|
|
3
|
-
// ANSI color codes for terminal output
|
|
4
|
-
const colors = {
|
|
5
|
-
reset: "\x1b[0m",
|
|
6
|
-
blue: "\x1b[34m",
|
|
7
|
-
cyan: "\x1b[36m",
|
|
8
|
-
yellow: "\x1b[33m",
|
|
9
|
-
red: "\x1b[31m",
|
|
10
|
-
bold: "\x1b[1m",
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
function format(tag: string, color: string) {
|
|
14
|
-
return `${color}${colors.bold}[${tag}]${colors.reset}`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function getEnvironment() {
|
|
18
|
-
return ENV.NODE_ENV === "development" || ENV.NODE_ENV === "staging"
|
|
19
|
-
? "development"
|
|
20
|
-
: ENV.NODE_ENV;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (
|
|
49
|
-
console.
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
console.
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
console.warn(format(tag, colors.yellow), ...args);
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
error(tag: string, ...args: unknown[]) {
|
|
63
|
-
if (getEnvironment() !== "development") return;
|
|
64
|
-
console.error(format(tag, colors.red), ...args);
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export default logger;
|
|
1
|
+
import { ENV } from "@/config";
|
|
2
|
+
|
|
3
|
+
// ANSI color codes for terminal output
|
|
4
|
+
const colors = {
|
|
5
|
+
reset: "\x1b[0m",
|
|
6
|
+
blue: "\x1b[34m",
|
|
7
|
+
cyan: "\x1b[36m",
|
|
8
|
+
yellow: "\x1b[33m",
|
|
9
|
+
red: "\x1b[31m",
|
|
10
|
+
bold: "\x1b[1m",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function format(tag: string, color: string) {
|
|
14
|
+
return `${color}${colors.bold}[${tag}]${colors.reset}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getEnvironment() {
|
|
18
|
+
return ENV.NODE_ENV === "development" || ENV.NODE_ENV === "staging"
|
|
19
|
+
? "development"
|
|
20
|
+
: ENV.NODE_ENV;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function shouldLog(level: "log" | "info" | "warn" | "error") {
|
|
24
|
+
if (level === "log") {
|
|
25
|
+
return getEnvironment() === "development";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(
|
|
32
|
+
format("logger", colors.blue),
|
|
33
|
+
`Logger initialized for ${getEnvironment()} environment.`,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const logger = {
|
|
37
|
+
log(tag: string, ...args: unknown[]) {
|
|
38
|
+
if (!shouldLog("log")) return;
|
|
39
|
+
console.log(format(tag, colors.blue), ...args);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
info(tag: string, ...args: unknown[]) {
|
|
43
|
+
if (!shouldLog("info")) return;
|
|
44
|
+
console.info(format(tag, colors.cyan), ...args);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
warn(tag: string, ...args: unknown[]) {
|
|
48
|
+
if (!shouldLog("warn")) return;
|
|
49
|
+
console.warn(format(tag, colors.yellow), ...args);
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
error(tag: string, ...args: unknown[]) {
|
|
53
|
+
if (!shouldLog("error")) return;
|
|
54
|
+
console.error(format(tag, colors.red), ...args);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default logger;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"target": "ES2020",
|
|
5
|
-
"module": "CommonJS",
|
|
6
|
-
"rootDir": "src",
|
|
7
|
-
"outDir": "dist",
|
|
8
|
-
|
|
9
|
-
"strict": true,
|
|
10
|
-
"noImplicitAny": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"skipLibCheck": true,
|
|
13
|
-
|
|
14
|
-
"paths": {
|
|
15
|
-
"@/*": ["./src/*"]
|
|
16
|
-
},
|
|
17
|
-
"types": ["node"]
|
|
18
|
-
},
|
|
19
|
-
"include": ["src"],
|
|
20
|
-
"exclude": ["node_modules", "dist"]
|
|
21
|
-
}
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "ES2020",
|
|
5
|
+
"module": "CommonJS",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noImplicitAny": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
|
|
14
|
+
"paths": {
|
|
15
|
+
"@/*": ["./src/*"]
|
|
16
|
+
},
|
|
17
|
+
"types": ["node"]
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"],
|
|
20
|
+
"exclude": ["node_modules", "dist"]
|
|
21
|
+
}
|