From 4f2c6cc6bcad1ec654870c3ffcff8515803df97a Mon Sep 17 00:00:00 2001 From: Andrew Fong Date: Tue, 1 Aug 2017 22:25:38 -0700 Subject: [PATCH] Update README --- README.md | 165 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 139 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 52a8117..f96a54e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -TS Boilerplate -============== +typed-routes +============ [![Build Status](https://travis-ci.org/esperco/typed-routes.svg?branch=master)](https://travis-ci.org/esperco/typed-routes) Routes with TypeScript support. @@ -14,28 +14,141 @@ Usage ```ts import createRoute from "typed-routes"; -let path = createRoute("data") - .extend("profiles") - .param("groupId") - .opt("userId", "defaultId"); - -/* - Typed routes can be matched against strings to return the extracted params - (if there's match) or to convert a params object to a param string -*/ -path.match("/data/profiles/123/xyz"); // => { groupId: "123", userId: "xyz" } -path.match("/data/profiles/123"); // => { groupId: "123", userId: "defaultId" } -path.match("/daat/profylez/123"); // => null - -/* - Typed routes can also convert a set of params to a string route. -*/ -path.from({ groupId: "123", userId: "xyz" }); // => "/data/profiles/123/xyz" -path.from({ groupId: "123" }); // => "/data/profiles/123" -path.from({ groopid: "123" }); // => Type error - -/* - Typed routes can be used to generate ExpressJS style paths. -*/ -path.pattern(); // => "/data/profiles/:groupId/:userId? +// Like "/data/profiles/:userId/info" in Express +let path = createRoute() + .extend("data", "profiles") + .param("userId") + .extend("info"); ``` + +Typed routes can be matched against strings to return the extracted params +(if there's match) or to convert a params object to a param string + +```ts +path.match("/data/profiles/xyz/info"); // => { userId: "xyz" } +path.match("/daat/profylez/xyz/info"); // => undefined +``` + +Typed routes can also convert a set of params to a string route. + +```ts +path.from({ userId: "xyz" }); // => "/data/profiles/xyz/info" +path.from({ uzerid: "xyz" }); // => Type error +``` + +Routes may have optional types and rest types as well + +```ts +let path = createRoute().param("groupId").opt("userId").rest(); +path.match("/gid/uid/a/b/c"); + // => { groupId: "gid", userId: "uid", rest: ["a", "b", "c"] } +path.match("/gid"); + // => { groupId: "gid", rest: [] } +``` + +Routes can specify types. + +```ts +import { default as createRoute, IntType } from "typed-routes"; + +let path = createRoute().extend("profile").param("uid", IntType); +path.match("/profile/123"); // => { uid: 123 } +path.match("/profile/abc"); // => undefined + +path.from({ uid: 123 }); // => "/profile/123" +path.from({ uid: "abc" }); // => Type error +``` + +Types are just an object with a parse and stringify function. For example, +this is the definition of the `DateTimeParam` type, which converts a Date +to milliseconds since epoch. You can provide your own types for more +customized behavior (such as returning a default value is one is undefined). + +```ts +const DateTimeParam = { + parse: (s: string): Date|undefined => { + let ret = new Date(parseInt(s)); + return isNaN(ret.getTime()) ? undefined : ret; + }, + stringify: (d: Date): string => d.getTime().toString() +}; +``` + +API +--- + +### createRoute + +```ts +createRoute({ + // What kind of "slash" separates paths? Defaults to "/". + delimiter: string; + + // Require that our route starts with a certain prefix. Defaults to "/". + prefix: string; + + // Require that our route ends with a certain suffix. Defaults to + // empty string. + suffix: string; +}): Route; +``` + +Creates a route object with certain settings. + + +### Route.extend + +```ts +route.extend(...parts: string[]): Route; +``` + +Adds static segments to route that must match exactly. + + +### Route.param + +```ts +route.param(name: string, type: ParamType = StringParam): Route; +``` + +Add a required parameter and optional type. + + +### Route.opt + +```ts +route.opt(name: string, type: ParamType = StringParam): OptRoute; +``` + +Add an optional parameter and type. `.extend` and `.param` cannot follow +a `.opt` command. + + +### Route.rest + +```ts +route.rest(type = StringParam): Route; +route.rest(name = "rest", type = StringParam): Route; +``` + +Add a field that captures multiple parts of the path as an array. Defaults +to using `rest` as the property but this can be changed. Type specifies +what kind of array we're working with (e.g. use `IntParam` or `FloatParam` +to type as `number[]`). + + +Built-In Param Types +-------------------- + +* `StrParam` - Default parameter. Types as string. + +* `IntParam` - Type as integer using `parseInt`. + +* `FloatParam` - Type as float using `parseFloat`. + +* `DateTimeParam` - Type as Date by serializing as milliseconds since epoch. + +* `ArrayParam(ParamType, delimiter = ",")` - A function that takes another + param type and returns as param type that parses as an array of the + original type. For instance, `ArrayParam(IntParam, "::")` will parse + `1::2::3` as `[1, 2, 3]`.