@gallop.software/studio 2.3.21 → 2.3.23

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.
@@ -1355,15 +1355,16 @@ async function handleMoveStream(request) {
1355
1355
  const newRelativePath = destWithoutPublic ? path6.join(destWithoutPublic, itemName) : itemName;
1356
1356
  const oldKey = "/" + oldRelativePath;
1357
1357
  const newKey = "/" + newRelativePath;
1358
- sendEvent({
1359
- type: "progress",
1360
- current: i + 1,
1361
- total,
1362
- percent: Math.round((i + 1) / total * 100),
1363
- currentFile: itemName
1364
- });
1365
1358
  if (meta[newKey]) {
1366
1359
  errors.push(`${itemName} already exists in destination`);
1360
+ sendEvent({
1361
+ type: "progress",
1362
+ current: i + 1,
1363
+ total,
1364
+ moved: moved.length,
1365
+ percent: Math.round((i + 1) / total * 100),
1366
+ currentFile: itemName
1367
+ });
1367
1368
  continue;
1368
1369
  }
1369
1370
  const entry = meta[oldKey];
@@ -1388,6 +1389,14 @@ async function handleMoveStream(request) {
1388
1389
  delete meta[oldKey];
1389
1390
  meta[newKey] = newEntry;
1390
1391
  moved.push(itemPath);
1392
+ sendEvent({
1393
+ type: "progress",
1394
+ current: i + 1,
1395
+ total,
1396
+ moved: moved.length,
1397
+ percent: Math.round((i + 1) / total * 100),
1398
+ currentFile: itemName
1399
+ });
1391
1400
  } else if (isPushedToR2 && isImage) {
1392
1401
  const buffer = await downloadFromCdn(oldKey);
1393
1402
  await fs6.mkdir(path6.dirname(newAbsolutePath), { recursive: true });
@@ -1416,21 +1425,53 @@ async function handleMoveStream(request) {
1416
1425
  delete meta[oldKey];
1417
1426
  meta[newKey] = newEntry;
1418
1427
  moved.push(itemPath);
1428
+ sendEvent({
1429
+ type: "progress",
1430
+ current: i + 1,
1431
+ total,
1432
+ moved: moved.length,
1433
+ percent: Math.round((i + 1) / total * 100),
1434
+ currentFile: itemName
1435
+ });
1419
1436
  } else {
1420
1437
  const absolutePath = getWorkspacePath(safePath);
1421
1438
  if (absoluteDestination.startsWith(absolutePath + path6.sep)) {
1422
1439
  errors.push(`Cannot move ${itemName} into itself`);
1440
+ sendEvent({
1441
+ type: "progress",
1442
+ current: i + 1,
1443
+ total,
1444
+ moved: moved.length,
1445
+ percent: Math.round((i + 1) / total * 100),
1446
+ currentFile: itemName
1447
+ });
1423
1448
  continue;
1424
1449
  }
1425
1450
  try {
1426
1451
  await fs6.access(absolutePath);
1427
1452
  } catch {
1428
1453
  errors.push(`${itemName} not found`);
1454
+ sendEvent({
1455
+ type: "progress",
1456
+ current: i + 1,
1457
+ total,
1458
+ moved: moved.length,
1459
+ percent: Math.round((i + 1) / total * 100),
1460
+ currentFile: itemName
1461
+ });
1429
1462
  continue;
1430
1463
  }
1431
1464
  try {
1432
1465
  await fs6.access(newAbsolutePath);
1433
1466
  errors.push(`${itemName} already exists in destination`);
1467
+ sendEvent({
1468
+ type: "progress",
1469
+ current: i + 1,
1470
+ total,
1471
+ moved: moved.length,
1472
+ percent: Math.round((i + 1) / total * 100),
1473
+ currentFile: itemName
1474
+ });
1434
1475
  continue;
1435
1476
  } catch {
1436
1477
  }
@@ -1464,10 +1505,26 @@ async function handleMoveStream(request) {
1464
1505
  }
1465
1506
  }
1466
1507
  moved.push(itemPath);
1508
+ sendEvent({
1509
+ type: "progress",
1510
+ current: i + 1,
1511
+ total,
1512
+ moved: moved.length,
1513
+ percent: Math.round((i + 1) / total * 100),
1514
+ currentFile: itemName
1515
+ });
1467
1516
  }
1468
1517
  } catch (err) {
1469
1518
  console.error(`Failed to move ${itemName}:`, err);
1470
1519
  errors.push(`Failed to move ${itemName}`);
1520
+ sendEvent({
1521
+ type: "progress",
1522
+ current: i + 1,
1523
+ total,
1524
+ moved: moved.length,
1525
+ percent: Math.round((i + 1) / total * 100),
1526
+ currentFile: itemName
1527
+ });
1471
1528
  }
1472
1529
  }
1473
1530
  await saveMeta(meta);
@@ -1667,22 +1724,31 @@ async function handleUnprocessStream(request) {
1667
1724
  if (!imageKey.startsWith("/")) {
1668
1725
  imageKey = `/${imageKey}`;
1669
1726
  }
1670
- sendEvent({
1671
- type: "progress",
1672
- current: i + 1,
1673
- total,
1674
- percent: Math.round((i + 1) / total * 100),
1675
- message: `Removing thumbnails for ${imageKey.slice(1)}...`
1676
- });
1677
1727
  try {
1678
1728
  const entry = getMetaEntry(meta, imageKey);
1679
1729
  if (!entry) {
1680
1730
  errors.push(imageKey);
1731
+ sendEvent({
1732
+ type: "progress",
1733
+ current: i + 1,
1734
+ total,
1735
+ processed: removed.length,
1736
+ percent: Math.round((i + 1) / total * 100),
1737
+ message: `Error: ${imageKey.slice(1)}`
1738
+ });
1681
1739
  continue;
1682
1740
  }
1683
1741
  const hasThumbnails = entry.sm || entry.md || entry.lg || entry.f;
1684
1742
  if (!hasThumbnails) {
1685
1743
  skipped.push(imageKey);
1744
+ sendEvent({
1745
+ type: "progress",
1746
+ current: i + 1,
1747
+ total,
1748
+ processed: removed.length,
1749
+ percent: Math.round((i + 1) / total * 100),
1750
+ message: `Skipped ${imageKey.slice(1)} (no thumbnails)`
1751
+ });
1686
1752
  continue;
1687
1753
  }
1688
1754
  const existingCdnIndex = entry.c;
@@ -1698,9 +1764,25 @@ async function handleUnprocessStream(request) {
1698
1764
  ...entry.c !== void 0 ? { c: entry.c } : {}
1699
1765
  };
1700
1766
  removed.push(imageKey);
1767
+ sendEvent({
1768
+ type: "progress",
1769
+ current: i + 1,
1770
+ total,
1771
+ processed: removed.length,
1772
+ percent: Math.round((i + 1) / total * 100),
1773
+ message: `Removed thumbnails for ${imageKey.slice(1)}`
1774
+ });
1701
1775
  } catch (error) {
1702
1776
  console.error(`Failed to unprocess ${imageKey}:`, error);
1703
1777
  errors.push(imageKey);
1778
+ sendEvent({
1779
+ type: "progress",
1780
+ current: i + 1,
1781
+ total,
1782
+ processed: removed.length,
1783
+ percent: Math.round((i + 1) / total * 100),
1784
+ message: `Failed: ${imageKey.slice(1)}`
1785
+ });
1704
1786
  }
1705
1787
  }
1706
1788
  sendEvent({ type: "cleanup", message: "Saving metadata..." });
@@ -1773,13 +1855,6 @@ async function handleReprocessStream(request) {
1773
1855
  if (!imageKey.startsWith("/")) {
1774
1856
  imageKey = `/${imageKey}`;
1775
1857
  }
1776
- sendEvent({
1777
- type: "progress",
1778
- current: i + 1,
1779
- total,
1780
- percent: Math.round((i + 1) / total * 100),
1781
- message: `Processing ${imageKey.slice(1)}...`
1782
- });
1783
1858
  try {
1784
1859
  let buffer;
1785
1860
  const entry = getMetaEntry(meta, imageKey);
@@ -1839,9 +1914,25 @@ async function handleReprocessStream(request) {
1839
1914
  meta[imageKey] = updatedEntry;
1840
1915
  }
1841
1916
  processed.push(imageKey);
1917
+ sendEvent({
1918
+ type: "progress",
1919
+ current: i + 1,
1920
+ total,
1921
+ processed: processed.length,
1922
+ percent: Math.round((i + 1) / total * 100),
1923
+ message: `Processed ${imageKey.slice(1)}`
1924
+ });
1842
1925
  } catch (error) {
1843
1926
  console.error(`Failed to reprocess ${imageKey}:`, error);
1844
1927
  errors.push(imageKey);
1928
+ sendEvent({
1929
+ type: "progress",
1930
+ current: i + 1,
1931
+ total,
1932
+ processed: processed.length,
1933
+ percent: Math.round((i + 1) / total * 100),
1934
+ message: `Failed: ${imageKey.slice(1)}`
1935
+ });
1845
1936
  }
1846
1937
  }
1847
1938
  sendEvent({ type: "cleanup", message: "Saving metadata..." });
@@ -1915,6 +2006,7 @@ async function handleDownloadStream(request) {
1915
2006
  type: "progress",
1916
2007
  current: i + 1,
1917
2008
  total: imageKeys.length,
2009
+ downloaded: downloaded.length,
1918
2010
  message: `Skipped ${imageKey} (not on cloud)`
1919
2011
  });
1920
2012
  continue;
@@ -2039,20 +2131,29 @@ async function handlePushUpdatesStream(request) {
2039
2131
  const itemPath = paths[i];
2040
2132
  const key = itemPath.startsWith("public/") ? "/" + itemPath.slice(7) : itemPath;
2041
2133
  const entry = meta[key];
2042
- sendEvent({
2043
- type: "progress",
2044
- current: i + 1,
2045
- total,
2046
- percent: Math.round((i + 1) / total * 100),
2047
- currentFile: path7.basename(key)
2048
- });
2049
2134
  if (!entry || entry.u !== 1) {
2050
2135
  skipped.push(key);
2136
+ sendEvent({
2137
+ type: "progress",
2138
+ current: i + 1,
2139
+ total,
2140
+ pushed: pushed.length,
2141
+ percent: Math.round((i + 1) / total * 100),
2142
+ currentFile: path7.basename(key)
2143
+ });
2051
2144
  continue;
2052
2145
  }
2053
2146
  const fileCdnUrl = entry.c !== void 0 ? cdnUrls[entry.c]?.replace(/\/$/, "") : void 0;
2054
2147
  if (!fileCdnUrl || fileCdnUrl !== r2PublicUrl) {
2055
2148
  skipped.push(key);
2149
+ sendEvent({
2150
+ type: "progress",
2151
+ current: i + 1,
2152
+ total,
2153
+ pushed: pushed.length,
2154
+ percent: Math.round((i + 1) / total * 100),
2155
+ currentFile: path7.basename(key)
2156
+ });
2056
2157
  continue;
2057
2158
  }
2058
2159
  try {
@@ -2083,9 +2184,26 @@ async function handlePushUpdatesStream(request) {
2083
2184
  await fs7.unlink(localPath);
2084
2185
  delete entry.u;
2085
2186
  pushed.push(key);
2187
+ sendEvent({
2188
+ type: "progress",
2189
+ current: i + 1,
2190
+ total,
2191
+ pushed: pushed.length,
2192
+ percent: Math.round((i + 1) / total * 100),
2193
+ currentFile: path7.basename(key)
2194
+ });
2086
2195
  } catch (error) {
2087
2196
  console.error(`Failed to push update for ${key}:`, error);
2088
2197
  errors.push(key);
2198
+ sendEvent({
2199
+ type: "progress",
2200
+ current: i + 1,
2201
+ total,
2202
+ pushed: pushed.length,
2203
+ percent: Math.round((i + 1) / total * 100),
2204
+ currentFile: path7.basename(key),
2205
+ message: `Failed: ${path7.basename(key)}`
2206
+ });
2089
2207
  }
2090
2208
  }
2091
2209
  sendEvent({ type: "cleanup", message: "Cleaning up..." });
@@ -2496,18 +2614,19 @@ async function handleImportUrls(request) {
2496
2614
  for (let i = 0; i < urls.length; i++) {
2497
2615
  const url = urls[i].trim();
2498
2616
  if (!url) continue;
2499
- sendEvent({
2500
- type: "progress",
2501
- current: i + 1,
2502
- total,
2503
- percent: Math.round((i + 1) / total * 100),
2504
- currentFile: url
2505
- });
2506
2617
  try {
2507
2618
  const { base, path: path10 } = parseImageUrl(url);
2508
2619
  const existingEntry = getMetaEntry(meta, path10);
2509
2620
  if (existingEntry) {
2510
2621
  skipped.push(path10);
2622
+ sendEvent({
2623
+ type: "progress",
2624
+ current: i + 1,
2625
+ total,
2626
+ imported: added.length,
2627
+ percent: Math.round((i + 1) / total * 100),
2628
+ currentFile: url
2629
+ });
2511
2630
  continue;
2512
2631
  }
2513
2632
  const cdnIndex = getOrAddCdnIndex(meta, base);
@@ -2518,9 +2637,25 @@ async function handleImportUrls(request) {
2518
2637
  c: cdnIndex
2519
2638
  });
2520
2639
  added.push(path10);
2640
+ sendEvent({
2641
+ type: "progress",
2642
+ current: i + 1,
2643
+ total,
2644
+ imported: added.length,
2645
+ percent: Math.round((i + 1) / total * 100),
2646
+ currentFile: url
2647
+ });
2521
2648
  } catch (error) {
2522
2649
  console.error(`Failed to import ${url}:`, error);
2523
2650
  errors.push(url);
2651
+ sendEvent({
2652
+ type: "progress",
2653
+ current: i + 1,
2654
+ total,
2655
+ imported: added.length,
2656
+ percent: Math.round((i + 1) / total * 100),
2657
+ currentFile: url
2658
+ });
2524
2659
  }
2525
2660
  }
2526
2661
  await saveMeta(meta);
@@ -2637,13 +2772,6 @@ async function handleGenerateFavicon(request) {
2637
2772
  });
2638
2773
  for (let i = 0; i < FAVICON_CONFIGS.length; i++) {
2639
2774
  const config = FAVICON_CONFIGS[i];
2640
- sendEvent({
2641
- type: "progress",
2642
- current: i + 1,
2643
- total,
2644
- percent: Math.round((i + 1) / total * 100),
2645
- message: `Generating ${config.name} (${config.size}x${config.size})...`
2646
- });
2647
2775
  try {
2648
2776
  const outputPath = path9.join(outputDir, config.name);
2649
2777
  await sharp5(sourcePath).resize(config.size, config.size, {
@@ -2651,9 +2779,25 @@ async function handleGenerateFavicon(request) {
2651
2779
  position: "center"
2652
2780
  }).png({ quality: 100 }).toFile(outputPath);
2653
2781
  generated.push(config.name);
2782
+ sendEvent({
2783
+ type: "progress",
2784
+ current: i + 1,
2785
+ total,
2786
+ processed: generated.length,
2787
+ percent: Math.round((i + 1) / total * 100),
2788
+ message: `Generated ${config.name}`
2789
+ });
2654
2790
  } catch (error) {
2655
2791
  console.error(`Failed to generate ${config.name}:`, error);
2656
2792
  errors.push(config.name);
2793
+ sendEvent({
2794
+ type: "progress",
2795
+ current: i + 1,
2796
+ total,
2797
+ processed: generated.length,
2798
+ percent: Math.round((i + 1) / total * 100),
2799
+ message: `Failed: ${config.name}`
2800
+ });
2657
2801
  }
2658
2802
  }
2659
2803
  let message = `Generated ${generated.length} favicon${generated.length !== 1 ? "s" : ""} to src/app/.`;