Add same-mode extra passes to Image v2, and hide Shot script from image Recommend.
Library tiles show a check when selected, and xAIGen can hide a preview from the details pane. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const { owner } = assertLibraryOwner(event)
|
||||
const id = String(getRouterParam(event, 'id') || '')
|
||||
const body = await readBody<{ folderId?: string; name?: string; family?: boolean; globalLocks?: string; permanenceRefs?: unknown }>(event).catch(() => ({} as { folderId?: string; name?: string; family?: boolean; globalLocks?: string; permanenceRefs?: unknown }))
|
||||
const body = await readBody<{ folderId?: string; name?: string; family?: boolean; globalLocks?: string; permanenceRefs?: unknown; hideThumbnail?: boolean }>(event).catch(() => ({} as { folderId?: string; name?: string; family?: boolean; globalLocks?: string; permanenceRefs?: unknown; hideThumbnail?: boolean }))
|
||||
const folderId = String(body?.folderId || '')
|
||||
const hasName = typeof body?.name === 'string'
|
||||
const family = body?.family === true
|
||||
const hasLocks = typeof body?.globalLocks === 'string'
|
||||
const hasRefs = Array.isArray(body?.permanenceRefs)
|
||||
if (!folderId && !hasName && !hasLocks && !hasRefs) {
|
||||
const hasHide = typeof body?.hideThumbnail === 'boolean'
|
||||
if (!folderId && !hasName && !hasLocks && !hasRefs && !hasHide) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Choose a library folder or a new name' })
|
||||
}
|
||||
const clip = getClip(owner, id)
|
||||
@@ -28,5 +29,6 @@ export default defineEventHandler(async (event) => {
|
||||
family: family || hasLocks
|
||||
})
|
||||
}
|
||||
if (hasHide) setClipHidden(owner, id, body.hideThumbnail === true)
|
||||
return publicLibrary(event)
|
||||
})
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const { owner } = assertLibraryOwner(event)
|
||||
const id = String(getRouterParam(event, 'id') || '')
|
||||
const body = await readBody<{ folderId?: string; name?: string; family?: boolean }>(event).catch(() => ({} as { folderId?: string; name?: string; family?: boolean }))
|
||||
const body = await readBody<{ folderId?: string; name?: string; family?: boolean; hideInput?: boolean }>(event).catch(() => ({} as { folderId?: string; name?: string; family?: boolean; hideInput?: boolean }))
|
||||
const folderId = String(body?.folderId || '')
|
||||
const hasName = typeof body?.name === 'string'
|
||||
const family = body?.family === true
|
||||
if (!folderId && !hasName) {
|
||||
const hasHide = typeof body?.hideInput === 'boolean'
|
||||
if (!folderId && !hasName && !hasHide) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Choose a library folder or a new name' })
|
||||
}
|
||||
const still = getStill(owner, id)
|
||||
@@ -19,5 +20,6 @@ export default defineEventHandler(async (event) => {
|
||||
if (family) await renameStillFamily(owner, id, body.name || '')
|
||||
else await renameStill(owner, id, body.name || '')
|
||||
}
|
||||
if (hasHide) setStillHidden(owner, id, body.hideInput === true)
|
||||
return publicLibrary(event)
|
||||
})
|
||||
|
||||
@@ -32,6 +32,18 @@ import { existsSync, readFileSync } from 'node:fs'
|
||||
|
||||
type ImageFile = { filename: string; data: Buffer; type?: string }
|
||||
|
||||
function parsePasses(raw: unknown) {
|
||||
if (!raw) return [] as { prompt: string }[]
|
||||
let parsed = raw
|
||||
if (typeof raw === 'string') {
|
||||
try { parsed = JSON.parse(raw) } catch { return [] }
|
||||
}
|
||||
if (!Array.isArray(parsed)) return []
|
||||
return parsed
|
||||
.map((item: { prompt?: unknown }) => ({ prompt: String(item?.prompt || '').trim() }))
|
||||
.filter(item => item.prompt)
|
||||
}
|
||||
|
||||
function parseBool(raw: unknown) {
|
||||
return raw === true || raw === 'true' || raw === '1' || raw === 1
|
||||
}
|
||||
@@ -124,10 +136,20 @@ export default defineEventHandler(async (event) => {
|
||||
mode === 'generate' ? 't2i' : mode === 'refine' ? 'refine' : 'scene'
|
||||
)
|
||||
const prompt = String(fields.prompt || '').trim()
|
||||
const extraPasses = parsePasses(fields.passes)
|
||||
const aspect = parseImageAspect(fields.aspect)
|
||||
if (!prompt && (mode === 'generate' || aspect === 'auto')) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'A prompt is required' })
|
||||
}
|
||||
if (extraPasses.length && (mode === 'refine' || mode === 'generate')) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Extra passes are only for Edit and Compose. Refine and Generate stay a single run.'
|
||||
})
|
||||
}
|
||||
if (extraPasses.some(item => !item.prompt)) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Each extra pass needs a prompt' })
|
||||
}
|
||||
if (!comfyConfigured()) {
|
||||
throw createError({
|
||||
statusCode: 503,
|
||||
@@ -301,6 +323,7 @@ export default defineEventHandler(async (event) => {
|
||||
extensions: [],
|
||||
queueAutoRun: false,
|
||||
negative: String(fields.negative || '').trim(),
|
||||
passes: extraPasses,
|
||||
referenceStillId: savedRef?.id,
|
||||
referenceStillFilename: savedRef?.filename,
|
||||
scaleToTotalPixels: mode !== 'generate',
|
||||
@@ -342,6 +365,7 @@ export default defineEventHandler(async (event) => {
|
||||
height: size?.height || 0,
|
||||
strength: refineStrength,
|
||||
hideThumbnail,
|
||||
folderLocked
|
||||
folderLocked,
|
||||
chainTotal: 1 + extraPasses.length
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user