2024-09-11 04:55:00 +00:00
|
|
|
import escapeStringRegexp from "escape-string-regexp";
|
2024-09-10 06:16:41 +00:00
|
|
|
import { SHARD_MAX_MATCH_COUNT, TOTAL_MAX_MATCH_COUNT } from "../environment";
|
2024-09-26 03:12:20 +00:00
|
|
|
import { listRepositoriesResponseSchema, searchResponseSchema } from "../schemas";
|
|
|
|
|
import { FileSourceRequest, FileSourceResponse, ListRepositoriesResponse, SearchRequest, SearchResponse } from "../types";
|
2024-09-11 04:55:00 +00:00
|
|
|
import { fileNotFound, invalidZoektResponse, ServiceError, unexpectedError } from "../serviceError";
|
2024-09-10 06:16:41 +00:00
|
|
|
import { isServiceError } from "../utils";
|
|
|
|
|
import { zoektFetch } from "./zoektClient";
|
|
|
|
|
|
2024-09-26 06:31:51 +00:00
|
|
|
export const search = async ({ query, maxMatchDisplayCount, whole }: SearchRequest): Promise<SearchResponse | ServiceError> => {
|
2024-09-10 06:16:41 +00:00
|
|
|
const body = JSON.stringify({
|
|
|
|
|
q: query,
|
|
|
|
|
// @see: https://github.com/TaqlaAI/zoekt/blob/main/api.go#L892
|
|
|
|
|
opts: {
|
|
|
|
|
NumContextLines: 2,
|
|
|
|
|
ChunkMatches: true,
|
2024-09-26 06:31:51 +00:00
|
|
|
MaxMatchDisplayCount: maxMatchDisplayCount,
|
2024-09-10 06:16:41 +00:00
|
|
|
Whole: !!whole,
|
|
|
|
|
ShardMaxMatchCount: SHARD_MAX_MATCH_COUNT,
|
|
|
|
|
TotalMaxMatchCount: TOTAL_MAX_MATCH_COUNT,
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const searchResponse = await zoektFetch({
|
|
|
|
|
path: "/api/search",
|
|
|
|
|
body,
|
|
|
|
|
method: "POST",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!searchResponse.ok) {
|
|
|
|
|
return invalidZoektResponse(searchResponse);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const searchBody = await searchResponse.json();
|
2024-09-10 19:24:12 +00:00
|
|
|
const parsedSearchResponse = searchResponseSchema.safeParse(searchBody);
|
|
|
|
|
if (!parsedSearchResponse.success) {
|
|
|
|
|
console.error(`Failed to parse zoekt response. Error: ${parsedSearchResponse.error}`);
|
|
|
|
|
return unexpectedError(`Something went wrong while parsing the response from zoekt`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parsedSearchResponse.data;
|
2024-09-10 06:16:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const getFileSource = async ({ fileName, repository }: FileSourceRequest): Promise<FileSourceResponse | ServiceError> => {
|
2024-09-10 19:24:12 +00:00
|
|
|
const escapedFileName = escapeStringRegexp(fileName);
|
|
|
|
|
const escapedRepository = escapeStringRegexp(repository);
|
|
|
|
|
|
2024-09-10 06:16:41 +00:00
|
|
|
const searchResponse = await search({
|
2024-09-10 19:24:12 +00:00
|
|
|
query: `${escapedFileName} repo:^${escapedRepository}$`,
|
2024-09-26 06:31:51 +00:00
|
|
|
maxMatchDisplayCount: 1,
|
2024-09-10 06:16:41 +00:00
|
|
|
whole: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (isServiceError(searchResponse)) {
|
|
|
|
|
return searchResponse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const files = searchResponse.Result.Files;
|
|
|
|
|
|
2024-09-10 19:24:12 +00:00
|
|
|
if (!files || files.length === 0) {
|
2024-09-10 06:16:41 +00:00
|
|
|
return fileNotFound(fileName, repository);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const source = files[0].Content ?? '';
|
|
|
|
|
return {
|
|
|
|
|
source
|
|
|
|
|
}
|
2024-09-11 04:55:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const listRepositories = async (): Promise<ListRepositoriesResponse | ServiceError> => {
|
|
|
|
|
const body = JSON.stringify({
|
|
|
|
|
opts: {
|
|
|
|
|
Field: 0,
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const listResponse = await zoektFetch({
|
|
|
|
|
path: "/api/list",
|
|
|
|
|
body,
|
2024-09-11 19:15:12 +00:00
|
|
|
method: "POST",
|
|
|
|
|
cache: "no-store",
|
2024-09-11 04:55:00 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!listResponse.ok) {
|
|
|
|
|
return invalidZoektResponse(listResponse);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const listBody = await listResponse.json();
|
|
|
|
|
const parsedListResponse = listRepositoriesResponseSchema.safeParse(listBody);
|
|
|
|
|
if (!parsedListResponse.success) {
|
|
|
|
|
console.error(`Failed to parse zoekt response. Error: ${parsedListResponse.error}`);
|
|
|
|
|
return unexpectedError(`Something went wrong while parsing the response from zoekt`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parsedListResponse.data;
|
2024-09-10 06:16:41 +00:00
|
|
|
}
|