@ballistix.digital/odata-query-builder

中文文档
0.12.0发布于 2026/10/23MITTypeScriptCommonJS零依赖近 30 天下载 2323

Typed, fluent OData v4 query-string builder for the dialect @ballistix.digital/typeorm-extensions serves.

原始使用文档
文档目录7 节
  1. Install
  2. Example
  3. What makes it typed
  4. A property read is never a method
  5. Escaping
  6. Documentation
  7. Contributing

@ballistix.digital/odata-query-builder

A typed, fluent builder for the OData v4 query strings that @ballistix.digital/typeorm-extensions serves.

It builds a query string. It does not fetch, and it does not know about the _embedded / _page response envelope. It has zero runtime dependencies.

Full documentation lives in docs/: a guide for a developer who uses the package, and maintainer pages for a developer who changes it.

Install

npm i @ballistix.digital/odata-query-builder

It needs Node 20 or newer, and TypeScript 5.9, 6.0 or 7.0.

Example

import { odataQuery } from '@ballistix.digital/odata-query-builder';

enum ProjectStatusEnum {
  DRAFT = 'draft',
  ACTIVE = 'active',
  ARCHIVED = 'archived',
}

// ProjectDto is your own DTO type. Getting started shows its shape.
const query = odataQuery<ProjectDto>()
  .filter((v, o) =>
    o.and(
      v.archived.isFalse(),
      v.status.in([ProjectStatusEnum.DRAFT, ProjectStatusEnum.ACTIVE]),
      v.children.any((a) => a.priority.ge(2)),
    ),
  )
  .select('id', 'name', 'status')
  .expand.parent((p) => p.select('name').expand.owner((u) => u.select('fullName')))
  .orderBy('name', 'desc')
  .top(25)
  .count()
  .toQueryString();
// $filter=archived eq false and status in ('draft','active') and children/any(a:a/priority ge 2)&$select=id,name,status&$expand=parent($select=name;$expand=owner($select=fullName))&$orderby=name desc&$top=25&$count=true

Getting started prints the ProjectDto shape the examples use.

What makes it typed

The scope a filter() callback receives is derived from the DTO type alone:

  • an own scalar column becomes an expression typed by the column's own type, so an enum column takes enum members and a number column refuses a string;
  • a _embedded to-one relation becomes a nested scope, emitted with /;
  • a _embedded to-many relation becomes a lambda namespace, so any and all are the only things reachable on it — which is what the server accepts;
  • a primitive array column (text[]) becomes a lambda namespace over the element.

expand.<relation> lists exactly the relations _embedded declares. There is no code generation, no $metadata document, and no configuration: the DTO convention is _embedded, and the library assumes it.

A property read is never a method

v.year is ambiguous at runtime: the year() function, or a column called year. Reading a property therefore never resolves a function. Read further from it and it was a path segment; call it and it was a function. Both roles work in one expression:

v.year.eq(v.date.asDate().year());
// year eq year(date)

Escaping

toQueryString() is already URL-safe. Do not run encodeURIComponent over it — that turns %25 into %2525. The escape rules list what each literal character becomes.

Use toParams() when the caller has its own serialiser (URLSearchParams, ky): it hands back the raw values so that serialiser's own encoding is the only one applied.

Documentation

  • Getting started — install, the _embedded assumption, a first query.
  • Querying — every verb, the expand namespace, filtered expansions and odataItem.
  • Filtering — operators, functions, lambdas, dates, cast and the combinators.
  • Sending the query — toQueryString() or toParams(), and the escape rules.
  • Errors — what the builder throws and how to catch it.
  • Cookbook — twelve call shapes with their strings.

Contributing

To run the tests and find your way around the source, read Conventions and Testing.

版本与发布记录

@ballistix.digital/odata-query-builder 共发布 13 个版本,首次发布于 2026/10/22;过去 12 个月发布了 13 个版本。

版本发布日期距今
0.12.0latest2026/10/2315 天前
0.11.02026/10/2315 天前
0.10.02026/10/2316 天前
0.9.02026/10/2316 天前
0.8.02026/10/2316 天前
0.7.02026/10/2316 天前

关于 @ballistix.digital/odata-query-builder 的常见问题

@ballistix.digital/odata-query-builder 是什么?

Typed, fluent OData v4 query-string builder for the dialect @ballistix.digital/typeorm-extensions serves.

如何安装 @ballistix.digital/odata-query-builder?

在项目目录运行 npm install @ballistix.digital/odata-query-builder,或使用 pnpm add / yarn add / bun add。

@ballistix.digital/odata-query-builder 支持 TypeScript 吗?

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

@ballistix.digital/odata-query-builder 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@ballistix.digital/odata-query-builder 需要什么版本的 Node.js?

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

@ballistix.digital/odata-query-builder 可以商用吗?

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

@ballistix.digital/odata-query-builder 的下载量有多少?

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

@ballistix.digital/odata-query-builder 还在维护吗?

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