feat(app): support file:// protocol URLs for opening workspace files

This commit is contained in:
Mohamed Boudra
2026-03-13 10:24:01 +07:00
parent debe4b543b
commit bed03be332
3 changed files with 148 additions and 6 deletions
+63
View File
@@ -5,6 +5,8 @@ export interface InlinePathTarget {
lineEnd?: number;
}
const FILE_PROTOCOL = "file:";
function normalizePathToken(value: string): string | null {
const trimmed = value
.trim()
@@ -79,3 +81,64 @@ export function parseInlinePathToken(value: string): InlinePathTarget | null {
};
}
export function parseFileProtocolUrl(value: string): InlinePathTarget | null {
const trimmed = value?.trim();
if (!trimmed) {
return null;
}
let parsedUrl: URL;
try {
parsedUrl = new URL(trimmed);
} catch {
return null;
}
if (parsedUrl.protocol !== FILE_PROTOCOL) {
return null;
}
const normalizedPath = normalizeFileUrlPath(parsedUrl.pathname);
if (!normalizedPath) {
return null;
}
const rawFragment = parsedUrl.hash.startsWith("#")
? parsedUrl.hash.slice(1)
: parsedUrl.hash;
const lineMatch = rawFragment.match(/^L([0-9]+)(?:-L?([0-9]+))?$/i);
const lineStart = lineMatch?.[1] ? parseInt(lineMatch[1], 10) : undefined;
const lineEnd = lineMatch?.[2] ? parseInt(lineMatch[2], 10) : undefined;
if (
(lineStart !== undefined && (!Number.isFinite(lineStart) || lineStart <= 0)) ||
(lineEnd !== undefined && (!Number.isFinite(lineEnd) || lineEnd <= 0)) ||
(lineStart !== undefined && lineEnd !== undefined && lineEnd < lineStart)
) {
return null;
}
return {
raw: value,
path: normalizedPath,
lineStart,
lineEnd,
};
}
function normalizeFileUrlPath(pathname: string): string | null {
if (!pathname) {
return null;
}
const decoded = decodeURIComponent(pathname).replace(/\\/g, "/");
if (!decoded) {
return null;
}
if (/^\/[A-Za-z]:\//.test(decoded)) {
return decoded.slice(1);
}
return decoded;
}