import type { ElectronApi } from '../../../../core/platform/electron/electron-api.models'; export function pluginFileParentDir(filePath: string): string { const normalized = filePath.replace(/\\/g, '/').replace(/\/+$/, ''); const index = normalized.lastIndexOf('/'); return index > 0 ? normalized.slice(0, index) : normalized; } export function pluginReadRootForFileUrl(fileUrl: string): string { const filePath = fileUrlToPath(fileUrl).replace(/\\/g, '/').replace(/\/+$/, ''); const basename = filePath.split('/').pop() ?? ''; if (fileUrl.endsWith('/') || !basename.includes('.')) { return filePath; } return pluginFileParentDir(filePath); } export function collectPluginReadRoots(...fileUrls: Array): string[] { const roots = new Set(); for (const fileUrl of fileUrls) { if (!fileUrl?.startsWith('file://')) { continue; } roots.add(pluginReadRootForFileUrl(fileUrl)); } return [...roots]; } export async function grantPluginReadRoots( api: Pick | null | undefined, ...fileUrls: Array ): Promise { if (!api?.grantPluginReadRoot) { return; } const roots = collectPluginReadRoots(...fileUrls); for (const root of roots) { await api.grantPluginReadRoot(root); } } export function fileUrlToPath(fileUrl: string): string { const url = new URL(fileUrl); const decodedPath = decodeURIComponent(url.pathname); if (/^\/[A-Za-z]:\//.test(decodedPath)) { return decodedPath.slice(1).replace(/\//g, '\\'); } return decodedPath; }