Skip to content

Commit

Permalink
Add JSON serialization for AppSpec (#2284)
Browse files Browse the repository at this point in the history
  • Loading branch information
Martinsos authored Sep 24, 2024
1 parent a2402cf commit 5a79eca
Show file tree
Hide file tree
Showing 32 changed files with 593 additions and 67 deletions.
4 changes: 2 additions & 2 deletions waspc/src/Wasp/Analyzer/TypeDefinitions/Class/IsDeclType.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Wasp.Analyzer.Evaluator.Bindings (Bindings)
import Wasp.Analyzer.Evaluator.EvaluationError (EvaluationError)
import Wasp.Analyzer.TypeChecker.AST (TypedExpr, WithCtx)
import Wasp.Analyzer.TypeDefinitions.Internal (DeclType, TypeDefinitions)
import qualified Wasp.AppSpec.Core.Decl as AppSpecDecl
import qualified Wasp.AppSpec.Core.IsDecl as AppSpecIsDecl

-- | Marks Haskell type as a representation of a specific Wasp declaration type.
-- This is supposed to be used on types from @AppSpec@ (the main Wasp IR)
Expand All @@ -27,7 +27,7 @@ import qualified Wasp.AppSpec.Core.Decl as AppSpecDecl
-- NOTE: If this Haskell type satisfies certain requirements, the IsDeclType instance for it
-- can be automatically derived from its shape by using
-- 'Wasp.Analyzer.TypeDefinitions.TH.makeDeclType'.
class (Typeable a, AppSpecDecl.IsDecl a) => IsDeclType a where
class (Typeable a, AppSpecIsDecl.IsDecl a) => IsDeclType a where
declType :: DeclType

-- | Evaluates a given Wasp "TypedExpr" to @a@, assuming given typed
Expand Down
3 changes: 2 additions & 1 deletion waspc/src/Wasp/AppSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import Wasp.AppSpec.Api (Api)
import Wasp.AppSpec.ApiNamespace (ApiNamespace)
import Wasp.AppSpec.App (App)
import Wasp.AppSpec.ConfigFile (ConfigFileRelocator (..))
import Wasp.AppSpec.Core.Decl (Decl, IsDecl, takeDecls)
import Wasp.AppSpec.Core.Decl (Decl, takeDecls)
import Wasp.AppSpec.Core.IsDecl (IsDecl)
import Wasp.AppSpec.Core.Ref (Ref, refName)
import Wasp.AppSpec.Crud (Crud)
import Wasp.AppSpec.Entity (Entity)
Expand Down
8 changes: 6 additions & 2 deletions waspc/src/Wasp/AppSpec/Action.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.Action
( Action (..),
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import Wasp.AppSpec.Core.Decl (IsDecl)
import GHC.Generics (Generic)
import Wasp.AppSpec.Core.IsDecl (IsDecl)
import Wasp.AppSpec.Core.Ref (Ref)
import Wasp.AppSpec.Entity
import Wasp.AppSpec.ExtImport
Expand All @@ -16,6 +20,6 @@ data Action = Action
entities :: Maybe [Ref Entity],
auth :: Maybe Bool
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

instance IsDecl Action
10 changes: 7 additions & 3 deletions waspc/src/Wasp/AppSpec/Api.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.Api
( Api (..),
Expand All @@ -8,8 +10,10 @@ module Wasp.AppSpec.Api
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import Wasp.AppSpec.Core.Decl (IsDecl)
import GHC.Generics (Generic)
import Wasp.AppSpec.Core.IsDecl (IsDecl)
import Wasp.AppSpec.Core.Ref (Ref)
import Wasp.AppSpec.Entity (Entity)
import Wasp.AppSpec.ExtImport (ExtImport)
Expand All @@ -21,7 +25,7 @@ data Api = Api
httpRoute :: (HttpMethod, String), -- (method, path), exe: (GET, "/foo/bar")
auth :: Maybe Bool
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

instance IsDecl Api

Expand All @@ -32,4 +36,4 @@ path :: Api -> String
path = snd . httpRoute

data HttpMethod = ALL | GET | POST | PUT | DELETE
deriving (Show, Eq, Ord, Data)
deriving (Show, Eq, Ord, Data, Generic, FromJSON)
8 changes: 6 additions & 2 deletions waspc/src/Wasp/AppSpec/ApiNamespace.hs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.ApiNamespace
( ApiNamespace (..),
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import Wasp.AppSpec.Core.Decl (IsDecl)
import GHC.Generics (Generic)
import Wasp.AppSpec.Core.IsDecl (IsDecl)
import Wasp.AppSpec.ExtImport (ExtImport)

data ApiNamespace = ApiNamespace
{ middlewareConfigFn :: ExtImport,
path :: String
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

instance IsDecl ApiNamespace
8 changes: 6 additions & 2 deletions waspc/src/Wasp/AppSpec/App.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App (App (..)) where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)
import Wasp.AppSpec.App.Auth (Auth)
import Wasp.AppSpec.App.Client (Client)
import Wasp.AppSpec.App.Db (Db)
import Wasp.AppSpec.App.EmailSender (EmailSender)
import Wasp.AppSpec.App.Server (Server)
import Wasp.AppSpec.App.Wasp (Wasp)
import Wasp.AppSpec.App.WebSocket (WebSocket)
import Wasp.AppSpec.Core.Decl (IsDecl)
import Wasp.AppSpec.Core.IsDecl (IsDecl)

data App = App
{ wasp :: Wasp,
Expand All @@ -23,6 +27,6 @@ data App = App
emailSender :: Maybe EmailSender,
webSocket :: Maybe WebSocket
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

instance IsDecl App
14 changes: 9 additions & 5 deletions waspc/src/Wasp/AppSpec/App/Auth.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}

module Wasp.AppSpec.App.Auth
Expand All @@ -20,8 +22,10 @@ module Wasp.AppSpec.App.Auth
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import Data.Maybe (isJust)
import GHC.Generics (Generic)
import Wasp.AppSpec.App.Auth.EmailVerification (EmailVerificationConfig)
import Wasp.AppSpec.App.Auth.PasswordReset (PasswordResetConfig)
import Wasp.AppSpec.App.EmailSender (EmailFromField)
Expand All @@ -41,7 +45,7 @@ data Auth = Auth
onBeforeLogin :: Maybe ExtImport,
onAfterLogin :: Maybe ExtImport
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

data AuthMethods = AuthMethods
{ usernameAndPassword :: Maybe UsernameAndPasswordConfig,
Expand All @@ -51,26 +55,26 @@ data AuthMethods = AuthMethods
keycloak :: Maybe ExternalAuthConfig,
email :: Maybe EmailAuthConfig
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

data UsernameAndPasswordConfig = UsernameAndPasswordConfig
{ userSignupFields :: Maybe ExtImport
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

data ExternalAuthConfig = ExternalAuthConfig
{ configFn :: Maybe ExtImport,
userSignupFields :: Maybe ExtImport
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

data EmailAuthConfig = EmailAuthConfig
{ userSignupFields :: Maybe ExtImport,
fromField :: EmailFromField,
emailVerification :: EmailVerificationConfig,
passwordReset :: PasswordResetConfig
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

isUsernameAndPasswordAuthEnabled :: Auth -> Bool
isUsernameAndPasswordAuthEnabled = isJust . usernameAndPassword . methods
Expand Down
6 changes: 5 additions & 1 deletion waspc/src/Wasp/AppSpec/App/Auth/EmailVerification.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.Auth.EmailVerification where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)
import Wasp.AppSpec.Core.Ref (Ref)
import Wasp.AppSpec.ExtImport (ExtImport)
import Wasp.AppSpec.Route (Route)
Expand All @@ -11,4 +15,4 @@ data EmailVerificationConfig = EmailVerificationConfig
{ getEmailContentFn :: Maybe ExtImport,
clientRoute :: Ref Route
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)
6 changes: 5 additions & 1 deletion waspc/src/Wasp/AppSpec/App/Auth/PasswordReset.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.Auth.PasswordReset where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)
import Wasp.AppSpec.Core.Ref (Ref)
import Wasp.AppSpec.ExtImport (ExtImport)
import Wasp.AppSpec.Route (Route)
Expand All @@ -11,4 +15,4 @@ data PasswordResetConfig = PasswordResetConfig
{ getEmailContentFn :: Maybe ExtImport,
clientRoute :: Ref Route
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)
6 changes: 5 additions & 1 deletion waspc/src/Wasp/AppSpec/App/Client.hs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.Client
( Client (..),
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)
import Wasp.AppSpec.ExtImport (ExtImport)

data Client = Client
Expand All @@ -14,4 +18,4 @@ data Client = Client
-- We expect the base dir to start with a slash e.g. /client
baseDir :: Maybe String
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)
8 changes: 6 additions & 2 deletions waspc/src/Wasp/AppSpec/App/Db.hs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.Db
( Db (..),
DbSystem (..),
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)
import Wasp.AppSpec.ExtImport (ExtImport)

data Db = Db
{ seeds :: Maybe [ExtImport]
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

data DbSystem = PostgreSQL | SQLite
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)
10 changes: 7 additions & 3 deletions waspc/src/Wasp/AppSpec/App/EmailSender.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.EmailSender
( EmailSender (..),
Expand All @@ -7,19 +9,21 @@ module Wasp.AppSpec.App.EmailSender
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)

data EmailSender = EmailSender
{ provider :: EmailProvider,
defaultFrom :: Maybe EmailFromField
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

data EmailProvider = SMTP | SendGrid | Mailgun | Dummy
deriving (Eq, Data, Show)
deriving (Show, Eq, Data, Generic, FromJSON)

data EmailFromField = EmailFromField
{ name :: Maybe String,
email :: String
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)
6 changes: 5 additions & 1 deletion waspc/src/Wasp/AppSpec/App/Server.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.Server
( Server (..),
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)
import Wasp.AppSpec.ExtImport (ExtImport)

data Server = Server
{ setupFn :: Maybe ExtImport,
middlewareConfigFn :: Maybe ExtImport
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)
8 changes: 6 additions & 2 deletions waspc/src/Wasp/AppSpec/App/Wasp.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.Wasp (Wasp (..)) where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import Wasp.AppSpec.Core.Decl (IsDecl)
import GHC.Generics (Generic)
import Wasp.AppSpec.Core.IsDecl (IsDecl)

data Wasp = Wasp
{ version :: String
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)

instance IsDecl Wasp
6 changes: 5 additions & 1 deletion waspc/src/Wasp/AppSpec/App/WebSocket.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}

module Wasp.AppSpec.App.WebSocket
( WebSocket (..),
)
where

import Data.Aeson (FromJSON)
import Data.Data (Data)
import GHC.Generics (Generic)
import Wasp.AppSpec.ExtImport (ExtImport)

data WebSocket = WebSocket
{ fn :: ExtImport,
autoConnect :: Maybe Bool
}
deriving (Show, Eq, Data)
deriving (Show, Eq, Data, Generic, FromJSON)
6 changes: 2 additions & 4 deletions waspc/src/Wasp/AppSpec/Core/Decl.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@

module Wasp.AppSpec.Core.Decl
( Decl,
IsDecl,
takeDecls,
makeDecl,
fromDecl,
)
where

import Data.Maybe (mapMaybe)
import Data.Typeable (Typeable, cast)

class (Typeable a) => IsDecl a
import Data.Typeable (cast)
import Wasp.AppSpec.Core.IsDecl (IsDecl)

-- | A container for any (IsDecl a) type, allowing you to have a heterogenous list of
-- Wasp declarations as [Decl].
Expand Down
Loading

0 comments on commit 5a79eca

Please sign in to comment.