@gallop.software/studio 1.4.6 → 1.5.0
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-TP2Y3ZEL.mjs → StudioUI-7QQIKNTF.mjs} +48 -1
- package/dist/{StudioUI-TP2Y3ZEL.mjs.map → StudioUI-7QQIKNTF.mjs.map} +1 -1
- package/dist/{StudioUI-FROMYB7Y.js → StudioUI-MZENRXN3.js} +48 -1
- package/dist/StudioUI-MZENRXN3.js.map +1 -0
- package/dist/handlers/index.js +91 -8
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/index.mjs +97 -14
- package/dist/handlers/index.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/StudioUI-FROMYB7Y.js.map +0 -1
package/dist/handlers/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "../chunk-VQJAJVAQ.mjs";
|
|
6
6
|
|
|
7
7
|
// src/handlers/index.ts
|
|
8
|
-
import { NextResponse as
|
|
8
|
+
import { NextResponse as NextResponse6 } from "next/server";
|
|
9
9
|
|
|
10
10
|
// src/handlers/list.ts
|
|
11
11
|
import { NextResponse } from "next/server";
|
|
@@ -1450,7 +1450,6 @@ async function handleUnprocessStream(request) {
|
|
|
1450
1450
|
percent: Math.round((i + 1) / total * 100),
|
|
1451
1451
|
message: `Removing thumbnails for ${imageKey.slice(1)}...`
|
|
1452
1452
|
});
|
|
1453
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1454
1453
|
try {
|
|
1455
1454
|
const entry = getMetaEntry(meta, imageKey);
|
|
1456
1455
|
if (!entry) {
|
|
@@ -2086,8 +2085,8 @@ import { encode as encode3 } from "blurhash";
|
|
|
2086
2085
|
function parseImageUrl(url) {
|
|
2087
2086
|
const parsed = new URL(url);
|
|
2088
2087
|
const base = `${parsed.protocol}//${parsed.host}`;
|
|
2089
|
-
const
|
|
2090
|
-
return { base, path:
|
|
2088
|
+
const path10 = parsed.pathname;
|
|
2089
|
+
return { base, path: path10 };
|
|
2091
2090
|
}
|
|
2092
2091
|
async function processRemoteImage(url) {
|
|
2093
2092
|
const response = await fetch(url);
|
|
@@ -2136,20 +2135,20 @@ async function handleImportUrls(request) {
|
|
|
2136
2135
|
currentFile: url
|
|
2137
2136
|
});
|
|
2138
2137
|
try {
|
|
2139
|
-
const { base, path:
|
|
2140
|
-
const existingEntry = getMetaEntry(meta,
|
|
2138
|
+
const { base, path: path10 } = parseImageUrl(url);
|
|
2139
|
+
const existingEntry = getMetaEntry(meta, path10);
|
|
2141
2140
|
if (existingEntry) {
|
|
2142
|
-
skipped.push(
|
|
2141
|
+
skipped.push(path10);
|
|
2143
2142
|
continue;
|
|
2144
2143
|
}
|
|
2145
2144
|
const cdnIndex = getOrAddCdnIndex(meta, base);
|
|
2146
2145
|
const imageData = await processRemoteImage(url);
|
|
2147
|
-
setMetaEntry(meta,
|
|
2146
|
+
setMetaEntry(meta, path10, {
|
|
2148
2147
|
o: imageData.o,
|
|
2149
2148
|
b: imageData.b,
|
|
2150
2149
|
c: cdnIndex
|
|
2151
2150
|
});
|
|
2152
|
-
added.push(
|
|
2151
|
+
added.push(path10);
|
|
2153
2152
|
} catch (error) {
|
|
2154
2153
|
console.error(`Failed to import ${url}:`, error);
|
|
2155
2154
|
errors.push(url);
|
|
@@ -2204,10 +2203,91 @@ async function handleUpdateCdns(request) {
|
|
|
2204
2203
|
}
|
|
2205
2204
|
}
|
|
2206
2205
|
|
|
2206
|
+
// src/handlers/favicon.ts
|
|
2207
|
+
import { NextResponse as NextResponse5 } from "next/server";
|
|
2208
|
+
import sharp5 from "sharp";
|
|
2209
|
+
import path9 from "path";
|
|
2210
|
+
import fs8 from "fs/promises";
|
|
2211
|
+
var FAVICON_CONFIGS = [
|
|
2212
|
+
{ name: "favicon.ico", size: 48 },
|
|
2213
|
+
{ name: "icon.png", size: 32 },
|
|
2214
|
+
{ name: "apple-icon.png", size: 180 }
|
|
2215
|
+
];
|
|
2216
|
+
async function handleGenerateFavicon(request) {
|
|
2217
|
+
try {
|
|
2218
|
+
const body = await request.json();
|
|
2219
|
+
const { imagePath } = body;
|
|
2220
|
+
if (!imagePath) {
|
|
2221
|
+
return NextResponse5.json({ error: "No image path provided" }, { status: 400 });
|
|
2222
|
+
}
|
|
2223
|
+
const fileName = path9.basename(imagePath).toLowerCase();
|
|
2224
|
+
if (fileName !== "favicon.png" && fileName !== "favicon.jpg") {
|
|
2225
|
+
return NextResponse5.json({
|
|
2226
|
+
error: "Source file must be named favicon.png or favicon.jpg"
|
|
2227
|
+
}, { status: 400 });
|
|
2228
|
+
}
|
|
2229
|
+
const sourcePath = path9.join(process.cwd(), "public", imagePath.replace(/^\//, ""));
|
|
2230
|
+
try {
|
|
2231
|
+
await fs8.access(sourcePath);
|
|
2232
|
+
} catch {
|
|
2233
|
+
return NextResponse5.json({ error: "Source file not found" }, { status: 404 });
|
|
2234
|
+
}
|
|
2235
|
+
let metadata;
|
|
2236
|
+
try {
|
|
2237
|
+
metadata = await sharp5(sourcePath).metadata();
|
|
2238
|
+
} catch {
|
|
2239
|
+
return NextResponse5.json({ error: "Source file is not a valid image" }, { status: 400 });
|
|
2240
|
+
}
|
|
2241
|
+
const outputDir = path9.join(process.cwd(), "src", "app");
|
|
2242
|
+
try {
|
|
2243
|
+
await fs8.access(outputDir);
|
|
2244
|
+
} catch {
|
|
2245
|
+
return NextResponse5.json({
|
|
2246
|
+
error: "Output directory src/app/ not found"
|
|
2247
|
+
}, { status: 500 });
|
|
2248
|
+
}
|
|
2249
|
+
const results = [];
|
|
2250
|
+
for (const config of FAVICON_CONFIGS) {
|
|
2251
|
+
try {
|
|
2252
|
+
const outputPath = path9.join(outputDir, config.name);
|
|
2253
|
+
await sharp5(sourcePath).resize(config.size, config.size, {
|
|
2254
|
+
fit: "cover",
|
|
2255
|
+
position: "center"
|
|
2256
|
+
}).png({ quality: 100 }).toFile(outputPath);
|
|
2257
|
+
results.push({
|
|
2258
|
+
name: config.name,
|
|
2259
|
+
size: config.size,
|
|
2260
|
+
success: true
|
|
2261
|
+
});
|
|
2262
|
+
} catch (error) {
|
|
2263
|
+
results.push({
|
|
2264
|
+
name: config.name,
|
|
2265
|
+
size: config.size,
|
|
2266
|
+
success: false,
|
|
2267
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
const successCount = results.filter((r) => r.success).length;
|
|
2272
|
+
const failCount = results.filter((r) => !r.success).length;
|
|
2273
|
+
return NextResponse5.json({
|
|
2274
|
+
success: failCount === 0,
|
|
2275
|
+
message: `Generated ${successCount} favicon${successCount !== 1 ? "s" : ""}${failCount > 0 ? `, ${failCount} failed` : ""}.`,
|
|
2276
|
+
sourceSize: `${metadata.width}x${metadata.height}`,
|
|
2277
|
+
results
|
|
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
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2207
2287
|
// src/handlers/index.ts
|
|
2208
2288
|
async function GET(request) {
|
|
2209
2289
|
if (process.env.NODE_ENV !== "development") {
|
|
2210
|
-
return
|
|
2290
|
+
return NextResponse6.json({ error: "Not available in production" }, { status: 403 });
|
|
2211
2291
|
}
|
|
2212
2292
|
const pathname = request.nextUrl.pathname;
|
|
2213
2293
|
const route = pathname.replace(/^\/api\/studio\/?/, "");
|
|
@@ -2229,11 +2309,11 @@ async function GET(request) {
|
|
|
2229
2309
|
if (route === "cdns") {
|
|
2230
2310
|
return handleGetCdns();
|
|
2231
2311
|
}
|
|
2232
|
-
return
|
|
2312
|
+
return NextResponse6.json({ error: "Not found" }, { status: 404 });
|
|
2233
2313
|
}
|
|
2234
2314
|
async function POST(request) {
|
|
2235
2315
|
if (process.env.NODE_ENV !== "development") {
|
|
2236
|
-
return
|
|
2316
|
+
return NextResponse6.json({ error: "Not available in production" }, { status: 403 });
|
|
2237
2317
|
}
|
|
2238
2318
|
const pathname = request.nextUrl.pathname;
|
|
2239
2319
|
const route = pathname.replace(/^\/api\/studio\/?/, "");
|
|
@@ -2279,11 +2359,14 @@ async function POST(request) {
|
|
|
2279
2359
|
if (route === "cdns") {
|
|
2280
2360
|
return handleUpdateCdns(request);
|
|
2281
2361
|
}
|
|
2282
|
-
|
|
2362
|
+
if (route === "generate-favicon") {
|
|
2363
|
+
return handleGenerateFavicon(request);
|
|
2364
|
+
}
|
|
2365
|
+
return NextResponse6.json({ error: "Not found" }, { status: 404 });
|
|
2283
2366
|
}
|
|
2284
2367
|
async function DELETE(request) {
|
|
2285
2368
|
if (process.env.NODE_ENV !== "development") {
|
|
2286
|
-
return
|
|
2369
|
+
return NextResponse6.json({ error: "Not available in production" }, { status: 403 });
|
|
2287
2370
|
}
|
|
2288
2371
|
return handleDelete(request);
|
|
2289
2372
|
}
|