@gallop.software/studio 2.3.166 → 2.3.167

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2449,11 +2449,51 @@ async function handleDeleteStream(request) {
2449
2449
  return;
2450
2450
  }
2451
2451
  const isCancelled = () => operationId ? isOperationCancelled(operationId) : false;
2452
+ async function countFilesInDir(dirPath) {
2453
+ let count = 0;
2454
+ try {
2455
+ const entries = await fs7.readdir(dirPath, { withFileTypes: true });
2456
+ for (const entry of entries) {
2457
+ if (entry.isDirectory()) {
2458
+ count += await countFilesInDir(path7.join(dirPath, entry.name));
2459
+ } else {
2460
+ count++;
2461
+ }
2462
+ }
2463
+ } catch {
2464
+ }
2465
+ return count;
2466
+ }
2467
+ let totalFiles = 0;
2468
+ for (const itemPath of paths) {
2469
+ if (!itemPath.startsWith("public/")) continue;
2470
+ const absolutePath = getWorkspacePath(itemPath);
2471
+ try {
2472
+ const stats = await fs7.stat(absolutePath);
2473
+ if (stats.isDirectory()) {
2474
+ totalFiles += await countFilesInDir(absolutePath);
2475
+ } else {
2476
+ totalFiles++;
2477
+ }
2478
+ } catch {
2479
+ const imageKey = "/" + itemPath.replace(/^public\//, "");
2480
+ const meta2 = await loadMeta();
2481
+ const prefix = imageKey + "/";
2482
+ let count = 0;
2483
+ for (const key of Object.keys(meta2)) {
2484
+ if (key.startsWith(prefix) || key === imageKey) {
2485
+ count++;
2486
+ }
2487
+ }
2488
+ totalFiles += count || 1;
2489
+ }
2490
+ }
2452
2491
  const meta = await loadMeta();
2453
2492
  const deleted = [];
2454
2493
  const errors = [];
2455
2494
  const sourceFolders = /* @__PURE__ */ new Set();
2456
- const total = paths.length;
2495
+ const total = totalFiles || paths.length;
2496
+ let currentProgress = 0;
2457
2497
  sendEvent({ type: "start", total });
2458
2498
  for (let i = 0; i < paths.length; i++) {
2459
2499
  if (isCancelled()) {
@@ -2476,12 +2516,13 @@ async function handleDeleteStream(request) {
2476
2516
  try {
2477
2517
  if (!itemPath.startsWith("public/")) {
2478
2518
  errors.push(`Invalid path: ${itemPath}`);
2519
+ currentProgress++;
2479
2520
  sendEvent({
2480
2521
  type: "progress",
2481
- current: i + 1,
2522
+ current: currentProgress,
2482
2523
  total,
2483
2524
  deleted: deleted.length,
2484
- percent: Math.round((i + 1) / total * 100),
2525
+ percent: Math.round(currentProgress / total * 100),
2485
2526
  currentFile: path7.basename(itemPath)
2486
2527
  });
2487
2528
  continue;
@@ -2495,6 +2536,7 @@ async function handleDeleteStream(request) {
2495
2536
  try {
2496
2537
  const stats = await fs7.stat(absolutePath);
2497
2538
  if (stats.isDirectory()) {
2539
+ const filesInDir = await countFilesInDir(absolutePath);
2498
2540
  await fs7.rm(absolutePath, { recursive: true });
2499
2541
  const prefix = imageKey + "/";
2500
2542
  for (const key of Object.keys(meta)) {
@@ -2518,6 +2560,7 @@ async function handleDeleteStream(request) {
2518
2560
  delete meta[key];
2519
2561
  }
2520
2562
  }
2563
+ currentProgress += filesInDir || 1;
2521
2564
  } else {
2522
2565
  await fs7.unlink(absolutePath);
2523
2566
  const isInImagesFolder = itemPath.startsWith("public/images/");
@@ -2538,6 +2581,7 @@ async function handleDeleteStream(request) {
2538
2581
  }
2539
2582
  delete meta[imageKey];
2540
2583
  }
2584
+ currentProgress++;
2541
2585
  }
2542
2586
  } catch {
2543
2587
  if (entry) {
@@ -2548,6 +2592,7 @@ async function handleDeleteStream(request) {
2548
2592
  }
2549
2593
  }
2550
2594
  delete meta[imageKey];
2595
+ currentProgress++;
2551
2596
  } else {
2552
2597
  const prefix = imageKey + "/";
2553
2598
  let foundAny = false;
@@ -2563,16 +2608,18 @@ async function handleDeleteStream(request) {
2563
2608
  }
2564
2609
  delete meta[key];
2565
2610
  foundAny = true;
2611
+ currentProgress++;
2566
2612
  }
2567
2613
  }
2568
2614
  if (!foundAny) {
2569
2615
  errors.push(`Not found: ${itemPath}`);
2616
+ currentProgress++;
2570
2617
  sendEvent({
2571
2618
  type: "progress",
2572
- current: i + 1,
2619
+ current: currentProgress,
2573
2620
  total,
2574
2621
  deleted: deleted.length,
2575
- percent: Math.round((i + 1) / total * 100),
2622
+ percent: Math.round(currentProgress / total * 100),
2576
2623
  currentFile: path7.basename(itemPath)
2577
2624
  });
2578
2625
  continue;
@@ -2587,10 +2634,10 @@ async function handleDeleteStream(request) {
2587
2634
  }
2588
2635
  sendEvent({
2589
2636
  type: "progress",
2590
- current: i + 1,
2637
+ current: currentProgress,
2591
2638
  total,
2592
2639
  deleted: deleted.length,
2593
- percent: Math.round((i + 1) / total * 100),
2640
+ percent: Math.round(currentProgress / total * 100),
2594
2641
  currentFile: path7.basename(itemPath)
2595
2642
  });
2596
2643
  }
@@ -4794,6 +4841,38 @@ async function handleFontsDeleteStream(request) {
4794
4841
  return jsonResponse({ error: `Path not allowed: ${p}` }, { status: 400 });
4795
4842
  }
4796
4843
  }
4844
+ async function countFilesInDir(dirPath) {
4845
+ let count = 0;
4846
+ try {
4847
+ const entries = await fs12.readdir(dirPath, { withFileTypes: true });
4848
+ for (const entry of entries) {
4849
+ if (entry.isDirectory()) {
4850
+ count += await countFilesInDir(path11.join(dirPath, entry.name));
4851
+ } else {
4852
+ count++;
4853
+ }
4854
+ }
4855
+ } catch {
4856
+ }
4857
+ return count;
4858
+ }
4859
+ async function getFilesInDir(dirPath, basePath) {
4860
+ const files = [];
4861
+ try {
4862
+ const entries = await fs12.readdir(dirPath, { withFileTypes: true });
4863
+ for (const entry of entries) {
4864
+ const fullPath = path11.join(dirPath, entry.name);
4865
+ const relativePath = path11.join(basePath, entry.name);
4866
+ if (entry.isDirectory()) {
4867
+ files.push(...await getFilesInDir(fullPath, relativePath));
4868
+ } else {
4869
+ files.push(relativePath);
4870
+ }
4871
+ }
4872
+ } catch {
4873
+ }
4874
+ return files;
4875
+ }
4797
4876
  const encoder = new TextEncoder();
4798
4877
  const stream = new ReadableStream({
4799
4878
  async start(controller) {
@@ -4802,28 +4881,50 @@ async function handleFontsDeleteStream(request) {
4802
4881
 
4803
4882
  `));
4804
4883
  };
4805
- const deleted = [];
4806
- const errors = [];
4807
- for (let i = 0; i < paths.length; i++) {
4808
- const p = paths[i];
4809
- const fileName = p.split("/").pop() || p;
4810
- send({ status: "progress", message: `Deleting ${fileName}...`, current: i + 1, total: paths.length });
4884
+ const allFiles = [];
4885
+ const foldersToDelete = [];
4886
+ for (const p of paths) {
4887
+ const fullPath = getWorkspacePath(p);
4811
4888
  try {
4812
- const fullPath = getWorkspacePath(p);
4813
4889
  const stat = await fs12.stat(fullPath);
4814
4890
  if (stat.isDirectory()) {
4815
- await fs12.rm(fullPath, { recursive: true });
4891
+ foldersToDelete.push(p);
4892
+ const filesInDir = await getFilesInDir(fullPath, p);
4893
+ for (const f of filesInDir) {
4894
+ allFiles.push({ path: f, isFolder: false, parentFolder: p });
4895
+ }
4816
4896
  } else {
4817
- await fs12.unlink(fullPath);
4897
+ allFiles.push({ path: p, isFolder: false });
4818
4898
  }
4819
- deleted.push(p);
4899
+ } catch {
4900
+ }
4901
+ }
4902
+ const total = allFiles.length;
4903
+ const deleted = [];
4904
+ const errors = [];
4905
+ let current = 0;
4906
+ for (const file of allFiles) {
4907
+ current++;
4908
+ const fileName = file.path.split("/").pop() || file.path;
4909
+ send({ status: "progress", message: `Deleting ${fileName}...`, current, total });
4910
+ try {
4911
+ const fullPath = getWorkspacePath(file.path);
4912
+ await fs12.unlink(fullPath);
4913
+ deleted.push(file.path);
4820
4914
  } catch (err) {
4821
- errors.push(`Failed to delete ${p}: ${err instanceof Error ? err.message : "Unknown error"}`);
4915
+ errors.push(`Failed to delete ${file.path}: ${err instanceof Error ? err.message : "Unknown error"}`);
4916
+ }
4917
+ }
4918
+ for (const folder of foldersToDelete) {
4919
+ try {
4920
+ const fullPath = getWorkspacePath(folder);
4921
+ await fs12.rm(fullPath, { recursive: true });
4922
+ } catch {
4822
4923
  }
4823
4924
  }
4824
4925
  send({
4825
4926
  status: "complete",
4826
- message: `Deleted ${deleted.length} item${deleted.length !== 1 ? "s" : ""}`,
4927
+ message: `Deleted ${deleted.length} file${deleted.length !== 1 ? "s" : ""}`,
4827
4928
  deleted,
4828
4929
  errors: errors.length > 0 ? errors : void 0
4829
4930
  });