gcanti / fp-ts-routing

A type-safe bidirectional routing library for TypeScript

Home Page:https://gcanti.github.io/fp-ts-routing/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

":" separator

scink opened this issue · comments

hi.
is it possible to use : separator in paths?
for example /env:{id}/item:{itemId}

You could try to define suitable a combinator, for example:

import * as R from 'fp-ts-routing'
import { none } from 'fp-ts/Option'

export const withPrefix = <A>(literal: string, m: R.Match<A>): R.Match<A> =>
  new R.Match(
    new R.Parser((r) => {
      if (r.parts.length === 0) {
        return none
      } else {
        const head = r.parts[0]
        return head.startsWith(literal)
          ? m.parser.run(new R.Route([head.substring(literal.length)].concat(r.parts.slice(1)), r.query))
          : none
      }
    }),
    new R.Formatter((r, a) => {
      const route = m.formatter.run(r, a)
      const parts = [...route.parts]
      const len = parts.length - 1
      parts[len] = literal + parts[len]
      const out = new R.Route(parts, route.query)
      return out
    })
  )

const route = withPrefix('env:', R.int('id')).then(withPrefix('item:', R.int('itemId')))

console.log(route.parser.run(R.Route.parse('/env%3A1/item%3A2'))) // => some([{ id: 1, itemId: 2 }, ...])

console.log(route.formatter.run(R.Route.empty, { id: 1, itemId: 2 }).toString()) // => '/env%3A1/item%3A2'

@gcanti i will try it, thank you!