Releases: EvanSchleret/FormForge
Release list
v2.1.0
✨ Highlights
📦 Advanced file upload validation
File fields now support accepted types, maximum file counts, per-file size limits, and cumulative size limits through the DSL and backend validation.
Form::define('documents')
->version('1')
->file('attachments')
->multiple()
->accept(['.pdf', 'image/*'])
->maxSize(5_000_000)
->maxFiles(3)
->maxTotalSize(10_000_000);🛡️ Optional ClamAV scanning
Managed and staged uploads can be scanned through a remote ClamAV REST service such as ajilaag/clamav-rest, with optional HTTPS Basic Authentication.
FORMFORGE_CLAMAV_ENABLED=true
FORMFORGE_CLAMAV_ENDPOINT=https://clamav.example.com/v2/scan
FORMFORGE_CLAMAV_USERNAME=clamav-client
FORMFORGE_CLAMAV_PASSWORD=secret
FORMFORGE_CLAMAV_TIMEOUT=30🚀 Features
- Uploads: add file limits and optional ClamAV REST antivirus scanning (
0e52645)
❤️ Contributors
Full Changelog: v2.0.0...v2.1.0
v2.0.0
v2.0.0
We are thrilled to announce FormForge (API) v2.0.0, a major release that strengthens the schema foundation, makes export/import flows reliable, and adds deterministic resolution by form UUID.
Added
- Introduced a stable exportable field model for schema-driven CSV template generation, import mapping, and header validation
- Added explicit flattening for composite fields, with
addressexpanded into exportable leaf fields - Added public form resolution by
form_uuid, with deterministic latest-version selection throughFormManager,ScopedFormManager, andFormDefinitionRepository - Added reusable export/import helper APIs so downstream consumers can rely on the same schema source of truth
Changed
- Export and import flows now share one schema-derived representation instead of assuming one field equals one column
- Composite fields are no longer treated as a single CSV column by default
- Latest-by-UUID resolution now uses stable ordering by
version_number DESCandid DESC - Validation and submission flows continue to use the same normalized schema model
Tests
- Added coverage for simple fields, composite fields,
addressexpansion, header validation, unknown and missing forms, and latest-by-UUID resolution
Full Changelog: v1.5.2...v2.0.0
v1.5.2
v1.5.2
Added
- Backend now accepts submission/validation payload keys by canonical
nameandfield_key(default mode:both) - New validation config:
formforge.validation.input_key_modewith:name_onlyfield_key_onlyboth(default)
Changed
- Input key resolution now follows:
- exact
name - fallback exact
field_key
- exact
- When both
nameandfield_keyare provided for the same field,nametakes precedence - Payload sanitization/allowed-fields flow now supports
field_keyinputs through canonical normalization
Error handling
- Explicit conflict error when multiple aliases target the same field in a conflicting way
- Unknown field behavior unchanged (
reject_unknown_fieldsstill applies as before)
Tests
- Added/updated coverage for:
name-only payloadfield_key-only payload- mixed
name + field_keypayload - collision/conflict scenarios
- unknown field rejection compatibility
Full Changelog: v1.5.1...v1.5.2
v1.5.1
v1.5.1
Fixed
- Added support for filtering form query routes by linked category slug using
field: "category_slug". - Resolved mismatch where
categoryfiltering targeted stored category reference (key) and could not match category slug values.
Added
- New
category_slugfield support inhttp.query_routes.forms.wherepredicates. - Feature test coverage for form query route filtering by category slug.
Full Changelog: v1.5.0...v1.5.1
v1.5.0
v1.5.0
Added
- Introduced
http.query_routesconfiguration for reusable, named query routes. - Added new management endpoints:
GET /form-routes/{routeKey}GET /category-routes/{routeKey}
- Enabled scoped and non-scoped support for query routes.
- Added nested predicate DSL with logical groups:
all(AND)any(OR)
- Added rich operators:
eq,neq,gt,gte,lt,ltein,not_incontains,starts_with,ends_withis_null,not_nullbetween
- Added aggregate filtering support:
responses_countfor form routesforms_countfor category routes
Changed
- HTTP route listing command now includes query route endpoints.
- Authorization action map and base policy now include:
management.form_routemanagement.category_route
Tests
- Added feature coverage for form route resolution and category route resolution.
Full Changelog: v1.4.0...v1.5.0
v1.4.0
v1.4.0
Added
- Runtime locale resolution for backend validation flows:
- explicit method locale
- query param (
formforge_locale) - header (
X-FormForge-Locale) - config/app locale fallback chain
- EN/FR translation resources for FormForge backend messages.
- Publishable package language files via
formforge-lang.
Changed
- Validation and field-level backend responses now use translatable message keys while preserving canonical technical keys.
- Partial validation flows continue to return canonical field keys; only message text is localized.
- Backend docs reorganized with a dedicated Validation section.
Notes
- Laravel native rule messages are still resolved by host app translation files.
Full Changelog: v1.3.0...v1.4.0
v1.3.0
v1.3.0
Added
- New normalized field descriptor API for FormForge schemas:
describeFields()onFormInstance,FormManager,ScopedFormManager
- New centralized field resolution API:
resolveField(...)matchingname,field_key,key,id
- New partial batch validation API:
validateFields(...)for subset-oriented field validation- Supports alias identifiers in
onlyFields - Returns errors keyed by canonical field
name - Returns explicit errors for unresolved
onlyFieldsidentifiers
Changed
validateField(...)now uses centralized field resolution to avoid divergence in alias matching logic
Behavior notes
- Existing APIs remain intact:
validate(...)unchanged (including unknown-field handling)validateField(...)signature and response shape unchanged
- Partial validation (
validateFields) is field-oriented:- Unknown payload keys are ignored
- No global unknown-fields rejection in this flow
Tests
- Added coverage for:
- alias resolution via
name,field_key,key,id - normalized descriptors (
options,required,lookup_keys, etc.) - partial subset validation (valid/invalid)
onlyFieldsalias support- unresolved identifier errors
- non-regression for existing
validate()/validateField()behavior
- alias resolution via
Full Changelog: v1.2.1...v1.3.0
v1.2.1
v1.2.1
Fixed
SubmissionValidator::validateField()now resolves fields using aliases, not onlyname.- Accepted field identifiers are now:
name,field_key,key, andid(normalized via trim + string cast). - Validation payload/rules still use the field canonical
name, preserving existing validation behavior. - Unknown identifiers still raise
UnknownFieldsExceptionwhen no alias matches.
Tests
- Added/updated feature tests to cover:
validateField('name', value)(existing behavior)validateField('field_key', value)validateField('key', value)validateField('id', value)- unknown key still throws
UnknownFieldsException
Full Changelog: v1.2.0...v1.2.1
v1.2.0
v1.2.0
Added
- Single-field validation capability for FormForge schemas, allowing validation of one input against one question in one form without creating a submission.
- New public API methods:
FormInstance::validateField(string $field, mixed $value): arrayFormManager::validateField(string $formKey, string $field, mixed $value, ?string $version = null): arrayScopedFormManager::validateField(string $formKey, string $field, mixed $value, ?string $version = null): array
- New HTTP endpoints (available in both scoped and non-scoped route trees):
POST /forms/{key}/validate-fieldPOST /forms/{key}/versions/{version}/validate-field
- New validation config option:
formforge.validation.field.stop_on_first_failure(default:false)
Changed
- Resolve endpoint group now also exposes targeted field validation routes, reusing existing endpoint middleware/auth/action routing patterns.
- Authorization action map extended with:
resolve.validate_field_latestresolve.validate_field_version
- Base policy contract extended with:
resolve_validate_field_latest(...)resolve_validate_field_version(...)
Notes
- Field-level validation returns a structured result (
valid,errors,validated) instead of persisting data. - Unknown field names are rejected consistently with existing validation behavior.
Full Changelog: v1.1.1...v1.2.0
v1.1.1
v1.1.1
Added
- Added support for
auto_publish(andautoPublish) in form managementcreateandpatchrequests POST /formscan now immediately publish the created form whenauto_publishistruePATCH /forms/{key}can now immediately publish the updated form whenauto_publishistrue- Publication now happens as part of the same management flow, returning the published revision in the response
Full Changelog: v1.1.0...v1.1.1