Documentation

API documentation

Matches the npm package exports. For a live REPL, use the playground.

Installation

Requires Node.js 18+.

bash
npm install mongo-query-tools

Basic Usage

Pass HTTP-shaped query params and a configuration object — you get a filter, sort, page, limit, and skip ready for MongoDB Driver or Mongoose.

typescript
import { buildMongoQuery } from "mongo-query-tools";

const options = buildMongoQuery(
  req.query as Record<string, string | string[] | undefined>,
  {
    searchableFields: ["name", "email"],
    allowedFilters: ["status", "role"],
    allowedSorts: ["createdAt", "name"],
    defaultFilters: { isDeleted: false },
    defaultSort: "-createdAt",
    maxLimit: 100,
    defaultPage: 1,
    defaultLimit: 10,
  },
);

Config Options

  • searchableFields

    Applied to case-insensitive substring search (OR combination).

  • allowedFilters

    Allow-list for filter keys originating from query params.

  • allowedSorts

    Field names allowed in sort tokens (omit + / - prefixes from this array).

  • defaultFilters

    Always merged. Unexpected query keys do not erase these predicates.

  • defaultSort

    Used when sort is missing or invalid (same string syntax: field asc, -field desc).

  • maxLimit

    Clamps resolved limit.

  • defaultPage, defaultLimit

    Fallbacks when pagination params absent or malformed. defaultLimit honours maxLimit.

  • conditionalFilters / conditionalFilter

    Branching merge via when / filter — later merges win on key clashes (Object.assign).

Conditional Filters

Layer tenancy or auth predicates without stuffing framework globals into the parser. when and filter receive the identical query forwarded to buildMongoQuery.

typescript
import { buildMongoQuery, type QueryParams } from "mongo-query-tools";

type AppQuery = QueryParams & { mode?: string };

const options = buildMongoQuery(req.query as AppQuery, {
  defaultFilters: { isDeleted: false },
  searchableFields: ["name", "email"],
  allowedFilters: ["role"],
  conditionalFilters: [
    {
      when: (query) => query.mode === "personal",
      filter: () => ({ ownerId: "current-user" }),
    },
  ],
});

Reserved Query Keys

Parsed as controls — never surfaced as standalone filter props even if accidentally listed inside allowedFilters.

  • page
  • limit
  • skip
  • sort
  • search

Sorting Format

Comma-separated segments. Prefix with - for descending, + for explicit ascending, or omit the prefix for ascending shorthand.

QuerySort
name{ name: 1 }
-createdAt{ createdAt: -1 }
-createdAt,name{ createdAt: -1, name: 1 }

If any segment violates allowedSorts, the entire sort clause is discarded and defaultSort resumes when present.

Pagination Behavior

  • •page ≥ 1; else defaultPage (fallback 1) applies.
  • •limit ≥ 1; else defaultLimit (fallback 10) then clamps through maxLimit.
  • •Present skip overrides canonical (page − 1) × limit.

TypeScript Exports

Consume whatever your bundler tree-shakes from the barrel:

typescript
import { buildMongoQuery } from "mongo-query-tools";
import type {
  BuildMongoQueryConfig,
  BuildMongoQueryResult,
  ConditionalFilterQuery,
  ConditionalFilterRule,
  QueryParams,
  SortSpec,
} from "mongo-query-tools";

Mongo Query Tools

Build safe MongoDB query objects from API query params. Keep allow-lists, pagination, and Mongo semantics consistent across list APIs.

© 2026 Mongo Query Tools