Utilities for constructing and using query parameters.
pnpm add @freckle/query-paramsThis package is ESM-only.
Appends a query string to baseUrl. null and undefined values are dropped,
arrays are joined with ,, and Moment values become epoch milliseconds. When
nothing is left to append, baseUrl is returned unchanged.
import {urlWithQueryParams} from '@freckle/query-params'
urlWithQueryParams('/api/students', {grade: 3, active: true})
// '/api/students?grade=3&active=true'
urlWithQueryParams('/api/students', {grade: null, ids: [1, 2, 3]})
// '/api/students?ids=1,2,3'
urlWithQueryParams('/api/students', {})
// '/api/students'Values of any other type throw:
urlWithQueryParams('/api/students', {a: {b: 1}})
// Error: Invalid type of query param object for key aThe query string on its own, without a base URL or ?. Returns null when every
value was dropped, which is what makes the urlWithQueryParams empty case work.
import {createAPIQueryParams} from '@freckle/query-params'
createAPIQueryParams({a: 1, b: 'x'}) // 'a=1&b=x'
createAPIQueryParams({}) // nullExpands a filter object into name[operator] keys, for APIs that take
range filters. Supported operators are in, notin, gt, gte, lt and lte.
import {toQueryParamObj, urlWithQueryParams} from '@freckle/query-params'
toQueryParamObj('score', {gte: 0.5, lt: 0.9})
// {'score[gte]': 0.5, 'score[lt]': 0.9}
urlWithQueryParams('/api/students', toQueryParamObj('score', {gte: 0.5}))
// '/api/students?score[gte]=0.5'Keys and values are interpolated as-is. Anything with a reserved character in it changes meaning rather than being escaped:
urlWithQueryParams('/api', {q: 'a&b=c'}) // '/api?q=a&b=c' -> server reads two params
urlWithQueryParams('/api', {q: 'a#b'}) // '/api?q=a#b' -> '#b' becomes a fragment
urlWithQueryParams('/api', {name: 'John Smith'}) // '/api?name=John Smith'Pass values that are already safe — ids, numbers, booleans, timestamps, enum strings — or encode them yourself before passing them in. Free-form text is not safe to pass directly.
- Package manager: pnpm (Node version pinned in
.nvmrc) pnpm build—tsc -p tsconfig.build.json, emits todist/pnpm test— Vitestpnpm coverage— Vitest with coverage, gated at 70% (lines/branches/functions/statements)pnpm typecheck—tsc --noEmit, includes test filespnpm lint— ESLintpnpm format/pnpm format-check— Prettierpnpm knip— unused files/dependencies/exports- CI runs all of the above on every PR, plus a check that
dist/is up to date
See RELEASE.md.