@gallop.software/studio 2.3.48 → 2.3.50

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.
@@ -11,7 +11,7 @@
11
11
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
12
12
  }
13
13
  </style>
14
- <script type="module" crossorigin src="/assets/index-Cxfnf-5i.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-T4g2jTSf.js"></script>
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
@@ -1361,34 +1361,7 @@ async function handleRename(request) {
1361
1361
  } catch {
1362
1362
  }
1363
1363
  if (isInOurR2 && !hasLocalFile && isImage) {
1364
- const buffer = await downloadFromCdn(oldKey);
1365
- await fs6.mkdir(path6.dirname(absoluteNewPath), { recursive: true });
1366
- await fs6.writeFile(absoluteNewPath, buffer);
1367
- if (hasThumbnails) {
1368
- const newThumbPaths = getAllThumbnailPaths(newKey);
1369
- const oldThumbPaths = getAllThumbnailPaths(oldKey);
1370
- for (let i = 0; i < oldThumbPaths.length; i++) {
1371
- try {
1372
- const thumbBuffer = await downloadFromCdn(oldThumbPaths[i]);
1373
- const newThumbLocalPath = getPublicPath(newThumbPaths[i]);
1374
- await fs6.mkdir(path6.dirname(newThumbLocalPath), { recursive: true });
1375
- await fs6.writeFile(newThumbLocalPath, thumbBuffer);
1376
- } catch {
1377
- }
1378
- }
1379
- }
1380
- await deleteFromCdn(oldKey, hasThumbnails);
1381
- await uploadOriginalToCdn(newKey);
1382
- if (hasThumbnails) {
1383
- await uploadToCdn(newKey);
1384
- }
1385
- try {
1386
- await fs6.unlink(absoluteNewPath);
1387
- } catch {
1388
- }
1389
- if (hasThumbnails) {
1390
- await deleteLocalThumbnails(newKey);
1391
- }
1364
+ await moveInCdn(oldKey, newKey, hasThumbnails);
1392
1365
  delete meta[oldKey];
1393
1366
  meta[newKey] = entry;
1394
1367
  await saveMeta(meta);
@@ -1411,13 +1384,7 @@ async function handleRename(request) {
1411
1384
  }
1412
1385
  }
1413
1386
  if (isInOurR2) {
1414
- const buffer = await fs6.readFile(absoluteNewPath);
1415
- await fs6.mkdir(path6.dirname(absoluteNewPath), { recursive: true });
1416
- await deleteFromCdn(oldKey, hasThumbnails);
1417
- await uploadOriginalToCdn(newKey);
1418
- if (hasThumbnails) {
1419
- await uploadToCdn(newKey);
1420
- }
1387
+ await moveInCdn(oldKey, newKey, hasThumbnails);
1421
1388
  try {
1422
1389
  await fs6.unlink(absoluteNewPath);
1423
1390
  } catch {
@@ -1558,19 +1525,9 @@ async function handleRenameStream(request) {
1558
1525
  const isInOurR22 = isInCloud2 && fileCdnUrl2 === publicUrl;
1559
1526
  const hasThumbnails2 = isProcessed(entry2);
1560
1527
  if (isInOurR22) {
1561
- const localFilePath = getPublicPath(newKey2);
1562
- let hasLocalFile = false;
1563
1528
  try {
1564
- await fs6.access(localFilePath);
1565
- hasLocalFile = true;
1566
- } catch {
1567
- }
1568
- if (hasLocalFile) {
1569
- await deleteFromCdn(oldKey2, hasThumbnails2);
1570
- await uploadOriginalToCdn(newKey2);
1571
- if (hasThumbnails2) {
1572
- await uploadToCdn(newKey2);
1573
- }
1529
+ await moveInCdn(oldKey2, newKey2, hasThumbnails2);
1530
+ const localFilePath = getPublicPath(newKey2);
1574
1531
  try {
1575
1532
  await fs6.unlink(localFilePath);
1576
1533
  } catch {
@@ -1578,39 +1535,8 @@ async function handleRenameStream(request) {
1578
1535
  if (hasThumbnails2) {
1579
1536
  await deleteLocalThumbnails(newKey2);
1580
1537
  }
1581
- } else {
1582
- try {
1583
- const buffer = await downloadFromCdn(oldKey2);
1584
- await fs6.mkdir(path6.dirname(localFilePath), { recursive: true });
1585
- await fs6.writeFile(localFilePath, buffer);
1586
- if (hasThumbnails2) {
1587
- const oldThumbPaths = getAllThumbnailPaths(oldKey2);
1588
- const newThumbPaths = getAllThumbnailPaths(newKey2);
1589
- for (let i = 0; i < oldThumbPaths.length; i++) {
1590
- try {
1591
- const thumbBuffer = await downloadFromCdn(oldThumbPaths[i]);
1592
- const newThumbLocalPath = getPublicPath(newThumbPaths[i]);
1593
- await fs6.mkdir(path6.dirname(newThumbLocalPath), { recursive: true });
1594
- await fs6.writeFile(newThumbLocalPath, thumbBuffer);
1595
- } catch {
1596
- }
1597
- }
1598
- }
1599
- await deleteFromCdn(oldKey2, hasThumbnails2);
1600
- await uploadOriginalToCdn(newKey2);
1601
- if (hasThumbnails2) {
1602
- await uploadToCdn(newKey2);
1603
- }
1604
- try {
1605
- await fs6.unlink(localFilePath);
1606
- } catch {
1607
- }
1608
- if (hasThumbnails2) {
1609
- await deleteLocalThumbnails(newKey2);
1610
- }
1611
- } catch (err) {
1612
- console.error(`Failed to re-upload ${oldKey2}:`, err);
1613
- }
1538
+ } catch (err) {
1539
+ console.error(`Failed to rename in CDN ${oldKey2}:`, err);
1614
1540
  }
1615
1541
  }
1616
1542
  delete meta[oldKey2];
@@ -1641,34 +1567,7 @@ async function handleRenameStream(request) {
1641
1567
  const hasThumbnails = entry ? isProcessed(entry) : false;
1642
1568
  sendEvent({ type: "start", total: 1, message: "Renaming file..." });
1643
1569
  if (isInOurR2 && !hasLocalItem && isImagePath) {
1644
- const buffer = await downloadFromCdn(oldKey);
1645
- await fs6.mkdir(path6.dirname(absoluteNewPath), { recursive: true });
1646
- await fs6.writeFile(absoluteNewPath, buffer);
1647
- if (hasThumbnails) {
1648
- const newThumbPaths = getAllThumbnailPaths(newKey);
1649
- const oldThumbPaths = getAllThumbnailPaths(oldKey);
1650
- for (let i = 0; i < oldThumbPaths.length; i++) {
1651
- try {
1652
- const thumbBuffer = await downloadFromCdn(oldThumbPaths[i]);
1653
- const newThumbLocalPath = getPublicPath(newThumbPaths[i]);
1654
- await fs6.mkdir(path6.dirname(newThumbLocalPath), { recursive: true });
1655
- await fs6.writeFile(newThumbLocalPath, thumbBuffer);
1656
- } catch {
1657
- }
1658
- }
1659
- }
1660
- await deleteFromCdn(oldKey, hasThumbnails);
1661
- await uploadOriginalToCdn(newKey);
1662
- if (hasThumbnails) {
1663
- await uploadToCdn(newKey);
1664
- }
1665
- try {
1666
- await fs6.unlink(absoluteNewPath);
1667
- } catch {
1668
- }
1669
- if (hasThumbnails) {
1670
- await deleteLocalThumbnails(newKey);
1671
- }
1570
+ await moveInCdn(oldKey, newKey, hasThumbnails);
1672
1571
  delete meta[oldKey];
1673
1572
  if (entry) meta[newKey] = entry;
1674
1573
  await saveMeta(meta);
@@ -1692,11 +1591,7 @@ async function handleRenameStream(request) {
1692
1591
  }
1693
1592
  }
1694
1593
  if (isInOurR2) {
1695
- await deleteFromCdn(oldKey, hasThumbnails);
1696
- await uploadOriginalToCdn(newKey);
1697
- if (hasThumbnails) {
1698
- await uploadToCdn(newKey);
1699
- }
1594
+ await moveInCdn(oldKey, newKey, hasThumbnails);
1700
1595
  try {
1701
1596
  await fs6.unlink(absoluteNewPath);
1702
1597
  } catch {
@@ -3087,6 +2982,7 @@ async function handleScanStream() {
3087
2982
  } catch {
3088
2983
  }
3089
2984
  sendEvent({ type: "cleanup", message: "Cleaning up empty folders..." });
2985
+ let emptyFoldersDeleted = 0;
3090
2986
  async function cleanEmptyFolders(dir) {
3091
2987
  try {
3092
2988
  const entries = await fs8.readdir(dir, { withFileTypes: true });
@@ -3096,14 +2992,43 @@ async function handleScanStream() {
3096
2992
  const fullPath = path8.join(dir, entry.name);
3097
2993
  if (fullPath === imagesDir) continue;
3098
2994
  await cleanEmptyFolders(fullPath);
3099
- await deleteEmptyFolders(fullPath);
2995
+ try {
2996
+ const subEntries = await fs8.readdir(fullPath);
2997
+ const meaningfulEntries = subEntries.filter((e) => !e.startsWith("."));
2998
+ if (meaningfulEntries.length === 0) {
2999
+ await fs8.rm(fullPath, { recursive: true });
3000
+ emptyFoldersDeleted++;
3001
+ }
3002
+ } catch {
3003
+ }
3100
3004
  }
3101
3005
  } catch {
3102
3006
  }
3103
3007
  }
3104
3008
  await cleanEmptyFolders(getPublicPath());
3009
+ async function cleanImagesEmptyFolders(dir) {
3010
+ try {
3011
+ const entries = await fs8.readdir(dir, { withFileTypes: true });
3012
+ let isEmpty = true;
3013
+ for (const entry of entries) {
3014
+ if (entry.isDirectory()) {
3015
+ const subDirEmpty = await cleanImagesEmptyFolders(path8.join(dir, entry.name));
3016
+ if (!subDirEmpty) isEmpty = false;
3017
+ } else if (!entry.name.startsWith(".")) {
3018
+ isEmpty = false;
3019
+ }
3020
+ }
3021
+ if (isEmpty && dir !== imagesDir) {
3022
+ await fs8.rm(dir, { recursive: true });
3023
+ emptyFoldersDeleted++;
3024
+ }
3025
+ return isEmpty;
3026
+ } catch {
3027
+ return true;
3028
+ }
3029
+ }
3105
3030
  try {
3106
- await cleanupEmptyFoldersRecursive(imagesDir);
3031
+ await cleanImagesEmptyFolders(imagesDir);
3107
3032
  } catch {
3108
3033
  }
3109
3034
  sendEvent({ type: "cleanup", message: "Checking for orphaned entries..." });
@@ -3146,7 +3071,8 @@ async function handleScanStream() {
3146
3071
  renamedFiles: renamed,
3147
3072
  orphanedFiles: orphanedFiles.length > 0 ? orphanedFiles : void 0,
3148
3073
  pendingUpdates: pendingUpdates.length,
3149
- orphanedEntries: orphanedEntries.length
3074
+ orphanedEntries: orphanedEntries.length,
3075
+ emptyFoldersDeleted: emptyFoldersDeleted > 0 ? emptyFoldersDeleted : void 0
3150
3076
  });
3151
3077
  } catch (error) {
3152
3078
  console.error("Scan failed:", error);