Fix GraphFX node port layout and previews

This commit is contained in:
2026-06-19 10:37:28 +02:00
parent 8c58aaae2b
commit 449a7aa071
4 changed files with 122 additions and 94 deletions

View File

@@ -112,22 +112,36 @@ function labelFor(name: string, io?: GraphFxIoValue) {
return io?.label || name
}
function imagePreviewUrl(value: unknown): string | null {
if (!value) return null
function imagePreviewUrl(value: unknown, depth = 0): string | null {
if (!value || depth > 4) return null
if (typeof value === 'string') {
if (value.startsWith('data:image/')) return value
if (/^[A-Za-z0-9+/=\r\n]+$/.test(value) && value.length > 80) return `data:image/png;base64,${value.replace(/\s+/g, '')}`
const trimmed = value.trim()
if (trimmed.startsWith('data:image/')) return trimmed
const base64Match = trimmed.match(/(?:base64,)?([A-Za-z0-9+/=\r\n]{40,})$/)
if (base64Match && /^[A-Za-z0-9+/=\r\n]+$/.test(base64Match[1])) return `data:image/png;base64,${base64Match[1].replace(/\s+/g, '')}`
return null
}
if (typeof value === 'object') {
const record = value as { src?: unknown; dataUrl?: unknown; base64?: unknown }
if (typeof record.src === 'string') return imagePreviewUrl(record.src)
if (typeof record.dataUrl === 'string') return imagePreviewUrl(record.dataUrl)
if (typeof record.base64 === 'string') return imagePreviewUrl(record.base64)
const record = value as Record<string, unknown>
for (const key of ['src', 'dataUrl', 'dataURL', 'url', 'href', 'base64', 'data', 'image', 'value']) {
const found = imagePreviewUrl(record[key], depth + 1)
if (found) return found
}
for (const nested of Object.values(record)) {
const found = imagePreviewUrl(nested, depth + 1)
if (found) return found
}
}
return null
}
function normalizedOptions(nodeName: string, direction: 'in' | 'out', name: string, io?: GraphFxIoValue) {
const options = ioOptionsFor(nodeName, direction, name, io?.definition)
if (!options.length) return []
const value = typeof io?.value === 'string' ? io.value : null
return value && !options.includes(value) ? [value, ...options] : options
}
function toPorts(nodeName: string, record: Record<string, GraphFxIoValue> | undefined, direction: 'in' | 'out') {
return Object.entries(record || {}).map(([name, io]) => {
const type = ioTypeFor(nodeName, direction, name, io?.type || io?.definition?.type)
@@ -137,8 +151,8 @@ function toPorts(nodeName: string, record: Record<string, GraphFxIoValue> | unde
type,
output: direction === 'in' ? io?.output || null : null,
value: direction === 'in' ? io?.value : undefined,
options: ioOptionsFor(nodeName, direction, name, io?.definition),
previewUrl: type === 'Image' ? imagePreviewUrl(io?.value) : null,
options: normalizedOptions(nodeName, direction, name, io),
previewUrl: imagePreviewUrl(io?.value),
}
})
}