@kequtech/tenon-orm

中文文档
0.4.7发布于 2026/11/01ISCTypeScriptES Module

A PostgreSQL ORM designed for coding agents, with explicit SQL, typed queries, and migrations

原始使用文档
文档目录5 节
  1. Query with SQL
  2. Designed for coding agents
  3. How Tenon fits together
  4. Share configuration with the CLI
  5. Documentation

Tenon ORM

A PostgreSQL ORM designed for coding agents. Built for Node.js and TypeScript.

Tenon keeps database work in forms coding agents can read, write, and check: explicit SQL, ordinary TypeScript functions, and SQL migrations. Queries carry their result types and execution options together, so an agent and the person reviewing its work can see what an operation does in one place.

npm install @kequtech/tenon-orm

Requires Node.js 24+, PostgreSQL 16+, and ESM. TypeScript applications need TypeScript 6+ and Node.js typings. The PostgreSQL driver, pgclear, is included.

Query with SQL

This example assumes a public.users table with integer id and text email columns and a main export in your shared configuration:

import { createTenon, sql } from '@kequtech/tenon-orm';
import { main } from './tenon.config.ts';

const db = createTenon(main);

try {
  const email = '[email protected]';
  const user = await db.query(
    sql<{ id: number; email: string }>`
      SELECT id, email FROM public.users WHERE email = ${email}
    `,
    { returns: 'oneOrNone' },
  );
  // user: { id: number; email: string } | undefined
} finally {
  await db.close();
}

${email} becomes $1 in the SQL, with the value passed separately. sql<Row> describes one returned row. returns chooses how Tenon gives those rows back:

returnsYou receiveRequired rows
manyreadonly Row[]Any number
oneOrNoneRow | undefinedZero or one
oneRowExactly one
native (default)Driver result with rows, rowCount, and fieldsAny number

A row-count mismatch throws. The modes do not add LIMIT or change the SQL. In a server, reuse one database instance and close it during shutdown. Supply environment variables through your application; Tenon does not load .env files.

Designed for coding agents

Tenon's API gives coding agents concrete code to work with and explicit contracts to preserve:

  • Readable SQL. Selected columns, joins, filters, and conflict handling are visible in the query. An agent can inspect the operation directly and use PostgreSQL's existing vocabulary.
  • Ordinary TypeScript. Reusable queries are functions. An agent can follow imports, change a function, and pass the same query code a database or transaction client.
  • Explicit write limits. A query can require exactly one affected row or set a maximum. Tenon rolls back the operation if that bound is violated.
  • Actionable checks. Generated table types describe storage contracts; tenon check reports contradictions between recoverable SQL and declared types. Freshness checks catch stale generated declarations, and database tests verify results and effects.

The guides and changelog ship with the package, giving an agent documentation for the installed version. For work in an existing project, start with the agent guide.

How Tenon fits together

  • SQL defines the operation. Use PostgreSQL joins, aggregates, constraints, and upserts directly. Reuse queries with ordinary functions; use fragments when parts of the SQL need to vary.
  • TypeScript describes the values. Declare query projections with sql<Row>. Optionally generate table read/insert/update types with tenon generate. Capture a versioned schema fingerprint with tenon schema for application-owned guards.
  • Transactions define what commits together. Use db.transaction(async (tx) => { ... }) and run every participating query through tx.
  • Write guards check affected rows. { affectedRows: { exact: 1 } } rolls back a write unless exactly one row was affected. { max: 1 } allows zero or one.
  • Migrations change the schema. Tenon's optional runner applies numbered SQL files. You can keep an existing schema and migration runner.

For object inputs, sql.insertValues(input) and sql.assignments(patch) build the column/value parts of a statement. The table, conditions, expressions, and conflict behavior stay in your SQL. There are no model instances or implicit relationship loading.

Query types are declarations. Tenon does not validate returned data against Row during execution. The optional tenon check command compares recoverable source queries with TypeScript types and PostgreSQL metadata. Keep database tests for actual results and write effects.

Some PostgreSQL values need care: bigint columns and count(*) read as exact strings, numeric and temporal values also default to strings, and JSON/array inputs use explicit encoding helpers. Command rowCount is a number or null. See value mappings before choosing application types.

Share configuration with the CLI

Run tenon init to create tenon.config.ts. Put connection settings and codecs in its main export, then reuse that object with createTenon(main). Initialization stays lazy, so builds that only import the database instance need no credentials.

The CLI uses the same config for migrations, tenon generate, freshness checks, tenon check, and tenon describe query.sql. For multiple databases, add named exports and select one with --database. See shared configuration for the complete setup.

Documentation

Start with Getting started for a complete table-to-query example. Then choose the guide for your task:

GuideWhat it covers
Shared configurationRuntime/CLI connection settings, codecs, command defaults, and overrides
Writing queriesParameters, reusable functions, joins, aggregates, pagination, and fragments
Writing dataInserts, patches, defaults, upserts, JSON, arrays, and batches
Schema types and valuesGeneration, read/write types, codecs, and domain validation
MigrationsCreating, applying, inspecting, and rolling back SQL migrations
Connections and driver accessPool configuration, shutdown, custom codecs, and native features
Checking query typesSource-aware checks and their supported SQL composition
Inspecting and testing queriesPostgreSQL metadata and tests of real behavior
Adopting TenonReplacing an ORM and transferring migration ownership
Agent guideA short implementation workflow for an existing project
API and CLI referenceSignatures, options, errors, commands, and troubleshooting

The README, guides, and changelog ship with the npm package. Read the documentation for your installed version when upgrading. Library maintenance is covered in CONTRIBUTING.md.

ISC licensed. Maintained by Kequtech.

版本与发布记录

@kequtech/tenon-orm 共发布 18 个版本,首次发布于 2026/10/24;过去 12 个月发布了 18 个版本。

版本发布日期距今
0.4.7latest2026/11/011 天前
0.4.62026/11/012 天前
0.4.52026/10/313 天前
0.4.42026/10/303 天前
0.4.32026/10/303 天前
0.4.22026/10/304 天前

关于 @kequtech/tenon-orm 的常见问题

@kequtech/tenon-orm 是什么?

一个PostgreSQL ORM设计用于编码代理,具有显式SQL,类型化查询和迁移

如何安装 @kequtech/tenon-orm?

在项目目录运行 npm install @kequtech/tenon-orm,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 tenon,可以用 npx tenon 直接运行。

@kequtech/tenon-orm 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@kequtech/tenon-orm 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@kequtech/tenon-orm 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@kequtech/tenon-orm 可以商用吗?

@kequtech/tenon-orm 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@kequtech/tenon-orm 还在维护吗?

最新版本 0.4.7 发布于 2026/11/01(1 天前);至今共发布 18 个版本,其中过去 12 个月发布了 18 个;首次发布于 2026/10/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。