Skip to content

rapiq

One query language between client & server. Build JSON:API-style queries on the client, parse them into a typed AST against schema allow-lists on the server — and turn them into SQL or TypeORM queries with composable adapters.

playground

SQL dialect

GET
/users?codec=url-expression&fields=id,name,age&filter=and(contains(name,'to'),gte(age,'21'))&page[limit]=25&sort=-age
SQL
SELECT "id", "name", "age"
FROM "users"
WHERE ("name" ~* $1 and "age" >= $2)
ORDER BY "age" DESC
LIMIT 25
-- params: ["to",21]

Live — @rapiq/parser-simple, @rapiq/codec-url and @rapiq/adapter-sql are running in your browser.

A pipeline, not a parser

🌐

JSON:API-style

Fields, filters, relations, pagination & sort — one consistent query scheme based on the JSON:API specification.

🌲

Typed query AST

Input parses into Query nodes that backends consume via the visitor pattern — new targets never touch core.

🛡️

Schema allow-lists

Declare what clients may request — allowed keys, defaults, mappings. Disallowed input is dropped or throws.

🧩

Pluggable parsers

Parse plain objects or an expression language — both dialects produce the exact same Query AST.

🗄️

SQL & TypeORM

Render parameterized SQL for five dialects, or apply a Query straight to a TypeORM SelectQueryBuilder.

🔒

TypeScript-first

Typed key paths via recursive NestedKeys<T> — allow-lists and defaults autocomplete against your records.

One AST, one package family

rapiq is a family of focused, composable packages. Install only what each side of your application needs — everything meets in the core query AST. Browse all packages →

@rapiq/core

The foundation — query AST, typed build layer and the schema system everything else builds on.

  • defineQuery() + condition helpers (eq, and, or, …)
  • defineSchema() + SchemaRegistry allow-lists
  • Parser base classes & typed errors
Read more →

@rapiq/parser-simple

Parses plain object/array input — the URL-query-like "simple" dialect.

  • Filters like { age: '>=18', name: '~jo~' }
  • Schema validation while parsing
  • Powers the URL decoder
Read more →

@rapiq/parser-expression

Parses the function-call expression dialect into the same Query AST.

  • and(eq(name, 'John'), gte(age, '18'))
  • Nested or() / not() groups on the wire
  • Default filter dialect of the URL codec
Read more →

@rapiq/parser-mongo

Parses MongoDB-style filter documents with typed values.

  • { age: { $gte: 18 } }, $and / $or / $not
  • $elemMatch incl. the element-level form
  • Grammar errors always throw typed
Read more →

@rapiq/codec-url

URL query-string codec — the transport between caller and receiver.

  • Expression filters by default
  • Legacy simple-filter decoding
  • Schema-aware encode & decode
Read more →

@rapiq/adapter-sql

Dialect-agnostic SQL adapter turning the AST into parameterized fragments.

  • Presets: Postgres, MySQL, SQLite, MSSQL, Oracle
  • Dialects are option objects, not subclasses
  • Visitor-driven — fragments accumulate per parameter
Read more →

@rapiq/adapter-typeorm

Applies a parsed Query directly to a TypeORM SelectQueryBuilder.

  • Mutates the query builder in place
  • Relations become joins automatically
  • Builds on the @rapiq/adapter-sql visitors
Read more →

@rapiq/adapter-prisma

Serializes a parsed Query into a Prisma findMany args object.

  • Pure value: no prisma dependency
  • Same-element relation semantics preserved
  • Engine-verified parity (SQLite & Postgres)
Read more →

@rapiq/adapter-drizzle

Serializes a parsed Query into a drizzle relational-queries findMany config.

  • Pure value: no drizzle dependency
  • Correlated EXISTS relation filters
  • Engine-verified parity in the default suite
Read more →

@rapiq/adapter-memory

Evaluates the same Query against in-memory objects & arrays.

  • Filters compile to plain predicates
  • SQL-parity semantics — guards agree with the database
  • Perfect for authorization checks & tests
Read more →

From client to query in three steps

Build on the client, transport as a query string, parse & validate on the server.

# client side — build & encode queries
npm install @rapiq/core @rapiq/codec-url

# server side — parse, validate & translate
npm install @rapiq/core @rapiq/parser-simple @rapiq/adapter-sql

@rapiq/adapter-typeorm

Straight into TypeORM

Apply a parsed Query directly to a SelectQueryBuilder — the adapter walks the AST and mutates the builder, nothing is stringified twice.

  • TypeormAdapter — wraps any SelectQueryBuilder
  • Visitor-driven — reuses the @rapiq/adapter-sql visitors
  • Relations → joins — allowed relations join automatically
  • Parameterized — filter values bind as parameters, never interpolated
Read the TypeORM guide →
controller.ts
import { TypeormAdapter } from '@rapiq/adapter-typeorm';

const queryBuilder = repository.createQueryBuilder('user');

const adapter = new TypeormAdapter({ queryBuilder });
adapter.execute(query);

const [entities, total] = await queryBuilder.getManyAndCount();

Released under the MIT License.