Skip to content

url

Parses the request URL into pathname, parsed query parameters, and the raw search string. Uses a fast single-pass parser (indexOf + slice) instead of the URL constructor for performance. Multi-value query parameters automatically become arrays.

Pipeline stage: Negotiation

import {url} from '@centralping/ergo';

None. The url() factory takes no parameters.

Returns a URL descriptor stored on the domain accumulator at acc.url:

{
pathname: '/users',
search: '?page=1&filter=a&filter=b',
query: {
page: '1',
filter: ['a', 'b']
}
}
Property Type Description
pathname string | undefined URL path before the query string
search string | undefined Raw query string including leading ?; undefined when absent
query Record<string, string | string[]> Parsed query parameters; multi-value keys become arrays
  • query uses a null-prototype object to prevent prototype pollution (including nested bracket objects created during parse). Bracket notation (e.g. fields[articles]=title) nests null-prototype objects at runtime; the published UrlResult.query type remains a flat Record<string, string | string[]> simplification matching ergo’s type declarations.
  • Bounded by maxPairs: 256 and maxLength: 8192 defaults
  • Conflicting scalar and nested keys keep the earlier value (first-wins); later conflicting assignments are skipped:
    • Scalar then nested (a=42&a[b]=99) and nested then scalar (a[b]=99&a=42)
    • Scalar then empty-bracket (a=42&a[]=2)
    • Empty-bracket then non-index nest (a[]=2&a[b]=1); numeric indices under arrays remain allowed (role[0]=user&role[1]=admin)
    • Plain-object then digit index (a[b]=y&a[0]=x); arrays keep index keys, objects keep non-index keys

None.

import {compose, url} from '@centralping/ergo';
const pipeline = compose(
url(),
(req, res, acc) => ({
response: {
body: {
path: acc.url.pathname,
page: acc.url.query.page,
},
},
}),
);

See the auto-generated url API docs.