@gallop.software/studio 2.3.27 → 2.3.29

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-5mrVXxKd.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-CyPSLD3Q.js"></script>
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
@@ -1272,6 +1272,7 @@ async function handleCreateFolder(request) {
1272
1272
  }
1273
1273
  }
1274
1274
  async function handleRename(request) {
1275
+ const publicUrl = process.env.CLOUDFLARE_R2_PUBLIC_URL?.replace(/\/$/, "");
1275
1276
  try {
1276
1277
  const { oldPath, newName } = await request.json();
1277
1278
  if (!oldPath || !newName) {
@@ -1282,48 +1283,109 @@ async function handleRename(request) {
1282
1283
  if (!absoluteOldPath.startsWith(getPublicPath())) {
1283
1284
  return jsonResponse({ error: "Invalid path" }, { status: 400 });
1284
1285
  }
1286
+ const oldRelativePath = safePath.replace(/^public\//, "");
1287
+ const oldKey = "/" + oldRelativePath;
1288
+ const isImage = isImageFile(path6.basename(oldPath));
1289
+ const meta = await loadMeta();
1290
+ const cdnUrls = getCdnUrls(meta);
1291
+ const entry = meta[oldKey];
1292
+ const isInCloud = entry?.c !== void 0;
1293
+ const fileCdnUrl = isInCloud && entry.c !== void 0 ? cdnUrls[entry.c] : void 0;
1294
+ const isInOurR2 = isInCloud && fileCdnUrl === publicUrl;
1295
+ const hasThumbnails = entry ? isProcessed(entry) : false;
1296
+ let hasLocalFile = false;
1297
+ let isFile = true;
1285
1298
  try {
1286
- await fs6.access(absoluteOldPath);
1299
+ const stats = await fs6.stat(absoluteOldPath);
1300
+ hasLocalFile = true;
1301
+ isFile = stats.isFile();
1287
1302
  } catch {
1288
- return jsonResponse({ error: "File or folder not found" }, { status: 404 });
1303
+ if (!isInCloud) {
1304
+ return jsonResponse({ error: "File or folder not found" }, { status: 404 });
1305
+ }
1289
1306
  }
1290
- const stats = await fs6.stat(absoluteOldPath);
1291
- const isFile = stats.isFile();
1292
- const isImage = isFile && isImageFile(path6.basename(oldPath));
1293
1307
  const sanitizedName = isFile ? slugifyFilename(newName) : slugifyFolderName(newName);
1294
1308
  if (!sanitizedName) {
1295
1309
  return jsonResponse({ error: "Invalid name" }, { status: 400 });
1296
1310
  }
1297
1311
  const parentDir = path6.dirname(absoluteOldPath);
1298
1312
  const absoluteNewPath = path6.join(parentDir, sanitizedName);
1313
+ const newRelativePath = path6.join(path6.dirname(oldRelativePath), sanitizedName);
1314
+ const newKey = "/" + newRelativePath;
1315
+ if (meta[newKey]) {
1316
+ return jsonResponse({ error: "An item with this name already exists" }, { status: 400 });
1317
+ }
1299
1318
  try {
1300
1319
  await fs6.access(absoluteNewPath);
1301
1320
  return jsonResponse({ error: "An item with this name already exists" }, { status: 400 });
1302
1321
  } catch {
1303
1322
  }
1304
- await fs6.rename(absoluteOldPath, absoluteNewPath);
1305
- if (isImage) {
1306
- const meta = await loadMeta();
1307
- const oldRelativePath = safePath.replace(/^public\//, "");
1308
- const newRelativePath = path6.join(path6.dirname(oldRelativePath), sanitizedName);
1309
- const oldKey = "/" + oldRelativePath;
1310
- const newKey = "/" + newRelativePath;
1311
- if (meta[oldKey]) {
1312
- const entry = meta[oldKey];
1313
- const oldThumbPaths = getAllThumbnailPaths(oldKey);
1323
+ if (isInOurR2 && !hasLocalFile && isImage) {
1324
+ const buffer = await downloadFromCdn(oldKey);
1325
+ await fs6.mkdir(path6.dirname(absoluteNewPath), { recursive: true });
1326
+ await fs6.writeFile(absoluteNewPath, buffer);
1327
+ if (hasThumbnails) {
1314
1328
  const newThumbPaths = getAllThumbnailPaths(newKey);
1329
+ const oldThumbPaths = getAllThumbnailPaths(oldKey);
1315
1330
  for (let i = 0; i < oldThumbPaths.length; i++) {
1316
- const oldThumbPath = getPublicPath(oldThumbPaths[i]);
1317
- const newThumbPath = getPublicPath(newThumbPaths[i]);
1318
- await fs6.mkdir(path6.dirname(newThumbPath), { recursive: true });
1319
1331
  try {
1320
- await fs6.rename(oldThumbPath, newThumbPath);
1332
+ const thumbBuffer = await downloadFromCdn(oldThumbPaths[i]);
1333
+ const newThumbLocalPath = getPublicPath(newThumbPaths[i]);
1334
+ await fs6.mkdir(path6.dirname(newThumbLocalPath), { recursive: true });
1335
+ await fs6.writeFile(newThumbLocalPath, thumbBuffer);
1321
1336
  } catch {
1322
1337
  }
1323
1338
  }
1324
- delete meta[oldKey];
1325
- meta[newKey] = entry;
1326
1339
  }
1340
+ await deleteFromCdn(oldKey, hasThumbnails);
1341
+ await uploadOriginalToCdn(newKey);
1342
+ if (hasThumbnails) {
1343
+ await uploadToCdn(newKey);
1344
+ }
1345
+ try {
1346
+ await fs6.unlink(absoluteNewPath);
1347
+ } catch {
1348
+ }
1349
+ if (hasThumbnails) {
1350
+ await deleteLocalThumbnails(newKey);
1351
+ }
1352
+ delete meta[oldKey];
1353
+ meta[newKey] = entry;
1354
+ await saveMeta(meta);
1355
+ const newPath2 = path6.join(path6.dirname(safePath), sanitizedName);
1356
+ return jsonResponse({ success: true, newPath: newPath2 });
1357
+ }
1358
+ if (hasLocalFile) {
1359
+ await fs6.rename(absoluteOldPath, absoluteNewPath);
1360
+ }
1361
+ if (isImage && entry) {
1362
+ const oldThumbPaths = getAllThumbnailPaths(oldKey);
1363
+ const newThumbPaths = getAllThumbnailPaths(newKey);
1364
+ for (let i = 0; i < oldThumbPaths.length; i++) {
1365
+ const oldThumbPath = getPublicPath(oldThumbPaths[i]);
1366
+ const newThumbPath = getPublicPath(newThumbPaths[i]);
1367
+ await fs6.mkdir(path6.dirname(newThumbPath), { recursive: true });
1368
+ try {
1369
+ await fs6.rename(oldThumbPath, newThumbPath);
1370
+ } catch {
1371
+ }
1372
+ }
1373
+ if (isInOurR2) {
1374
+ const buffer = await fs6.readFile(absoluteNewPath);
1375
+ await fs6.mkdir(path6.dirname(absoluteNewPath), { recursive: true });
1376
+ await deleteFromCdn(oldKey, hasThumbnails);
1377
+ await uploadOriginalToCdn(newKey);
1378
+ if (hasThumbnails) {
1379
+ await uploadToCdn(newKey);
1380
+ }
1381
+ try {
1382
+ await fs6.unlink(absoluteNewPath);
1383
+ } catch {
1384
+ }
1385
+ await deleteLocalThumbnails(newKey);
1386
+ }
1387
+ delete meta[oldKey];
1388
+ meta[newKey] = entry;
1327
1389
  await saveMeta(meta);
1328
1390
  }
1329
1391
  const newPath = path6.join(path6.dirname(safePath), sanitizedName);