@gallop.software/studio 1.4.7 → 1.5.1

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.
@@ -2085,8 +2085,8 @@ async function handleDeleteOrphans(request) {
2085
2085
  function parseImageUrl(url) {
2086
2086
  const parsed = new URL(url);
2087
2087
  const base = `${parsed.protocol}//${parsed.host}`;
2088
- const path9 = parsed.pathname;
2089
- return { base, path: path9 };
2088
+ const path10 = parsed.pathname;
2089
+ return { base, path: path10 };
2090
2090
  }
2091
2091
  async function processRemoteImage(url) {
2092
2092
  const response = await fetch(url);
@@ -2135,20 +2135,20 @@ async function handleImportUrls(request) {
2135
2135
  currentFile: url
2136
2136
  });
2137
2137
  try {
2138
- const { base, path: path9 } = parseImageUrl(url);
2139
- const existingEntry = getMetaEntry(meta, path9);
2138
+ const { base, path: path10 } = parseImageUrl(url);
2139
+ const existingEntry = getMetaEntry(meta, path10);
2140
2140
  if (existingEntry) {
2141
- skipped.push(path9);
2141
+ skipped.push(path10);
2142
2142
  continue;
2143
2143
  }
2144
2144
  const cdnIndex = getOrAddCdnIndex(meta, base);
2145
2145
  const imageData = await processRemoteImage(url);
2146
- setMetaEntry(meta, path9, {
2146
+ setMetaEntry(meta, path10, {
2147
2147
  o: imageData.o,
2148
2148
  b: imageData.b,
2149
2149
  c: cdnIndex
2150
2150
  });
2151
- added.push(path9);
2151
+ added.push(path10);
2152
2152
  } catch (error) {
2153
2153
  console.error(`Failed to import ${url}:`, error);
2154
2154
  errors.push(url);
@@ -2203,6 +2203,118 @@ async function handleUpdateCdns(request) {
2203
2203
  }
2204
2204
  }
2205
2205
 
2206
+ // src/handlers/favicon.ts
2207
+
2208
+
2209
+
2210
+ var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_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
+ const encoder = new TextEncoder();
2218
+ let imagePath;
2219
+ try {
2220
+ const body = await request.json();
2221
+ imagePath = body.imagePath;
2222
+ if (!imagePath) {
2223
+ return _server.NextResponse.json({ error: "No image path provided" }, { status: 400 });
2224
+ }
2225
+ } catch (e45) {
2226
+ return _server.NextResponse.json({ error: "Invalid request body" }, { status: 400 });
2227
+ }
2228
+ const fileName = _path2.default.basename(imagePath).toLowerCase();
2229
+ if (fileName !== "favicon.png" && fileName !== "favicon.jpg") {
2230
+ return _server.NextResponse.json({
2231
+ error: "Source file must be named favicon.png or favicon.jpg"
2232
+ }, { status: 400 });
2233
+ }
2234
+ const sourcePath = _path2.default.join(process.cwd(), "public", imagePath.replace(/^\//, ""));
2235
+ try {
2236
+ await _promises2.default.access(sourcePath);
2237
+ } catch (e46) {
2238
+ return _server.NextResponse.json({ error: "Source file not found" }, { status: 404 });
2239
+ }
2240
+ let metadata;
2241
+ try {
2242
+ metadata = await _sharp2.default.call(void 0, sourcePath).metadata();
2243
+ } catch (e47) {
2244
+ return _server.NextResponse.json({ error: "Source file is not a valid image" }, { status: 400 });
2245
+ }
2246
+ const outputDir = _path2.default.join(process.cwd(), "src", "app");
2247
+ try {
2248
+ await _promises2.default.access(outputDir);
2249
+ } catch (e48) {
2250
+ return _server.NextResponse.json({
2251
+ error: "Output directory src/app/ not found"
2252
+ }, { status: 500 });
2253
+ }
2254
+ const stream = new ReadableStream({
2255
+ async start(controller) {
2256
+ const sendEvent = (data) => {
2257
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}
2258
+
2259
+ `));
2260
+ };
2261
+ try {
2262
+ const total = FAVICON_CONFIGS.length;
2263
+ const generated = [];
2264
+ const errors = [];
2265
+ sendEvent({
2266
+ type: "start",
2267
+ total,
2268
+ sourceSize: `${metadata.width}x${metadata.height}`
2269
+ });
2270
+ for (let i = 0; i < FAVICON_CONFIGS.length; i++) {
2271
+ const config = FAVICON_CONFIGS[i];
2272
+ sendEvent({
2273
+ type: "progress",
2274
+ current: i + 1,
2275
+ total,
2276
+ percent: Math.round((i + 1) / total * 100),
2277
+ message: `Generating ${config.name} (${config.size}x${config.size})...`
2278
+ });
2279
+ try {
2280
+ const outputPath = _path2.default.join(outputDir, config.name);
2281
+ await _sharp2.default.call(void 0, sourcePath).resize(config.size, config.size, {
2282
+ fit: "cover",
2283
+ position: "center"
2284
+ }).png({ quality: 100 }).toFile(outputPath);
2285
+ generated.push(config.name);
2286
+ } catch (error) {
2287
+ console.error(`Failed to generate ${config.name}:`, error);
2288
+ errors.push(config.name);
2289
+ }
2290
+ }
2291
+ let message = `Generated ${generated.length} favicon${generated.length !== 1 ? "s" : ""} to src/app/.`;
2292
+ if (errors.length > 0) {
2293
+ message += ` ${errors.length} failed.`;
2294
+ }
2295
+ sendEvent({
2296
+ type: "complete",
2297
+ processed: generated.length,
2298
+ errors: errors.length,
2299
+ message
2300
+ });
2301
+ controller.close();
2302
+ } catch (error) {
2303
+ console.error("Favicon generation error:", error);
2304
+ sendEvent({ type: "error", message: "Failed to generate favicons" });
2305
+ controller.close();
2306
+ }
2307
+ }
2308
+ });
2309
+ return new Response(stream, {
2310
+ headers: {
2311
+ "Content-Type": "text/event-stream",
2312
+ "Cache-Control": "no-cache",
2313
+ Connection: "keep-alive"
2314
+ }
2315
+ });
2316
+ }
2317
+
2206
2318
  // src/handlers/index.ts
2207
2319
  async function GET(request) {
2208
2320
  if (process.env.NODE_ENV !== "development") {
@@ -2278,6 +2390,9 @@ async function POST(request) {
2278
2390
  if (route === "cdns") {
2279
2391
  return handleUpdateCdns(request);
2280
2392
  }
2393
+ if (route === "generate-favicon") {
2394
+ return handleGenerateFavicon(request);
2395
+ }
2281
2396
  return _server.NextResponse.json({ error: "Not found" }, { status: 404 });
2282
2397
  }
2283
2398
  async function DELETE(request) {