servant-typescript-0.1.0.2: TypeScript client generation for Servant
Copyright(c) 2022 Tom McLaughlin
LicenseBSD3
Stabilityexperimental
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

Servant.TypeScript

Contents

Description

This library generates TypeScript client libraries for Servant.

First, make sure you have TypeScript instances defined for all of the types used in the API.

data User = User {
  name :: String
  , age :: Int
  , email :: String
  } deriving (Eq, Show)
deriveJSONAndTypeScript A.defaultOptions ''User

If you need to generate lots of boilerplate instances, the functions in aeson-typescript's Recursive module can be your friend. I've used recursivelyDeriveMissingTypeScriptInstancesFor to derive instances for the Kubernetes API.

Next, you'll need some Servant API:

type UserAPI = "users" :> Get '[JSON] [User]
          :<|> "albert" :> Get '[JSON] User
          :<|> "isaac" :> Get '[JSON] User

Generating the library is as simple as this:

main = writeTypeScriptLibrary (Proxy :: Proxy UserAPI) "/my/destination/folder/"
Synopsis

Documentation

writeTypeScriptLibrary :: MainConstraints api => Proxy api -> FilePath -> IO () Source #

Write the TypeScript client library for the given API to the given folder using default options.

writeTypeScriptLibrary' :: forall api. MainConstraints api => ServantTypeScriptOptions -> Proxy api -> FilePath -> IO () Source #

Write the TypeScript client library for the given API to the given folder.

Options

extraTypes :: ServantTypeScriptOptions -> [TSType] Source #

Extra TypeScript types to include in the d.ts file.

Useful if you want to expose types that don't appear in your API, for whatever reason.

getFileKey :: ServantTypeScriptOptions -> Req Text -> FilePath Source #

Determine to which output file the client function for the given request is mapped.

Useful to break up larger APIs into separate files based on criteria like route prefixes.

It's fine if the file key contains sub-directories; they will be created as needed.

A good approach is to split on case req ^. (reqFuncName . _FunctionName) of ....

Default implementation is const "client.ts".

getFunctionName :: ServantTypeScriptOptions -> Req Text -> Text Source #

Mangle a given request into a corresponding client function name. By default, just prepends the HTTP method to the camel-cased route.

getFunctions :: ServantTypeScriptOptions -> (Req Text -> Text) -> [Req Text] -> Text Source #

Given a list of requests, output a complete TypeScript module with the (exported) client functions, ready to be consumed by your TypeScript app.

For example, you can import dependencies at the top to use in your functions. The default version relies on the NPM "query-string" package to construct URLs. It uses the built-in window.fetch by default, but allows you to pass your own fetch function instead (useful for server-side rendering etc.). The default client functions return Promises with the given return value, and on failure they reject the promise with a value of interface { status: number; text: string; }.

If you want to write your own getFunctions, check out the GetFunctions module for inspiration.

The first argument passed to getFunctions is the getFunctionName function.

Misc