From e9ef283677361c96665ec34afb497b8d63433f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 20:39:20 +0200 Subject: [PATCH 01/11] Fail if you find both wasp files --- .../StarterTemplates/Templating.hs | 6 +++--- waspc/src/Wasp/Project/Analyze.hs | 18 +++++++++++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs b/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs index 1a38a8c5df..69b072fe85 100644 --- a/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs +++ b/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs @@ -26,9 +26,9 @@ replaceTemplatePlaceholdersInWaspFile :: NewProjectAppName -> NewProjectName -> Path' Abs (Dir WaspProjectDir) -> IO () replaceTemplatePlaceholdersInWaspFile appName projectName projectDir = findWaspFile projectDir >>= \case - Nothing -> return () - Just (WaspLang absMainWaspFile) -> replaceTemplatePlaceholders absMainWaspFile - Just (WaspTs absMainTsFile) -> replaceTemplatePlaceholders absMainTsFile + Left _error -> return () + Right (WaspLang absMainWaspFile) -> replaceTemplatePlaceholders absMainWaspFile + Right (WaspTs absMainTsFile) -> replaceTemplatePlaceholders absMainTsFile where replaceTemplatePlaceholders = replaceTemplatePlaceholdersInFileOnDisk appName projectName diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 3a6f3f53ae..0bfb8d1683 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -7,7 +7,6 @@ module Wasp.Project.Analyze ) where -import Control.Applicative ((<|>)) import Control.Arrow (ArrowChoice (left)) import Control.Concurrent (newChan) import Control.Concurrent.Async (concurrently) @@ -52,7 +51,6 @@ import qualified Wasp.Psl.Ast.Schema as Psl.Schema import qualified Wasp.Psl.Parser.Schema as Psl.Parser import Wasp.Psl.Valid (getValidDbSystemFromPrismaSchema) import qualified Wasp.Psl.Valid as PslV -import Wasp.Util (maybeToEither) import Wasp.Util.Aeson (encodeToString) import qualified Wasp.Util.IO as IOUtil import Wasp.Util.StrongPath (replaceRelExtension) @@ -64,7 +62,7 @@ analyzeWaspProject :: CompileOptions -> IO (Either [CompileError] AS.AppSpec, [CompileWarning]) analyzeWaspProject waspDir options = do - waspFilePathOrError <- maybeToEither [fileNotFoundMessage] <$> findWaspFile waspDir + waspFilePathOrError <- left (: []) <$> findWaspFile waspDir case waspFilePathOrError of Left err -> return (Left err, []) @@ -79,8 +77,6 @@ analyzeWaspProject waspDir options = do EC.analyzeExternalConfigs waspDir >>= \case Left errors -> return (Left errors, []) Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations - where - fileNotFoundMessage = "Couldn't find the *.wasp file in the " ++ toFilePath waspDir ++ " directory" data WaspFile = WaspLang !(Path' Abs (File WaspLangFile)) @@ -242,14 +238,22 @@ constructAppSpec waspDir options externalConfigs parsedPrismaSchema decls = do return $ runValidation ASV.validateAppSpec appSpec -findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Maybe WaspFile) +findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either String WaspFile) findWaspFile waspDir = do files <- fst <$> IOUtil.listDirectory waspDir - return $ findWaspTsFile files <|> findWaspLangFile files + return $ case (findWaspTsFile files, findWaspLangFile files) of + (Just _, Just _) -> Left bothFilesFoundMessage + (Nothing, Nothing) -> Left fileNotFoundMessage + (Just waspTsFile, Nothing) -> Right waspTsFile + (Nothing, Just waspLangFile) -> Right waspLangFile where findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.mts" files findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files findFileThatEndsWith suffix files = SP.castFile . (waspDir ) <$> find ((suffix `isSuffixOf`) . toFilePath) files + fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.mts file in the " ++ toFilePath waspDir ++ " directory" + bothFilesFoundMessage = + "Found both *.wasp and *.wasp.mts files in the project directory. " + ++ "You must choose how you want to define your app (using Wasp or TypeScript) and only keep one of them." analyzePrismaSchema :: Path' Abs (Dir WaspProjectDir) -> IO (Either [CompileError] Psl.Schema.Schema, [CompileWarning]) analyzePrismaSchema waspProjectDir = do From 0dc74356bed254f51270f9a29e58698199069024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 20:54:01 +0200 Subject: [PATCH 02/11] Change tsconfig file name --- waspc/src/Wasp/Project/Analyze.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 0bfb8d1683..bde134b1fb 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -99,7 +99,7 @@ analyzeWaspTsFile :: Path' Abs (Dir WaspProjectDir) -> Psl.Schema.Schema -> Path analyzeWaspTsFile waspProjectDir prismaSchemaAst waspFilePath = runExceptT $ do -- TODO: I'm not yet sure where tsconfig.node.json location should come from -- because we also need that knowledge when generating a TS SDK project. - compiledWaspJsFile <- ExceptT $ compileWaspTsFile waspProjectDir [relfile|tsconfig.node.json|] waspFilePath + compiledWaspJsFile <- ExceptT $ compileWaspTsFile waspProjectDir [relfile|tsconfig.wasp.json|] waspFilePath declsJsonFile <- ExceptT $ executeMainWaspJsFile waspProjectDir prismaSchemaAst compiledWaspJsFile ExceptT $ readDecls prismaSchemaAst declsJsonFile From 3e9efc82f5a0e3dfc73ecb87a3f674ba99bb57bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 21:00:16 +0200 Subject: [PATCH 03/11] Clean up imports --- waspc/src/Wasp/Project/Analyze.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index bde134b1fb..8fb85f2a78 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -14,10 +14,8 @@ import Control.Monad.Except (ExceptT (..), liftEither, runExceptT) import qualified Data.Aeson as Aeson import Data.Conduit.Process.Typed (ExitCode (..)) import Data.List (find, isSuffixOf) -import StrongPath (Abs, Dir, File', Path', Rel, basename, toFilePath, ()) +import StrongPath (Abs, Dir, File, File', Path', Rel, basename, relfile, toFilePath, ()) import qualified StrongPath as SP -import StrongPath.TH (relfile) -import StrongPath.Types (File) import qualified Wasp.Analyzer as Analyzer import Wasp.Analyzer.AnalyzeError (getErrorMessageAndCtx) import Wasp.Analyzer.Parser.Ctx (Ctx) From 24f65ec4512b670474795172a94c4bb07740dda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 21:03:19 +0200 Subject: [PATCH 04/11] Fix some more imports --- waspc/src/Wasp/Project/Analyze.hs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 8fb85f2a78..9967ac7f93 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -14,8 +14,7 @@ import Control.Monad.Except (ExceptT (..), liftEither, runExceptT) import qualified Data.Aeson as Aeson import Data.Conduit.Process.Typed (ExitCode (..)) import Data.List (find, isSuffixOf) -import StrongPath (Abs, Dir, File, File', Path', Rel, basename, relfile, toFilePath, ()) -import qualified StrongPath as SP +import StrongPath (Abs, Dir, File, File', Path', Rel, basename, castFile, fromAbsFile, relfile, toFilePath, ()) import qualified Wasp.Analyzer as Analyzer import Wasp.Analyzer.AnalyzeError (getErrorMessageAndCtx) import Wasp.Analyzer.Parser.Ctx (Ctx) @@ -131,7 +130,7 @@ compileWaspTsFile waspProjectDir tsconfigNodeFileInWaspProjectDir waspFilePath = where outDir = waspProjectDir dotWaspDirInWaspProjectDir absCompiledWaspJsFile = outDir compiledWaspJsFileInDotWaspDir - compiledWaspJsFileInDotWaspDir = SP.castFile $ case replaceRelExtension (basename waspFilePath) ".mjs" of + compiledWaspJsFileInDotWaspDir = castFile $ case replaceRelExtension (basename waspFilePath) ".mjs" of Just path -> path Nothing -> error $ "Couldn't calculate the compiled JS file path for " ++ toFilePath waspFilePath ++ "." @@ -154,8 +153,8 @@ executeMainWaspJsFile waspProjectDir prismaSchemaAst absCompiledMainWaspJsFile = -- Before this, I had the entrypoint file hardcoded, which was bad -- too: waspProjectDir [relfile|node_modules/wasp-config/dist/run.js|] [ "wasp-config", - SP.fromAbsFile absCompiledMainWaspJsFile, - SP.fromAbsFile absDeclsOutputFile, + fromAbsFile absCompiledMainWaspJsFile, + fromAbsFile absDeclsOutputFile, encodeToString allowedEntityNames ] J.Wasp @@ -247,7 +246,7 @@ findWaspFile waspDir = do where findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.mts" files findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files - findFileThatEndsWith suffix files = SP.castFile . (waspDir ) <$> find ((suffix `isSuffixOf`) . toFilePath) files + findFileThatEndsWith suffix files = castFile . (waspDir ) <$> find ((suffix `isSuffixOf`) . toFilePath) files fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.mts file in the " ++ toFilePath waspDir ++ " directory" bothFilesFoundMessage = "Found both *.wasp and *.wasp.mts files in the project directory. " From edd7a85f161f59ef7fb427bd7d50ad9bd508324b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 21:05:46 +0200 Subject: [PATCH 05/11] Change type name --- waspc/src/Wasp/Project/Analyze.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 9967ac7f93..014105c7a5 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -85,7 +85,7 @@ data WaspTsFile data CompiledWaspJsFile -data DeclsJsonFile +data AppSpecDeclsJsonFile analyzeWaspFile :: Path' Abs (Dir WaspProjectDir) -> Psl.Schema.Schema -> WaspFile -> IO (Either [CompileError] [AS.Decl]) analyzeWaspFile waspDir prismaSchemaAst = \case @@ -138,7 +138,7 @@ executeMainWaspJsFile :: Path' Abs (Dir WaspProjectDir) -> Psl.Schema.Schema -> Path' Abs (File CompiledWaspJsFile) -> - IO (Either [CompileError] (Path' Abs (File DeclsJsonFile))) + IO (Either [CompileError] (Path' Abs (File AppSpecDeclsJsonFile))) executeMainWaspJsFile waspProjectDir prismaSchemaAst absCompiledMainWaspJsFile = do chan <- newChan (_, runExitCode) <- do @@ -167,7 +167,7 @@ executeMainWaspJsFile waspProjectDir prismaSchemaAst absCompiledMainWaspJsFile = absDeclsOutputFile = waspProjectDir dotWaspDirInWaspProjectDir [relfile|decls.json|] allowedEntityNames = Psl.Schema.getModelNames prismaSchemaAst -readDecls :: Psl.Schema.Schema -> Path' Abs (File DeclsJsonFile) -> IO (Either [CompileError] [AS.Decl]) +readDecls :: Psl.Schema.Schema -> Path' Abs (File AppSpecDeclsJsonFile) -> IO (Either [CompileError] [AS.Decl]) readDecls prismaSchemaAst declsJsonFile = runExceptT $ do entityDecls <- liftEither entityDeclsOrErrors remainingDecls <- ExceptT declsFromJsonOrError From ae76820cd4a4a16a665a9412514b23d3e1c6fb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 21:33:48 +0200 Subject: [PATCH 06/11] Implement review changes --- .../StarterTemplates/Templating.hs | 2 +- waspc/src/Wasp/Project/Analyze.hs | 56 ++++++++++++------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs b/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs index 69b072fe85..2be2430864 100644 --- a/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs +++ b/waspc/cli/src/Wasp/Cli/Command/CreateNewProject/StarterTemplates/Templating.hs @@ -9,7 +9,7 @@ import qualified Data.Text as T import StrongPath (Abs, Dir, File, Path') import Wasp.Cli.Command.CreateNewProject.Common (defaultWaspVersionBounds) import Wasp.Cli.Command.CreateNewProject.ProjectDescription (NewProjectAppName, NewProjectName) -import Wasp.Project.Analyze (WaspFile (..), findWaspFile) +import Wasp.Project.Analyze (WaspFilePath (..), findWaspFile) import Wasp.Project.Common (WaspProjectDir) import Wasp.Project.ExternalConfig.PackageJson (findPackageJsonFile) import qualified Wasp.Util.IO as IOUtil diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 014105c7a5..9a254318e2 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -3,7 +3,7 @@ module Wasp.Project.Analyze analyzeWaspFileContent, findWaspFile, analyzePrismaSchema, - WaspFile (..), + WaspFilePath (..), ) where @@ -14,7 +14,21 @@ import Control.Monad.Except (ExceptT (..), liftEither, runExceptT) import qualified Data.Aeson as Aeson import Data.Conduit.Process.Typed (ExitCode (..)) import Data.List (find, isSuffixOf) -import StrongPath (Abs, Dir, File, File', Path', Rel, basename, castFile, fromAbsFile, relfile, toFilePath, ()) +import StrongPath + ( Abs, + Dir, + File, + File', + Path', + Rel, + basename, + castFile, + fromAbsDir, + fromAbsFile, + fromRelFile, + relfile, + (), + ) import qualified Wasp.Analyzer as Analyzer import Wasp.Analyzer.AnalyzeError (getErrorMessageAndCtx) import Wasp.Analyzer.Parser.Ctx (Ctx) @@ -75,7 +89,7 @@ analyzeWaspProject waspDir options = do Left errors -> return (Left errors, []) Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations -data WaspFile +data WaspFilePath = WaspLang !(Path' Abs (File WaspLangFile)) | WaspTs !(Path' Abs (File WaspTsFile)) @@ -87,7 +101,7 @@ data CompiledWaspJsFile data AppSpecDeclsJsonFile -analyzeWaspFile :: Path' Abs (Dir WaspProjectDir) -> Psl.Schema.Schema -> WaspFile -> IO (Either [CompileError] [AS.Decl]) +analyzeWaspFile :: Path' Abs (Dir WaspProjectDir) -> Psl.Schema.Schema -> WaspFilePath -> IO (Either [CompileError] [AS.Decl]) analyzeWaspFile waspDir prismaSchemaAst = \case WaspLang waspFilePath -> analyzeWaspLangFile prismaSchemaAst waspFilePath WaspTs waspFilePath -> analyzeWaspTsFile waspDir prismaSchemaAst waspFilePath @@ -97,7 +111,7 @@ analyzeWaspTsFile waspProjectDir prismaSchemaAst waspFilePath = runExceptT $ do -- TODO: I'm not yet sure where tsconfig.node.json location should come from -- because we also need that knowledge when generating a TS SDK project. compiledWaspJsFile <- ExceptT $ compileWaspTsFile waspProjectDir [relfile|tsconfig.wasp.json|] waspFilePath - declsJsonFile <- ExceptT $ executeMainWaspJsFile waspProjectDir prismaSchemaAst compiledWaspJsFile + declsJsonFile <- ExceptT $ executeMainWaspJsFileAndGetDeclsFile waspProjectDir prismaSchemaAst compiledWaspJsFile ExceptT $ readDecls prismaSchemaAst declsJsonFile compileWaspTsFile :: @@ -115,31 +129,31 @@ compileWaspTsFile waspProjectDir tsconfigNodeFileInWaspProjectDir waspFilePath = "npx" [ "tsc", "-p", - toFilePath (waspProjectDir tsconfigNodeFileInWaspProjectDir), + fromAbsFile (waspProjectDir tsconfigNodeFileInWaspProjectDir), "--noEmit", "false", "--outDir", - toFilePath outDir + fromAbsDir outDir ] J.Wasp chan ) - case tscExitCode of - ExitFailure _status -> return $ Left ["Got TypeScript compiler errors for " ++ toFilePath waspFilePath ++ "."] - ExitSuccess -> return $ Right absCompiledWaspJsFile + return $ case tscExitCode of + ExitFailure _status -> Left ["Got TypeScript compiler errors for " ++ fromAbsFile waspFilePath ++ "."] + ExitSuccess -> Right absCompiledWaspJsFile where outDir = waspProjectDir dotWaspDirInWaspProjectDir absCompiledWaspJsFile = outDir compiledWaspJsFileInDotWaspDir compiledWaspJsFileInDotWaspDir = castFile $ case replaceRelExtension (basename waspFilePath) ".mjs" of Just path -> path - Nothing -> error $ "Couldn't calculate the compiled JS file path for " ++ toFilePath waspFilePath ++ "." + Nothing -> error $ "Couldn't calculate the compiled JS file path for " ++ fromAbsFile waspFilePath ++ "." -executeMainWaspJsFile :: +executeMainWaspJsFileAndGetDeclsFile :: Path' Abs (Dir WaspProjectDir) -> Psl.Schema.Schema -> Path' Abs (File CompiledWaspJsFile) -> IO (Either [CompileError] (Path' Abs (File AppSpecDeclsJsonFile))) -executeMainWaspJsFile waspProjectDir prismaSchemaAst absCompiledMainWaspJsFile = do +executeMainWaspJsFileAndGetDeclsFile waspProjectDir prismaSchemaAst absCompiledMainWaspJsFile = do chan <- newChan (_, runExitCode) <- do concurrently @@ -170,7 +184,7 @@ executeMainWaspJsFile waspProjectDir prismaSchemaAst absCompiledMainWaspJsFile = readDecls :: Psl.Schema.Schema -> Path' Abs (File AppSpecDeclsJsonFile) -> IO (Either [CompileError] [AS.Decl]) readDecls prismaSchemaAst declsJsonFile = runExceptT $ do entityDecls <- liftEither entityDeclsOrErrors - remainingDecls <- ExceptT declsFromJsonOrError + remainingDecls <- ExceptT $ left (: []) <$> declsFromJsonOrError return $ entityDecls ++ remainingDecls where entityDeclsOrErrors = @@ -180,9 +194,9 @@ readDecls prismaSchemaAst declsJsonFile = runExceptT $ do declsFromJsonOrError = do declsBytestring <- IOUtil.readFileBytes declsJsonFile - return $ case Aeson.eitherDecode declsBytestring of - Left err -> Left ["Error while parsing the declarations from JSON: " ++ err] - Right value -> Right value + return $ + left ("Error while reading the declarations from JSON: " ++) $ + Aeson.eitherDecode declsBytestring analyzeWaspLangFile :: Psl.Schema.Schema -> Path' Abs (File WaspLangFile) -> IO (Either [CompileError] [AS.Decl]) analyzeWaspLangFile prismaSchemaAst waspFilePath = do @@ -235,7 +249,7 @@ constructAppSpec waspDir options externalConfigs parsedPrismaSchema decls = do return $ runValidation ASV.validateAppSpec appSpec -findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either String WaspFile) +findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either String WaspFilePath) findWaspFile waspDir = do files <- fst <$> IOUtil.listDirectory waspDir return $ case (findWaspTsFile files, findWaspLangFile files) of @@ -246,8 +260,8 @@ findWaspFile waspDir = do where findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.mts" files findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files - findFileThatEndsWith suffix files = castFile . (waspDir ) <$> find ((suffix `isSuffixOf`) . toFilePath) files - fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.mts file in the " ++ toFilePath waspDir ++ " directory" + findFileThatEndsWith suffix files = castFile . (waspDir ) <$> find ((suffix `isSuffixOf`) . fromRelFile) files + fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.mts file in the " ++ fromAbsDir waspDir ++ " directory" bothFilesFoundMessage = "Found both *.wasp and *.wasp.mts files in the project directory. " ++ "You must choose how you want to define your app (using Wasp or TypeScript) and only keep one of them." @@ -269,7 +283,7 @@ analyzePrismaSchema waspProjectDir = do -- NOTE: linking here to migration docs because I think it's the most common reason why schema.prisma file is missing. -- After people mostly start using 0.14.0+ they will have schema.prisma file, so this message will be less relevant. -- If we see that this message is still relevant, we can change it to be more general. - couldntFindPrismaSchemaMessage = "Couldn't find the schema.prisma file in the " ++ toFilePath waspProjectDir ++ " directory. \nRead more: https://wasp-lang.dev/docs/migrate-from-0-13-to-0-14#migrate-to-the-new-schemaprisma-file" + couldntFindPrismaSchemaMessage = "Couldn't find the schema.prisma file in the " ++ fromAbsDir waspProjectDir ++ " directory. \nRead more: https://wasp-lang.dev/docs/migrate-from-0-13-to-0-14#migrate-to-the-new-schemaprisma-file" runValidation :: (result -> [ValidationError]) -> result -> (Either [CompileError] result, [CompileWarning]) runValidation getErrorsAndWarnings result = From 7eab0bc8bb0d5ff085bcfe0e199f1368cf82b2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 21:58:07 +0200 Subject: [PATCH 07/11] Fix failing tests --- waspc/src/Wasp/AppSpec/Core/Decl.hs | 26 ++++++++++++++++++++++++++ waspc/test/AppSpec/FromJSONTest.hs | 4 ++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/waspc/src/Wasp/AppSpec/Core/Decl.hs b/waspc/src/Wasp/AppSpec/Core/Decl.hs index 6d82175152..bbe6bddd22 100644 --- a/waspc/src/Wasp/AppSpec/Core/Decl.hs +++ b/waspc/src/Wasp/AppSpec/Core/Decl.hs @@ -1,5 +1,6 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE TupleSections #-} +{-# LANGUAGE TypeApplications #-} module Wasp.AppSpec.Core.Decl ( Decl, @@ -9,9 +10,20 @@ module Wasp.AppSpec.Core.Decl ) where +import Control.Applicative ((<|>)) import Data.Maybe (mapMaybe) import Data.Typeable (cast) +import Wasp.AppSpec.Action (Action) +import Wasp.AppSpec.Api (Api) +import Wasp.AppSpec.ApiNamespace (ApiNamespace) +import Wasp.AppSpec.App (App) import Wasp.AppSpec.Core.IsDecl (IsDecl) +import Wasp.AppSpec.Crud (Crud) +import Wasp.AppSpec.Entity (Entity) +import Wasp.AppSpec.Job (Job) +import Wasp.AppSpec.Page (Page) +import Wasp.AppSpec.Query (Query) +import Wasp.AppSpec.Route (Route) -- | A container for any (IsDecl a) type, allowing you to have a heterogenous list of -- Wasp declarations as [Decl]. @@ -19,6 +31,20 @@ import Wasp.AppSpec.Core.IsDecl (IsDecl) data Decl where Decl :: (IsDecl a) => String -> a -> Decl +instance Show Decl where + show decl = + show $ + (show <$> fromDecl @Api decl) + <|> (show <$> fromDecl @Route decl) + <|> (show <$> fromDecl @Crud decl) + <|> (show <$> fromDecl @App decl) + <|> (show <$> fromDecl @Action decl) + <|> (show <$> fromDecl @Job decl) + <|> (show <$> fromDecl @Entity decl) + <|> (show <$> fromDecl @Page decl) + <|> (show <$> fromDecl @ApiNamespace decl) + <|> (show <$> fromDecl @Query decl) + -- | Extracts all declarations of a certain type from a @[Decl]@s takeDecls :: (IsDecl a) => [Decl] -> [(String, a)] takeDecls = mapMaybe fromDecl diff --git a/waspc/test/AppSpec/FromJSONTest.hs b/waspc/test/AppSpec/FromJSONTest.hs index b4af9e4125..1d0d2d8e7b 100644 --- a/waspc/test/AppSpec/FromJSONTest.hs +++ b/waspc/test/AppSpec/FromJSONTest.hs @@ -278,8 +278,8 @@ spec_AppSpecFromJSON = do } ) where - extNamedImportJson = [trimming| { "kind": "named", "name" : "foo", "path": "folder/file.js" }|] - extDefaultImportJson = [trimming| { "kind": "default", "name" : "foo", "path": "folder/subfolder/file.js" }|] + extNamedImportJson = [trimming| { "kind": "named", "name" : "foo", "path": "@src/folder/file.js" }|] + extDefaultImportJson = [trimming| { "kind": "default", "name" : "foo", "path": "@src/folder/subfolder/file.js" }|] fooEntityRef = [trimming| { "name": "foo", "declType": "Entity" }|] barEntityRef = [trimming| { "name": "bar", "declType": "Entity" }|] From 8c8cb4f3754237edc2a579216d971f6bc11db0fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 22:13:04 +0200 Subject: [PATCH 08/11] Remove duplication when parsing ext imports --- .../Evaluation/TypedExpr/Combinators.hs | 24 ++++--------------- waspc/src/Wasp/AppSpec/ExtImport.hs | 12 ++++++---- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs b/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs index 26598d58e2..1632f68379 100644 --- a/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs +++ b/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs @@ -155,34 +155,18 @@ tuple4 eval1 eval2 eval3 eval4 = evaluation $ \(typeDefs, bindings) -> withCtx $ -- | An evaluation that expects an "ExtImport". extImport :: TypedExprEvaluation AppSpec.ExtImport.ExtImport extImport = evaluation' . withCtx $ \ctx -> \case - TypedAST.ExtImport name extImportPath -> + TypedAST.ExtImport name extImportPath -> -- NOTE(martin): This parsing here could instead be done in Parser. -- I don't have a very good reason for doing it here instead of Parser, except -- for being somewhat simpler to implement. -- So we might want to move it to Parser at some point in the future, if we -- figure out that is better (it sounds/feels like it could be). - case stripImportPrefix extImportPath of - Just relFileFP -> case SP.parseRelFileP relFileFP of - Left err -> mkParseError ctx $ show err - Right relFileSP -> pure $ AppSpec.ExtImport.ExtImport name relFileSP - Nothing -> - mkParseError - ctx - $ "Path in external import must start with \"" ++ extSrcPrefix ++ "\"!" + case AppSpec.ExtImport.parseExtImportPath extImportPath of + Left err -> mkParseError ctx err + Right importPath -> pure $ AppSpec.ExtImport.ExtImport name importPath expr -> Left $ ER.mkEvaluationError ctx $ ER.ExpectedType T.ExtImportType (TypedAST.exprType expr) where mkParseError ctx msg = Left $ ER.mkEvaluationError ctx $ ER.ParseError $ ER.EvaluationParseError msg - stripImportPrefix importPath = stripPrefix extSrcPrefix importPath - -- Filip: We no longer want separation between client and server code - -- todo (filip): Do we still want to know whic is which. We might (because of the reloading). - -- For now, as we'd like (expect): - -- - Nodemon watches all files in the user's source folder (client files - -- included), but tsc only compiles the server files (I think because it - -- knows that the others aren't used). I am not yet sure how it knows this. - -- - Vite also only triggers on client files. I am not sure how it knows - -- about the difference either. - -- todo (filip): investigate - extSrcPrefix = "@src/" -- | An evaluation that expects a "JSON". json :: TypedExprEvaluation AppSpec.JSON.JSON diff --git a/waspc/src/Wasp/AppSpec/ExtImport.hs b/waspc/src/Wasp/AppSpec/ExtImport.hs index 907eb5dd42..fee7606a78 100644 --- a/waspc/src/Wasp/AppSpec/ExtImport.hs +++ b/waspc/src/Wasp/AppSpec/ExtImport.hs @@ -6,15 +6,17 @@ module Wasp.AppSpec.ExtImport ( ExtImport (..), ExtImportName (..), importIdentifier, + parseExtImportPath, ) where +import Control.Arrow (left) import Data.Aeson (FromJSON (parseJSON), withObject, (.:)) import Data.Aeson.Types (ToJSON) import Data.Data (Data) import Data.List (stripPrefix) import GHC.Generics (Generic) -import StrongPath (File', Path, Posix, Rel, parseRelFileP) +import StrongPath (File', Path, Posix, Rel) import qualified StrongPath as SP import Wasp.AppSpec.ExternalFiles (SourceExternalCodeDir) @@ -58,13 +60,13 @@ importIdentifier (ExtImport importName _) = case importName of ExtImportModule n -> n ExtImportField n -> n --- TODO: Remove duplication parseExtImportPath :: String -> Either String ExtImportPath parseExtImportPath extImportPath = case stripImportPrefix extImportPath of - Just relFileFP -> case SP.parseRelFileP relFileFP of - Left err -> Left $ "Failed to parse relative posix path to file: " ++ show err - Right path' -> Right path' Nothing -> Left $ "Path in external import must start with \"" ++ extSrcPrefix ++ "\"!" + Just relFileFP -> + left + (("Failed to parse relative posix path to file: " ++) . show) + $ SP.parseRelFileP relFileFP where stripImportPrefix importPath = stripPrefix extSrcPrefix importPath -- Filip: We no longer want separation between client and server code From d0ba9e545ac1b88dfcf5b14e79458f6285d254be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 22:16:37 +0200 Subject: [PATCH 09/11] Remove redundant variable --- waspc/src/Wasp/Analyzer.hs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/waspc/src/Wasp/Analyzer.hs b/waspc/src/Wasp/Analyzer.hs index 02530caf48..8c4c98a68a 100644 --- a/waspc/src/Wasp/Analyzer.hs +++ b/waspc/src/Wasp/Analyzer.hs @@ -166,11 +166,10 @@ analyze prismaSchemaAst = getEntityDecls :: Psl.Schema.Schema -> Either [AnalyzeError] [Decl] getEntityDecls schema = - wrapAnalyzerError TypeError (typeCheck stdTypes ast) + wrapAnalyzerError TypeError (typeCheck stdTypes astWithEntitiesOnly) >>= (wrapAnalyzerError EvaluationError . evaluate stdTypes) where - entityStatements = parseEntityStatements schema - ast = Parser.AST entityStatements + astWithEntitiesOnly = Parser.AST $ parseEntityStatements schema wrapAnalyzerError :: (e -> AnalyzeError) -> Either e a -> Either [AnalyzeError] a wrapAnalyzerError makeError = left ((: []) . makeError) From 4eec3c1859603a0dfdb71a809a7e16e75baeb4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 22:17:56 +0200 Subject: [PATCH 10/11] Remove trailling space --- .../Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs b/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs index 1632f68379..8e6c70c7bd 100644 --- a/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs +++ b/waspc/src/Wasp/Analyzer/Evaluator/Evaluation/TypedExpr/Combinators.hs @@ -155,7 +155,8 @@ tuple4 eval1 eval2 eval3 eval4 = evaluation $ \(typeDefs, bindings) -> withCtx $ -- | An evaluation that expects an "ExtImport". extImport :: TypedExprEvaluation AppSpec.ExtImport.ExtImport extImport = evaluation' . withCtx $ \ctx -> \case - TypedAST.ExtImport name extImportPath -> + TypedAST.ExtImport name extImportPath -> + -- NOTE(martin): This parsing here could instead be done in Parser. -- NOTE(martin): This parsing here could instead be done in Parser. -- I don't have a very good reason for doing it here instead of Parser, except -- for being somewhat simpler to implement. From 1699df25fc991e7ae95f9258c2d66e3ce2f7ba6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Sodi=C4=87?= Date: Mon, 7 Oct 2024 22:21:57 +0200 Subject: [PATCH 11/11] Revert Show instance for Decl --- waspc/src/Wasp/AppSpec/Core/Decl.hs | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/waspc/src/Wasp/AppSpec/Core/Decl.hs b/waspc/src/Wasp/AppSpec/Core/Decl.hs index bbe6bddd22..6d82175152 100644 --- a/waspc/src/Wasp/AppSpec/Core/Decl.hs +++ b/waspc/src/Wasp/AppSpec/Core/Decl.hs @@ -1,6 +1,5 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE TupleSections #-} -{-# LANGUAGE TypeApplications #-} module Wasp.AppSpec.Core.Decl ( Decl, @@ -10,20 +9,9 @@ module Wasp.AppSpec.Core.Decl ) where -import Control.Applicative ((<|>)) import Data.Maybe (mapMaybe) import Data.Typeable (cast) -import Wasp.AppSpec.Action (Action) -import Wasp.AppSpec.Api (Api) -import Wasp.AppSpec.ApiNamespace (ApiNamespace) -import Wasp.AppSpec.App (App) import Wasp.AppSpec.Core.IsDecl (IsDecl) -import Wasp.AppSpec.Crud (Crud) -import Wasp.AppSpec.Entity (Entity) -import Wasp.AppSpec.Job (Job) -import Wasp.AppSpec.Page (Page) -import Wasp.AppSpec.Query (Query) -import Wasp.AppSpec.Route (Route) -- | A container for any (IsDecl a) type, allowing you to have a heterogenous list of -- Wasp declarations as [Decl]. @@ -31,20 +19,6 @@ import Wasp.AppSpec.Route (Route) data Decl where Decl :: (IsDecl a) => String -> a -> Decl -instance Show Decl where - show decl = - show $ - (show <$> fromDecl @Api decl) - <|> (show <$> fromDecl @Route decl) - <|> (show <$> fromDecl @Crud decl) - <|> (show <$> fromDecl @App decl) - <|> (show <$> fromDecl @Action decl) - <|> (show <$> fromDecl @Job decl) - <|> (show <$> fromDecl @Entity decl) - <|> (show <$> fromDecl @Page decl) - <|> (show <$> fromDecl @ApiNamespace decl) - <|> (show <$> fromDecl @Query decl) - -- | Extracts all declarations of a certain type from a @[Decl]@s takeDecls :: (IsDecl a) => [Decl] -> [(String, a)] takeDecls = mapMaybe fromDecl