@gallop.software/studio 2.3.45 → 2.3.47
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 +50 -99
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -208,7 +208,7 @@ async function processImage(buffer, imageKey) {
|
|
|
208
208
|
|
|
209
209
|
// src/handlers/utils/cdn.ts
|
|
210
210
|
import { promises as fs3 } from "fs";
|
|
211
|
-
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand } from "@aws-sdk/client-s3";
|
|
211
|
+
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, CopyObjectCommand } from "@aws-sdk/client-s3";
|
|
212
212
|
|
|
213
213
|
// src/types.ts
|
|
214
214
|
function getThumbnailPath(originalPath, size) {
|
|
@@ -400,6 +400,34 @@ async function deleteOriginalFromCdn(imageKey) {
|
|
|
400
400
|
} catch {
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
|
+
async function copyInCdn(oldKey, newKey) {
|
|
404
|
+
const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME;
|
|
405
|
+
if (!bucketName) throw new Error("R2 bucket not configured");
|
|
406
|
+
const r2 = getR2Client();
|
|
407
|
+
const oldKeyClean = oldKey.replace(/^\//, "");
|
|
408
|
+
const newKeyClean = newKey.replace(/^\//, "");
|
|
409
|
+
await r2.send(
|
|
410
|
+
new CopyObjectCommand({
|
|
411
|
+
Bucket: bucketName,
|
|
412
|
+
CopySource: `${bucketName}/${oldKeyClean}`,
|
|
413
|
+
Key: newKeyClean
|
|
414
|
+
})
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
async function moveInCdn(oldKey, newKey, hasThumbnails) {
|
|
418
|
+
await copyInCdn(oldKey, newKey);
|
|
419
|
+
if (hasThumbnails) {
|
|
420
|
+
const oldThumbPaths = getAllThumbnailPaths(oldKey);
|
|
421
|
+
const newThumbPaths = getAllThumbnailPaths(newKey);
|
|
422
|
+
for (let i = 0; i < oldThumbPaths.length; i++) {
|
|
423
|
+
try {
|
|
424
|
+
await copyInCdn(oldThumbPaths[i], newThumbPaths[i]);
|
|
425
|
+
} catch {
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
await deleteFromCdn(oldKey, hasThumbnails);
|
|
430
|
+
}
|
|
403
431
|
|
|
404
432
|
// src/handlers/utils/response.ts
|
|
405
433
|
function jsonResponse(data, init) {
|
|
@@ -1808,43 +1836,20 @@ async function handleMoveStream(request) {
|
|
|
1808
1836
|
const itemCdnUrl = isItemInCloud ? cdnUrls[itemEntry.c] : void 0;
|
|
1809
1837
|
const isItemInR2 = isItemInCloud && itemCdnUrl === r2PublicUrl;
|
|
1810
1838
|
const itemHasThumbnails = isProcessed(itemEntry);
|
|
1839
|
+
let vItemMoved = false;
|
|
1811
1840
|
if (isItemInR2) {
|
|
1812
1841
|
try {
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
await fs6.mkdir(path6.dirname(itemLocalPath), { recursive: true });
|
|
1816
|
-
await fs6.writeFile(itemLocalPath, buffer);
|
|
1817
|
-
if (itemHasThumbnails) {
|
|
1818
|
-
const oldThumbPaths = getAllThumbnailPaths(vItem.oldKey);
|
|
1819
|
-
const newThumbPaths = getAllThumbnailPaths(vItem.newKey);
|
|
1820
|
-
for (let t = 0; t < oldThumbPaths.length; t++) {
|
|
1821
|
-
try {
|
|
1822
|
-
const thumbBuffer = await downloadFromCdn(oldThumbPaths[t]);
|
|
1823
|
-
const newThumbLocalPath = getPublicPath(newThumbPaths[t]);
|
|
1824
|
-
await fs6.mkdir(path6.dirname(newThumbLocalPath), { recursive: true });
|
|
1825
|
-
await fs6.writeFile(newThumbLocalPath, thumbBuffer);
|
|
1826
|
-
} catch {
|
|
1827
|
-
}
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
await deleteFromCdn(vItem.oldKey, itemHasThumbnails);
|
|
1831
|
-
await uploadOriginalToCdn(vItem.newKey);
|
|
1832
|
-
if (itemHasThumbnails) {
|
|
1833
|
-
await uploadToCdn(vItem.newKey);
|
|
1834
|
-
}
|
|
1835
|
-
try {
|
|
1836
|
-
await fs6.unlink(itemLocalPath);
|
|
1837
|
-
} catch {
|
|
1838
|
-
}
|
|
1839
|
-
if (itemHasThumbnails) {
|
|
1840
|
-
await deleteLocalThumbnails(vItem.newKey);
|
|
1841
|
-
}
|
|
1842
|
+
await moveInCdn(vItem.oldKey, vItem.newKey, itemHasThumbnails);
|
|
1843
|
+
vItemMoved = true;
|
|
1842
1844
|
} catch (err) {
|
|
1843
1845
|
console.error(`Failed to move cloud item ${vItem.oldKey}:`, err);
|
|
1846
|
+
delete meta[vItem.oldKey];
|
|
1844
1847
|
}
|
|
1845
1848
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1849
|
+
if (vItemMoved) {
|
|
1850
|
+
delete meta[vItem.oldKey];
|
|
1851
|
+
meta[vItem.newKey] = itemEntry;
|
|
1852
|
+
}
|
|
1848
1853
|
processedFiles++;
|
|
1849
1854
|
sendEvent({
|
|
1850
1855
|
type: "progress",
|
|
@@ -1907,37 +1912,11 @@ async function handleMoveStream(request) {
|
|
|
1907
1912
|
currentFile: itemName
|
|
1908
1913
|
});
|
|
1909
1914
|
} else if (isPushedToR2 && isImage) {
|
|
1910
|
-
|
|
1911
|
-
await fs6.mkdir(path6.dirname(newAbsolutePath), { recursive: true });
|
|
1912
|
-
await fs6.writeFile(newAbsolutePath, buffer);
|
|
1913
|
-
let newEntry = {
|
|
1914
|
-
o: entry?.o,
|
|
1915
|
-
b: entry?.b
|
|
1916
|
-
};
|
|
1917
|
-
if (hasProcessedThumbnails) {
|
|
1918
|
-
const processedEntry = await processImage(buffer, newKey);
|
|
1919
|
-
newEntry = { ...newEntry, ...processedEntry };
|
|
1920
|
-
}
|
|
1921
|
-
await uploadOriginalToCdn(newKey);
|
|
1922
|
-
if (hasProcessedThumbnails) {
|
|
1923
|
-
await uploadToCdn(newKey);
|
|
1924
|
-
}
|
|
1925
|
-
await deleteFromCdn(oldKey, hasProcessedThumbnails);
|
|
1926
|
-
try {
|
|
1927
|
-
await fs6.unlink(newAbsolutePath);
|
|
1928
|
-
} catch {
|
|
1929
|
-
}
|
|
1930
|
-
if (hasProcessedThumbnails) {
|
|
1931
|
-
await deleteLocalThumbnails(newKey);
|
|
1932
|
-
}
|
|
1933
|
-
await deleteEmptyFolders(path6.dirname(newAbsolutePath));
|
|
1934
|
-
if (hasProcessedThumbnails) {
|
|
1935
|
-
const newThumbRelPath = newKey.slice(1);
|
|
1936
|
-
await deleteEmptyFolders(path6.join(getPublicPath("images"), newThumbRelPath));
|
|
1937
|
-
}
|
|
1938
|
-
newEntry.c = entry?.c;
|
|
1915
|
+
await moveInCdn(oldKey, newKey, hasProcessedThumbnails);
|
|
1939
1916
|
delete meta[oldKey];
|
|
1940
|
-
|
|
1917
|
+
if (entry) {
|
|
1918
|
+
meta[newKey] = entry;
|
|
1919
|
+
}
|
|
1941
1920
|
moved.push(itemPath);
|
|
1942
1921
|
processedFiles++;
|
|
1943
1922
|
sendEvent({
|
|
@@ -2095,11 +2074,7 @@ async function handleMoveStream(request) {
|
|
|
2095
2074
|
const fileIsInR2 = fileIsInCloud && fileCdnUrl2 === r2PublicUrl;
|
|
2096
2075
|
const fileHasThumbs = isProcessed(fileEntry);
|
|
2097
2076
|
if (fileIsInR2) {
|
|
2098
|
-
await
|
|
2099
|
-
await uploadOriginalToCdn(fileNewKey);
|
|
2100
|
-
if (fileHasThumbs) {
|
|
2101
|
-
await uploadToCdn(fileNewKey);
|
|
2102
|
-
}
|
|
2077
|
+
await moveInCdn(fileOldKey, fileNewKey, fileHasThumbs);
|
|
2103
2078
|
}
|
|
2104
2079
|
delete meta[fileOldKey];
|
|
2105
2080
|
meta[fileNewKey] = fileEntry;
|
|
@@ -2120,44 +2095,20 @@ async function handleMoveStream(request) {
|
|
|
2120
2095
|
const cloudCdnUrl = cloudIsInCloud ? cdnUrls[cloudEntry.c] : void 0;
|
|
2121
2096
|
const cloudIsInR2 = cloudIsInCloud && cloudCdnUrl === r2PublicUrl;
|
|
2122
2097
|
const cloudHasThumbs = isProcessed(cloudEntry);
|
|
2098
|
+
let cloudFileMoved = false;
|
|
2123
2099
|
if (cloudIsInR2) {
|
|
2124
2100
|
try {
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
await fs6.mkdir(path6.dirname(cloudLocalPath), { recursive: true });
|
|
2128
|
-
await fs6.writeFile(cloudLocalPath, buffer);
|
|
2129
|
-
if (cloudHasThumbs) {
|
|
2130
|
-
const oldThumbPaths = getAllThumbnailPaths(cloudFile.oldKey);
|
|
2131
|
-
const newThumbPaths = getAllThumbnailPaths(cloudFile.newKey);
|
|
2132
|
-
for (let t = 0; t < oldThumbPaths.length; t++) {
|
|
2133
|
-
try {
|
|
2134
|
-
const thumbBuffer = await downloadFromCdn(oldThumbPaths[t]);
|
|
2135
|
-
const newThumbLocalPath = getPublicPath(newThumbPaths[t]);
|
|
2136
|
-
await fs6.mkdir(path6.dirname(newThumbLocalPath), { recursive: true });
|
|
2137
|
-
await fs6.writeFile(newThumbLocalPath, thumbBuffer);
|
|
2138
|
-
} catch {
|
|
2139
|
-
}
|
|
2140
|
-
}
|
|
2141
|
-
}
|
|
2142
|
-
await deleteFromCdn(cloudFile.oldKey, cloudHasThumbs);
|
|
2143
|
-
await uploadOriginalToCdn(cloudFile.newKey);
|
|
2144
|
-
if (cloudHasThumbs) {
|
|
2145
|
-
await uploadToCdn(cloudFile.newKey);
|
|
2146
|
-
}
|
|
2147
|
-
try {
|
|
2148
|
-
await fs6.unlink(cloudLocalPath);
|
|
2149
|
-
} catch {
|
|
2150
|
-
}
|
|
2151
|
-
if (cloudHasThumbs) {
|
|
2152
|
-
await deleteLocalThumbnails(cloudFile.newKey);
|
|
2153
|
-
}
|
|
2154
|
-
await deleteEmptyFolders(path6.dirname(cloudLocalPath));
|
|
2101
|
+
await moveInCdn(cloudFile.oldKey, cloudFile.newKey, cloudHasThumbs);
|
|
2102
|
+
cloudFileMoved = true;
|
|
2155
2103
|
} catch (err) {
|
|
2156
2104
|
console.error(`Failed to move cloud file ${cloudFile.oldKey}:`, err);
|
|
2105
|
+
delete meta[cloudFile.oldKey];
|
|
2157
2106
|
}
|
|
2158
2107
|
}
|
|
2159
|
-
|
|
2160
|
-
|
|
2108
|
+
if (cloudFileMoved) {
|
|
2109
|
+
delete meta[cloudFile.oldKey];
|
|
2110
|
+
meta[cloudFile.newKey] = cloudEntry;
|
|
2111
|
+
}
|
|
2161
2112
|
processedFiles++;
|
|
2162
2113
|
sendEvent({
|
|
2163
2114
|
type: "progress",
|