packages feed

ihp-ide-1.4.0: IHP/IDE/CodeGen/MailGenerator.hs

module IHP.IDE.CodeGen.MailGenerator (buildPlan, buildPlan', MailConfig (..)) where

import IHP.Prelude
import IHP.IDE.CodeGen.Types
import qualified Data.Text as Text
import qualified IHP.IDE.SchemaDesigner.Parser as SchemaDesigner
import IHP.IDE.SchemaDesigner.Types
import Text.Countable (singularize, pluralize)

data MailConfig = MailConfig
    { controllerName :: Text
    , applicationName :: Text
    , modelName :: Text
    , mailName :: Text
    } deriving (Eq, Show)

buildPlan :: Text -> Text -> Text -> IO (Either Text [GeneratorAction])
buildPlan mailName applicationName controllerName' =
    if (null mailName || null controllerName')
        then pure $ Left "Neither mail name nor controller name can be empty"
        else do
            schema <- SchemaDesigner.parseSchemaSql >>= \case
                Left parserError -> pure []
                Right statements -> pure statements
            let modelName = tableNameToModelName controllerName'
            let controllerName = tableNameToControllerName controllerName'
            let viewConfig = MailConfig { .. }
            pure $ Right $ buildPlan' schema viewConfig

-- E.g. qualifiedMailModuleName config "Confirmation" == "Web.Mail.Users.Confirmation"
qualifiedViewModuleName :: MailConfig -> Text -> Text
qualifiedViewModuleName config mailName =
    config.applicationName <> ".Mail." <> config.controllerName <> "." <> ucfirst mailName

buildPlan' :: [Statement] -> MailConfig -> [GeneratorAction]
buildPlan' schema config =
        let
            controllerName = config.controllerName
            name = config.mailName
            singularName = config.modelName
            singularVariableName = lcfirst singularName
            pluralVariableName = lcfirst controllerName
            nameWithSuffix = if "Mail" `isSuffixOf` name
                then name
                else name <> "Mail" --e.g. "Test" -> "TestMail"
            nameWithoutSuffix = if "Mail" `isSuffixOf` name
                then Text.replace "Mail" "" name
                else name --e.g. "TestMail" -> "Test"

            indexAction = pluralize singularName <> "Action"

            modelFields :: [Text]
            modelFields = [ modelNameToTableName pluralVariableName, pluralVariableName ]
                    |> mapMaybe (fieldsForTable schema)
                    |> head
                    |> fromMaybe []

            mail =
                ""
                <> "module " <> qualifiedViewModuleName config nameWithoutSuffix <> " where\n"
                <> "import " <> config.applicationName <> ".View.Prelude\n"
                <> "import IHP.MailPrelude\n"
                <> "\n"
                <> "data " <> nameWithSuffix <> " = " <> nameWithSuffix <> " { " <> singularVariableName <> " :: " <> singularName <> " }\n"
                <> "\n"
                <> "instance BuildMail " <> nameWithSuffix <> " where\n"
                <> "    subject = \"Subject\"\n"
                <> "    to " <> nameWithSuffix <> " { .. } = Address { addressName = Just \"Firstname Lastname\", addressEmail = \"fname.lname@example.com\" }\n"
                <> "    from = \"hi@example.com\"\n"
                <> "    html " <> nameWithSuffix <> " { .. } = [hsx|\n"
                <> "        Hello World\n"
                <> "    |]\n"
        in
            [ EnsureDirectory { directory = config.applicationName <> "/Mail/" <> controllerName }
            , CreateFile { filePath = config.applicationName <> "/Mail/" <> controllerName <> "/" <> nameWithoutSuffix <> ".hs", fileContent = mail }
            , AddImport { filePath = config.applicationName <> "/Controller/" <> controllerName <> ".hs", fileContent = "import " <> qualifiedViewModuleName config nameWithoutSuffix }
            ]