v3.20.0
Highlights
@byline/core,@byline/db-postgres— added virtual fields, a newvirtual: trueflag on any field. A virtual field is edited in the admin and travels with the save like any other value — so every lifecycle hook (beforeCreate/beforeUpdateand theafter*counterparts) sees it in the in-flightdata— but it is never persisted and never read back. The storage flatten step skips it wholesale (nostore_*row is written), which is the single enforcement point adapters must honour. The canonical use case is a transient control such as a "generate thumbnail" checkbox that triggers a side effect during the save without leaving a stored value that could re-fire on the next save. Virtual applies at any nesting depth — a virtual field inside anarrayitemgroupis skipped per item, and marking a structure field (group/array/blocks) virtual omits the entire subtree.validateCollections()enforces the constraints at boot: a virtual field must beoptionalor carry adefaultValue;counter, upload-capablefile/image, and any field referenced byuseAsTitle/useAsPath/searchcannot be virtual.
Bug Fixes
@byline/admin,@byline/core— fixed array item removal silently no-opping. Removing an item from anarrayfield and saving could leave the removed item in place — it would reappear on the next load — because the removal patch was dropped during patch application. Thearray.*patch handling inapply-patchesand the array field widget now apply removals correctly, with regression coverage added to the patch test suite.
All other @byline/* packages bumped to 3.20.0 in lockstep with no behavioural changes this cycle.