@application-kit/typeorm

中文文档
0.5.2发布于 2026/11/07MITTypeScriptESM + CJS近 30 天下载 2496

Курсорный листинг на TypeORM: контракты листинга, пагинатор, фильтры, ORM-база сущности, конфиг и корневой модуль соединения Postgres, SQL-логгер с маской bind-параметров

原始使用文档
文档目录8 节
  1. Установка
  2. Точки входа
  3. Листинг в репозитории
  4. Обработчик query
  5. ORM-база
  6. Логгер SQL
  7. Соединение с Postgres
  8. CLI миграций

@application-kit/typeorm

Курсорный листинг на TypeORM: контракты листинга (пагинатор, сортировка, фильтры), курсорный пагинатор поверх SelectQueryBuilder, перевод фильтров в where, ORM-база сущности и конфиг соединения с Postgres из окружения.

Установка

yarn add @application-kit/typeorm

Peer-зависимости: typeorm, @nestjs/common; для входа /nest — @nestjs/cqrs, @nestjs/typeorm, nestjs-pino, class-transformer, class-validator, reflect-metadata; для DatabaseLogger входа /logging — nestjs-pino (объявлены опциональными: корню и /listing они не нужны).

Точки входа

ВходЧто внутриЗависимости
@application-kit/typeorm/listingFilterInterface, FiltersMatchMode, SortingInterface, SortOrder, PaginatorInterface, ListingRepositoryInterfaceнет — годится для браузерного кода
@application-kit/typeormgetListByCursor, CursorPaginator, getWhereByFilters, isUniqueViolation, estimateRowCount, withIdTiebreaker, AbstractOrmEntity, PackageOrmInterfacetypeorm, @nestjs/common
@application-kit/typeorm/nestTypeormRootModule, ListingQuery, ListingHandler, DatabaseConfig, DatabaseEnvironment, createCliDataSource@nestjs/common, @nestjs/cqrs, @nestjs/typeorm, nestjs-pino, class-transformer, class-validator, reflect-metadata
@application-kit/typeorm/loggingcreateTypeormLogger, TypeormQueryLogger, createSqlParameterMask, runAsInfrastructureQuery, isInfrastructureQuery, SqlLoggerInterface, DatabaseLoggernestjs-pino — createTypeormLogger и DatabaseLogger

Клиент (Vue, GraphQL-типы) импортирует только /listing: корень тянет TypeORM и Nest. Nest-интеграции (DI-модули, CQRS, конфиг) — только во входе /nest, корень их не реэкспортирует и @nestjs/typeorm/nestjs-pino не тянет.

Листинг в репозитории

import { getListByCursor } from '@application-kit/typeorm'
import type { ListingRepositoryInterface } from '@application-kit/typeorm/listing'

export class UserRepository implements ListingRepositoryInterface<User> {
  public async list(paginator, sorting, filters) {
    return getListByCursor(UserEntity, this.repository.createQueryBuilder('user'), toDomain, paginator, filters, sorting)
  }
}

Неверный курсор страницы — InvalidPageCursorError (BadRequestException, HTTP 400).

Обработчик query

import { ListingHandler, ListingQuery } from '@application-kit/typeorm/nest'

export class GetUsersQuery extends ListingQuery {}

@QueryHandler(GetUsersQuery)
export class GetUsersHandler extends ListingHandler<User> {
  public constructor(@Inject(USER_REPOSITORY) repository: UserRepository) {
    super(repository)
  }
}

ORM-база

AbstractOrmEntity — колонки id (uuid), createdAt, updatedAt; OrmEntityProps<E> — свойства сущности без них. Имя отличается от доменного AbstractEntity из DDD-библиотек намеренно.

Логгер SQL

TypeormQueryLogger — адаптер Logger TypeORM поверх любого pino-совместимого логгера (SqlLoggerInterface: debug/info/warn/error). SQL приложения пишется на info с bind-параметрами, медленный запрос — warn, упавший — error с ошибкой под ключом err; SQL из области runAsInfrastructureQuery (пробы health, которые иначе дают до 97 % потока логов сервиса) уходит на debug.

createTypeormLogger(pinoParams, maskSqlParameters?) — сборка на pino-логгере: TypeormQueryLogger поверх DatabaseLogger с маской по умолчанию. Одна сборка на корень соединения (TypeormRootModule) и CLI миграций — калибровка маски у них не разъедется. Маска bind-параметров — аргумент:

import { createSqlParameterMask, createTypeormLogger } from '@application-kit/typeorm/logging'

const maskSqlParameters = createSqlParameterMask({
  // Порог усечения строки; по умолчанию 256 — user-agent сессии доезжает целиком, дамп обрезается.
  maxValueLength: 256,
  // Формы потребителя проверяются раньше форм по умолчанию.
  forms: [{ label: 'session-token', pattern: /^[\da-f]{64}$/u }],
})

const logger = createTypeormLogger(pinoParams, maskSqlParameters)

Маска смотрит на форму значения, а не на имя колонки (параметры TypeORM позиционные): по умолчанию скрываются bcrypt-хеши, JWT, hex-хеши от 32 символов, шифротекст AES-GCM из трёх base64-кусков, base32 от 16 символов и base64 от 40 — на месте значения метка [masked:<label>]; значение длиннее порога — префикс с пометкой …[truncated:<длина>]. Остальные значения (email, идентификаторы, числа) остаются в логе: по ним разбирают заявки. Массив параметром обходится поэлементно, объекты (JSONB) — нет. Секрет с формой обычного текста маска не ловит.

DatabaseLogger — отдельный PinoLogger с контекстом DatabaseLogger: контекст живёт в экземпляре, и общий логгер приложения под SQL занимать нельзя. Область пробы открывает вызывающий:

return runAsInfrastructureQuery(async () => this.health.check(indicators))

Соединение с Postgres

DatabaseConfig собирает DataSourceOptions из окружения DB_* (DatabaseEnvironment — класс валидации class-validator): соединение всегда с верификацией сертификата сервера, statement_timeout сессии, стратегия имён TypeormPluralNamingStrategy (зависимость пакета) — под неё пишутся сущности и миграции потребителя. entities, migrations и logger в опциях нет — их добавляет вызывающий.

ПеременнаяНазначение
DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORDадрес и учётные данные
DB_SSL_CA_FILEпуть к CA сервера БД — обязателен во всех окружениях; нечитаемый файл роняет процесс на буте, а не отключает проверку
DB_STATEMENT_TIMEOUT_MSпотолок времени SQL-запроса, мс; не задан — без потолка. Задаётся процессам, обслуживающим пользовательские запросы; миграциям, CLI и консьюмерам — нет: у них легитимно долгие запросы

Регистрацию и валидацию окружения делает приложение — пакет отдаёт классы и корень соединения:

import { DatabaseConfig, DatabaseEnvironment, TypeormRootModule } from '@application-kit/typeorm/nest'

// @libs-for-dev/nestjs-config-module: конфиг и env-класс — провайдеры, валидация на старте
const databaseConfigsModule = ConfigsModule.forFeature([DatabaseConfig], [DatabaseEnvironment])

TypeormRootModule.forRoot({ imports: [databaseConfigsModule] })

TypeormRootModule.forRoot({ imports, maskSqlParameters? }) — TypeOrmModule.forRootAsync с опциями DatabaseConfig, autoLoadEntities (entities пакетов kit регистрирует их собственный TypeOrmModule.forFeature) и логгером createTypeormLogger. Логгер собирается из параметров глобального LoggerModule nestjs-pino (PARAMS_PROVIDER_TOKEN): он обязан быть в графе процесса.

createDataSourceOptions({ maxQueryExecutionTime }) — порог медленного запроса для логгера TypeORM, по умолчанию 1000 мс.

CLI миграций

createCliDataSource собирает DataSource для typeorm -d без Nest-контейнера: опции DatabaseConfig, миграции и entities продукта глобами и таблицы пакетов — их объекты orm (PackageOrmInterface: классы entities и миграций).

import { orm as mailerOrm } from '@application-kit/mailer'
import { orm as outboxOrm } from '@application-kit/transaction-outbox'
import { createCliDataSource, DatabaseConfig, DatabaseEnvironment } from '@application-kit/typeorm/nest'

export default createCliDataSource({
  app: { buildDirs: ['modules', 'libs'], sourceDirs: ['src'] },
  config: new DatabaseConfig(exposeObjectWithValidation(process.env, DatabaseEnvironment)),
  logger: typeormQueryLogger,
  packages: [outboxOrm, mailerOrm],
})

Каталоги — относительно cwd CLI; внутри каждого миграции ищутся по **/typeorm/migrations/, entities — по **/typeorm/entities/. sourceDirs — исходники под ts-node: миграции .ts/.js и entities (по ним migration:generate сравнивает схему). buildDirs — скомпилированный код образа: только миграции .js (рядом лежат .d.ts), entities для migration:run не нужны. Глоб по корню образа не годится — он нашёл бы миграции пакетов в node_modules дважды (ESM и CJS), поэтому пакеты отдают классы. logger обязателен: без него CLI пишет дефолтным логгером TypeORM простым текстом, мимо маски bind-параметров (/logging).

版本与发布记录

@application-kit/typeorm 共发布 9 个版本,首次发布于 2026/10/04;过去 12 个月发布了 9 个版本。

版本发布日期距今
0.5.2latest2026/11/071 天前
0.5.12026/10/2612 天前
0.5.02026/10/2118 天前
0.4.02026/10/1721 天前
0.3.02026/10/1227 天前
0.2.02026/10/1127 天前

关于 @application-kit/typeorm 的常见问题

@application-kit/typeorm 是什么?

Курсорный листинг на TypeORM: контракты листинга, пагинатор, фильтры, ORM-база сущности, конфиг и корневой модуль соединения Postgres, SQL-логгер с маской bind-параметров

如何安装 @application-kit/typeorm?

在项目目录运行 npm install @application-kit/typeorm,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:typeorm(^1.0.0)、@nestjs/common(^11.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@application-kit/typeorm 支持 TypeScript 吗?

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

@application-kit/typeorm 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@application-kit/typeorm 需要什么版本的 Node.js?

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

@application-kit/typeorm 可以商用吗?

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

@application-kit/typeorm 的下载量有多少?

根据 npm 官方下载统计,@application-kit/typeorm 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,496 次,日均约 83 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@application-kit/typeorm 还在维护吗?

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