@n8io/url
v0.1.5
Published
π A tiny library that is meant to be a drop in replacement for the native `URL` class with some extra functionality to hydrate route and search parameters.
Downloads
2
Readme
@n8io/url
π A tiny library that is a drop in replacement for the native URL
class with some extra functionality to hydrate route and search parameters.
Basic Usage
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,
}
)
Getting Started
pnpm install @n8io/url
Demo
Don't take my word for it, play with the demo examples.
APIs
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(route, params, 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.
URL
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.
Example usage: URL
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,
}
)
Frequently Asked Questions
Do I have to learn yet another api?
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.
url(params, options?): URL
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
Example usage: url
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
hydrateRoute(route, params, options?): string
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
.
Example usage: hydrateRoute
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
hydrateSearchParams(route, params, options?): string
This function hydrates a route's search parameters via a plain old javascript object, all while respecting existing values.
It takes three parameters:
route
: A string that represents the route.params
: A search params object (e.g.{ utm_source: 'facebook' }
).options?
: An optional object that includesallowNull
.
Example usage: hydrateSearchParams
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(route, params, options)
// /users/n8io/repos?page=1&per_page=25&sort=name&direction=asc
Contributing
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.