0.0.2 • Published 2 years ago

fp-ts-routing-gen-temp v0.0.2

Weekly downloads
-
License
-
Repository
-
Last release
2 years ago

fp-ts-routing-gen

Generate a Route Discriminated Union and the corresponding fp-ts-routing matching and router code from a simple definition.

In short

Go from this

/
/dashboard
/login?back_to

To this:

// IMPORTANT !!!
// Do not edit this file by hand!
//
// This code is generated by fp-ts-routing-gen (https://github.com/scarf/fp-ts-routing-gen)
// To update the generated code run change 'example.dsl' and run:
//
//   $ fp-ts-routing-gen --input 'example.dsl' --out 'example.ts'

import { pipe } from 'fp-ts/function';
import * as O from 'fp-ts/Option';
import * as Routing from 'fp-ts-routing';

type Index = { tag: 'Index' };
type Dashboard = { tag: 'Dashboard' };
type Login = { tag: 'Login'; back_to?: string };

export type Route = Index | Dashboard | Login;

export type RouteTag = Route['tag'];

export const match =
  <R>(matcher: {
    Index: (r: Index) => R;
    Dashboard: (r: Dashboard) => R;
    Login: (r: Login) => R;
  }) =>
  (route: Route): R => {
    switch (route.tag) {
      case 'Index':
        return matcher.Index(route);
      case 'Dashboard':
        return matcher.Dashboard(route);
      case 'Login':
        return matcher.Login(route);
    }
  };

const index = { tag: 'Index' };
const dashboard = { tag: 'Dashboard' };
const login = (back_to?: string): Route => ({
  tag: 'Login',
  back_to,
});

export const Route = {
  index,
  dashboard,
  login,
};

const indexMatch = Routing.end;
const dashboardMatch = Routing.lit('dashboard').then(Routing.end);
const loginMatch = Routing
  .lit('login')
  .then(
    // Optional query properties
    // @reference: https://github.com/gcanti/fp-ts-routing/issues/59#issuecomment-800801913
    Routing.query(
      t.exact(
        t.partial({
          back_to: t.string,
        }),
      ),
    )
  )
  .then(Routing.end);

export const Match = {
  index: indexMatch,
  dashboard: dashboardMatch,
  login: loginMatch,
};

const router = Routing.zero<Route>()
  .alt(Match.index.parser.map(() => Route.index))
  .alt(Match.dashboard.parser.map(() => Route.dashboard))
  .alt(Match.login.parser.map(({ back_to }) => Route.login({ back_to })));

export const parse = (path: string): Route =>
  Routing.parse(router, Routing.Route.parse(path), Route.index);

export const parseO = (path: string): O.Option<Route> =>
  Routing.parse(router.map(O.some), Routing.Route.parse(path), O.none);

export const format = (route: Route): string =>
  pipe(
    route,
    match<string>({
      Index: () => Routing.format(Match.index.formatter, {}),
      Dashboard: () => Routing.format(Match.dashboard.formatter, {}),
      Login: ({ back_to }) =>
        Routing.format(Match.login.formatter, { back_to }),
    }),
  );