@gallop.software/studio 1.5.0 → 1.5.2
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/{StudioUI-MZENRXN3.js → StudioUI-2UVUYHHA.js} +180 -34
- package/dist/StudioUI-2UVUYHHA.js.map +1 -0
- package/dist/{StudioUI-7QQIKNTF.mjs → StudioUI-74IZDKCP.mjs} +174 -28
- package/dist/StudioUI-74IZDKCP.mjs.map +1 -0
- package/dist/{chunk-VQJAJVAQ.mjs → chunk-FOKLOMKO.mjs} +1 -1
- package/dist/chunk-FOKLOMKO.mjs.map +1 -0
- package/dist/{chunk-WOHZ4LYG.js → chunk-X6F6IFY3.js} +1 -1
- package/dist/chunk-X6F6IFY3.js.map +1 -0
- package/dist/handlers/index.js +147 -92
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/index.mjs +114 -59
- package/dist/handlers/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -3
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/StudioUI-7QQIKNTF.mjs.map +0 -1
- package/dist/StudioUI-MZENRXN3.js.map +0 -1
- package/dist/chunk-VQJAJVAQ.mjs.map +0 -1
- package/dist/chunk-WOHZ4LYG.js.map +0 -1
package/dist/handlers/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
getAllThumbnailPaths,
|
|
3
3
|
getThumbnailPath,
|
|
4
4
|
isProcessed
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-FOKLOMKO.mjs";
|
|
6
6
|
|
|
7
7
|
// src/handlers/index.ts
|
|
8
8
|
import { NextResponse as NextResponse6 } from "next/server";
|
|
@@ -343,6 +343,20 @@ function getExistingThumbnails(originalPath, entry) {
|
|
|
343
343
|
}
|
|
344
344
|
return thumbnails;
|
|
345
345
|
}
|
|
346
|
+
function countCloudAndLocal(folderPrefix, fileEntries) {
|
|
347
|
+
let cloudCount = 0;
|
|
348
|
+
let localCount = 0;
|
|
349
|
+
for (const [key, entry] of fileEntries) {
|
|
350
|
+
if (key.startsWith(folderPrefix)) {
|
|
351
|
+
if (entry.c !== void 0) {
|
|
352
|
+
cloudCount++;
|
|
353
|
+
} else {
|
|
354
|
+
localCount++;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return { cloudCount, localCount };
|
|
359
|
+
}
|
|
346
360
|
async function handleList(request) {
|
|
347
361
|
const searchParams = request.nextUrl.searchParams;
|
|
348
362
|
const requestedPath = searchParams.get("path") || "public";
|
|
@@ -462,6 +476,8 @@ async function handleList(request) {
|
|
|
462
476
|
const isImagesFolder = entry.name === "images" && !relativePath;
|
|
463
477
|
const folderPath = relativePath ? `public/${relativePath}/${entry.name}` : `public/${entry.name}`;
|
|
464
478
|
let fileCount = 0;
|
|
479
|
+
let cloudCount = 0;
|
|
480
|
+
let localCount = 0;
|
|
465
481
|
if (isImagesFolder) {
|
|
466
482
|
for (const [key, metaEntry] of fileEntries) {
|
|
467
483
|
if (isProcessed(metaEntry)) {
|
|
@@ -473,12 +489,17 @@ async function handleList(request) {
|
|
|
473
489
|
for (const k of metaKeys) {
|
|
474
490
|
if (k.startsWith(folderPrefix)) fileCount++;
|
|
475
491
|
}
|
|
492
|
+
const counts = countCloudAndLocal(folderPrefix, fileEntries);
|
|
493
|
+
cloudCount = counts.cloudCount;
|
|
494
|
+
localCount = counts.localCount;
|
|
476
495
|
}
|
|
477
496
|
items.push({
|
|
478
497
|
name: entry.name,
|
|
479
498
|
path: folderPath,
|
|
480
499
|
type: "folder",
|
|
481
500
|
fileCount,
|
|
501
|
+
cloudCount,
|
|
502
|
+
localCount,
|
|
482
503
|
isProtected: isImagesFolder
|
|
483
504
|
});
|
|
484
505
|
}
|
|
@@ -521,11 +542,14 @@ async function handleList(request) {
|
|
|
521
542
|
for (const k of metaKeys) {
|
|
522
543
|
if (k.startsWith(folderPrefix)) fileCount++;
|
|
523
544
|
}
|
|
545
|
+
const counts = countCloudAndLocal(folderPrefix, fileEntries);
|
|
524
546
|
items.push({
|
|
525
547
|
name: folderName,
|
|
526
548
|
path: relativePath ? `public/${relativePath}/${folderName}` : `public/${folderName}`,
|
|
527
549
|
type: "folder",
|
|
528
550
|
fileCount,
|
|
551
|
+
cloudCount: counts.cloudCount,
|
|
552
|
+
localCount: counts.localCount,
|
|
529
553
|
isProtected: isInsideImagesFolder
|
|
530
554
|
});
|
|
531
555
|
}
|
|
@@ -2214,74 +2238,105 @@ var FAVICON_CONFIGS = [
|
|
|
2214
2238
|
{ name: "apple-icon.png", size: 180 }
|
|
2215
2239
|
];
|
|
2216
2240
|
async function handleGenerateFavicon(request) {
|
|
2241
|
+
const encoder = new TextEncoder();
|
|
2242
|
+
let imagePath;
|
|
2217
2243
|
try {
|
|
2218
2244
|
const body = await request.json();
|
|
2219
|
-
|
|
2245
|
+
imagePath = body.imagePath;
|
|
2220
2246
|
if (!imagePath) {
|
|
2221
2247
|
return NextResponse5.json({ error: "No image path provided" }, { status: 400 });
|
|
2222
2248
|
}
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2249
|
+
} catch {
|
|
2250
|
+
return NextResponse5.json({ error: "Invalid request body" }, { status: 400 });
|
|
2251
|
+
}
|
|
2252
|
+
const fileName = path9.basename(imagePath).toLowerCase();
|
|
2253
|
+
if (fileName !== "favicon.png" && fileName !== "favicon.jpg") {
|
|
2254
|
+
return NextResponse5.json({
|
|
2255
|
+
error: "Source file must be named favicon.png or favicon.jpg"
|
|
2256
|
+
}, { status: 400 });
|
|
2257
|
+
}
|
|
2258
|
+
const sourcePath = path9.join(process.cwd(), "public", imagePath.replace(/^\//, ""));
|
|
2259
|
+
try {
|
|
2260
|
+
await fs8.access(sourcePath);
|
|
2261
|
+
} catch {
|
|
2262
|
+
return NextResponse5.json({ error: "Source file not found" }, { status: 404 });
|
|
2263
|
+
}
|
|
2264
|
+
let metadata;
|
|
2265
|
+
try {
|
|
2266
|
+
metadata = await sharp5(sourcePath).metadata();
|
|
2267
|
+
} catch {
|
|
2268
|
+
return NextResponse5.json({ error: "Source file is not a valid image" }, { status: 400 });
|
|
2269
|
+
}
|
|
2270
|
+
const outputDir = path9.join(process.cwd(), "src", "app");
|
|
2271
|
+
try {
|
|
2272
|
+
await fs8.access(outputDir);
|
|
2273
|
+
} catch {
|
|
2274
|
+
return NextResponse5.json({
|
|
2275
|
+
error: "Output directory src/app/ not found"
|
|
2276
|
+
}, { status: 500 });
|
|
2277
|
+
}
|
|
2278
|
+
const stream = new ReadableStream({
|
|
2279
|
+
async start(controller) {
|
|
2280
|
+
const sendEvent = (data) => {
|
|
2281
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}
|
|
2282
|
+
|
|
2283
|
+
`));
|
|
2284
|
+
};
|
|
2251
2285
|
try {
|
|
2252
|
-
const
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
size: config.size,
|
|
2260
|
-
success: true
|
|
2286
|
+
const total = FAVICON_CONFIGS.length;
|
|
2287
|
+
const generated = [];
|
|
2288
|
+
const errors = [];
|
|
2289
|
+
sendEvent({
|
|
2290
|
+
type: "start",
|
|
2291
|
+
total,
|
|
2292
|
+
sourceSize: `${metadata.width}x${metadata.height}`
|
|
2261
2293
|
});
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2294
|
+
for (let i = 0; i < FAVICON_CONFIGS.length; i++) {
|
|
2295
|
+
const config = FAVICON_CONFIGS[i];
|
|
2296
|
+
sendEvent({
|
|
2297
|
+
type: "progress",
|
|
2298
|
+
current: i + 1,
|
|
2299
|
+
total,
|
|
2300
|
+
percent: Math.round((i + 1) / total * 100),
|
|
2301
|
+
message: `Generating ${config.name} (${config.size}x${config.size})...`
|
|
2302
|
+
});
|
|
2303
|
+
try {
|
|
2304
|
+
const outputPath = path9.join(outputDir, config.name);
|
|
2305
|
+
await sharp5(sourcePath).resize(config.size, config.size, {
|
|
2306
|
+
fit: "cover",
|
|
2307
|
+
position: "center"
|
|
2308
|
+
}).png({ quality: 100 }).toFile(outputPath);
|
|
2309
|
+
generated.push(config.name);
|
|
2310
|
+
} catch (error) {
|
|
2311
|
+
console.error(`Failed to generate ${config.name}:`, error);
|
|
2312
|
+
errors.push(config.name);
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
let message = `Generated ${generated.length} favicon${generated.length !== 1 ? "s" : ""} to src/app/.`;
|
|
2316
|
+
if (errors.length > 0) {
|
|
2317
|
+
message += ` ${errors.length} failed.`;
|
|
2318
|
+
}
|
|
2319
|
+
sendEvent({
|
|
2320
|
+
type: "complete",
|
|
2321
|
+
processed: generated.length,
|
|
2322
|
+
errors: errors.length,
|
|
2323
|
+
message
|
|
2268
2324
|
});
|
|
2325
|
+
controller.close();
|
|
2326
|
+
} catch (error) {
|
|
2327
|
+
console.error("Favicon generation error:", error);
|
|
2328
|
+
sendEvent({ type: "error", message: "Failed to generate favicons" });
|
|
2329
|
+
controller.close();
|
|
2269
2330
|
}
|
|
2270
2331
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
} catch (error) {
|
|
2280
|
-
console.error("Favicon generation error:", error);
|
|
2281
|
-
return NextResponse5.json({
|
|
2282
|
-
error: "Failed to generate favicons"
|
|
2283
|
-
}, { status: 500 });
|
|
2284
|
-
}
|
|
2332
|
+
});
|
|
2333
|
+
return new Response(stream, {
|
|
2334
|
+
headers: {
|
|
2335
|
+
"Content-Type": "text/event-stream",
|
|
2336
|
+
"Cache-Control": "no-cache",
|
|
2337
|
+
Connection: "keep-alive"
|
|
2338
|
+
}
|
|
2339
|
+
});
|
|
2285
2340
|
}
|
|
2286
2341
|
|
|
2287
2342
|
// src/handlers/index.ts
|