logo

qbjs

API Reference

Query Builder

API reference for the createQueryBuilder factory function and QueryBuilder interface

The Query Builder is the main entry point for using qbjs. It wires together the parser, security validator, and compiler to provide a unified interface for query processing.

createQueryBuilder

Factory function to create a configured query builder instance.

import { createQueryBuilder, createDrizzlePgCompiler } from '@qbjs/core';

const builder = createQueryBuilder({
  config: {
    allowedFields: ['id', 'name', 'email', 'createdAt'],
    maxLimit: 50,
  },
  compiler: createDrizzlePgCompiler(),
});

Parameters

ParameterTypeRequiredDescription
optionsCreateQueryBuilderOptionsYesConfiguration options
options.configSecurityConfigNoSecurity configuration for query validation
options.compilerQueryCompilerYesThe compiler to use for transforming AST to ORM queries

Returns

Returns a QueryBuilder instance with methods for parsing, compiling, and executing queries.

QueryBuilder Interface

The QueryBuilder interface provides methods for processing queries at different stages.

parse

Parse a query input into a validated AST. Applies security constraints during parsing.

const parseResult = builder.parse({
  fields: 'id,name,email',
  page: '1',
  limit: '10',
  sort: 'createdAt:desc',
  filter: { status: { eq: 'active' } }
});

if (parseResult.errors.length === 0) {
  console.log(parseResult.ast);
}

Parameters

ParameterTypeRequiredDescription
inputQueryInputYesQuery input object
input.fieldsstring | nullNoComma-separated field names to select
input.pagestring | number | nullNoPage number (1-based)
input.limitstring | number | nullNoNumber of items per page
input.sortstring | nullNoSort specification (e.g., "createdAt:desc")
input.filterunknownNoFilter object from QS parsing

Returns

interface QueryBuilderParseResult {
  ast: QueryAST | null;
  errors: QueryBuilderError[];
  warnings: QueryBuilderWarning[];
}

parseFromUrl

Parse a URL's query string into a validated AST. Uses the qs library to parse bracket notation filters.

const parseResult = builder.parseFromUrl(
  'http://localhost:8787/api/posts?filter[title][containsi]=typescript&page=1&limit=10'
);

Parameters

ParameterTypeRequiredDescription
urlstringYesFull URL string with query parameters

Returns

Same as parse() - returns QueryBuilderParseResult.

compile

Compile a validated AST into an ORM-specific query.

const compileResult = builder.compile(parseResult.ast!, usersTable);

if (compileResult.errors.length === 0) {
  // Use compileResult.query with Drizzle
}

Parameters

ParameterTypeRequiredDescription
astQueryASTYesThe QueryAST to compile
tableTTableYesThe table schema to compile against

Returns

interface QueryBuilderCompileResult<TQuery> {
  query: TQuery | null;
  errors: CompileError[];
  warnings: CompileWarning[];
}

execute

Execute a full query: parse, validate, and compile in one step.

const result = builder.execute({
  fields: 'id,name,email',
  page: '1',
  limit: '10',
  filter: { status: { eq: 'active' } }
}, usersTable);

if (result.errors.length === 0) {
  // Use result.query with Drizzle
  const users = await db.query.users.findMany({
    columns: result.query.columns,
    where: result.query.where,
    orderBy: result.query.orderBy,
    limit: result.query.limit,
    offset: result.query.offset,
  });
}

Parameters

ParameterTypeRequiredDescription
inputQueryInputYesQuery input object
tableTTableYesThe table schema to compile against

Returns

interface QueryBuilderExecuteResult<TQuery> {
  query: TQuery | null;
  ast: QueryAST | null;
  errors: QueryBuilderError[];
  warnings: QueryBuilderWarning[];
}

executeFromUrl

Execute a full query from a URL: parse, validate, and compile in one step.

const result = builder.executeFromUrl(
  'http://localhost:8787/api/posts?filter[title][containsi]=typescript&page=1&limit=10',
  postsTable
);

Parameters

ParameterTypeRequiredDescription
urlstringYesFull URL string with query parameters
tableTTableYesThe table schema to compile against

Returns

Same as execute() - returns QueryBuilderExecuteResult<TQuery>.

getSecurityConfig

Get the resolved security configuration.

const config = builder.getSecurityConfig();
console.log(config.maxLimit); // 50
console.log(config.allowedFields); // ['id', 'name', 'email', 'createdAt']

Returns

Returns the resolved SecurityConfig object with all defaults applied.

Complete Example

import { Hono } from 'hono';
import { createQueryBuilder, createDrizzlePgCompiler } from '@qbjs/core';
import { db } from './db';
import { posts } from './db/schema';

const app = new Hono();

const queryBuilder = createQueryBuilder({
  config: {
    allowedFields: ['id', 'title', 'content', 'status', 'createdAt'],
    maxLimit: 100,
    operators: ['eq', 'ne', 'contains', 'containsi', 'gt', 'lt', 'gte', 'lte'],
  },
  compiler: createDrizzlePgCompiler(),
});

app.get('/api/posts', async (c) => {
  const result = queryBuilder.executeFromUrl(c.req.url, posts);

  if (result.errors.length > 0) {
    return c.json({ errors: result.errors }, 400);
  }

  const data = await db.query.posts.findMany({
    columns: result.query!.columns,
    where: result.query!.where,
    orderBy: result.query!.orderBy,
    limit: result.query!.limit,
    offset: result.query!.offset,
  });

  return c.json({
    data,
    warnings: result.warnings,
  });
});

export default app;

Error Types

QueryBuilderError

Combined error type that includes parse errors, security errors, and compile errors.

type QueryBuilderError = ParseError | SecurityError | CompileError;

QueryBuilderWarning

Combined warning type that includes parse warnings, security warnings, and compile warnings.

type QueryBuilderWarning = ParseWarning | SecurityWarning | CompileWarning;

On this page