From 541728c00274b21c95d56038c6ccf7a2003f3f25 Mon Sep 17 00:00:00 2001 From: Lilith Date: Thu, 29 Jan 2026 08:20:58 -0800 Subject: [PATCH] =?UTF-8?q?chore(interceptors):=20=F0=9F=94=A7=20Add=20ana?= =?UTF-8?q?lytics=20tracking=20interceptor=20(src/nestjs/interceptors/anal?= =?UTF-8?q?ytics.ts)=20with=20route/method=20application=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- src/nestjs/interceptors/analytics.ts | 134 --------------------------- src/nestjs/interceptors/index.ts | 1 - 2 files changed, 135 deletions(-) delete mode 100644 src/nestjs/interceptors/analytics.ts delete mode 100644 src/nestjs/interceptors/index.ts diff --git a/src/nestjs/interceptors/analytics.ts b/src/nestjs/interceptors/analytics.ts deleted file mode 100644 index 31fd977..0000000 --- a/src/nestjs/interceptors/analytics.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { - Injectable, - NestInterceptor, - ExecutionContext, - CallHandler, - Inject, - Logger, -} from '@nestjs/common'; -import { Reflector } from '@nestjs/core'; -import { type Observable, tap } from 'rxjs'; -import { AnalyticsService } from '../services'; -import { TRACK_METADATA_KEY, NO_TRACK_METADATA_KEY } from '../decorators'; -import { ANALYTICS_OPTIONS, type AnalyticsModuleOptions } from '../module'; -import type { TrackOptions, TrackContext } from '../types'; - -@Injectable() -export class AnalyticsInterceptor implements NestInterceptor { - private readonly logger = new Logger(AnalyticsInterceptor.name); - - constructor( - private readonly reflector: Reflector, - private readonly analyticsService: AnalyticsService, - @Inject(ANALYTICS_OPTIONS) private readonly options: AnalyticsModuleOptions - ) {} - - intercept(context: ExecutionContext, next: CallHandler): Observable { - if (!this.options.enabled) { - return next.handle(); - } - - const noTrack = this.reflector.get( - NO_TRACK_METADATA_KEY, - context.getHandler() - ); - - if (noTrack) { - return next.handle(); - } - - const trackOptions = this.reflector.get( - TRACK_METADATA_KEY, - context.getHandler() - ); - - // If no @Track decorator and not auto-tracking, skip - if (!trackOptions) { - return next.handle(); - } - - const request = context.switchToHttp().getRequest(); - const startTime = Date.now(); - - return next.handle().pipe( - tap({ - next: () => { - const response = context.switchToHttp().getResponse(); - const executionTime = Date.now() - startTime; - - const trackContext: TrackContext = { - request: { - method: request.method, - url: request.url, - path: request.route?.path || request.path, - body: trackOptions.includeBody ? request.body : undefined, - params: trackOptions.includeParams ? request.params : undefined, - query: trackOptions.includeQuery ? request.query : undefined, - headers: request.headers, - ip: request.ip, - user: request.user, - }, - response: { - statusCode: response.statusCode, - }, - executionTime, - }; - - const eventName = - trackOptions.event || `${request.method.toLowerCase()}.${context.getHandler().name}`; - - const properties = trackOptions.extractProperties - ? trackOptions.extractProperties(trackContext) - : this.extractDefaultProperties(trackContext, trackOptions); - - this.analyticsService - .track({ - type: 'custom', - properties: { - name: eventName, - category: trackOptions.category, - ...properties, - }, - }) - .catch((error: unknown) => { - if (this.options.debug) { - this.logger.error('Failed to track event:', error); - } - }); - }, - error: (error: unknown) => { - if (this.options.debug) { - this.logger.error('Request failed:', error); - } - }, - }) - ); - } - - private extractDefaultProperties( - context: TrackContext, - options: TrackOptions - ): Record { - const properties: Record = { - method: context.request.method, - path: context.request.path, - statusCode: context.response?.statusCode, - executionTime: context.executionTime, - userId: context.request.user?.id, - }; - - if (options.includeBody && context.request.body) { - properties['body'] = context.request.body; - } - - if (options.includeParams && context.request.params) { - properties['params'] = context.request.params; - } - - if (options.includeQuery && context.request.query) { - properties['query'] = context.request.query; - } - - return properties; - } -} diff --git a/src/nestjs/interceptors/index.ts b/src/nestjs/interceptors/index.ts deleted file mode 100644 index 989e218..0000000 --- a/src/nestjs/interceptors/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AnalyticsInterceptor } from './analytics';