Referência da API¶
Superfície pública completa do tempest-db-js. O núcleo importa do nível do pacote; as
migrações vivem no subcaminho tempest-db-js/migrations:
import {
Model, column, sql,
type InferModel, type InferInsert,
select, insert, update, del,
and, or, not,
createEngine, createSyncEngine,
join, hasMany, belongsTo, loadRelations,
BaseRepository,
} from "tempest-db-js";
import { reflectSchema, diffSchema, MigrationRunner } from "tempest-db-js/migrations";
Referência viva
Esta página resume toda a superfície pública atual. A fonte da verdade são os docstrings JSDoc no código — o editor mostra a assinatura completa de cada símbolo no autocomplete.
Schema¶
Model¶
Classe base abstrata de toda tabela. Subclasses definem static tablename e campos
de coluna.
column¶
Fábrica de colunas tipadas (espelha os tipos genéricos do SQLAlchemy).
| Método | Tipo TS | Tipo SQL |
|---|---|---|
column.smallInteger() |
number |
SMALLINT |
column.integer() |
number |
INTEGER |
column.bigInteger() |
bigint |
BIGINT |
column.numeric(p?, s?) / column.decimal(p?, s?) |
string |
NUMERIC(p,s) |
column.real() |
number |
REAL |
column.double() |
number |
DOUBLE PRECISION |
column.varchar(n) / column.string(n) |
string |
VARCHAR(n) |
column.char(n) |
string |
CHAR(n) |
column.text() |
string |
TEXT |
column.boolean() |
boolean |
BOOLEAN |
column.date() |
Date |
DATE |
column.time({ timezone? }) |
string |
TIME |
column.datetime({ timezone? }) |
Date |
DATETIME/TIMESTAMP |
column.timestamp({ timezone? }) |
Date |
TIMESTAMP |
column.blob() |
Uint8Array |
BLOB/BYTEA |
column.json<T>() |
T |
JSON |
column.jsonb<T>() |
T |
JSONB |
column.uuid() |
string |
UUID |
column.enum(...vals) |
união literal | ENUM |
Modificadores encadeáveis (retornam um novo Column com a flag aplicada):
| Modificador | Efeito |
|---|---|
.primaryKey() |
Marca como PK; implica hasDefault. |
.notNull() |
Torna o tipo inferido não-anulável. |
.default(value) |
Default no insert (valor T ou expressão de sql); marca opcional no insert. |
.onUpdate(value) |
Reaplica a cada UPDATE (ex.: updated_at). |
sql — defaults portáveis¶
Expressões server-side, renderizadas por dialeto (à la func do SQLAlchemy):
| Função | Render | Uso |
|---|---|---|
sql.now() |
CURRENT_TIMESTAMP / now() |
created_at/updated_at |
sql.currentDate() |
CURRENT_DATE |
data de criação |
sql.currentTime() |
CURRENT_TIME |
hora |
sql.uuidv4() |
gen_random_uuid() / fallback |
PK UUID |
sql.raw(expr) |
verbatim | escape hatch |
O default fica guardado em column.<campo>.defaultValue / .onUpdateValue —
alimenta o IR de migração.
columnsOf(Model)¶
Reflete a classe nos seus Column em runtime (Record<string, Column>). Base da
serialização e do reflector de schema das migrações.
InferModel<typeof Model>¶
Tipo da linha lida. Colunas notNull/primaryKey são não-anuláveis; as demais
viram T | null.
InferInsert<typeof Model>¶
Tipo da linha a inserir. Colunas com default (ou PK) são opcionais (?); o resto
é obrigatório.
SELECT¶
select(Model) / select(Model, columns)¶
| Forma | Resultado inferido |
|---|---|
select(User) |
InferModel<typeof User>[] |
select(User, ["id", "name"]) |
Pick<InferModel<typeof User>, "id" \| "name">[] |
SelectBuilder<Full, Proj>¶
| Método | Descrição |
|---|---|
.where(input) |
Filtra; chaves tipadas contra Full, operadores tipados por coluna. |
.orderBy(column, direction?) |
Ordena por coluna ("asc" | "desc", default "asc"). |
.limit(n) |
Limita o número de linhas. |
.offset(n) |
Pula as primeiras n linhas. |
.node |
A AST SelectNode (read-only). |
Operadores de where (OperatorsFor<T>)¶
Cada valor de where aceita um match exato (shorthand de eq) ou um objeto de
operador restrito ao tipo da coluna:
| Tipo | Operadores permitidos |
|---|---|
string |
eq, ne, in, notIn, like, ilike, isNull |
number / bigint / Date |
eq, ne, in, notIn, gt, gte, lt, lte, between, isNull |
boolean |
eq, ne, isNull |
| json / blob | eq, ne, in, notIn, isNull |
OPERATORS (runtime) e o tipo Operator listam o conjunto completo. Operador
inválido pro tipo = erro de compilação.
Combinadores and / or / not¶
A forma objeto é AND implícito. Pra lógica composta, use os combinadores (em select/update/delete/join):
| Símbolo | Faz |
|---|---|
and(...args) |
(...) AND (...) |
or(...args) |
(...) OR (...) |
not(arg) |
NOT (...) |
Cada arg é a forma objeto ({ col: ... }) ou outro combinador. Passe o tipo da
linha (or<UserRow>(...)) pra key-safety dentro do combinador.
INSERT¶
insert(Model)¶
Retorna InsertBuilder.
| Método | Descrição |
|---|---|
.values(row \| rows) |
Tipado por InferInsert<typeof Model>. Aceita 1 ou N. |
.returning() |
Resultado vira a linha completa. |
.returning(columns) |
Resultado vira Pick das colunas. |
Sem returning, o resultado da execução é number (linhas afetadas).
UPDATE¶
update(Model)¶
Retorna UpdateBuilder<Full, false> (não-guarded).
| Método | Descrição |
|---|---|
.set(values) |
Partial<Full> — só as colunas informadas mudam. |
.where(input) |
Filtra e marca Guarded = true. |
.unguarded() |
Opt-in explícito pra atualizar todas as linhas (Guarded = true). |
.returning() / .returning(cols) |
Como no insert. |
DELETE¶
del(Model)¶
Retorna DeleteBuilder<Full, false> (del porque delete é reservado).
| Método | Descrição |
|---|---|
.where(input) |
Filtra e marca Guarded = true. |
.unguarded() |
Opt-in explícito pra deletar todas as linhas. |
.returning() / .returning(cols) |
Como no insert. |
Tipos da AST¶
Expostos pra ferramentas e dialetos: SelectNode, InsertNode, UpdateNode,
DeleteNode, OrderTerm, SortDirection, WhereInput, Returning.
URL do banco¶
parseDatabaseUrl(url)¶
Analisa uma string de conexão e identifica o dialeto, igual ao make_url do
SQLAlchemy. Aceita (e ignora) sufixo de driver async (+asyncpg, +aiosqlite).
import { parseDatabaseUrl, detectDialect } from "tempest-db-js";
parseDatabaseUrl("postgresql://app:secret@localhost:5432/mydb");
// { dialect: "postgresql", host: "localhost", port: 5432, user: "app",
// password: "secret", database: "mydb", driver: null, options: {}, raw: "..." }
parseDatabaseUrl("sqlite:///app.db"); // { dialect: "sqlite", database: "app.db", ... }
detectDialect("sqlite://:memory:"); // "sqlite"
| Símbolo | Descrição |
|---|---|
parseDatabaseUrl(url) |
ParsedDatabaseUrl (dialeto + partes de conexão). |
detectDialect(url) |
Só o Dialect ("sqlite" \| "postgresql"). |
ParsedDatabaseUrl |
Tipo do resultado. |
InvalidDatabaseUrl |
Erro lançado em URL sem scheme ou dialeto desconhecido. |
Serialização¶
Converte entre linha (valores nativos), dict e JSON, com coerção por tipo de
coluna — à la model_dump / model_validate do Pydantic.
import { toDict, toJSON, stringify, fromDict, parse } from "tempest-db-js";
toJSON(User, row); // { ...JSON-safe: Date→ISO, bigint→string, blob→base64 }
toDict(User, row); // { ...nativos, só colunas conhecidas }
stringify(User, row); // string JSON
fromDict(User, payload); // linha validada (coage string→Date/bigint/Uint8Array; JSON.parse)
parse(User, jsonString); // fromDict(JSON.parse(...))
| Função | Faz |
|---|---|
toDict(Model, row) |
Dict de valores nativos, restrito às colunas. |
toJSON(Model, row) |
Objeto JSON-safe (Date→ISO, bigint→string, Uint8Array→base64). |
stringify(Model, row) |
JSON.stringify(toJSON(...)). |
fromDict(Model, data) |
Linha validada a partir de um dict; coage tipos; valida obrigatórios. |
parse(Model, json) |
fromDict(Model, JSON.parse(json)). |
ValidationError |
Lançado quando uma coluna obrigatória falta. |
Compilação SQL (dialetos)¶
A AST de um builder vira SQL parametrizado via um dialeto — o único lugar onde
SQL nasce. Sempre placeholders (? no SQLite, $1 no Postgres), nunca interpolação
(injection-safe por construção). O compile só monta a SQL; quem roda é a sessão
(veja Execução abaixo).
import { getDialect, select, Model, column } from "tempest-db-js";
const sqlite = getDialect("sqlite");
const compiled = sqlite.compile(
select(User).where({ age: { gte: 18 } }).orderBy("name").limit(10).node,
);
// { sql: 'SELECT * FROM "users" WHERE "age" >= ? ORDER BY "name" ASC LIMIT ?',
// params: [18, 10] }
| Símbolo | Descrição |
|---|---|
getDialect("sqlite" \| "postgresql") |
Instância de dialeto. |
BaseDialect.compile(node) |
CompiledQuery ({ sql, params }). |
SqliteDialect / PostgresDialect |
Implementações concretas. |
CompiledQuery |
{ sql: string; params: readonly unknown[] }. |
QueryNode |
União das ASTs compiláveis. |
Diferenças por dialeto: placeholder (? vs $1) e ilike (nativo ILIKE no
Postgres; LIKE no SQLite, case-insensitive em ASCII).
Execução (engine / sessão)¶
Banco identificado pela URL; execução async por padrão, sync opcional pra SQLite.
| Símbolo | Descrição |
|---|---|
createEngine(url, opts?) |
AsyncEngine (SQLite ou PostgreSQL). |
createSyncEngine(url, opts?) |
SyncEngine (SQLite; lança em Postgres). |
engine.session() |
Abre uma Session/SyncSession. |
engine.transaction(fn) |
Bloco transacional (commit/rollback automático). |
engine.close() |
Fecha o driver. |
session.execute(builder) |
Roda e coage; retorna um Result. |
session.stream(builder) |
Iteração preguiçosa (sync: Iterable; async: AsyncIterable). |
session.beginNested(fn) |
Savepoint (transação aninhada). |
createEngine(url, { pool }) |
PoolOptions (size/idleTimeoutMs/connectTimeoutMs) — PostgreSQL. |
Terminais do Result (async retornam Promise):
| Terminal | Retorna |
|---|---|
.all() |
Row[] |
.first() |
Row \| null |
.one() |
Row (erro NoResultError se ≠ 1) |
.oneOrNull() |
Row \| null (erro se > 1) |
.scalar() |
valor da 1ª coluna \| null |
.scalars() |
valores da 1ª coluna [] |
.rowsAffected() |
number |
Drivers: SQLite via node:sqlite embutido (NodeSqliteDriver); PostgreSQL via
postgres.js (lazy). O guard de update/del é exigido por execute (tipo
Executable).
Joins¶
| Símbolo | Descrição |
|---|---|
join(Model, alias) |
Inicia um JoinBuilder<{ [alias]: Row }>. |
.innerJoin(Model, alias, on) |
Inner join; adiciona { [alias]: Row }. |
.leftJoin(Model, alias, on) |
Left join; adiciona { [alias]: Row \| null }. |
.where(input) |
Filtra por refs alias.column tipadas. |
.orderBy(ref, dir?) / .limit(n) / .offset(n) |
Como no select. |
on mapeia refs de fontes existentes pra refs da nova tabela (igualdade):
{ "user.id": "order.userId" }. O resultado é um objeto por alias, coagido por
modelo; leftJoin produz null quando não há correspondência.
Relations¶
| Símbolo | Faz |
|---|---|
hasMany(() => Target, { localKey, foreignKey }) |
Relação 1-N. |
belongsTo(() => Target, { localKey, foreignKey }) |
Relação N-1. |
loadRelations(session, rows, spec) |
Eager-load (1 query/relação); resultado tipado. |
hasMany → Row[]; belongsTo → Row | null.
Migrações (tempest-db-js/migrations)¶
| Símbolo | Faz |
|---|---|
reflectSchema(models) / reflectTable(model) |
Modelo → Schema IR. |
diffSchema(atual, alvo) |
IR × IR → Operation[]. |
invert / invertAll |
Inverso de operações (pro down()). |
renderOperation(op, dialect) |
Operação → SQL. |
generateMigration(draft) |
Codegen de arquivo TS. |
topoOrder / heads |
Ordenação + pontas do DAG. |
MigrationRunner / Op |
Aplica/reverte; version table. |
replaySchema(migrations) |
IR "atual" sem banco. |
introspectSqlite / checkDrift |
Schema vivo + drift (SQLite). |
introspectPostgres / checkDriftPostgres |
Idem (PostgreSQL, estrutural). |
runMigrationCli(argv, config) |
CLI: upgrade/downgrade/check/revision... |