Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

url-shape

axtk305ISC1.2.4

Type-safe schema-based URL builder

url builder, url, schema, typed schema, type-safe, zod, yup

readme

npm Lightweight TypeScript ✓ browser ✓ node ✓

url-shape

Type-safe schema-based URL builder

🔹 Create a URL schema with a schema lib like Zod or Yup:

import {createURLSchema} from 'url-shape';
import {z} from 'zod';

export const {url, match, validate} = createURLSchema({
    '/': null, // goes without parameters
    '/sections/:id': {
        params: z.object({
            id: z.coerce.number(),
        }),
    },
    '/search': {
        query: z.object({
            term: z.string(),
            view: z.optional(z.enum(['full', 'compact'])),
        }),
    },
});

If you are using Zod, remember to use the .coerce part in the schema for non-string parameters so that string URL components are converted to the preferred types.

🔹 Use the functions returned from createURLSchema() to build, match, and validate URLs in a type-safe manner: a type-aware code editor will highlight typos in the URLs and type mismatches in their parameters.

url('/sections/:id', {params: {id: 10}}).href // '/sections/10'
url('/sections/:id', {params: {id: 10}}).toString() // '/sections/10'
String(url('/sections/:id', {params: {id: 10}})) // '/sections/10'

url('/sections/:id').exec('/sections/42') // {params: {id: 42}}
url('/sections/:id').exec('/x/42') // null

url('/sections/:id').compile({params: {id: 10}}) // '/sections/10'
url('/search').compile({query: {term: 'shape'}}) // '/search?term=shape'

match('/sections/:id', '/sections/10') // {params: {id: 10}}
match('/sections/:id', '/x') // null

validate('/sections/10') // true, found in the schema
validate('/x') // false, not found in the schema

🔹 The URL builder can also be used without schema validation:

const {url, match, validate} = createURLSchema(null);

url('/sections/:id', {params: {id: 'x'}}) // '/sections/x'
match('/x/:name', '/x/intro') // {params: {name: 'intro'}}
validate('/x') // true, all URLs are fine when there's no schema