/* eslint-disable @typescript-eslint/no-explicit-any */ // eslint-disable-next-line import/named import { MatchesPosition, MeiliSearch, SearchParams, SearchResponse } from "meilisearch"; import { isDefined } from "./asserts"; import { MeiliDocumentsType } from "shared/meilisearch-graphql-typings/meiliTypes"; const meili = new MeiliSearch({ host: process.env.NEXT_PUBLIC_URL_MEILISEARCH ?? "", apiKey: process.env.NEXT_PUBLIC_MEILISEARCH_KEY, }); interface CustomSearchParams extends Omit< SearchParams, "cropMarker" | "highlightPostTag" | "highlightPreTag" | "q" | "showMatchesPosition" > {} type CustomHit> = T & { _formatted: Partial; _matchesPosition: MatchesPosition; }; type CustomHits> = CustomHit[]; export interface CustomSearchResponse extends Omit, "hits"> { hits: CustomHits; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const meiliSearch = async ( indexName: I, query: string, options: CustomSearchParams ) => { const index = meili.index(indexName); return (await index.search["documents"]>(query, { ...options, attributesToHighlight: options.attributesToHighlight ?? ["*"], highlightPreTag: "", highlightPostTag: "", showMatchesPosition: true, cropLength: 20, cropMarker: "...", })) as unknown as CustomSearchResponse["documents"]>; }; export const containsHighlight = (text: string | null | undefined): boolean => isDefined(text) && text.includes("");