This commit is contained in:
2025-11-21 16:31:04 +03:30
parent 7505c29c78
commit a8f2f4b50c
+20 -20
View File
@@ -3,32 +3,43 @@ import { GqlExecutionContext } from '@nestjs/graphql';
import { FastifyReply, FastifyRequest } from 'fastify'; import { FastifyReply, FastifyRequest } from 'fastify';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Reflector } from '@nestjs/core';
@Injectable() @Injectable()
export class ResponseInterceptor implements NestInterceptor { export class ResponseInterceptor implements NestInterceptor {
constructor(private reflector: Reflector) {} constructor() {}
private isGraphQLBody(body: unknown): boolean {
if (!body || typeof body !== 'object') {
return false;
}
const bodyObj = body as Record<string, unknown>;
return !!(bodyObj.query || bodyObj.mutation || bodyObj.operationName);
}
intercept(context: ExecutionContext, next: CallHandler<Record<string, unknown>>): Observable<unknown> { intercept(context: ExecutionContext, next: CallHandler<Record<string, unknown>>): Observable<unknown> {
// Check if this is a GraphQL request // Check if this is a GraphQL request
// GraphQL requests should bypass this interceptor as they handle their own response format // GraphQL requests should bypass this interceptor as they handle their own response format
// Method 1: Check context type (most reliable for GraphQL) // Method 1: Try to create GraphQL context - if it doesn't throw, it's GraphQL
const contextType = context.getType(); try {
if (contextType === 'graphql') { const gqlContext = GqlExecutionContext.create(context);
return next.handle(); // If we can create it and it has GraphQL-specific properties, it's GraphQL
if (gqlContext && gqlContext.getInfo()) {
return next.handle();
}
} catch {
// Not a GraphQL context, continue
} }
// Method 2: Check request URL and body for GraphQL endpoint // Method 2: Check request URL and body for GraphQL endpoint
try { try {
const request = context.switchToHttp().getRequest<FastifyRequest>(); const request = context.switchToHttp().getRequest<FastifyRequest>();
// Check URL path // Check URL path
if (request.url?.includes('/graphql') || request.routerPath?.includes('/graphql')) { if (request.url?.includes('/graphql')) {
return next.handle(); return next.handle();
} }
// Check if request body contains GraphQL query/mutation // Check if request body contains GraphQL query/mutation
const body = request.body as any; if (this.isGraphQLBody(request.body)) {
if (body && typeof body === 'object' && (body.query || body.mutation || body.operationName)) {
return next.handle(); return next.handle();
} }
} catch { } catch {
@@ -44,17 +55,6 @@ export class ResponseInterceptor implements NestInterceptor {
return next.handle(); return next.handle();
} }
// Method 4: Try to create GraphQL context - if it doesn't throw, it's GraphQL
try {
const gqlContext = GqlExecutionContext.create(context);
// If we can create it and it has GraphQL-specific properties, it's GraphQL
if (gqlContext && gqlContext.getInfo) {
return next.handle();
}
} catch {
// Not a GraphQL context, continue
}
// For REST endpoints, wrap the response // For REST endpoints, wrap the response
try { try {
const ctx = context.switchToHttp().getResponse<FastifyReply>(); const ctx = context.switchToHttp().getResponse<FastifyReply>();