All files / src/shared/lib/helpers virtualFilesystem.ts

100% Statements 58/58
100% Branches 20/20
100% Functions 9/9
100% Lines 45/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 9144x 312x           44x 4x   44x 41x   44x 32x 32x   28x 28x     44x 11x 11x   8x 8x     44x 50x 50x   49x   49x   28x 28x     44x         29x 29x 29x     29x 6x       23x 14x 14x     9x     44x       20x   20x   20x 11x     9x 9x     44x       20x 20x 1x   19x    
export const normalizePath = (path: string): string =>
  path
    .replace(/\\/g, "/")
    .replace(/\/+/g, "/")
    .replace(/^\/+/, "")
    .replace(/\/$/, "");
 
export const splitPath = (path: string): string[] =>
  normalizePath(path).split("/").filter(Boolean);
 
export const joinPath = (...segments: string[]): string =>
  normalizePath(segments.filter(Boolean).join("/"));
 
export const getBaseName = (path: string): string => {
  const norm = normalizePath(path);
  if (!norm) return "";
 
  const lastSlash = norm.lastIndexOf("/");
  return lastSlash === -1 ? norm : norm.slice(lastSlash + 1);
};
 
export const getParentPath = (path: string): string => {
  const norm = normalizePath(path);
  if (!norm) return "";
 
  const lastSlash = norm.lastIndexOf("/");
  return lastSlash === -1 ? "" : norm.slice(0, lastSlash);
};
 
export const isDescendantPath = (parent: string, child: string): boolean => {
  const parentNorm = normalizePath(parent);
  if (!parentNorm) return false;
 
  const childNorm = normalizePath(child);
 
  if (!childNorm.startsWith(parentNorm)) return false;
 
  const nextChar = childNorm[parentNorm.length];
  return nextChar === undefined || nextChar === "/";
};
 
export const reparentFolderPath = (
  originalPath: string,
  draggedPath: string,
  dropFolder: string,
): string | null => {
  const originalNorm = normalizePath(originalPath);
  const draggedNorm = normalizePath(draggedPath);
  const dropNorm = normalizePath(dropFolder);
 
  // Can't move a file, only a folder
  if (originalPath === draggedPath) {
    return null;
  }
 
  // Folder move
  if (isDescendantPath(draggedNorm, originalNorm)) {
    const relative = originalNorm.slice(draggedNorm.length);
    return joinPath(dropNorm, getBaseName(draggedNorm), relative);
  }
 
  return null;
};
 
export const reparentEntityPath = (
  originalPath: string,
  toPath: string,
): string => {
  const isUnnamed = originalPath.endsWith("/") || originalPath.endsWith("\\");
 
  const base = isUnnamed ? "" : getBaseName(originalPath);
 
  if (base) {
    return joinPath(toPath, base);
  }
 
  const normalized = normalizePath(toPath);
  return normalized ? normalized + "/" : "";
};
 
export const canMoveFolder = (
  draggedPath: string,
  dropFolder: string,
): boolean => {
  const draggedNorm = normalizePath(draggedPath);
  if (!draggedNorm) {
    return false;
  }
  return !isDescendantPath(draggedNorm, dropFolder);
};