Changelog¶
The format follows Keep a Changelog and the project adopts Semantic Versioning.
[0.1.0] — 2026-06-29¶
First public release, published on npm.
Added¶
- Phase 1 — class-based declarative schema. The
Modelbase class + thecolumnfactory with a rich type catalog mirroring SQLAlchemy (smallInteger,integer,bigInteger→bigint,numeric/decimal→string,real,double,varchar/string,char,text,boolean,date,time,datetime,timestamp,blob→Uint8Array,json<T>/jsonb<T>,uuid,enum→literal union). Modifiers.primaryKey(),.notNull(),.default(),.onUpdate(). Types inferred byInferModel(SELECT) andInferInsert(insert). - Portable defaults (
sql.now(),sql.uuidv4(), etc.), stored on the column for the migration IR. parseDatabaseUrl/detectDialect— database identified via URL (à lamake_url).- Serialization (
toDict/toJSON/stringify/fromDict/parse) with per-column-type coercion. - Phase 3 — operators typed per column type (
OperatorsFor<T>):string→like/ilike/in;number/bigint/Date→ordered+between;boolean→ eq/isNull. An invalid combination = compile error. - Phase 4a — per-dialect SQL compilation:
getDialect(...).compile(node)→ parameterized{ sql, params }(?/$1), SELECT/INSERT/UPDATE/DELETE +RETURNING; nativeilikein Postgres. - Phase 4b — real execution:
createEngine(async) /createSyncEngine(SQLite sync),Session.executewith typed terminals,engine.transaction+ savepoints, row coercion. SQLite vianode:sqlite; PostgreSQL viapostgres.js. - Phase 5 — typed joins:
join(Model, alias).innerJoin/leftJoin(...)→ composite type{ [alias]: Row },leftJoinnullable; typedalias.columnrefs. - Phase 6 — migrations (
tempest-db-js/migrations, Alembic-style):reflectSchema,diffSchema, typed operations +invert,renderOperation(per-dialect DDL),generateMigration, DAG graph (topoOrder/heads),MigrationRunner(realupgrade/downgrade). SQL only in the renderer. - Phase 7 — repository:
BaseRepository<Model>(typed CRUD + pagination) overAsyncSession, 404 convention (RecordNotFound/[]),PaginationFilter/PaginationResultaligned withtempest-fastapi-sdk. - Refinements:
and/or/notcombinators inwhere(select/update/delete/ join); SQLite batch-mode (recreate_table) for column changes preserving the data; SQLite introspection +checkDrift(compares the live DB with the models). - More refinements:
session.stream(query)(lazy sync/async iteration);hasMany/belongsTorelations +loadRelations(typed eager-loading, no N+1); migration CLIrunMigrationCli(upgrade/downgrade/check/revision --autogenerate); structural PostgreSQL (introspection, named enum,PoolOptions). - Phase 2 — typed query builder (pure AST, no execution).
select(Model)/select(Model, [cols])→ full-row orPickinference, with.where(),.orderBy(),.limit(),.offset().insert(Model).values(...)typed byInferInsert, with.returning().update(Model)/del(Model)with a typed state guard: the query only becomes executable after an explicit.where(...)or.unguarded()— an accidental full-table UPDATE/DELETE becomes a compile error..returning(cols)inferring aPickprojection on every mutation.
- Bilingual documentation (PT-BR + EN-US) in MkDocs Material, published on GitHub Pages.
Notes¶
- Alpha (
v0.1.0). The public surface may still change beforev1.0. - SQLite execution is real and tested (
node:sqlite); PostgreSQL viapostgres.js.