All files / src/modules/search search.resolver.ts

55.88% Statements 19/34
48% Branches 12/25
36.36% Functions 4/11
54.83% Lines 17/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 6911x 11x 11x 11x 11x 11x 11x 11x 11x     11x   11x 11x     22x   11x 11x                                                                                       22x 11x      
import { Resolver, Query, Args } from '@nestjs/graphql';
import { UseGuards } from '@nestjs/common';
import { SearchService } from '@app/modules/search/search.service';
import { PrismaService } from '@app/modules/prisma/prisma.service';
import { SearchResponseDto } from './dto/search-response.dto';
import { FilterManifestResponse } from './dto/filter-manifest.dto';
import { SearchFilterInput } from '@app/modules/search/dto/search-filter.input';
import { GqlAuthGuard } from '@app/common/guards/gql-auth.guard';
import { sanitizeInput } from '@app/utils/sanitize';
 
@Resolver()
export class SearchResolver {
  constructor(
    private readonly searchService: SearchService,
    private readonly prisma: PrismaService,
  ) {}
 
  @Query(() => SearchResponseDto, { name: 'search' })
  @UseGuards(GqlAuthGuard)
  async search(
    @Args('filter', { type: () => SearchFilterInput }) filter: SearchFilterInput,
  ): Promise<SearchResponseDto> {
    const sanitized = sanitizeInput(filter);
    const { resultIds, facets, searchAfter } = await this.searchService.search(
      sanitized,
    );
 
    Iif (resultIds.length === 0) {
      return { 
        results: [], 
        facets: facets ? JSON.stringify(facets) : undefined, 
        searchAfter: searchAfter ? searchAfter.map(String) : undefined 
      };
    }
 
    const numericIds = resultIds.map((id) => parseInt(id, 10));
 
    type ListingWithPhotos = { id: number; photos: { url: string }[] } & Record<string, unknown>;
    const listings = (await this.prisma.client.listing.findMany({
      where: { id: { in: numericIds } },
      include: { photos: true },
    })) as ListingWithPhotos[];
 
    const listingsById = new Map<number, ListingWithPhotos & { photoUrls: string[] }>(
      listings.map((l: ListingWithPhotos) => [
        l.id,
        {
          ...(l as ListingWithPhotos),
          photoUrls: l.photos.map((p: { url: string }) => p.url),
        },
      ]),
    );
 
    const orderedListings = numericIds
      .map((id) => listingsById.get(id) as any)
      .filter((l) => l !== undefined) as any;
 
    return { 
      results: orderedListings, 
      facets: facets ? JSON.stringify(facets) : undefined,
      searchAfter: searchAfter ? searchAfter.map(String) : undefined
    };
  }
 
  @Query(() => FilterManifestResponse, { name: 'filterManifest' })
  getFilterManifest() {
    return this.searchService.getFilterManifest();
  }
}