You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
codegen-ts: projection field extends drops isArray / storage:jsonb — array/jsonb columns generate as string, diverging from the Kotlin port #204
When a projection (view) field is bound to a base-entity field via a dotted extends, the @metaobjectsdev/codegen-ts port does not carry the base field's isArray / storage: jsonb through the extends resolution — but the Kotlin port does. So for identical metadata, the two ports emit different types for the same projection field, and the TS output is both wrong and internally inconsistent.
Repro (minimal)
Base entity with an array column and a jsonb column:
A projection binds them via bare extends (no restated shape — this is intentional: keeping the projection a pure extends passthrough is what keeps it meta migrate-ready):
Kotlin codegen — correct (resolves extends and carries the shape):
val conditions:List<String>
val profile:JsonElement
TS codegen (codegen-ts 0.15.21) — wrong: both the Drizzle column and the Zod schema flatten the array to a scalar string, and they even disagree with each other on the jsonb column:
// drizzle tableconditions: text("conditions"),// should be text("conditions").array()profile: jsonb("profile"),// drizzle gets jsonb right…// zod schemaconditions: z.string(),// should be z.array(z.string())profile: z.string(),// …but zod says string — internally inconsistent with the drizzle jsonb() above
Impact
The projection's generated TS type is a type-lie: a text[] column is typed string, and a jsonb column is typed string even though the same generated file's Drizzle side declares jsonb(). Any consumer that trusts the generated type — or .parse()s a real row through the generated Zod schema — gets the wrong type or a runtime validation failure, because the actual wire shape (defined by the Kotlin-generated projection that backs the REST/read API) is an array / object.
This is a lagging-port divergence: the Kotlin port carries isArray / storage through extends, the TS port drops it. The ports should agree on the resolved field shape (cf. "keep all ports in sync").
Suggested fix
In codegen-ts, when resolving a projection field's extends, inherit the referenced base field's isArray and storage / dbColumnType (jsonb) the same way the Kotlin port does — so the Drizzle column, the Zod schema, and the Kotlin type all agree. Fixing it in the generator (rather than forcing adopters to re-state isArray/storage on every projection field) also preserves the pure-extends passthrough shape that keeps projections meta migrate-ready.
Shipped in the coordinated 0.17.0 (npm / PyPI / NuGet) · 7.9.0 (Maven Central) release — live on all four registries (PR #215, tag v0.17.0). Cross-port, conformance-gated. See CHANGELOG [0.17.0].
Activity
feat(#195): precise projection read-schema nullability for the new or…
docs(#195): CHANGELOG + roadmap follow-ups + agent-docs vocab
fix(#195): reject a non-object origin.computed @expr cross-port (clos…
fix(#204): projection view field carries isArray through extends (TS)
docs(roadmap): track the projection/view-materialization epic (#206-212)
dmealing commentedon Jul 18, 2026
Shipped in the coordinated 0.17.0 (npm / PyPI / NuGet) · 7.9.0 (Maven Central) release — live on all four registries (PR #215, tag
v0.17.0). Cross-port, conformance-gated. See CHANGELOG [0.17.0].