-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
Problem
fields() currently returns FieldMeta which mixes three concerns:
- Database metadata (
primaryKey,autoIncrement,inserted, etc.) - from.db.*()methods - Form interpretation (
type: "email" | "textarea",required, etc.) - computed/inferred - Zod constraints (
min,max,minLength,maxLength,options) - extracted from schema internals
This creates problems:
- Form logic doesn't belong in a database library
- HTML input types (
FieldType) are opinionated and leak into core - Consumers can't easily access raw db metadata without the "cooking"
- The flattened structure loses information
Solution
1. Simplify fields() to return raw data
interface FieldInfo {
name: string;
schema: ZodType; // raw Zod schema
db: FieldDBMeta; // raw db metadata from .db.*()
}
interface Relation {
table: Table;
fields(): TableFields; // navigate to related table
}
type TableFields = Record<string, FieldInfo | Relation>;2. Remove from Zen
FieldType(HTML input types)FieldMeta(the cooked/flattened type)extractFieldMeta()(the cooking function)- Computed properties:
type,required,min,max,minLength,maxLength,options
3. Create @b9g/forms (separate package)
Headless schema introspection for form generation:
- Zod type inference → field types
- Constraint extraction → validation hints
- Db-awareness → skip auto-generated fields, handle relations
- Works with any form library (TanStack Form, RHF, etc.)
Breaking Changes
fields()return type changes fromFieldMetatoFieldInfoFieldTypeandFieldMetaexports removed- Consumers needing form metadata should use
@b9g/forms(or accessschema.meta()directly)
Migration
// Before
const fields = Users.fields();
fields.email.type; // "email"
fields.email.required; // true
// After
const fields = Users.fields();
fields.email.schema; // ZodString (use Zod APIs)
fields.email.db.autoIncrement; // boolean
fields.email.schema.isOptional(); // use Zod directly
// Or use @b9g/forms for form-specific metadata
import { formFields } from "@b9g/forms";
const form = formFields(Users);
form.email.type; // "email"
form.email.required; // trueRelated
- Addresses the underlying issue from FieldMeta should expose hasDefault/autoIncrement for primary keys #13 (raw db metadata access)
- Related to Validation runs on read despite documentation stating otherwise #14: removing validation from
fields()introspection aligns with the principle that validation should happen on writes, not reads/introspection
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels