Skip to content

Commit c8977b5

Browse files
samuelho-devclaude
andcommitted
chore: changeset for XTable + bare-row table split (minor)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 5292a8e commit c8977b5

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

.changeset/table-row-split.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
"prisma-effect-kysely": minor
3+
---
4+
5+
feat: emit `XTable` (Kysely table) + bare `X` (Selectable SELECT row) per table
6+
7+
Each model now generates **two** schemas instead of one, following Kysely's own
8+
`PersonTable``Person` naming convention:
9+
10+
- **`{Name}Table`** — the wrapper-laden struct (`columnType()`/`generated()`
11+
intact). It drives the Kysely `DB` interface, where its `ColumnType<>`/
12+
`Generated<>` brands give `.insertInto`/`.updateTable` their insert/update
13+
variance. Per Kysely's rule, this table type is never a query-result type.
14+
- **`{Name}`** (bare) — the SELECT row, `Selectable({Name}Table)` with the
15+
wrappers stripped. This is the composable, value+type-merged schema that
16+
contracts, RPC outputs, and decode boundaries bind to. It is derived once by
17+
the generator, so consumers never re-wrap `Selectable(...)` themselves.
18+
19+
`export type {Name} = typeof {Name}.Type` (the SELECT row type). The `DB`
20+
interface entry is `Schema.Schema.Type<typeof {Name}Table>` — referencing the
21+
wrapper-laden table so Kysely query typing keeps working (gated by the
22+
`kysely-values-type-inference` regression test).
23+
24+
**Why not `@effect/sql` `Model.Class`?** A type spike showed `Model.Class`
25+
(which encodes insert/update variance in separate `.insert`/`.update` Effect
26+
schemas) is incompatible with the Kysely `DB` interface: Kysely needs the
27+
TS-level `ColumnType`/`Generated` wrappers on the table type, which `Model.Class`
28+
abandons — `db.insertInto(...).values(...)` then demands generated columns. The
29+
`Table` + bare-row split keeps both the Effect-schema and Kysely-query halves
30+
working.
31+
32+
This resolves the table-vs-row name clash (bare `X` = row, `XTable` = table)
33+
and eliminates per-consumer `Selectable(...)` repetition, with no `Model.Class`,
34+
import aliases, namespace imports, or `*Schema` suffixes.
35+
36+
**Migration for consumers:** the bare `X` export flips from the wrapper-laden
37+
table to the SELECT row. Replace `Selectable<X>``X`, `Selectable(X)``X`,
38+
and `Insertable<X>`/`Updateable<X>``Insertable<typeof XTable>`/
39+
`Updateable<typeof XTable>`. Join tables (no `XTable` emitted) keep
40+
`Selectable<JoinTable>`.
41+
42+
Also: `domain-detector` replaces a `@ts-expect-error` with a
43+
`'schemaLocation' in model` type guard; `JoinTableInfo[]` parameters are now
44+
`readonly`.

0 commit comments

Comments
 (0)