仓库指标
- 星标
- (1 个星标)
- PR 合并指标
- (PR 指标待抓取)
描述
🧩 Description
Create a modular, class-based Common Utility Module containing reusable tools like API response formatter, logger, async handler, error formatter, env validator, token utilities, and constants.
This utility layer should:
-
Export clean utility classes and helpers
-
Be used across all feature modules like Auth, User, Payment, etc.
-
Follow a consistent, scalable pattern
-
Avoid code duplication and centralize logic
🧱 Why This Is Important
-
🧼 Promotes clean architecture (DRY, SOLID)
-
🚀 Speeds up dev by reusing common helpers
-
💬 Gives consistent API messages and status
-
🧠 Helps with debugging (logger, error formatting)
-
✅ Makes controllers smaller and simpler
🟢 Difficulty Level: Intermediate
Requires:
-
TypeScript, class-based structure
-
Node.js utilities (JWT, env, files)
-
Clean code practices
✅ Tasks
📁 Final Folder Structure
src/
└── utils/
├── Response.ts # Class-based response handler
├── TryCatch.ts # Async error wrapper class
├── Logger.ts # Logging class
├── ErrorHandler.ts # Global error formatter
├── Pagination.ts # Helper class
├── Slugify.ts # Title slug utility
├── Token.ts # JWT helpers
├── File.ts # File/mime util
├── ValidateEnv.ts # Validate env vars
├── index.ts # Barrel export
└── constants/
├── HttpStatus.ts
├── Messages.ts
1. 🧾 Response.ts – SendResponse Class
export class SendResponse {
static success(res, data = {}, message = 'Success', statusCode = 200) {
return res.status(statusCode).json({
success: true,
message,
data,
});
}
static error(res, message = 'Something went wrong', statusCode = 500, error = {}) {
return res.status(statusCode).json({
success: false,
message,
error,
});
}
}
✅ Usage
return SendResponse.success(res, userData, 'User created', 201);
return SendResponse.error(res, 'User not found', 404)
2. ⚙️ TryCatch.ts – Async Error Wrapper
export class TryCatch {
static wrap(fn) {
return function (req, res, next) {
Promise.resolve(fn(req, res, next)).catch(next);
};
}
}
✅ Usage:
router.get('/', TryCatch.wrap(controller.getAll));
3. 📦 Logger.ts – Logger Class
export class Logger {
static info(msg: string) {
console.info(`[INFO] ${msg}`);
}
static error(msg: string, err?: any) {
console.error(`[ERROR] ${msg}`, err || '');
}
static warn(msg: string) {
console.warn(`[WARN] ${msg}`);
}
}
✅ Usage:
Logger.info('Payment created');
Logger.error('Failed to connect', error);
4. ❗ ErrorHandler.ts – Global Error Middleware
export class ErrorHandler {
static handle(err, req, res, next) {
const status = err.status || 500;
const message = err.message || 'Internal Server Error';
Logger.error(message, err);
return SendResponse.error(res, message, status, {
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
});
}
✅ Usage:
app.use(ErrorHandler.handle);
5. 📜 Pagination.ts – Pagination Utility
export class Pagination {
static paginate(page: number, limit: number) {
const skip = (page - 1) * limit;
return { skip, limit };
}
}
✅ Usage:
const { skip, limit } = Pagination.paginate(req.query.page, req.query.limit);
6. 🔠 Slugify.ts – Slugify Helper
export class Slugify {
static from(text: string): string {
return text.toLowerCase().trim().replace(/\s+/g, '-').replace(/[^\w\-]+/g, '');
}
}
✅ Usage:
const slug = Slugify.from('Create Product Title');
7. 🔐 Token.ts – JWT Helper
import jwt from 'jsonwebtoken';
export class Token {
static sign(payload: object, secret: string, expiresIn = '1d') {
return jwt.sign(payload, secret, { expiresIn });
}
static verify(token: string, secret: string) {
return jwt.verify(token, secret);
}
}
✅ Usage:
const token = Token.sign({ userId: 1 }, process.env.JWT_SECRET);
const decoded = Token.verify(token, process.env.JWT_SECRET);
8. 📁 ValidateEnv.ts – ENV Checker
export class ValidateEnv {
static check(requiredKeys: string[]) {
requiredKeys.forEach((key) => {
if (!process.env[key]) {
throw new Error(`Missing required env var: ${key}`);
}
});
}
}
✅ Usage:
ValidateEnv.check(['PORT', 'JWT_SECRET', 'DB_URI']);
9. 📁 constants/HttpStatus.ts
export const HttpStatus = {
OK: 200,
CREATED: 201,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
INTERNAL_SERVER_ERROR: 500,
};
10. 📁 constants/Messages.ts
export const Messages = {
USER_CREATED: 'User created successfully',
USER_NOT_FOUND: 'User not found',
VALIDATION_FAILED: 'Invalid input data',
};
📘 README.md Instructions
Include usage examples for:
-
SendResponse.success() & .error()
-
TryCatch.wrap()
-
Logger.info()
-
Token.sign() / .verify()
-
Pagination.paginate()
-
Slugify.from()
-
ValidateEnv.check()
-
HttpStatus, Messages
📦 Barrel Export (index.ts)
export * from './Response';
export * from './TryCatch';
export * from './Logger';
export * from './ErrorHandler';
export * from './Pagination';
export * from './Slugify';
export * from './Token';
export * from './File';
export * from './ValidateEnv';
export * from './constants/HttpStatus';
export * from './constants/Messages';
🎯 Expected Outcome
[x] Fully reusable utility module for all FastKit features
[x] Unified response/error/logging system
[x] Cleaner controller code via TryCatch
[x] Easy to onboard other developers
[x] Boost productivity across all modules
🙋🏻♂️ Looking For
Contributors to:
-
Add unit tests for all helpers
-
Add more utilities (e.g., DateFormatter, FileUploader)
-
Add i18n-ready message constants
-
Improve Logger with winston or pino