v3.21.0
Highlights
-
@byline/client/@byline/core— the client SDK now infers document field types per collection.BylineClientandcreateBylineClientare generic over a registry map (BylineClient<TRegistry>), soclient.collection('pages')returns aCollectionHandlealready typed to that collection's fields — per-call generics likefindByPath<PageFields>(…)are no longer needed, and referencing an unknown collection path is now a compile error rather than a silentany. Apps derive the map from their existing collection tuple viaInferCollectionRegistry<typeof collections>(a keyed projection ofCollectionFieldDataover the definitions), so there is a single source of truth and no parallel type list to maintain. Fully backward-compatible: the default registry leaves untypedcollection(path: string)call sites compiling unchanged. The CLIbyline-examplesandbylinetemplates were updated to scaffold the sharedcollections/index.tstuple and aclient.server.tsaccessor demonstrating the pattern. -
@byline/core— newemitCollectionTypes(collections)deterministic type emitter. It walks the evaluated collection definitions (never the TypeScript source AST, so imported fields, shared blocks, spreads, and factory-built definitions all resolve correctly) and returns standalone structural TypeScript plus a schema fingerprint. This gives applications a committed, generation-based type artifact that decouples public-frontend consumers from schema source modules and lays the contract foundation for the deferred stable HTTP API. Output is deterministic (stable key ordering) and covered by fixtures spanning every field type.
Bug Fixes
-
@byline/core— field-data and relation type contracts aligned with actual storage behaviour.hasManyrelation fields now infer as arrays (they previously inferred as a single reference);decimalfields type asstringto match Postgres's precision-preserving restoration, and filefileSizetypes asnumber— with the Zod builder corrected to agree with both, closing a latent strict-parse mismatch on the read path. The relation read states are now named contracts (RelatedDocumentValue,UnpopulatedRelationValue,PopulatedRelationValue,UnresolvedRelationValue,CycleRelationValue, and theRelationReadValue/RelationFieldReadValueunions) so populated, unresolved, and cycle envelopes are distinguishable in consumer types. -
@byline/core/@byline/admin/@byline/db-postgres— numeric writes are now canonicalized at the boundary. A newnormalizeNumericFieldshelper normalizes integer/float values tonumberand decimal tostringinsidedocument-lifecyclecreate/update; the admin numerical field widget emits canonical values; and the storage flatten path coerces defensively instead of blind-casting. The net effect is that non-admin writers — seed scripts, migrations, and any future API client — can no longer persist mistyped numerics that only surfaced later on read. -
@byline/core— relation cardinality is now part of the collection fingerprint, so toggling a relation'shasManychanges the schema hash (previously the two shapes fingerprinted identically).
Chores
- monorepo —
listSearchconfiguration guidance added to the example collections and CLI templates, documenting the split between admin list-view quick-search and the search-providersearch.body.
All other @byline/* packages bumped to 3.21.0 in lockstep with no behavioural changes this cycle.