import type { Field } from '@/types/field' /** Resolved file-upload behavior for public forms (defaults; Pro extends via hook). */ export interface FileUploadFieldConfig { allowsMultiple: boolean maxUploadCount: number acceptHint: string } function parseFieldSettings(field: Field): Record { const raw = field as Record const settings = raw.settings if (!settings) return {} if (typeof settings === 'object' && settings !== null) { return settings as Record } if (typeof settings === 'string') { try { return JSON.parse(settings) as Record } catch { return {} } } return {} } function hasFileUploadProFeature(): boolean { try { if (window.IvyForms?.hasProFeature?.('file_upload_pro')) { return true } return !!window.IvyForms?.pro?.features?.file_upload_pro } catch { return false } } /** Build HTML accept string from persisted field settings (Lite + saved Pro config). */ export function acceptHintFromField(field: Field): string { const raw = field as Record const settings = parseFieldSettings(field) const exts = raw.allowedFileExtensions ?? settings.allowedFileExtensions if (Array.isArray(exts) && exts.length > 0 && hasFileUploadProFeature()) { return exts .filter((e): e is string => typeof e === 'string' && e.trim() !== '') .map((e) => { const ext = e.trim() return ext.startsWith('.') ? ext : `.${ext}` }) .join(',') } const accept = raw.accept ?? settings.accept ?? raw.acceptedTypes ?? settings.acceptedTypes return typeof accept === 'string' ? accept : '' } function resolveAcceptHint(field: Field): string { return acceptHintFromField(field) } /** Conservative Lite defaults; Pro (or other extensions) override via hook. */ export function defaultFileUploadFieldConfig(field: Field): FileUploadFieldConfig { return { allowsMultiple: false, maxUploadCount: 1, acceptHint: resolveAcceptHint(field), } } export function resolveFileUploadFieldConfig(field: Field): FileUploadFieldConfig { const base = defaultFileUploadFieldConfig(field) const hooks = window.IvyForms?.api?.hooks ?? window.IvyForms?.hooks if (!hooks?.applyFilters) { return base } const candidate = hooks.applyFilters('ivyforms/file-upload/field_config', base, field) as | Partial | null | undefined const filtered = candidate && typeof candidate === 'object' ? candidate : {} // Multi-file limits are Pro-owned: never re-apply persisted field flags here. // Lite defaults (single file) apply only when no hook overrides them. return { allowsMultiple: typeof filtered.allowsMultiple === 'boolean' ? filtered.allowsMultiple : base.allowsMultiple, maxUploadCount: Number.isFinite(Number(filtered.maxUploadCount)) && Number(filtered.maxUploadCount) >= 0 ? Number(filtered.maxUploadCount) : base.maxUploadCount, acceptHint: typeof filtered.acceptHint === 'string' && filtered.acceptHint !== '' ? filtered.acceptHint : base.acceptHint, } }