fp-ts-routing
Giulio Canti作
docs
github
サンプル
code:ts
import * as assert from 'assert'
import { end, format, int, lit, parse, Route, zero } from 'fp-ts-routing'
ページごとに型とconstructorを作る
code:ts
type Home = { readonly _tag: 'Home' }
const home: Location = { _tag: 'Home' }
code:ts
type User = {
readonly _tag: 'User'
readonly id: number
}
const user = (id: number): Location => ({ _tag: 'User', id })
code:ts
type Invoice = {
readonly _tag: 'Invoice'
readonly userId: number
readonly invoiceId: number
}
const invoice = (userId: number, invoiceId: number): Location => ({ _tag: 'Invoice', userId, invoiceId })
code:ts
type NotFound = {
readonly _tag: 'NotFound'
}
const notFound: Location = { _tag: 'NotFound' }
全Locationを表す型
code:ts
type Location = Home | User | Invoice | NotFound
routingのmatching patternを定義
code:ts
const defaults = end // rootにmatch
const homeMatch = lit('home').then(end) // /home
const userIdMatch = lit('users').then(int('userId')) // /users/:userId
const userMatch = userIdMatch.then(end) // /users/:userId
const invoiceMatch = userIdMatch.then(lit('invoice')).then(int('invoiceId')).then(end) // /users/:userId/invoice/:invoiceId
routerを定義
code:ts
const router = zero<Location>()
.alt(defaults.parser.map(() => home))
.alt(homeMatch.parser.map(() => home))
.alt(userMatch.parser.map(({ userId }) => user(userId)))
.alt(invoiceMatch.parser.map(({ userId, invoiceId }) => invoice(userId, invoiceId)))
parse
URL文字列からLocation型を解析するヘルパー関数
code:ts
const parseLocation = (s: string): Location => parse(router, Route.parse(s), notFound)
code:ts
assert.strictEqual(parseLocation('/'), home)
assert.strictEqual(parseLocation('/home'), home)
assert.deepEqual(parseLocation('/users/1'), user(1))
assert.deepEqual(parseLocation('/users/1/invoice/2'), invoice(1, 2))
assert.strictEqual(parseLocation('/foo'), notFound)
format
Location型からURL文字列を生成
code:ts
assert.strictEqual(format(userMatch.formatter, { userId: 1 }), '/users/1')
assert.strictEqual(format(invoiceMatch.formatter, { userId: 1, invoiceId: 2 }), '/users/1/invoice/2')