Files
aigen/server/api/library/stills.post.ts
T
towsty c5ed4d7ac4 Ship duration control, hidden previews, job resume, and desktop file purge.
The slider never left this machine, so deploy the generate UI with separate input/output hide toggles, reconnect in-progress jobs after refresh, and delete Comfy input/output files after they are saved to the library.
2026-08-25 20:25:36 -05:00

37 lines
1.3 KiB
TypeScript

export default defineEventHandler(async (event) => {
const form = await readMultipartFormData(event)
if (!form?.length) {
throw createError({ statusCode: 400, statusMessage: 'Expected an image upload' })
}
const fields: Record<string, string> = {}
let image: { filename: string; data: Buffer; type?: string } | null = null
for (const part of form) {
if (part.name === 'image' && part.filename && part.data?.length) {
image = { filename: part.filename, data: part.data, type: part.type }
} else if (part.name && part.data) {
fields[part.name] = part.data.toString('utf8')
}
}
if (!image) {
throw createError({ statusCode: 400, statusMessage: 'An image is required' })
}
const { owner } = assertLibraryOwner(event)
const library = publicLibrary(event)
const folderId = library.folders.some(folder => folder.id === fields.folderId)
? fields.folderId
: library.folders[0]?.id
if (!folderId) {
throw createError({ statusCode: 400, statusMessage: 'Create a library folder first' })
}
assertFolderExists(event, folderId)
const still = await saveStill({
ownerKey: owner,
folderId,
filename: image.filename,
data: image.data,
width: Number(fields.width || 0),
height: Number(fields.height || 0)
})
return { still, ...publicLibrary(event) }
})