import { CallHandler, ExecutionContext, Injectable, NestInterceptor, StreamableFile, } from "@nestjs/common"; import { Readable } from "stream"; import { Observable } from "rxjs"; import { map } from "rxjs/operators"; import { flatResponseModules } from "../constants/apiModules"; export interface StandardResponse { success: true; data: T; timestamp: string; } @Injectable() export class ResponseTransformInterceptor implements NestInterceptor< T, StandardResponse | T > { intercept( _context: ExecutionContext, next: CallHandler, ): Observable | T> { return next.handle().pipe( map((data) => { if ( data instanceof StreamableFile || data instanceof Buffer || data instanceof Readable ) { return data; } const request = _context.switchToHttp().getRequest(); const path = request.route?.path ?? request.originalUrl ?? ""; const shouldFlatten = flatResponseModules.some((module) => path.startsWith(module), ); if ( shouldFlatten && data && typeof data === "object" ) { if(!Array.isArray(data)){ return { success: true, ...data, timestamp: new Date().toISOString(), }; } else { return data; } } if(path.startsWith("/api/positions/hierarchy") || path.startsWith("/api/positions/current")){ return data; } return { success: true, data, timestamp: new Date().toISOString(), }; }), ); } }