@gallop.software/studio 0.1.80 → 0.1.82

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/handlers/index.ts","../../src/handlers/list.ts","../../src/handlers/utils/meta.ts","../../src/handlers/utils/files.ts","../../src/handlers/utils/thumbnails.ts","../../src/handlers/utils/cdn.ts","../../src/handlers/files.ts","../../src/handlers/images.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server'\n\n// List handlers\nimport { handleList, handleSearch, handleListFolders, handleCountImages, handleFolderImages } from './list'\n\n// File handlers\nimport { handleUpload, handleDelete, handleCreateFolder, handleRename, handleMove } from './files'\n\n// Image handlers\nimport { handleSync, handleReprocess, handleProcessAllStream } from './images'\n\n/**\n * Unified GET handler for all Studio API routes\n */\nexport async function GET(request: NextRequest) {\n if (process.env.NODE_ENV !== 'development') {\n return NextResponse.json({ error: 'Not available in production' }, { status: 403 })\n }\n\n const pathname = request.nextUrl.pathname\n const route = pathname.replace(/^\\/api\\/studio\\/?/, '')\n\n // Route: /api/studio/list-folders (must come before 'list' check)\n if (route === 'list-folders') {\n return handleListFolders()\n }\n\n // Route: /api/studio/list\n if (route === 'list' || route.startsWith('list')) {\n return handleList(request)\n }\n\n // Route: /api/studio/count-images\n if (route === 'count-images') {\n return handleCountImages()\n }\n\n // Route: /api/studio/folder-images\n if (route === 'folder-images') {\n return handleFolderImages(request)\n }\n\n // Route: /api/studio/search\n if (route === 'search') {\n return handleSearch(request)\n }\n\n return NextResponse.json({ error: 'Not found' }, { status: 404 })\n}\n\n/**\n * Unified POST handler for all Studio API routes\n */\nexport async function POST(request: NextRequest) {\n if (process.env.NODE_ENV !== 'development') {\n return NextResponse.json({ error: 'Not available in production' }, { status: 403 })\n }\n\n const pathname = request.nextUrl.pathname\n const route = pathname.replace(/^\\/api\\/studio\\/?/, '')\n\n // Route: /api/studio/upload\n if (route === 'upload') {\n return handleUpload(request)\n }\n\n // Route: /api/studio/delete\n if (route === 'delete') {\n return handleDelete(request)\n }\n\n // Route: /api/studio/sync\n if (route === 'sync') {\n return handleSync(request)\n }\n\n // Route: /api/studio/reprocess\n if (route === 'reprocess') {\n return handleReprocess(request)\n }\n\n // Route: /api/studio/process-all (streaming)\n if (route === 'process-all') {\n return handleProcessAllStream()\n }\n\n // Route: /api/studio/create-folder\n if (route === 'create-folder') {\n return handleCreateFolder(request)\n }\n\n // Route: /api/studio/rename\n if (route === 'rename') {\n return handleRename(request)\n }\n\n // Route: /api/studio/move\n if (route === 'move') {\n return handleMove(request)\n }\n\n return NextResponse.json({ error: 'Not found' }, { status: 404 })\n}\n\n/**\n * Unified DELETE handler\n */\nexport async function DELETE(request: NextRequest) {\n if (process.env.NODE_ENV !== 'development') {\n return NextResponse.json({ error: 'Not available in production' }, { status: 403 })\n }\n\n return handleDelete(request)\n}\n","import { NextRequest, NextResponse } from 'next/server'\nimport { promises as fs } from 'fs'\nimport path from 'path'\nimport sharp from 'sharp'\nimport type { FileItem } from '../types'\nimport { isImageFile, isMediaFile, getFolderStats } from './utils'\n\nexport async function handleList(request: NextRequest) {\n const searchParams = request.nextUrl.searchParams\n const requestedPath = searchParams.get('path') || 'public'\n\n try {\n const safePath = requestedPath.replace(/\\.\\./g, '')\n const absolutePath = path.join(process.cwd(), safePath)\n\n if (!absolutePath.startsWith(process.cwd())) {\n return NextResponse.json({ error: 'Invalid path' }, { status: 400 })\n }\n\n const items: FileItem[] = []\n const entries = await fs.readdir(absolutePath, { withFileTypes: true })\n\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue\n\n const itemPath = path.join(safePath, entry.name)\n\n if (entry.isDirectory()) {\n const folderStats = await getFolderStats(path.join(absolutePath, entry.name))\n items.push({\n name: entry.name,\n path: itemPath,\n type: 'folder',\n fileCount: folderStats.fileCount,\n totalSize: folderStats.totalSize,\n })\n } else if (isMediaFile(entry.name)) {\n const filePath = path.join(absolutePath, entry.name)\n const stats = await fs.stat(filePath)\n const isImage = isImageFile(entry.name)\n \n let thumbnail: string | undefined\n let hasThumbnail = false\n let dimensions: { width: number; height: number } | undefined\n \n if (isImage) {\n const relativePath = safePath.replace(/^public\\/?/, '')\n \n if (relativePath === 'images' || relativePath.startsWith('images/')) {\n thumbnail = itemPath.replace('public', '')\n hasThumbnail = true\n } else {\n const ext = path.extname(entry.name).toLowerCase()\n const baseName = path.basename(entry.name, ext)\n const thumbnailDir = relativePath ? `images/${relativePath}` : 'images'\n const thumbnailName = `${baseName}-sm${ext === '.png' ? '.png' : '.jpg'}`\n const thumbnailPath = path.join(process.cwd(), 'public', thumbnailDir, thumbnailName)\n \n try {\n await fs.access(thumbnailPath)\n thumbnail = `/${thumbnailDir}/${thumbnailName}`\n hasThumbnail = true\n } catch {\n thumbnail = itemPath.replace('public', '')\n hasThumbnail = false\n }\n }\n \n if (!entry.name.toLowerCase().endsWith('.svg')) {\n try {\n const metadata = await sharp(filePath).metadata()\n if (metadata.width && metadata.height) {\n dimensions = { width: metadata.width, height: metadata.height }\n }\n } catch {\n // Ignore dimension errors\n }\n }\n }\n \n items.push({\n name: entry.name,\n path: itemPath,\n type: 'file',\n size: stats.size,\n thumbnail,\n hasThumbnail,\n dimensions,\n })\n }\n }\n\n return NextResponse.json({ items })\n } catch (error) {\n console.error('Failed to list directory:', error)\n return NextResponse.json({ error: 'Failed to list directory' }, { status: 500 })\n }\n}\n\nexport async function handleSearch(request: NextRequest) {\n const searchParams = request.nextUrl.searchParams\n const query = searchParams.get('q')?.toLowerCase() || ''\n \n if (query.length < 2) {\n return NextResponse.json({ items: [] })\n }\n\n try {\n const items: FileItem[] = []\n const publicDir = path.join(process.cwd(), 'public')\n\n async function searchDir(dir: string, relativePath: string): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue\n\n const fullPath = path.join(dir, entry.name)\n const itemPath = relativePath ? `public/${relativePath}/${entry.name}` : `public/${entry.name}`\n const itemRelPath = relativePath ? `${relativePath}/${entry.name}` : entry.name\n\n if (entry.isDirectory()) {\n await searchDir(fullPath, itemRelPath)\n } else if (isImageFile(entry.name)) {\n if (itemPath.toLowerCase().includes(query)) {\n const stats = await fs.stat(fullPath)\n \n let thumbnail: string | undefined\n let hasThumbnail = false\n let dimensions: { width: number; height: number } | undefined\n\n const ext = path.extname(entry.name).toLowerCase()\n const baseName = path.basename(entry.name, ext)\n const thumbnailDir = relativePath ? `images/${relativePath}` : 'images'\n const thumbnailName = `${baseName}-sm${ext === '.png' ? '.png' : '.jpg'}`\n const thumbnailPath = path.join(process.cwd(), 'public', thumbnailDir, thumbnailName)\n\n try {\n await fs.access(thumbnailPath)\n thumbnail = `/${thumbnailDir}/${thumbnailName}`\n hasThumbnail = true\n } catch {\n thumbnail = `/${itemRelPath}`\n hasThumbnail = false\n }\n\n if (!entry.name.toLowerCase().endsWith('.svg')) {\n try {\n const metadata = await sharp(fullPath).metadata()\n if (metadata.width && metadata.height) {\n dimensions = { width: metadata.width, height: metadata.height }\n }\n } catch {\n // Ignore dimension errors\n }\n }\n\n items.push({\n name: entry.name,\n path: itemPath,\n type: 'file',\n size: stats.size,\n thumbnail,\n hasThumbnail,\n dimensions,\n })\n }\n }\n }\n } catch {\n // Ignore directory access errors\n }\n }\n\n await searchDir(publicDir, '')\n\n return NextResponse.json({ items })\n } catch (error) {\n console.error('Failed to search:', error)\n return NextResponse.json({ error: 'Failed to search' }, { status: 500 })\n }\n}\n\nexport async function handleListFolders() {\n try {\n const publicDir = path.join(process.cwd(), 'public')\n const folders: { path: string; name: string; depth: number }[] = []\n\n async function scanDir(dir: string, relativePath: string, depth: number): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n if (entry.name.startsWith('.')) continue\n\n const folderRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name\n folders.push({\n path: `public/${folderRelativePath}`,\n name: entry.name,\n depth\n })\n\n await scanDir(path.join(dir, entry.name), folderRelativePath, depth + 1)\n }\n } catch {\n // Ignore errors\n }\n }\n\n folders.push({ path: 'public', name: 'public', depth: 0 })\n await scanDir(publicDir, '', 1)\n\n return NextResponse.json({ folders })\n } catch (error) {\n console.error('Failed to list folders:', error)\n return NextResponse.json({ error: 'Failed to list folders' }, { status: 500 })\n }\n}\n\nexport async function handleCountImages() {\n try {\n const allImages: string[] = []\n\n async function scanPublicFolder(dir: string, relativePath: string = ''): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n \n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue\n \n const fullPath = path.join(dir, entry.name)\n const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name\n\n if (relPath === 'images' || relPath.startsWith('images/')) continue\n\n if (entry.isDirectory()) {\n await scanPublicFolder(fullPath, relPath)\n } else if (isImageFile(entry.name)) {\n allImages.push(relPath)\n }\n }\n } catch {\n // Directory might not exist\n }\n }\n\n const publicDir = path.join(process.cwd(), 'public')\n await scanPublicFolder(publicDir)\n\n return NextResponse.json({\n count: allImages.length,\n images: allImages,\n })\n } catch (error) {\n console.error('Failed to count images:', error)\n return NextResponse.json({ error: 'Failed to count images' }, { status: 500 })\n }\n}\n\nexport async function handleFolderImages(request: NextRequest) {\n try {\n const searchParams = request.nextUrl.searchParams\n const foldersParam = searchParams.get('folders')\n \n if (!foldersParam) {\n return NextResponse.json({ error: 'No folders provided' }, { status: 400 })\n }\n\n const folders = foldersParam.split(',')\n const allImages: string[] = []\n\n async function scanFolder(dir: string, relativePath: string = ''): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n \n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue\n \n const fullPath = path.join(dir, entry.name)\n const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name\n\n if (entry.isDirectory()) {\n await scanFolder(fullPath, relPath)\n } else if (isImageFile(entry.name)) {\n allImages.push(relPath)\n }\n }\n } catch {\n // Directory might not exist\n }\n }\n\n for (const folder of folders) {\n const relativePath = folder.replace(/^public\\/?/, '')\n \n if (relativePath === 'images' || relativePath.startsWith('images/')) continue\n \n const folderPath = path.join(process.cwd(), folder)\n await scanFolder(folderPath, relativePath)\n }\n\n return NextResponse.json({\n count: allImages.length,\n images: allImages,\n })\n } catch (error) {\n console.error('Failed to get folder images:', error)\n return NextResponse.json({ error: 'Failed to get folder images' }, { status: 500 })\n }\n}\n","import { promises as fs } from 'fs'\nimport path from 'path'\nimport type { LeanMeta } from '../../types'\n\nexport async function loadMeta(): Promise<LeanMeta> {\n const metaPath = path.join(process.cwd(), '_data', '_meta.json')\n \n try {\n const content = await fs.readFile(metaPath, 'utf-8')\n return JSON.parse(content) as LeanMeta\n } catch {\n return {}\n }\n}\n\nexport async function saveMeta(meta: LeanMeta): Promise<void> {\n const dataDir = path.join(process.cwd(), '_data')\n await fs.mkdir(dataDir, { recursive: true })\n const metaPath = path.join(dataDir, '_meta.json')\n await fs.writeFile(metaPath, JSON.stringify(meta, null, 2))\n}\n","import { promises as fs } from 'fs'\nimport path from 'path'\n\nexport function isImageFile(filename: string): boolean {\n const ext = path.extname(filename).toLowerCase()\n return ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.ico', '.bmp', '.tiff', '.tif'].includes(ext)\n}\n\nexport function isMediaFile(filename: string): boolean {\n const ext = path.extname(filename).toLowerCase()\n // Images\n if (['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.ico', '.bmp', '.tiff', '.tif'].includes(ext)) return true\n // Videos\n if (['.mp4', '.webm', '.mov', '.avi', '.mkv', '.m4v'].includes(ext)) return true\n // Audio\n if (['.mp3', '.wav', '.ogg', '.m4a', '.flac', '.aac'].includes(ext)) return true\n // Documents/PDFs\n if (['.pdf'].includes(ext)) return true\n return false\n}\n\nexport function getContentType(filePath: string): string {\n const ext = path.extname(filePath).toLowerCase()\n switch (ext) {\n case '.jpg':\n case '.jpeg':\n return 'image/jpeg'\n case '.png':\n return 'image/png'\n case '.gif':\n return 'image/gif'\n case '.webp':\n return 'image/webp'\n case '.svg':\n return 'image/svg+xml'\n default:\n return 'application/octet-stream'\n }\n}\n\nexport async function getFolderStats(folderPath: string): Promise<{ fileCount: number; totalSize: number }> {\n let fileCount = 0\n let totalSize = 0\n\n async function scanFolder(dir: string): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue\n const fullPath = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n await scanFolder(fullPath)\n } else if (isMediaFile(entry.name)) {\n fileCount++\n const stats = await fs.stat(fullPath)\n totalSize += stats.size\n }\n }\n } catch { /* ignore errors */ }\n }\n\n await scanFolder(folderPath)\n return { fileCount, totalSize }\n}\n","import { promises as fs } from 'fs'\nimport path from 'path'\nimport sharp from 'sharp'\nimport { encode } from 'blurhash'\nimport type { LeanImageEntry } from '../../types'\n\nexport const DEFAULT_SIZES: Record<string, { width: number; suffix: string }> = {\n small: { width: 300, suffix: '-sm' },\n medium: { width: 700, suffix: '-md' },\n large: { width: 1400, suffix: '-lg' },\n}\n\nexport async function processImage(\n buffer: Buffer,\n imageKey: string\n): Promise<LeanImageEntry> {\n const sharpInstance = sharp(buffer)\n const metadata = await sharpInstance.metadata()\n const originalWidth = metadata.width || 0\n const originalHeight = metadata.height || 0\n\n // Remove leading slash for path operations\n const keyWithoutSlash = imageKey.startsWith('/') ? imageKey.slice(1) : imageKey\n const baseName = path.basename(keyWithoutSlash, path.extname(keyWithoutSlash))\n const ext = path.extname(keyWithoutSlash).toLowerCase()\n const imageDir = path.dirname(keyWithoutSlash)\n\n const imagesPath = path.join(process.cwd(), 'public', 'images', imageDir === '.' ? '' : imageDir)\n await fs.mkdir(imagesPath, { recursive: true })\n\n const isPng = ext === '.png'\n const outputExt = isPng ? '.png' : '.jpg'\n \n // Generate full size\n const fullFileName = imageDir === '.' ? `${baseName}${outputExt}` : `${imageDir}/${baseName}${outputExt}`\n const fullPath = path.join(process.cwd(), 'public', 'images', fullFileName)\n \n if (isPng) {\n await sharp(buffer).png({ quality: 85 }).toFile(fullPath)\n } else {\n await sharp(buffer).jpeg({ quality: 85 }).toFile(fullPath)\n }\n\n // Generate thumbnail sizes\n for (const [, sizeConfig] of Object.entries(DEFAULT_SIZES)) {\n const { width: maxWidth, suffix } = sizeConfig\n if (originalWidth <= maxWidth) {\n continue // Skip if original is smaller than this size\n }\n\n const ratio = originalHeight / originalWidth\n const newHeight = Math.round(maxWidth * ratio)\n const sizeFileName = `${baseName}${suffix}${outputExt}`\n const sizeFilePath = imageDir === '.' ? sizeFileName : `${imageDir}/${sizeFileName}`\n const sizePath = path.join(process.cwd(), 'public', 'images', sizeFilePath)\n\n if (isPng) {\n await sharp(buffer).resize(maxWidth, newHeight).png({ quality: 80 }).toFile(sizePath)\n } else {\n await sharp(buffer).resize(maxWidth, newHeight).jpeg({ quality: 80 }).toFile(sizePath)\n }\n }\n\n // Generate blurhash\n const { data, info } = await sharp(buffer)\n .resize(32, 32, { fit: 'inside' })\n .ensureAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n const blurhash = encode(new Uint8ClampedArray(data), info.width, info.height, 4, 4)\n\n return {\n w: originalWidth,\n h: originalHeight,\n blur: blurhash,\n }\n}\n","import { promises as fs } from 'fs'\nimport path from 'path'\nimport { S3Client, GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3'\nimport { getAllThumbnailPaths } from '../../types'\nimport { getContentType } from './files'\n\nfunction getR2Client() {\n const accountId = process.env.CLOUDFLARE_R2_ACCOUNT_ID\n const accessKeyId = process.env.CLOUDFLARE_R2_ACCESS_KEY_ID\n const secretAccessKey = process.env.CLOUDFLARE_R2_SECRET_ACCESS_KEY\n\n if (!accountId || !accessKeyId || !secretAccessKey) {\n throw new Error('R2 not configured')\n }\n\n return new S3Client({\n region: 'auto',\n endpoint: `https://${accountId}.r2.cloudflarestorage.com`,\n credentials: { accessKeyId, secretAccessKey },\n })\n}\n\nexport async function downloadFromCdn(originalPath: string): Promise<Buffer> {\n const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME\n if (!bucketName) throw new Error('R2 bucket not configured')\n\n const r2 = getR2Client()\n\n const response = await r2.send(\n new GetObjectCommand({\n Bucket: bucketName,\n Key: originalPath.replace(/^\\//, ''),\n })\n )\n\n const stream = response.Body as NodeJS.ReadableStream\n const chunks: Buffer[] = []\n for await (const chunk of stream) {\n chunks.push(Buffer.from(chunk))\n }\n return Buffer.concat(chunks)\n}\n\nexport async function uploadToCdn(imageKey: string): Promise<void> {\n const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME\n if (!bucketName) throw new Error('R2 bucket not configured')\n\n const r2 = getR2Client()\n\n // Upload all thumbnail sizes derived from imageKey\n for (const thumbPath of getAllThumbnailPaths(imageKey)) {\n const localPath = path.join(process.cwd(), 'public', thumbPath)\n try {\n const fileBuffer = await fs.readFile(localPath)\n await r2.send(\n new PutObjectCommand({\n Bucket: bucketName,\n Key: thumbPath.replace(/^\\//, ''),\n Body: fileBuffer,\n ContentType: getContentType(thumbPath),\n })\n )\n } catch {\n // File might not exist (e.g., if image is smaller than thumbnail size)\n }\n }\n}\n\nexport async function deleteLocalThumbnails(imageKey: string): Promise<void> {\n for (const thumbPath of getAllThumbnailPaths(imageKey)) {\n const localPath = path.join(process.cwd(), 'public', thumbPath)\n try {\n await fs.unlink(localPath)\n } catch {\n // File might not exist\n }\n }\n}\n","import { NextRequest, NextResponse } from 'next/server'\nimport { promises as fs } from 'fs'\nimport path from 'path'\nimport sharp from 'sharp'\nimport { encode } from 'blurhash'\nimport type { LeanImageEntry } from '../types'\nimport { getAllThumbnailPaths } from '../types'\nimport { loadMeta, saveMeta, isImageFile, DEFAULT_SIZES } from './utils'\n\nexport async function handleUpload(request: NextRequest) {\n try {\n const formData = await request.formData()\n const file = formData.get('file') as File | null\n const targetPath = formData.get('path') as string || 'public'\n\n if (!file) {\n return NextResponse.json({ error: 'No file provided' }, { status: 400 })\n }\n\n const bytes = await file.arrayBuffer()\n const buffer = Buffer.from(bytes)\n\n const fileName = file.name\n const baseName = path.basename(fileName, path.extname(fileName))\n const ext = path.extname(fileName).toLowerCase()\n\n const isImage = isImageFile(fileName)\n const isSvg = ext === '.svg'\n const isProcessableImage = isImage && !isSvg\n\n const meta = await loadMeta()\n\n let relativeDir = ''\n if (targetPath === 'public') {\n relativeDir = ''\n } else if (targetPath.startsWith('public/')) {\n relativeDir = targetPath.replace('public/', '')\n }\n \n if (relativeDir === 'images' || relativeDir.startsWith('images/')) {\n return NextResponse.json(\n { error: 'Cannot upload to images/ folder. Upload to public/ instead - thumbnails are generated automatically.' },\n { status: 400 }\n )\n }\n\n const uploadDir = path.join(process.cwd(), 'public', relativeDir)\n await fs.mkdir(uploadDir, { recursive: true })\n await fs.writeFile(path.join(uploadDir, fileName), buffer)\n\n if (!isImage) {\n return NextResponse.json({ \n success: true, \n message: 'File uploaded successfully (non-image, no thumbnails generated)',\n path: `public/${relativeDir ? relativeDir + '/' : ''}${fileName}`\n })\n }\n \n const imageKey = '/' + (relativeDir ? `${relativeDir}/${fileName}` : fileName)\n\n if (meta[imageKey]) {\n return NextResponse.json(\n { error: `File '${imageKey}' already exists in meta` },\n { status: 409 }\n )\n }\n\n const imagesPath = path.join(process.cwd(), 'public', 'images', relativeDir)\n await fs.mkdir(imagesPath, { recursive: true })\n\n let originalWidth = 0\n let originalHeight = 0\n let blurhash = ''\n\n const originalPath = `/${relativeDir ? relativeDir + '/' : ''}${fileName}`\n\n if (isSvg) {\n const fullPath = path.join(imagesPath, fileName)\n await fs.writeFile(fullPath, buffer)\n } else if (isProcessableImage) {\n const sharpInstance = sharp(buffer)\n const metadata = await sharpInstance.metadata()\n originalWidth = metadata.width || 0\n originalHeight = metadata.height || 0\n\n const outputExt = ext === '.png' ? '.png' : '.jpg'\n const fullFileName = `${baseName}${outputExt}`\n const fullPath = path.join(imagesPath, fullFileName)\n \n if (ext === '.png') {\n await sharp(buffer).png({ quality: 85 }).toFile(fullPath)\n } else {\n await sharp(buffer).jpeg({ quality: 85 }).toFile(fullPath)\n }\n\n for (const [, sizeConfig] of Object.entries(DEFAULT_SIZES)) {\n const { width: maxWidth, suffix } = sizeConfig\n if (originalWidth <= maxWidth) {\n continue\n }\n\n const ratio = originalHeight / originalWidth\n const newHeight = Math.round(maxWidth * ratio)\n const sizeFileName = `${baseName}${suffix}${outputExt}`\n const sizePath = path.join(imagesPath, sizeFileName)\n\n if (ext === '.png') {\n await sharp(buffer).resize(maxWidth, newHeight).png({ quality: 80 }).toFile(sizePath)\n } else {\n await sharp(buffer).resize(maxWidth, newHeight).jpeg({ quality: 80 }).toFile(sizePath)\n }\n }\n\n const { data, info } = await sharp(buffer)\n .resize(32, 32, { fit: 'inside' })\n .ensureAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n blurhash = encode(new Uint8ClampedArray(data), info.width, info.height, 4, 4)\n }\n\n const entry: LeanImageEntry = {\n w: originalWidth,\n h: originalHeight,\n blur: blurhash,\n }\n\n meta[originalPath] = entry\n await saveMeta(meta)\n\n return NextResponse.json({ success: true, imageKey: originalPath, entry })\n } catch (error) {\n console.error('Failed to upload:', error)\n const message = error instanceof Error ? error.message : 'Unknown error'\n return NextResponse.json({ error: `Failed to upload file: ${message}` }, { status: 500 })\n }\n}\n\nexport async function handleDelete(request: NextRequest) {\n try {\n const { paths } = await request.json() as { paths: string[] }\n\n if (!paths || !Array.isArray(paths) || paths.length === 0) {\n return NextResponse.json({ error: 'No paths provided' }, { status: 400 })\n }\n\n const meta = await loadMeta()\n const deleted: string[] = []\n const errors: string[] = []\n\n for (const itemPath of paths) {\n try {\n if (!itemPath.startsWith('public/')) {\n errors.push(`Invalid path: ${itemPath}`)\n continue\n }\n\n const absolutePath = path.join(process.cwd(), itemPath)\n const stats = await fs.stat(absolutePath)\n\n if (stats.isDirectory()) {\n await fs.rm(absolutePath, { recursive: true })\n \n const prefix = '/' + itemPath\n .replace(/^public\\/images\\/?/, '')\n .replace(/^public\\/?/, '')\n \n for (const key of Object.keys(meta)) {\n if (key.startsWith(prefix)) {\n delete meta[key]\n }\n }\n } else {\n await fs.unlink(absolutePath)\n\n const isInImagesFolder = itemPath.startsWith('public/images/')\n \n if (!isInImagesFolder) {\n const imageKey = '/' + itemPath.replace(/^public\\//, '')\n if (meta[imageKey]) {\n for (const thumbPath of getAllThumbnailPaths(imageKey)) {\n const absoluteThumbPath = path.join(process.cwd(), 'public', thumbPath)\n try { await fs.unlink(absoluteThumbPath) } catch { /* ignore */ }\n }\n delete meta[imageKey]\n }\n }\n }\n\n deleted.push(itemPath)\n } catch (error) {\n console.error(`Failed to delete ${itemPath}:`, error)\n errors.push(itemPath)\n }\n }\n\n await saveMeta(meta)\n\n return NextResponse.json({\n success: true,\n deleted,\n errors: errors.length > 0 ? errors : undefined,\n })\n } catch (error) {\n console.error('Failed to delete:', error)\n return NextResponse.json({ error: 'Failed to delete files' }, { status: 500 })\n }\n}\n\nexport async function handleCreateFolder(request: NextRequest) {\n try {\n const { parentPath, name } = await request.json()\n\n if (!name || typeof name !== 'string') {\n return NextResponse.json({ error: 'Folder name is required' }, { status: 400 })\n }\n\n const sanitizedName = name.replace(/[<>:\"/\\\\|?*]/g, '').trim()\n if (!sanitizedName) {\n return NextResponse.json({ error: 'Invalid folder name' }, { status: 400 })\n }\n\n const safePath = (parentPath || 'public').replace(/\\.\\./g, '')\n const folderPath = path.join(process.cwd(), safePath, sanitizedName)\n\n if (!folderPath.startsWith(path.join(process.cwd(), 'public'))) {\n return NextResponse.json({ error: 'Invalid path' }, { status: 400 })\n }\n\n try {\n await fs.access(folderPath)\n return NextResponse.json({ error: 'A folder with this name already exists' }, { status: 400 })\n } catch {\n // Good - folder doesn't exist\n }\n\n await fs.mkdir(folderPath, { recursive: true })\n\n return NextResponse.json({ success: true, path: path.join(safePath, sanitizedName) })\n } catch (error) {\n console.error('Failed to create folder:', error)\n return NextResponse.json({ error: 'Failed to create folder' }, { status: 500 })\n }\n}\n\nexport async function handleRename(request: NextRequest) {\n try {\n const { oldPath, newName } = await request.json()\n\n if (!oldPath || !newName) {\n return NextResponse.json({ error: 'Path and new name are required' }, { status: 400 })\n }\n\n const sanitizedName = newName.replace(/[<>:\"/\\\\|?*]/g, '').trim()\n if (!sanitizedName) {\n return NextResponse.json({ error: 'Invalid name' }, { status: 400 })\n }\n\n const safePath = oldPath.replace(/\\.\\./g, '')\n const absoluteOldPath = path.join(process.cwd(), safePath)\n const parentDir = path.dirname(absoluteOldPath)\n const absoluteNewPath = path.join(parentDir, sanitizedName)\n\n if (!absoluteOldPath.startsWith(path.join(process.cwd(), 'public'))) {\n return NextResponse.json({ error: 'Invalid path' }, { status: 400 })\n }\n\n try {\n await fs.access(absoluteOldPath)\n } catch {\n return NextResponse.json({ error: 'File or folder not found' }, { status: 404 })\n }\n\n try {\n await fs.access(absoluteNewPath)\n return NextResponse.json({ error: 'An item with this name already exists' }, { status: 400 })\n } catch {\n // Good - new path doesn't exist\n }\n\n const stats = await fs.stat(absoluteOldPath)\n const isFile = stats.isFile()\n const isImage = isFile && isImageFile(path.basename(oldPath))\n\n await fs.rename(absoluteOldPath, absoluteNewPath)\n\n if (isImage) {\n const meta = await loadMeta()\n const oldRelativePath = safePath.replace(/^public\\//, '')\n const newRelativePath = path.join(path.dirname(oldRelativePath), sanitizedName)\n const oldKey = '/' + oldRelativePath\n const newKey = '/' + newRelativePath\n\n if (meta[oldKey]) {\n const entry = meta[oldKey]\n\n const oldThumbPaths = getAllThumbnailPaths(oldKey)\n const newThumbPaths = getAllThumbnailPaths(newKey)\n\n for (let i = 0; i < oldThumbPaths.length; i++) {\n const oldThumbPath = path.join(process.cwd(), 'public', oldThumbPaths[i])\n const newThumbPath = path.join(process.cwd(), 'public', newThumbPaths[i])\n \n await fs.mkdir(path.dirname(newThumbPath), { recursive: true })\n \n try {\n await fs.rename(oldThumbPath, newThumbPath)\n } catch {\n // Thumbnail might not exist\n }\n }\n\n delete meta[oldKey]\n meta[newKey] = entry\n }\n\n await saveMeta(meta)\n }\n\n const newPath = path.join(path.dirname(safePath), sanitizedName)\n return NextResponse.json({ success: true, newPath })\n } catch (error) {\n console.error('Failed to rename:', error)\n return NextResponse.json({ error: 'Failed to rename' }, { status: 500 })\n }\n}\n\nexport async function handleMove(request: NextRequest) {\n try {\n const { paths, destination } = await request.json()\n\n if (!paths || !Array.isArray(paths) || paths.length === 0) {\n return NextResponse.json({ error: 'Paths are required' }, { status: 400 })\n }\n\n if (!destination || typeof destination !== 'string') {\n return NextResponse.json({ error: 'Destination is required' }, { status: 400 })\n }\n\n const safeDestination = destination.replace(/\\.\\./g, '')\n const absoluteDestination = path.join(process.cwd(), safeDestination)\n\n if (!absoluteDestination.startsWith(path.join(process.cwd(), 'public'))) {\n return NextResponse.json({ error: 'Invalid destination' }, { status: 400 })\n }\n\n try {\n const destStats = await fs.stat(absoluteDestination)\n if (!destStats.isDirectory()) {\n return NextResponse.json({ error: 'Destination is not a folder' }, { status: 400 })\n }\n } catch {\n return NextResponse.json({ error: 'Destination folder not found' }, { status: 404 })\n }\n\n const moved: string[] = []\n const errors: string[] = []\n const meta = await loadMeta()\n let metaChanged = false\n\n for (const itemPath of paths) {\n const safePath = itemPath.replace(/\\.\\./g, '')\n const absolutePath = path.join(process.cwd(), safePath)\n const itemName = path.basename(safePath)\n const newAbsolutePath = path.join(absoluteDestination, itemName)\n\n if (absoluteDestination.startsWith(absolutePath + path.sep)) {\n errors.push(`Cannot move ${itemName} into itself`)\n continue\n }\n\n try {\n await fs.access(absolutePath)\n } catch {\n errors.push(`${itemName} not found`)\n continue\n }\n\n try {\n await fs.access(newAbsolutePath)\n errors.push(`${itemName} already exists in destination`)\n continue\n } catch {\n // Good - doesn't exist\n }\n\n try {\n await fs.rename(absolutePath, newAbsolutePath)\n\n const stats = await fs.stat(newAbsolutePath)\n if (stats.isFile() && isImageFile(itemName)) {\n const oldRelativePath = safePath.replace(/^public\\//, '')\n const newRelativePath = path.join(safeDestination.replace(/^public\\//, ''), itemName)\n const oldKey = '/' + oldRelativePath\n const newKey = '/' + newRelativePath\n\n if (meta[oldKey]) {\n const entry = meta[oldKey]\n\n const oldThumbPaths = getAllThumbnailPaths(oldKey)\n const newThumbPaths = getAllThumbnailPaths(newKey)\n\n for (let i = 0; i < oldThumbPaths.length; i++) {\n const oldThumbPath = path.join(process.cwd(), 'public', oldThumbPaths[i])\n const newThumbPath = path.join(process.cwd(), 'public', newThumbPaths[i])\n \n await fs.mkdir(path.dirname(newThumbPath), { recursive: true })\n\n try {\n await fs.rename(oldThumbPath, newThumbPath)\n } catch {\n // Thumbnail might not exist\n }\n }\n\n delete meta[oldKey]\n meta[newKey] = entry\n metaChanged = true\n }\n }\n\n moved.push(itemPath)\n } catch {\n errors.push(`Failed to move ${itemName}`)\n }\n }\n\n if (metaChanged) {\n await saveMeta(meta)\n }\n\n return NextResponse.json({\n success: errors.length === 0,\n moved,\n errors: errors.length > 0 ? errors : undefined\n })\n } catch (error) {\n console.error('Failed to move:', error)\n return NextResponse.json({ error: 'Failed to move items' }, { status: 500 })\n }\n}\n","import { NextRequest, NextResponse } from 'next/server'\nimport { promises as fs } from 'fs'\nimport path from 'path'\nimport { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'\nimport { getAllThumbnailPaths } from '../types'\nimport {\n loadMeta,\n saveMeta,\n isImageFile,\n getContentType,\n processImage,\n downloadFromCdn,\n uploadToCdn,\n deleteLocalThumbnails,\n} from './utils'\n\nexport async function handleSync(request: NextRequest) {\n const accountId = process.env.CLOUDFLARE_R2_ACCOUNT_ID\n const accessKeyId = process.env.CLOUDFLARE_R2_ACCESS_KEY_ID\n const secretAccessKey = process.env.CLOUDFLARE_R2_SECRET_ACCESS_KEY\n const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME\n const publicUrl = process.env.CLOUDFLARE_R2_PUBLIC_URL\n\n if (!accountId || !accessKeyId || !secretAccessKey || !bucketName || !publicUrl) {\n return NextResponse.json(\n { error: 'R2 not configured. Set CLOUDFLARE_R2_* environment variables.' },\n { status: 400 }\n )\n }\n\n try {\n const { imageKeys } = await request.json() as { imageKeys: string[] }\n\n if (!imageKeys || !Array.isArray(imageKeys) || imageKeys.length === 0) {\n return NextResponse.json({ error: 'No image keys provided' }, { status: 400 })\n }\n\n const meta = await loadMeta()\n\n const r2 = new S3Client({\n region: 'auto',\n endpoint: `https://${accountId}.r2.cloudflarestorage.com`,\n credentials: { accessKeyId, secretAccessKey },\n })\n\n const synced: string[] = []\n const errors: string[] = []\n\n for (const imageKey of imageKeys) {\n const entry = meta[imageKey]\n if (!entry) {\n errors.push(`Image not found in meta: ${imageKey}`)\n continue\n }\n\n if (entry.s) {\n synced.push(imageKey)\n continue\n }\n\n try {\n for (const thumbPath of getAllThumbnailPaths(imageKey)) {\n const localPath = path.join(process.cwd(), 'public', thumbPath)\n try {\n const fileBuffer = await fs.readFile(localPath)\n await r2.send(\n new PutObjectCommand({\n Bucket: bucketName,\n Key: thumbPath.replace(/^\\//, ''),\n Body: fileBuffer,\n ContentType: getContentType(thumbPath),\n })\n )\n } catch {\n // File might not exist\n }\n }\n\n entry.s = 1\n\n for (const thumbPath of getAllThumbnailPaths(imageKey)) {\n const localPath = path.join(process.cwd(), 'public', thumbPath)\n try { await fs.unlink(localPath) } catch { /* ignore */ }\n }\n\n synced.push(imageKey)\n } catch (error) {\n console.error(`Failed to sync ${imageKey}:`, error)\n errors.push(imageKey)\n }\n }\n\n await saveMeta(meta)\n\n return NextResponse.json({\n success: true,\n synced,\n errors: errors.length > 0 ? errors : undefined,\n })\n } catch (error) {\n console.error('Failed to sync:', error)\n return NextResponse.json({ error: 'Failed to sync to CDN' }, { status: 500 })\n }\n}\n\nexport async function handleReprocess(request: NextRequest) {\n try {\n const { imageKeys } = await request.json() as { imageKeys: string[] }\n\n if (!imageKeys || !Array.isArray(imageKeys) || imageKeys.length === 0) {\n return NextResponse.json({ error: 'No image keys provided' }, { status: 400 })\n }\n\n const meta = await loadMeta()\n const processed: string[] = []\n const errors: string[] = []\n\n for (const imageKey of imageKeys) {\n try {\n let buffer: Buffer\n const entry = meta[imageKey]\n \n const originalPath = path.join(process.cwd(), 'public', imageKey)\n \n try {\n buffer = await fs.readFile(originalPath)\n } catch {\n if (entry?.s) {\n buffer = await downloadFromCdn(imageKey)\n } else {\n throw new Error(`File not found: ${imageKey}`)\n }\n }\n\n const updatedEntry = await processImage(buffer, imageKey)\n \n if (entry?.s) {\n updatedEntry.s = 1\n await uploadToCdn(imageKey)\n await deleteLocalThumbnails(imageKey)\n }\n \n meta[imageKey] = updatedEntry\n processed.push(imageKey)\n } catch (error) {\n console.error(`Failed to reprocess ${imageKey}:`, error)\n errors.push(imageKey)\n }\n }\n\n await saveMeta(meta)\n\n return NextResponse.json({\n success: true,\n processed,\n errors: errors.length > 0 ? errors : undefined,\n })\n } catch (error) {\n console.error('Failed to reprocess:', error)\n return NextResponse.json({ error: 'Failed to reprocess images' }, { status: 500 })\n }\n}\n\nexport async function handleProcessAllStream() {\n const encoder = new TextEncoder()\n \n const stream = new ReadableStream({\n async start(controller) {\n const sendEvent = (data: object) => {\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\\n\\n`))\n }\n\n try {\n const meta = await loadMeta()\n const processed: string[] = []\n const errors: string[] = []\n const orphansRemoved: string[] = []\n\n const allImages: Array<{ key: string; fullPath: string }> = []\n\n async function scanPublicFolder(dir: string, relativePath: string = ''): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n \n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue\n \n const fullPath = path.join(dir, entry.name)\n const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name\n\n if (relPath === 'images' || relPath.startsWith('images/')) continue\n\n if (entry.isDirectory()) {\n await scanPublicFolder(fullPath, relPath)\n } else if (isImageFile(entry.name)) {\n allImages.push({ key: relPath, fullPath })\n }\n }\n } catch {\n // Directory might not exist\n }\n }\n\n const publicDir = path.join(process.cwd(), 'public')\n await scanPublicFolder(publicDir)\n\n const total = allImages.length\n sendEvent({ type: 'start', total })\n\n for (let i = 0; i < allImages.length; i++) {\n const { key, fullPath } = allImages[i]\n const imageKey = '/' + key\n \n sendEvent({ \n type: 'progress', \n current: i + 1, \n total, \n percent: Math.round(((i + 1) / total) * 100),\n currentFile: key \n })\n\n try {\n const buffer = await fs.readFile(fullPath)\n const ext = path.extname(key).toLowerCase()\n const isSvg = ext === '.svg'\n\n if (isSvg) {\n const imageDir = path.dirname(key)\n const imagesPath = path.join(process.cwd(), 'public', 'images', imageDir === '.' ? '' : imageDir)\n await fs.mkdir(imagesPath, { recursive: true })\n \n const fileName = path.basename(key)\n const destPath = path.join(imagesPath, fileName)\n await fs.writeFile(destPath, buffer)\n\n meta[imageKey] = {\n w: 0,\n h: 0,\n blur: '',\n }\n } else {\n const existingEntry = meta[imageKey]\n const processedEntry = await processImage(buffer, imageKey)\n \n if (existingEntry?.s) {\n processedEntry.s = 1\n }\n \n meta[imageKey] = processedEntry\n }\n\n processed.push(key)\n } catch (error) {\n console.error(`Failed to process ${key}:`, error)\n errors.push(key)\n }\n }\n\n sendEvent({ type: 'cleanup', message: 'Removing orphaned thumbnails...' })\n \n const trackedPaths = new Set<string>()\n for (const imageKey of Object.keys(meta)) {\n for (const thumbPath of getAllThumbnailPaths(imageKey)) {\n trackedPaths.add(thumbPath)\n }\n }\n\n async function findOrphans(dir: string, relativePath: string = ''): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n \n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue\n\n const fullPath = path.join(dir, entry.name)\n const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name\n\n if (entry.isDirectory()) {\n await findOrphans(fullPath, relPath)\n } else if (isImageFile(entry.name)) {\n const publicPath = `/images/${relPath}`\n if (!trackedPaths.has(publicPath)) {\n try {\n await fs.unlink(fullPath)\n orphansRemoved.push(publicPath)\n } catch (err) {\n console.error(`Failed to remove orphan ${publicPath}:`, err)\n }\n }\n }\n }\n } catch {\n // Directory might not exist\n }\n }\n\n const imagesDir = path.join(process.cwd(), 'public', 'images')\n await findOrphans(imagesDir)\n\n async function removeEmptyDirs(dir: string): Promise<boolean> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true })\n let isEmpty = true\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const subDirEmpty = await removeEmptyDirs(path.join(dir, entry.name))\n if (!subDirEmpty) isEmpty = false\n } else {\n isEmpty = false\n }\n }\n\n if (isEmpty && dir !== imagesDir) {\n await fs.rmdir(dir)\n }\n\n return isEmpty\n } catch {\n return true\n }\n }\n\n await removeEmptyDirs(imagesDir)\n await saveMeta(meta)\n\n sendEvent({ \n type: 'complete', \n processed: processed.length, \n orphansRemoved: orphansRemoved.length,\n errors: errors.length,\n })\n } catch (error) {\n console.error('Failed to process all:', error)\n sendEvent({ type: 'error', message: 'Failed to process images' })\n } finally {\n controller.close()\n }\n }\n })\n\n return new Response(stream, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n },\n })\n}\n"],"mappings":"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","names":["NextResponse","fs","path","sharp","fs","path","fs","path","fs","path","path","fs","path","fs","sharp","NextResponse","fs","path","sharp","encode","NextResponse","path","fs","sharp","encode","NextResponse","fs","path","S3Client","PutObjectCommand","NextResponse","S3Client","path","fs","PutObjectCommand","NextResponse"]}
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var _chunkUFCWGUAGjs = require('./chunk-UFCWGUAG.js');
14
14
  var _react = require('react');
15
15
  var _react3 = require('@emotion/react');
16
16
  var _jsxruntime = require('@emotion/react/jsx-runtime');
17
- var StudioUI = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./StudioUI-OAZ7CTB4.js"))));
17
+ var StudioUI = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./StudioUI-YFDO5MGG.js"))));
18
18
  var spin = _react3.keyframes`
19
19
  to {
20
20
  transform: rotate(360deg);
package/dist/index.mjs CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  import { useState, useEffect, lazy, Suspense } from "react";
15
15
  import { css, keyframes } from "@emotion/react";
16
16
  import { Fragment, jsx, jsxs } from "@emotion/react/jsx-runtime";
17
- var StudioUI = lazy(() => import("./StudioUI-VPNL5NMI.mjs"));
17
+ var StudioUI = lazy(() => import("./StudioUI-VJVOSOPD.mjs"));
18
18
  var spin = keyframes`
19
19
  to {
20
20
  transform: rotate(360deg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gallop.software/studio",
3
- "version": "0.1.80",
3
+ "version": "0.1.82",
4
4
  "description": "Media manager for Gallop templates - upload, process, and sync images to CDN",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -12,9 +12,9 @@
12
12
  "require": "./dist/index.js"
13
13
  },
14
14
  "./handlers": {
15
- "types": "./dist/handlers.d.ts",
16
- "import": "./dist/handlers.mjs",
17
- "require": "./dist/handlers.js"
15
+ "types": "./dist/handlers/index.d.ts",
16
+ "import": "./dist/handlers/index.mjs",
17
+ "require": "./dist/handlers/index.js"
18
18
  }
19
19
  },
20
20
  "files": [