Skip to content

Commit bddbb76

Browse files
refactor a bunch of stuff + add support for passing in Query IR to search api
1 parent 3fd5f49 commit bddbb76

10 files changed

Lines changed: 1017 additions & 650 deletions

File tree

packages/web/src/app/api/(server)/search/route.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,18 @@ export const POST = async (request: NextRequest) => {
1414
schemaValidationError(parsed.error)
1515
);
1616
}
17+
18+
const {
19+
query,
20+
...options
21+
} = parsed.data;
1722

18-
const response = await search(parsed.data);
23+
const response = await search({
24+
queryType: 'string',
25+
query,
26+
options,
27+
});
28+
1929
if (isServiceError(response)) {
2030
return serviceErrorResponse(response);
2131
}

packages/web/src/app/api/(server)/stream_search/route.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,17 @@ export const POST = async (request: NextRequest) => {
1414
return serviceErrorResponse(schemaValidationError(parsed.error));
1515
}
1616

17-
const stream = await streamSearch(parsed.data);
17+
const {
18+
query,
19+
...options
20+
} = parsed.data;
21+
22+
const stream = await streamSearch({
23+
queryType: 'string',
24+
query,
25+
options,
26+
});
27+
1828
if (isServiceError(stream)) {
1929
return serviceErrorResponse(stream);
2030
}

packages/web/src/features/chat/tools.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,15 @@ Multiple expressions can be or'd together with or, negated with -, or grouped wi
178178
});
179179

180180
const response = await search({
181+
queryType: 'string',
181182
query,
182-
matches: limit ?? 100,
183-
contextLines: 3,
184-
whole: false,
185-
isCaseSensitivityEnabled: true,
186-
isRegexEnabled: true,
183+
options: {
184+
matches: limit ?? 100,
185+
contextLines: 3,
186+
whole: false,
187+
isCaseSensitivityEnabled: true,
188+
isRegexEnabled: true,
189+
}
187190
});
188191

189192
if (isServiceError(response)) {
@@ -219,11 +222,11 @@ export const searchReposTool = tool({
219222
}),
220223
execute: async ({ query, limit }) => {
221224
const reposResponse = await getRepos();
222-
225+
223226
if (isServiceError(reposResponse)) {
224227
return reposResponse;
225228
}
226-
229+
227230
// Configure Fuse.js for fuzzy searching
228231
const fuse = new Fuse(reposResponse, {
229232
keys: [
@@ -234,7 +237,7 @@ export const searchReposTool = tool({
234237
includeScore: true,
235238
minMatchCharLength: 1,
236239
});
237-
240+
238241
const searchResults = fuse.search(query, { limit: limit ?? 10 });
239242

240243
searchResults.sort((a, b) => (a.score ?? 0) - (b.score ?? 0));
@@ -253,11 +256,11 @@ export const listAllReposTool = tool({
253256
inputSchema: z.object({}),
254257
execute: async () => {
255258
const reposResponse = await getRepos();
256-
259+
257260
if (isServiceError(reposResponse)) {
258261
return reposResponse;
259262
}
260-
263+
261264
return reposResponse.map((repo) => repo.repoName);
262265
}
263266
});

packages/web/src/features/codeNav/api.ts

Lines changed: 103 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { isServiceError } from "@/lib/utils";
77
import { withOptionalAuthV2 } from "@/withAuthV2";
88
import { SearchResponse } from "../search/types";
99
import { FindRelatedSymbolsRequest, FindRelatedSymbolsResponse } from "./types";
10+
import { QueryIR } from '../search/ir';
1011

1112
// The maximum number of matches to return from the search API.
1213
const MAX_REFERENCE_COUNT = 1000;
@@ -19,14 +20,37 @@ export const findSearchBasedSymbolReferences = async (props: FindRelatedSymbolsR
1920
revisionName = "HEAD",
2021
} = props;
2122

22-
const query = `\\b${symbolName}\\b rev:${revisionName} ${getExpandedLanguageFilter(language)}`;
23+
const languageFilter = getExpandedLanguageFilter(language);
24+
25+
const query: QueryIR = {
26+
and: {
27+
children: [
28+
{
29+
regexp: {
30+
regexp: `\\b${symbolName}\\b`,
31+
case_sensitive: true,
32+
file_name: false,
33+
content: true,
34+
}
35+
},
36+
{
37+
branch: {
38+
pattern: revisionName,
39+
exact: true,
40+
}
41+
},
42+
languageFilter,
43+
]
44+
}
45+
}
2346

2447
const searchResult = await search({
48+
queryType: 'ir',
2549
query,
26-
matches: MAX_REFERENCE_COUNT,
27-
contextLines: 0,
28-
isCaseSensitivityEnabled: true,
29-
isRegexEnabled: true,
50+
options: {
51+
matches: MAX_REFERENCE_COUNT,
52+
contextLines: 0,
53+
}
3054
});
3155

3256
if (isServiceError(searchResult)) {
@@ -39,27 +63,54 @@ export const findSearchBasedSymbolReferences = async (props: FindRelatedSymbolsR
3963

4064
export const findSearchBasedSymbolDefinitions = async (props: FindRelatedSymbolsRequest): Promise<FindRelatedSymbolsResponse | ServiceError> => sew(() =>
4165
withOptionalAuthV2(async () => {
42-
const {
43-
symbolName,
44-
language,
45-
revisionName = "HEAD",
46-
} = props;
66+
const {
67+
symbolName,
68+
language,
69+
revisionName = "HEAD",
70+
} = props;
4771

48-
const query = `sym:\\b${symbolName}\\b rev:${revisionName} ${getExpandedLanguageFilter(language)}`;
72+
const languageFilter = getExpandedLanguageFilter(language);
73+
74+
const query: QueryIR = {
75+
and: {
76+
children: [
77+
{
78+
symbol: {
79+
expr: {
80+
regexp: {
81+
regexp: `\\b${symbolName}\\b`,
82+
case_sensitive: true,
83+
file_name: false,
84+
content: true,
85+
}
86+
},
87+
}
88+
},
89+
{
90+
branch: {
91+
pattern: revisionName,
92+
exact: true,
93+
}
94+
},
95+
languageFilter,
96+
]
97+
}
98+
}
4999

50-
const searchResult = await search({
51-
query,
100+
const searchResult = await search({
101+
queryType: 'ir',
102+
query,
103+
options: {
52104
matches: MAX_REFERENCE_COUNT,
53105
contextLines: 0,
54-
isCaseSensitivityEnabled: true,
55-
isRegexEnabled: true,
56-
});
57-
58-
if (isServiceError(searchResult)) {
59-
return searchResult;
60106
}
107+
});
108+
109+
if (isServiceError(searchResult)) {
110+
return searchResult;
111+
}
61112

62-
return parseRelatedSymbolsSearchResponse(searchResult);
113+
return parseRelatedSymbolsSearchResponse(searchResult);
63114
}));
64115

65116
const parseRelatedSymbolsSearchResponse = (searchResult: SearchResponse): FindRelatedSymbolsResponse => {
@@ -89,14 +140,43 @@ const parseRelatedSymbolsSearchResponse = (searchResult: SearchResponse): FindRe
89140
}
90141

91142
// Expands the language filter to include all variants of the language.
92-
const getExpandedLanguageFilter = (language: string) => {
143+
const getExpandedLanguageFilter = (language: string): QueryIR => {
93144
switch (language) {
94145
case "TypeScript":
95146
case "JavaScript":
96147
case "JSX":
97148
case "TSX":
98-
return `(lang:TypeScript or lang:JavaScript or lang:JSX or lang:TSX)`
149+
return {
150+
or: {
151+
children: [
152+
{
153+
language: {
154+
language: "TypeScript",
155+
}
156+
},
157+
{
158+
language: {
159+
language: "JavaScript",
160+
}
161+
},
162+
{
163+
language: {
164+
language: "JSX",
165+
}
166+
},
167+
{
168+
language: {
169+
language: "TSX",
170+
}
171+
},
172+
]
173+
},
174+
}
99175
default:
100-
return `lang:${language}`
176+
return {
177+
language: {
178+
language: language,
179+
},
180+
}
101181
}
102182
}

packages/web/src/features/search/fileSourceApi.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,46 @@ import { isServiceError } from "../../lib/utils";
55
import { search } from "./searchApi";
66
import { sew } from "@/actions";
77
import { withOptionalAuthV2 } from "@/withAuthV2";
8+
import { QueryIR } from './ir';
89
// @todo (bkellam) #574 : We should really be using `git show <hash>:<path>` to fetch file contents here.
910
// This will allow us to support permalinks to files at a specific revision that may not be indexed
1011
// by zoekt.
1112

1213
export const getFileSource = async ({ fileName, repository, branch }: FileSourceRequest): Promise<FileSourceResponse | ServiceError> => sew(() =>
1314
withOptionalAuthV2(async () => {
14-
let query = `file:${fileName} repo:^${repository}$`;
15-
if (branch) {
16-
query = query.concat(` rev:${branch}`);
15+
const query: QueryIR = {
16+
and: {
17+
children: [
18+
{
19+
repo: {
20+
regexp: `^${repository}$`,
21+
},
22+
},
23+
{
24+
regexp: {
25+
regexp: fileName,
26+
case_sensitive: true,
27+
file_name: true,
28+
content: false
29+
},
30+
},
31+
...(branch ? [{
32+
branch: {
33+
pattern: branch,
34+
exact: true,
35+
},
36+
}]: [])
37+
]
38+
}
1739
}
1840

1941
const searchResponse = await search({
42+
queryType: 'ir',
2043
query,
21-
matches: 1,
22-
whole: true,
23-
isCaseSensitivityEnabled: true,
24-
isRegexEnabled: true,
44+
options: {
45+
matches: 1,
46+
whole: true,
47+
}
2548
});
2649

2750
if (isServiceError(searchResponse)) {

0 commit comments

Comments
 (0)