fix(server): treat bare slash queries as search terms in project picker

Queries like "faro/main" were treated as literal paths relative to ~,
so the picker tried to list ~/faro/ (which doesn't exist) instead of
searching the home tree for paths containing "faro/main". Only treat
queries as paths when explicitly rooted with ~, ~/, ./, or /.
This commit is contained in:
Mohamed Boudra
2026-03-29 23:10:15 +07:00
parent fd030e8673
commit 930660074d
@@ -604,7 +604,13 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null
return null; return null;
} }
// Only treat the query as a literal path when the user explicitly roots it
// with ~, ~/, ./, or an absolute path. Bare queries like "faro/main" are
// search terms, not paths.
let isRooted = false;
if (normalized.startsWith("~")) { if (normalized.startsWith("~")) {
isRooted = true;
normalized = normalized.slice(1); normalized = normalized.slice(1);
if (normalized.startsWith("/")) { if (normalized.startsWith("/")) {
normalized = normalized.slice(1); normalized = normalized.slice(1);
@@ -612,6 +618,7 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null
} }
if (path.isAbsolute(normalized)) { if (path.isAbsolute(normalized)) {
isRooted = true;
const absolute = path.resolve(normalized); const absolute = path.resolve(normalized);
if (!isPathInsideRoot(homeRoot, absolute)) { if (!isPathInsideRoot(homeRoot, absolute)) {
return null; return null;
@@ -619,6 +626,9 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null
normalized = normalizeRelativePath(homeRoot, absolute); normalized = normalizeRelativePath(homeRoot, absolute);
} }
if (normalized.startsWith("./")) {
isRooted = true;
}
normalized = normalized.replace(/^\.\/+/, "").replace(/\/{2,}/g, "/"); normalized = normalized.replace(/^\.\/+/, "").replace(/\/{2,}/g, "/");
if (!normalized) { if (!normalized) {
// Treat "~" and "~/" as a request to browse the home root. // Treat "~" and "~/" as a request to browse the home root.
@@ -632,13 +642,21 @@ function normalizeQueryParts(query: string, homeRoot: string): QueryParts | null
return null; return null;
} }
const isPathQuery = normalized.includes("/"); const isPathQuery = isRooted && normalized.includes("/");
if (!isPathQuery) {
return {
isPathQuery: false,
parentPart: "",
searchTerm: normalized,
};
}
const slashIndex = normalized.lastIndexOf("/"); const slashIndex = normalized.lastIndexOf("/");
const parentPart = slashIndex >= 0 ? normalized.slice(0, slashIndex) : ""; const parentPart = normalized.slice(0, slashIndex);
const searchTerm = slashIndex >= 0 ? normalized.slice(slashIndex + 1) : normalized; const searchTerm = normalized.slice(slashIndex + 1);
return { return {
isPathQuery, isPathQuery: true,
parentPart, parentPart,
searchTerm, searchTerm,
}; };