packages feed

aeson-typescript 0.1.0.3 → 0.1.0.4

raw patch · 5 files changed

+99/−7 lines, 5 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Data.Aeson.TypeScript.TH: data TSDeclaration
+ Data.Aeson.TypeScript.TH: deriveJSONAndTypeScript :: Options -> Name -> Q [Dec]
+ Data.Aeson.TypeScript.TH: formatTSDeclarations' :: FormattingOptions -> [TSDeclaration] -> String

Files

README.md view
@@ -55,6 +55,21 @@ $(deriveTypeScript (getJSONOptions (Proxy :: Proxy MyType)) ''MyType) ``` +Or, if you want to be even more concise and don't mind defining the instances in the same file,++```haskell+myOptions = defaultOptions {fieldLabelModifier = drop 4}++$(deriveJSONAndTypeScript myOptions ''MyType)+```++Remembering that the Template Haskell `Q` monad is an ordinary monad, you can derive instances for several types at once like this:++```haskell+$(mconcat <$> traverse (deriveJSONAndTypeScript myOptions) [''MyType1, ''MyType2, ''MyType3])+```++ # Suggestions for use  This library was written to make it easier to typecheck your TypeScript frontend against your Haskell backend. Here's how I like to integrate it into my workflow:
aeson-typescript.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 642ba0d728cb3be28a4296b85b360f01995570c1a66ec3a36bfb1432d2095f58+-- hash: d5296dac0383543d81935518f35792eb914876a69e7b96def8b6dcfdbd6a53f5  name:           aeson-typescript-version:        0.1.0.3+version:        0.1.0.4 synopsis:       Generate TypeScript definition files from your ADTs description:    Please see the README on Github at <https://github.com/codedownio/aeson-typescript#readme> category:       Text, Web, JSON
src/Data/Aeson/TypeScript/Instances.hs view
@@ -87,4 +87,4 @@   getTypeScriptType _ = [i|{[k: #{getTypeScriptType (Proxy :: Proxy a)}]: #{getTypeScriptType (Proxy :: Proxy b)}}|]  instance (TypeScript a) => TypeScript (Set a) where-  getTypeScriptType _ = (((getTypeScriptType (Proxy :: Proxy a))) <> "[]");+  getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) <> "[]";
src/Data/Aeson/TypeScript/TH.hs view
@@ -11,7 +11,7 @@ If you already use Aeson's Template Haskell support to derive your instances, then deriving TypeScript is as simple as  @-$(deriveTypeScript myAesonOptions ''MyType)+$('deriveTypeScript' myAesonOptions ''MyType) @  For example,@@ -35,7 +35,7 @@ Now we can use the newly created instances.  @->>> putStrLn $ formatTSDeclarations $ getTypeScriptDeclarations (Proxy :: Proxy D)+>>> putStrLn $ 'formatTSDeclarations' $ 'getTypeScriptDeclarations' (Proxy :: Proxy D)  type D\<T\> = "nullary" | IUnary\<T\> | IProduct\<T\> | IRecord\<T\>; @@ -61,6 +61,30 @@ $(deriveTypeScript (getJSONOptions (Proxy :: Proxy MyType)) ''MyType) @ +Or, if you want to be even more concise and don't mind defining the instances in the same file,++@+myOptions = 'defaultOptions' {'fieldLabelModifier' = 'drop' 4}++$(deriveJSONAndTypeScript myOptions ''MyType)+@++Remembering that the Template Haskell 'Q' monad is an ordinary monad, you can derive instances for several types at once like this:++@+$('mconcat' \<$\> 'traverse' ('deriveJSONAndTypeScript' myOptions) [''MyType1, ''MyType2, ''MyType3])+@++Once you've defined all necessary instances, you can write a main function to dump them out into a @.d.ts@ file. For example:++@+main = putStrLn $ 'formatTSDeclarations' (+  ('getTypeScriptDeclaration' (Proxy :: Proxy MyType1)) <>+  ('getTypeScriptDeclaration' (Proxy :: Proxy MyType2)) <>+  ...+)+@+ -}  module Data.Aeson.TypeScript.TH (@@ -69,19 +93,24 @@   -- * The main typeclass   TypeScript(..), +  TSDeclaration,+   -- * Formatting declarations   formatTSDeclarations,+  formatTSDeclarations',   formatTSDeclaration,   FormattingOptions(..),    -- * Convenience tools   HasJSONOptions(..),+  deriveJSONAndTypeScript,    module Data.Aeson.TypeScript.Instances   ) where  import Control.Monad import Data.Aeson as A+import Data.Aeson.TH as A import Data.Aeson.TypeScript.Formatting import Data.Aeson.TypeScript.Instances () import Data.Aeson.TypeScript.Types@@ -142,7 +171,7 @@   getTypeScriptType _ = "T10"  --- | Generates a 'TypeScript' instance declaration for the given data type or data family instance constructor.+-- | Generates a 'TypeScript' instance declaration for the given data type. deriveTypeScript :: Options                  -- ^ Encoding options.                  -> Name@@ -265,6 +294,23 @@   let brackets = AppE (VarE 'mconcat) (ListE [stringE "<", headType, tailsWithCommas, stringE ">"])    return $ (AppE (AppE (VarE 'mappend) baseName) brackets)++-- * Convenience functions++-- | Convenience function to generate 'A.ToJSON', 'A.FromJSON', and 'TypeScript' instances simultaneously, so the instances are guaranteed to be in sync.+--+-- This function is given mainly as an illustration. If you want some other permutation of instances, such as 'A.ToJSON' and 'A.TypeScript' only, just take a look at the source and write your own version.+--+-- @since 0.1.0.4+deriveJSONAndTypeScript :: Options+                        -- ^ Encoding options.+                        -> Name+                        -- ^ Name of the type for which to generate 'A.ToJSON', 'A.FromJSON', and 'TypeScript' instance declarations.+                        -> Q [Dec]+deriveJSONAndTypeScript options name = do+  ts <- deriveTypeScript options name+  json <- A.deriveJSON options name+  return $ ts <> json  -- * Util stuff 
src/Data/Aeson/TypeScript/Types.hs view
@@ -10,6 +10,7 @@ import Data.Data import Data.Monoid import Data.Proxy+import Data.Set import Data.String import Data.String.Interpolate.IsString import qualified Data.Text as T@@ -18,6 +19,36 @@ import Language.Haskell.TH.Datatype  -- | The typeclass that defines how a type is turned into TypeScript.+--+-- The 'getTypeScriptDeclarations' method describes the top-level declarations that are needed for a type,+-- while 'getTypeScriptType' describes how references to the type should be translated. The 'getTypeScriptOptional'+-- method exists purely so that 'Maybe' types can be encoded with a question mark.+--+--  Instances for common types are built-in and are usually very simple; for example,+--+-- @+-- instance TypeScript Bool where+--   getTypeScriptType _ = "boolean"+-- @+--+-- Most of the time you should not need to write instances by hand; in fact, the 'TSDeclaration'+-- constructors are deliberately opaque. However, you may occasionally need to specify the type of something.+-- For example, since 'UTCTime' is encoded to a JSON string and is not built-in to this library:+--+-- @+-- import Data.Time.Clock (UTCTime)+--+-- instance TypeScript UTCTime where+--   getTypeScriptType _ = "string"+-- @+--+-- If you need to write a definition for a higher-order type, it may depend on a type parameter. For example,+-- a 'Set' is encoded to a JSON list of the underlying type:+--+-- @+-- instance (TypeScript a) => TypeScript (Set a) where+--   getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) <> "[]";+-- @ class TypeScript a where   getTypeScriptDeclarations :: Proxy a -> [TSDeclaration]   -- ^ Get the declaration(s) needed for this type.@@ -45,7 +76,7 @@ newtype TSString a = TSString { unpackTSString :: String } deriving Show  instance IsString (TSString a) where-  fromString x = TSString x+  fromString = TSString  -- * Formatting options