API documentation
Matches the npm package exports. For a live REPL, use the playground.
On this page
Installation
Requires Node.js 18+.
npm install mongo-query-toolsBasic 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.
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 substringsearch(OR combination).allowedFilters— allow-list for filter keys originating from query params.allowedSorts— field names allowed insorttokens (omit+/-prefixes from this array).defaultFilters— always merged. Unexpected query keys do not erase these predicates.defaultSort— used whensortis missing or invalid (same string syntax:fieldasc,-fielddesc).maxLimit— clamps resolvedlimit.defaultPage,defaultLimit— fallbacks when pagination params absent or malformed.defaultLimithonoursmaxLimit.conditionalFilters/conditionalFilter— branching merge viawhen/ 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.
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.
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; elsedefaultPage(fallback1) applies.limit≥1; elsedefaultLimit(fallback10) then clamps throughmaxLimit.- Present
skipoverrides canonical(page − 1) × limit.
TypeScript Exports
Consume whatever your bundler tree-shakes from the barrel:
import { buildMongoQuery } from "mongo-query-tools";
import type {
BuildMongoQueryConfig,
BuildMongoQueryResult,
ConditionalFilterQuery,
ConditionalFilterRule,
QueryParams,
SortSpec,
} from "mongo-query-tools";