Function bodies 503 total
createIOServer method · typescript · L28-L34 (7 LOC)backend/src/common/adapters/redis-io.adapter.ts
createIOServer(port: number, options?: ServerOptions) {
const server = super.createIOServer(port, options);
if (this.adapterConstructor) {
server.adapter(this.adapterConstructor);
}
return server;
}RedisCacheService class · typescript · L6-L66 (61 LOC)backend/src/common/cache/redis-cache.service.ts
export class RedisCacheService implements OnModuleDestroy {
private redis: Redis;
private connected = false;
constructor(private configService: ConfigService) {
this.redis = new Redis({
host: this.configService.get('REDIS_HOST', 'localhost'),
port: this.configService.get('REDIS_PORT', 6379),
lazyConnect: true,
});
this.redis.connect().then(() => {
this.connected = true;
console.log('[Cache] Redis connected');
}).catch(() => {
console.warn('[Cache] Redis not available, caching disabled');
});
}
async get<T>(key: string): Promise<T | null> {
if (!this.connected) return null;
try {
const data = await this.redis.get(key);
return data ? JSON.parse(data) : null;
} catch {
return null;
}
}
async set(key: string, value: any, ttlSeconds = 300): Promise<void> {
if (!this.connected) return;
try {
await this.redis.set(key, JSON.stringify(value), 'EX', ttlSeconds);
} catch {}constructor method · typescript · L10-L22 (13 LOC)backend/src/common/cache/redis-cache.service.ts
constructor(private configService: ConfigService) {
this.redis = new Redis({
host: this.configService.get('REDIS_HOST', 'localhost'),
port: this.configService.get('REDIS_PORT', 6379),
lazyConnect: true,
});
this.redis.connect().then(() => {
this.connected = true;
console.log('[Cache] Redis connected');
}).catch(() => {
console.warn('[Cache] Redis not available, caching disabled');
});
}get method · typescript · L24-L32 (9 LOC)backend/src/common/cache/redis-cache.service.ts
async get<T>(key: string): Promise<T | null> {
if (!this.connected) return null;
try {
const data = await this.redis.get(key);
return data ? JSON.parse(data) : null;
} catch {
return null;
}
}set method · typescript · L34-L39 (6 LOC)backend/src/common/cache/redis-cache.service.ts
async set(key: string, value: any, ttlSeconds = 300): Promise<void> {
if (!this.connected) return;
try {
await this.redis.set(key, JSON.stringify(value), 'EX', ttlSeconds);
} catch {}
}del method · typescript · L41-L46 (6 LOC)backend/src/common/cache/redis-cache.service.ts
async del(key: string): Promise<void> {
if (!this.connected) return;
try {
await this.redis.del(key);
} catch {}
}delByPattern method · typescript · L49-L61 (13 LOC)backend/src/common/cache/redis-cache.service.ts
async delByPattern(pattern: string): Promise<void> {
if (!this.connected) return;
try {
let cursor = '0';
do {
const [nextCursor, keys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
cursor = nextCursor;
if (keys.length > 0) {
await this.redis.del(...keys);
}
} while (cursor !== '0');
} catch {}
}All rows above produced by Repobility · https://repobility.com
onModuleDestroy method · typescript · L63-L65 (3 LOC)backend/src/common/cache/redis-cache.service.ts
onModuleDestroy() {
this.redis?.disconnect();
}ApiResponse class · typescript · L1-L13 (13 LOC)backend/src/common/dto/api-response.dto.ts
export class ApiResponse<T> {
success: boolean;
data: T;
message?: string;
timestamp: string;
constructor(data: T, message?: string) {
this.success = true;
this.data = data;
this.message = message;
this.timestamp = new Date().toISOString();
}
}constructor method · typescript · L7-L12 (6 LOC)backend/src/common/dto/api-response.dto.ts
constructor(data: T, message?: string) {
this.success = true;
this.data = data;
this.message = message;
this.timestamp = new Date().toISOString();
}ApiErrorResponse class · typescript · L15-L24 (10 LOC)backend/src/common/dto/api-response.dto.ts
export class ApiErrorResponse {
success: boolean;
error: {
statusCode: number;
message: string | string[];
error?: string;
};
timestamp: string;
path: string;
}HttpExceptionFilter class · typescript · L12-L49 (38 LOC)backend/src/common/filters/http-exception.filter.ts
export class HttpExceptionFilter implements ExceptionFilter {
private readonly logger = new Logger(HttpExceptionFilter.name);
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
let status = HttpStatus.INTERNAL_SERVER_ERROR;
let message: string | string[] = 'Đã xảy ra lỗi hệ thống';
let error = 'Internal Server Error';
if (exception instanceof HttpException) {
status = exception.getStatus();
const exceptionResponse = exception.getResponse();
if (typeof exceptionResponse === 'string') {
message = exceptionResponse;
} else if (typeof exceptionResponse === 'object') {
const res = exceptionResponse as any;
message = res.message || exception.message;
error = res.error || 'Error';
}
} else {
this.logger.error(
`Unexpected error: ${exception}`,
exceptionRolesGuard class · typescript · L6-L24 (19 LOC)backend/src/common/guards/roles.guard.ts
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles || requiredRoles.length === 0) {
return true;
}
const { user } = context.switchToHttp().getRequest();
// super_admin có quyền truy cập tất cả
if (user?.role === 'super_admin') return true;
return requiredRoles.includes(user?.role);
}
}canActivate method · typescript · L9-L23 (15 LOC)backend/src/common/guards/roles.guard.ts
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles || requiredRoles.length === 0) {
return true;
}
const { user } = context.switchToHttp().getRequest();
// super_admin có quyền truy cập tất cả
if (user?.role === 'super_admin') return true;
return requiredRoles.includes(user?.role);
}TenantGuard class · typescript · L10-L30 (21 LOC)backend/src/common/guards/tenant.guard.ts
export class TenantGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) return true;
const request = context.switchToHttp().getRequest();
const user = request.user;
if (user?.companyId) {
request.companyId = user.companyId;
}
return true;
}
}Same scanner, your repo: https://repobility.com — Repobility
canActivate method · typescript · L13-L29 (17 LOC)backend/src/common/guards/tenant.guard.ts
canActivate(context: ExecutionContext): boolean {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) return true;
const request = context.switchToHttp().getRequest();
const user = request.user;
if (user?.companyId) {
request.companyId = user.companyId;
}
return true;
}LoggingInterceptor class · typescript · L11-L26 (16 LOC)backend/src/common/interceptors/logging.interceptor.ts
export class LoggingInterceptor implements NestInterceptor {
private readonly logger = new Logger('HTTP');
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
const { method, url } = request;
const now = Date.now();
return next.handle().pipe(
tap(() => {
const duration = Date.now() - now;
this.logger.log(`${method} ${url} - ${duration}ms`);
}),
);
}
}intercept method · typescript · L14-L25 (12 LOC)backend/src/common/interceptors/logging.interceptor.ts
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
const { method, url } = request;
const now = Date.now();
return next.handle().pipe(
tap(() => {
const duration = Date.now() - now;
this.logger.log(`${method} ${url} - ${duration}ms`);
}),
);
}tap method · typescript · L20-L23 (4 LOC)backend/src/common/interceptors/logging.interceptor.ts
tap(() => {
const duration = Date.now() - now;
this.logger.log(`${method} ${url} - ${duration}ms`);
}),ResponseInterceptor class · typescript · L10-L20 (11 LOC)backend/src/common/interceptors/response.interceptor.ts
export class ResponseInterceptor<T> implements NestInterceptor<T> {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
map((data) => ({
success: true,
data,
timestamp: new Date().toISOString(),
})),
);
}
}intercept method · typescript · L11-L19 (9 LOC)backend/src/common/interceptors/response.interceptor.ts
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(
map((data) => ({
success: true,
data,
timestamp: new Date().toISOString(),
})),
);
}map method · typescript · L13-L17 (5 LOC)backend/src/common/interceptors/response.interceptor.ts
map((data) => ({
success: true,
data,
timestamp: new Date().toISOString(),
})),AppLoggerService class · typescript · L7-L151 (145 LOC)backend/src/common/logger/app-logger.service.ts
export class AppLoggerService implements LoggerService {
private logger: winston.Logger;
private logDir: string;
private retentionDays: number;
constructor() {
this.logDir = join(process.cwd(), 'logs');
this.retentionDays = +(process.env.LOG_RETENTION_DAYS || '14');
const maxFiles = `${this.retentionDays}d`;
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.printf(({ timestamp, level, message, context, trace }) =>
`[${timestamp}] ${level.toUpperCase().padEnd(7)} [${context || 'App'}] ${message}${trace ? `\n${trace}` : ''}`
),
),
transports: [
// Console
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.printf(({ timestamp, level, message, context }) =>
`[${timestamp}] ${level}All rows scored by the Repobility analyzer (https://repobility.com)
constructor method · typescript · L12-L58 (47 LOC)backend/src/common/logger/app-logger.service.ts
constructor() {
this.logDir = join(process.cwd(), 'logs');
this.retentionDays = +(process.env.LOG_RETENTION_DAYS || '14');
const maxFiles = `${this.retentionDays}d`;
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.printf(({ timestamp, level, message, context, trace }) =>
`[${timestamp}] ${level.toUpperCase().padEnd(7)} [${context || 'App'}] ${message}${trace ? `\n${trace}` : ''}`
),
),
transports: [
// Console
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.printf(({ timestamp, level, message, context }) =>
`[${timestamp}] ${level} [${context || 'App'}] ${message}`
),
),
}),
// Daily rotate file - tất cả logs
new (winston.transports acleanupOldFiles method · typescript · L61-L86 (26 LOC)backend/src/common/logger/app-logger.service.ts
private async cleanupOldFiles() {
try {
const fs = await import('fs/promises');
const files = await fs.readdir(this.logDir);
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - this.retentionDays);
for (const f of files) {
const filepath = join(this.logDir, f);
// Xoá file audit JSON (winston tạo tự động, không cần giữ)
if (f.endsWith('-audit.json')) {
await fs.unlink(filepath).catch(() => {});
continue;
}
// Xoá log cũ hơn retention
if (f.endsWith('.log')) {
const dateMatch = f.match(/(\d{4}-\d{2}-\d{2})/);
if (dateMatch && new Date(dateMatch[1]) < cutoff) {
await fs.unlink(filepath).catch(() => {});
}
}
}
} catch {}
}log method · typescript · L88-L90 (3 LOC)backend/src/common/logger/app-logger.service.ts
log(message: string, context?: string) {
this.logger.info(message, { context });
}error method · typescript · L92-L94 (3 LOC)backend/src/common/logger/app-logger.service.ts
error(message: string, trace?: string, context?: string) {
this.logger.error(message, { trace, context });
}warn method · typescript · L96-L98 (3 LOC)backend/src/common/logger/app-logger.service.ts
warn(message: string, context?: string) {
this.logger.warn(message, { context });
}debug method · typescript · L100-L102 (3 LOC)backend/src/common/logger/app-logger.service.ts
debug(message: string, context?: string) {
this.logger.debug(message, { context });
}verbose method · typescript · L104-L106 (3 LOC)backend/src/common/logger/app-logger.service.ts
verbose(message: string, context?: string) {
this.logger.verbose(message, { context });
}readLogFile method · typescript · L109-L126 (18 LOC)backend/src/common/logger/app-logger.service.ts
async readLogFile(date: string, type: 'all' | 'error' = 'all', lines = 200): Promise<string[]> {
const fs = await import('fs/promises');
// Validate date format để chống path traversal
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) return [];
const filename = type === 'error' ? `${date}-error.log` : `${date}.log`;
const logDir = join(process.cwd(), 'logs');
const filepath = join(logDir, filename);
// Đảm bảo path không thoát khỏi logs/
if (!filepath.startsWith(logDir)) return [];
try {
const content = await fs.readFile(filepath, 'utf-8');
const allLines = content.split('\n').filter(Boolean);
return allLines.slice(-lines);
} catch {
return [];
}
}Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
RedisThrottlerStorage class · typescript · L7-L81 (75 LOC)backend/src/common/throttler/redis-throttler.storage.ts
export class RedisThrottlerStorage implements ThrottlerStorage, OnModuleDestroy {
private redis: Redis;
constructor(private configService: ConfigService) {
this.redis = new Redis({
host: this.configService.get('REDIS_HOST', 'localhost'),
port: this.configService.get('REDIS_PORT', 6379),
lazyConnect: true,
});
this.redis.connect().catch(() => {
console.warn('[Throttler] Redis not available, falling back to no-op');
});
}
async increment(
key: string,
ttl: number,
limit: number,
blockDuration: number,
throttlerName: string,
): Promise<{ totalHits: number; timeToExpire: number; isBlocked: boolean; timeToBlockExpire: number }> {
const redisKey = `throttle:${throttlerName}:${key}`;
const blockKey = `throttle:block:${throttlerName}:${key}`;
const ttlSec = Math.ceil(ttl / 1000);
try {
// Check if blocked
if (blockDuration > 0) {
const blocked = await this.redis.get(blockKey);
iconstructor method · typescript · L10-L19 (10 LOC)backend/src/common/throttler/redis-throttler.storage.ts
constructor(private configService: ConfigService) {
this.redis = new Redis({
host: this.configService.get('REDIS_HOST', 'localhost'),
port: this.configService.get('REDIS_PORT', 6379),
lazyConnect: true,
});
this.redis.connect().catch(() => {
console.warn('[Throttler] Redis not available, falling back to no-op');
});
}increment method · typescript · L21-L27 (7 LOC)backend/src/common/throttler/redis-throttler.storage.ts
async increment(
key: string,
ttl: number,
limit: number,
blockDuration: number,
throttlerName: string,
): Promise<{ totalHits: number; timeToExpire: number; isBlocked: boolean; timeToBlockExpire: number }> {onModuleDestroy method · typescript · L78-L80 (3 LOC)backend/src/common/throttler/redis-throttler.storage.ts
onModuleDestroy() {
this.redis?.disconnect();
}bootstrap function · typescript · L14-L75 (62 LOC)backend/src/main.ts
async function bootstrap() {
const logger = new AppLoggerService();
const app = await NestFactory.create<NestExpressApplication>(AppModule, { logger });
app.setGlobalPrefix('api');
// Serve uploaded files
app.useStaticAssets(join(__dirname, '..', 'uploads'), {
prefix: '/uploads/',
});
const configService = app.get(ConfigService);
// Security headers
app.use(helmet());
// CORS — chỉ cho phép origins cụ thể
const allowedOrigins = (configService.get('CORS_ORIGINS') || 'http://localhost:3005,http://xe16cho.com:3005,https://xe16cho.com').split(',');
app.enableCors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(null, false);
}
},
credentials: true,
});
// Redis adapter cho Socket.IO (scale WebSocket qua nhiều instances)
const redisIoAdapter = new RedisIoAdapter(app, configService);
try {
await redisIoAdapter.connectToRedis();ActivityLog class · typescript · L5-L29 (25 LOC)backend/src/modules/admin/activity-log.entity.ts
export class ActivityLog {
@PrimaryGeneratedColumn()
id: number;
@Column()
userId: number;
@Column({ length: 100 })
userName: string;
@Column({ length: 50 })
action: string;
@Column({ type: 'text', nullable: true })
detail: string;
@Column({ length: 50, nullable: true })
targetType: string;
@Column({ nullable: true })
targetId: number;
@CreateDateColumn()
createdAt: Date;
}AdminController class · typescript · L7-L146 (140 LOC)backend/src/modules/admin/admin.controller.ts
export class AdminController {
private appLogger = new AppLoggerService();
constructor(private readonly adminService: AdminService) {}
@Get('dashboard')
@Roles('admin')
getDashboard() {
return this.adminService.getDashboard();
}
@Get('revenue')
@Roles('admin')
getRevenue(
@Query('startDate') startDate: string,
@Query('endDate') endDate: string,
) {
return this.adminService.getRevenueByPeriod(startDate, endDate);
}
@Get('users')
@Roles('admin')
getUsers(
@Query('page') page?: string,
@Query('limit') limit?: string,
@Query('role') role?: string,
) {
return this.adminService.getUsers(+(page || '1'), +(limit || '20'), role);
}
@Patch('users/:id/toggle-active')
@Roles('admin')
toggleUserActive(@Param('id', ParseIntPipe) id: number) {
return this.adminService.toggleUserActive(id);
}
@Get('bookings')
@Roles('admin')
getBookings(
@Query('page') page?: string,
@Query('limit') limit?: string,
@QuegetDashboard method · typescript · L14-L16 (3 LOC)backend/src/modules/admin/admin.controller.ts
getDashboard() {
return this.adminService.getDashboard();
}All rows above produced by Repobility · https://repobility.com
getRevenue method · typescript · L20-L25 (6 LOC)backend/src/modules/admin/admin.controller.ts
getRevenue(
@Query('startDate') startDate: string,
@Query('endDate') endDate: string,
) {
return this.adminService.getRevenueByPeriod(startDate, endDate);
}getUsers method · typescript · L29-L35 (7 LOC)backend/src/modules/admin/admin.controller.ts
getUsers(
@Query('page') page?: string,
@Query('limit') limit?: string,
@Query('role') role?: string,
) {
return this.adminService.getUsers(+(page || '1'), +(limit || '20'), role);
}toggleUserActive method · typescript · L39-L41 (3 LOC)backend/src/modules/admin/admin.controller.ts
toggleUserActive(@Param('id', ParseIntPipe) id: number) {
return this.adminService.toggleUserActive(id);
}getBookings method · typescript · L45-L51 (7 LOC)backend/src/modules/admin/admin.controller.ts
getBookings(
@Query('page') page?: string,
@Query('limit') limit?: string,
@Query('status') status?: string,
) {
return this.adminService.getBookings(+(page || '1'), +(limit || '20'), status);
}getSettings method · typescript · L57-L59 (3 LOC)backend/src/modules/admin/admin.controller.ts
getSettings() {
return this.adminService.getAllSettings();
}getPublicConfig method · typescript · L63-L65 (3 LOC)backend/src/modules/admin/admin.controller.ts
getPublicConfig() {
return this.adminService.getPublicConfig();
}saveSettings method · typescript · L69-L71 (3 LOC)backend/src/modules/admin/admin.controller.ts
saveSettings(@CurrentUser() user: any, @Body() body: Record<string, string>) {
return this.adminService.saveSettings(body, user);
}getSubscriptionStats method · typescript · L75-L77 (3 LOC)backend/src/modules/admin/admin.controller.ts
getSubscriptionStats() {
return this.adminService.getSubscriptionStats();
}Same scanner, your repo: https://repobility.com — Repobility
getPendingSubscriptions method · typescript · L82-L84 (3 LOC)backend/src/modules/admin/admin.controller.ts
getPendingSubscriptions() {
return this.adminService.getPendingSubscriptions();
}approveSubscription method · typescript · L88-L90 (3 LOC)backend/src/modules/admin/admin.controller.ts
approveSubscription(@CurrentUser() user: any, @Param('id', ParseIntPipe) id: number) {
return this.adminService.approveSubscription(id, user);
}rejectSubscription method · typescript · L94-L96 (3 LOC)backend/src/modules/admin/admin.controller.ts
rejectSubscription(@CurrentUser() user: any, @Param('id', ParseIntPipe) id: number) {
return this.adminService.rejectSubscription(id, user);
}