1.5.0 • Published 3 months ago

@pomle/paths v1.5.0

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

Paths

A JavaScript and TypeScript lib for handling type rich URLs in web apps.

Usage

Paths

Start by defining paths. Paths are usually created once in a single module, then imported for usage.

import { createPath, codecs } from '@pomle/paths';

const user = createPath('/user/:userId', {
  userId: codecs.string,
});

const userPost = user.append('/posts/:postId', {
  postId: codecs.number,
});

export const paths = {
  user,
  userPost,
};

Create URLs

import { paths } from './paths';

const url = paths.userPost.build({
  userId: 'pomle',
  postId: 24,
});

console.log(url); // Prints "/user/pomle/posts/24"

Parse path params from URLs

import { paths } from './paths';

const values = paths.userPost.parse('/user/pomle/posts/24');

console.log(values); // Prints {userId: "pomle", postId: 24}

Non-matching or under-matching returns null

import { paths } from './paths';

// Returns null
paths.userPost.parse('/not/user/posts');

// Returns null
paths.userPost.parse('/user/pomle');

Decode params already parsed

import { paths } from './paths';

const values = paths.userPost.decode({
  userId: 'pomle',
  postId: '24',
});

console.log(values); // Prints {userId: "pomle", postId: 24}

Query

Define query params

import { createQuery, codecs } from '@pomle/paths';

const searchFilter = createQuery({
  username: codecs.string,
  range: codecs.number,
});

Parse query string from URL

// Location ?username=Pontus+Alexander&range=3&range=5

const values = searchFilter.parse(window.location.search);

console.log(values);
/*
{
  username: ["Pontus Alexander"],
  range: [3, 5]
}
*/

Update query string

// Location ?username=Pontus+Alexander&range=3&range=5

const qs = searchFilter.build({
  username: ['Pontus Alexander'],
  range: [3, 5],
});

console.log(qs);
// ?username=Pontus+Alexander&range=3&range=5

Codecs

There are 4 codecs bundled

import { codecs } from '@pomle/paths';

codecs.string

Encodes strings safely

import { createQuery, codecs } from '@pomle/paths';

const searchOptions = createQuery({
  query: codecs.string,
});

codecs.boolean

Encodes true/false as "0" and "1"

import { createQuery, codecs } from '@pomle/paths';

const viewOptions = createQuery({
  showAll: codecs.boolean,
});

codecs.number

Encodes number safely

import { createQuery, codecs } from '@pomle/paths';

const searchOptions = createQuery({
  pageSize: codecs.number,
  pageNo: codecs.number,
});

codecs.oneOf

Ensures values are in a list of known values. If no match is found, first is returned.

import { createQuery, codecs } from '@pomle/paths';

const CAR_TYPES = ['sedan', 'hatchback', 'truck'] as const;

const carType = codecs.oneOf(CAR_TYPES);

const carOptions = createQuery({
  type: carType,
});

Creating custom codecs

Do not encode and decode with encodeURIComponent or decodeURIComponent manually. It will be handled by the library.

import { createPath, createCodec } from '@pomle/paths';
import { DateTime } from 'luxon';

const dateCodec = createCodec<DateTime>(
  (date) => {
    return date.toISO();
  },
  (text: string) => {
    return DateTime.fromISO(text);
  },
);

const bookings = createPath('/bookings/:dayOfArrival', {
  dayOfArrival: dateCodec,
});

const url = bookings.url({
  dayOfArrival: DateTime.now(),
});

Codec Tips!

The oneOf codec can take enums.

enum State {
  Low,
  Medium,
  High,
}

const states = [State.Low, State.Medium, State.High] as const;
const intensity = codecs.oneOf(states);

const options = createQuery({
  strength: intensity,
});

The oneOf codec can take any object that implements .toString.

const MyTypeOne = {
  toString() {
    return 'one';
  },
};

const MyTypeTwo = {
  toString() {
    return 'two';
  },
};

const states = [MyTypeOne, MyTypeTwo] as const;
const state = codecs.oneOf(states);
1.5.0

3 months ago

1.4.1

4 months ago

1.4.1-0

4 months ago

1.4.0-2

2 years ago

1.4.0

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.3.0-0

2 years ago

1.3.1-2

2 years ago

1.3.1-1

2 years ago

1.3.1-0

2 years ago

1.2.0

2 years ago

1.1.0

2 years ago

1.2.0-0

2 years ago

1.1.0-0

2 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.1-0

3 years ago

1.0.0

3 years ago

0.1.0-0

3 years ago

0.0.0-0

3 years ago