π A tiny library that is a drop in replacement for the native URL
class with some extra functionality to hydrate route and search parameters.
import { URL } from '@n8io/url'
const url = new URL(
'/',
apiUrl,
{
pathname: '/users/:username/repos',
// Based on the pathname π...
// the route params are type checked π
routeParams: { username: 'n8io' },
searchParams,
}
)
pnpm install @n8io/url
Don't take my word for it, play with the demo examples.
This library provides the following utility functions:
URL
- A drop in replacement for the nativeURL
interface, supercharged with route and search parameter hydrationurl(params, options?): URL
- A utility to generate a hydratedURL
from a base url, route, and search parametershydrateRoute(route, params, options?): string
- Given a route (e.g./dogs/:breed
), hydrate the route with a type safe route params object (e.g.{ breed: 'pug' }
)hydrateSearchParams({ params, route }, options?): string
- Given a route, hydrate the route's search parameters via a plain old javascript object (e.g.{ utm_source: 'facebook' }
) while respecting existing values.
Why is this even needed? Doesn't the native
URL
give us all the tools we need?
The URL
and URLSearchParams
apis are great and they provide us with all of the tools needed to manipulate urls. However the constructor for a new URL is quite rigid (new URL(url: string, base?: string)
).
This library's URL
function provides a more ergonomic api for generating a URL from route and search parameters.
const githubApiUrl = 'https://api.github.com/'
const routes = {
USER_REPOSITORIES: '/users/:username/repos',
}
const routeParams = { username: 'n8io' }
const searchParams = {
page: 1,
per_page: 25,
sort: 'name',
direction: 'asc',
}
// The native `URL` api...
const route = routes.REPOSITORY.replace(':username', routeParams.username)
const url = new URL(route, githubApiUrl)
url.searchParams.set('page', search.page.toString())
url.searchParams.set('pageSize', search.pageSize.toString())
url.searchParams.set('sort', 'name')
url.searchParams.set('sortBy', 'asc')
// This library's `URL`...
import { URL } from '@n8io/url'
const url = new URL(
'/',
githubApiUrl,
{
pathname: '/users/:username/repos',
// Based on the pathname π...
// the route params are type checked π
routeParams,
searchParams,
}
)
No. When you create a new URL(...)
, you get an instance of the native URL class. We're not modifying or monkey patching anything in the native URL api. All we're doing is overlaying our own class to handle a 3rd options
parameter before returning the new instance. You can be confident that if/when future changes are made to the native URL class your instances will automatically have access to these changes, because again, we're returning you a native URL instance.
Given a base url, route, and search parameters it returns a fully hydrated URL
instance.
It takes two parameters:
params
: An object that includesbaseUrl
,pathname?
,routeParams?
, andsearchParams?
.options?
: An optional object that includesallowRouteParamNulls
andallowSearchParamNulls
import { url } from '@n8io/url'
const params = {
baseUrl: 'https://api.github.com',
pathname: '/users/:username/repos',
routeParams: { username: 'n8io' },
searchParams: { page: 1, per_page: 25, sort: 'name', direction: 'asc' },
}
const options = {
allowRouteParamNulls: false,
allowSearchParamNulls: false,
}
const hydratedUrl = url(params, options)
// https://api.github.com/users/n8io/repos?page=1&per_page=25&sort=name&direction=asc
Given a route and route params return a hydrated route string.
It takes three parameters:
route
: A string that represents the route (e.g./dogs/:breed
).params
: A route params object (e.g.{ breed: 'pug' }
).options?
: An optional object that includesallowNull
.
import { hydrateRoute } from '@n8io/url'
const route = '/users/:username/repos'
const params = { username: 'n8io' }
const options = { allowNull: false }
const hydratedRoute = hydrateRoute(route, params, options)
// /users/n8io/repos
This function hydrates a route's search parameters via a plain old javascript object, all while respecting existing values.
It takes three parameters:
params
: A search params object (e.g.{ utm_source: 'facebook' }
).route
: A string that represents the route.options?
: An optional object that includesallowNull
.
import { hydrateSearchParams } from '@n8io/url'
const route = '/users/n8io/repos'
const params = { page: 1, per_page: 25, sort: 'name', direction: 'asc' }
const options = { allowNull: false }
const hydratedSearchParams = hydrateSearchParams({ params, route }, options)
// /users/n8io/repos?page=1&per_page=25&sort=name&direction=asc
We welcome contributions from the community. If you'd like to contribute to this project, please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Make your changes and write tests if applicable.
- Commit your changes and push them to your fork.
- Open a pull request to the main repository.