@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.
- package/dist/server/index.js +186 -42
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -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/.`;
|