Skip to content

v3.21.0

Choose a tag to compare

@58bits 58bits released this 15 Jul 01:56

Highlights

  • @byline/client / @byline/core — the client SDK now infers document field types per collection. BylineClient and createBylineClient are generic over a registry map (BylineClient<TRegistry>), so client.collection('pages') returns a CollectionHandle already typed to that collection's fields — per-call generics like findByPath<PageFields>(…) are no longer needed, and referencing an unknown collection path is now a compile error rather than a silent any. Apps derive the map from their existing collection tuple via InferCollectionRegistry<typeof collections> (a keyed projection of CollectionFieldData over the definitions), so there is a single source of truth and no parallel type list to maintain. Fully backward-compatible: the default registry leaves untyped collection(path: string) call sites compiling unchanged. The CLI byline-examples and byline templates were updated to scaffold the shared collections/index.ts tuple and a client.server.ts accessor demonstrating the pattern.

  • @byline/core — new emitCollectionTypes(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. hasMany relation fields now infer as arrays (they previously inferred as a single reference); decimal fields type as string to match Postgres's precision-preserving restoration, and file fileSize types as number — 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 the RelationReadValue / RelationFieldReadValue unions) 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 new normalizeNumericFields helper normalizes integer/float values to number and decimal to string inside document-lifecycle create/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's hasMany changes the schema hash (previously the two shapes fingerprinted identically).

Chores

  • monorepolistSearch configuration guidance added to the example collections and CLI templates, documenting the split between admin list-view quick-search and the search-provider search.body.

All other @byline/* packages bumped to 3.21.0 in lockstep with no behavioural changes this cycle.