@vibeorm/sql
v5.3.0
Published
Dialect-aware SQL layer for VibeORM v2 — SQL AST, renderers and capability tables for postgres, sqlite and mysql
Maintainers
Readme
@vibeorm/sql
Part of VibeORM — a type-safe TypeScript ORM for Bun and Node. Prisma-schema or TypeScript-DSL input, a canonical schema IR, a generated client, and a dialect-aware SQL layer over PostgreSQL, PGlite, SQLite and MySQL.
The dialect-aware SQL layer. Every decision about SQL text — quoting, placeholders, per-dialect strategy switches, value encoding — lives in this package, so the runtime and migrate build a dialect-neutral AST and never concatenate SQL themselves.
bun add @vibeorm/sqlStable.
2.0.0, published under thelatestdist-tag. The v1 line stays installable asvibeorm@1.
Most users never install this directly — it ships as a dependency of vibeorm. Reach for it when you are building tooling on the IR or SQL layer.
What it exports
- SQL AST:
SqlStatement(SelectStatement,InsertStatement,UpdateStatement,DeleteStatement) andSqlExpr, plus the supporting node typesColRef,TableRef,SelectExpr,OrderTerm,AggRef,AggSelect,LateralJoin,InnerJoin,OnConflictClause,SetOperation,ListSetOperation,RowNumberProjection. Guards:isSetOperation,isListSetOperation,isSqlDefaultCell, and theSQL_DEFAULT_CELLmarker. - Dialects:
postgresDialect,sqliteDialect,mysqlDialect, theSqlDialecttype, and the registrySQL_DIALECTS/getSqlDialect. A dialect carriesquoteIdentplus the strategy switches:= ANYversusINexpansion,ILIKEversusLOWER(...) LIKE LOWER(...), the upsert form,ESCAPEclause presence,RETURNINGavailability. - Capability tables:
DIALECT_CAPABILITIES,POSTGRES_CAPABILITIES,SQLITE_CAPABILITIES,MYSQL_CAPABILITIES— frozen objects consumed by the runtime, migrate, the generator and the E2E harness. A feature a dialect cannot express throwsVIBE_UNSUPPORTED_CAPABILITYrather than degrading. - Codec tables:
DIALECT_CODECS,POSTGRES_CODECS,SQLITE_CODECS,MYSQL_CODECS,decodeIsNoop, and theCodecTable/ScalarCodec/WireFidelitytypes. All per-dialect value encode and decode lives here, in one place, instead of scattered through query builders. - Rendering:
renderStatement({ dialect, statement })returnsRenderedQuery({ text, values, returning });renderExprandrenderFragmentrender sub-parts against a sharedParamCollector. Placeholders always come fromParamCollector, never from hand-written$1or?. - LIKE helpers:
escapeLikePattern,escapeGlobPattern,containsPattern,startsWithPattern,endsWithPattern,strictMatchPattern.
Rendering an AST
import { postgresDialect, renderStatement, sqliteDialect } from "@vibeorm/sql";
import type { SqlStatement } from "@vibeorm/sql";
const statement: SqlStatement = {
kind: "select",
table: { name: "User" },
columns: [{ name: "id" }, { name: "email" }],
where: { kind: "cmp", op: "eq", column: { name: "id" }, value: 1 },
};
renderStatement({ dialect: postgresDialect, statement });
// { text: `SELECT "id", "email" FROM "User" WHERE "id" = $1`, values: [1], ... }
renderStatement({ dialect: sqliteDialect, statement });
// { text: `SELECT "id", "email" FROM "User" WHERE "id" = ?`, values: [1], ... }The returning field reports "native" when RETURNING was rendered, "omitted" when it was requested but the dialect lacks it (the caller re-selects), and "none" when it was not requested.
Reviewable SQL
Every statement shape this package can emit is pinned to its exact SQL text and parameters, per dialect, in sql-catalog.md. The file is generated from test-asserted cases (tests/catalog/cases.ts), so it cannot drift from the renderers.
Adding or changing a rendering means adding or updating a catalog case in the same change; bun run catalog:check enforces that in CI. Reviewing the catalog diff is how wrong quoting, bad placeholder order or dialect drift becomes visible without running a database.
