diff --git a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/main.wasp b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/main.wasp index 1f02583e4f..88044a7c03 100644 --- a/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/main.wasp +++ b/waspc/e2e-test/test-outputs/waspBuild-golden/waspBuild/main.wasp @@ -1,6 +1,6 @@ app waspBuild { wasp: { - version: "^0.15.2" + version: "^0.16.0" }, title: "waspBuild" } diff --git a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/main.wasp b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/main.wasp index 982cf4e8f0..70a8f46525 100644 --- a/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/main.wasp +++ b/waspc/e2e-test/test-outputs/waspCompile-golden/waspCompile/main.wasp @@ -1,6 +1,6 @@ app waspCompile { wasp: { - version: "^0.15.2" + version: "^0.16.0" }, title: "waspCompile" } diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/main.wasp b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/main.wasp index dd7184c671..48fddedeec 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/main.wasp +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/main.wasp @@ -1,6 +1,6 @@ app waspComplexTest { wasp: { - version: "^0.15.2" + version: "^0.16.0" }, auth: { userEntity: User, diff --git a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/main.wasp b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/main.wasp index 815644889f..f0a485ec43 100644 --- a/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/main.wasp +++ b/waspc/e2e-test/test-outputs/waspJob-golden/waspJob/main.wasp @@ -1,6 +1,6 @@ app waspJob { wasp: { - version: "^0.15.2" + version: "^0.16.0" }, title: "waspJob" } diff --git a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/main.wasp b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/main.wasp index 2a6ad7d962..99e0d47b2d 100644 --- a/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/main.wasp +++ b/waspc/e2e-test/test-outputs/waspMigrate-golden/waspMigrate/main.wasp @@ -1,6 +1,6 @@ app waspMigrate { wasp: { - version: "^0.15.2" + version: "^0.16.0" }, title: "waspMigrate" } diff --git a/waspc/e2e-test/test-outputs/waspNew-golden/waspNew/main.wasp b/waspc/e2e-test/test-outputs/waspNew-golden/waspNew/main.wasp index 96b3500b7f..995a2401e8 100644 --- a/waspc/e2e-test/test-outputs/waspNew-golden/waspNew/main.wasp +++ b/waspc/e2e-test/test-outputs/waspNew-golden/waspNew/main.wasp @@ -1,6 +1,6 @@ app waspNew { wasp: { - version: "^0.15.2" + version: "^0.16.0" }, title: "waspNew" } diff --git a/waspc/examples/todoApp/main.wasp b/waspc/examples/todoApp/main.wasp index f827d34e83..9dd232da7d 100644 --- a/waspc/examples/todoApp/main.wasp +++ b/waspc/examples/todoApp/main.wasp @@ -1,6 +1,6 @@ app todoApp { wasp: { - version: "^0.15.0" + version: "^0.16.0" }, title: "ToDo App", // head: [], diff --git a/waspc/examples/todoApp/package-lock.json b/waspc/examples/todoApp/package-lock.json index 9b072296ec..c834474f40 100644 --- a/waspc/examples/todoApp/package-lock.json +++ b/waspc/examples/todoApp/package-lock.json @@ -11,6 +11,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.26.2", + "tailwindcss": "^3.2.7", "wasp": "file:.wasp/out/sdk/wasp" }, "devDependencies": { diff --git a/waspc/examples/todoApp/package.json b/waspc/examples/todoApp/package.json index df4c8fc162..5bb1ee9f41 100644 --- a/waspc/examples/todoApp/package.json +++ b/waspc/examples/todoApp/package.json @@ -11,7 +11,8 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.26.2", - "wasp": "file:.wasp/out/sdk/wasp" + "wasp": "file:.wasp/out/sdk/wasp", + "tailwindcss": "^3.2.7" }, "devDependencies": { "@types/express": "^4.17.13", diff --git a/waspc/headless-test/examples/todoApp/package.json b/waspc/headless-test/examples/todoApp/package.json index 15751e4481..be070df5b7 100644 --- a/waspc/headless-test/examples/todoApp/package.json +++ b/waspc/headless-test/examples/todoApp/package.json @@ -6,7 +6,8 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.26.2", - "wasp": "file:.wasp/out/sdk/wasp" + "wasp": "file:.wasp/out/sdk/wasp", + "tailwindcss": "^3.2.7" }, "devDependencies": { "@types/cors": "^2.8.5", diff --git a/waspc/src/Wasp/AppSpec.hs b/waspc/src/Wasp/AppSpec.hs index 44b4196601..adf351bdac 100644 --- a/waspc/src/Wasp/AppSpec.hs +++ b/waspc/src/Wasp/AppSpec.hs @@ -16,7 +16,6 @@ module Wasp.AppSpec getRoutes, getJobs, resolveRef, - doesConfigFileExist, asAbsWaspProjectDirFile, getApp, getApiNamespaces, @@ -26,7 +25,7 @@ module Wasp.AppSpec where import Data.List (find) -import Data.Maybe (fromMaybe, isJust) +import Data.Maybe (fromMaybe) import Data.Text (Text) import StrongPath (Abs, Dir, File', Path', Rel, ()) import Wasp.AppSpec.Action (Action) @@ -149,10 +148,6 @@ resolveRef spec ref = $ find ((== refName ref) . fst) $ getDecls spec -doesConfigFileExist :: AppSpec -> Path' (Rel WaspProjectDir) File' -> Bool -doesConfigFileExist spec file = - isJust $ find ((==) file . _pathInWaspProjectDir) (configFiles spec) - asAbsWaspProjectDirFile :: AppSpec -> Path' (Rel WaspProjectDir) File' -> Path' Abs File' asAbsWaspProjectDirFile spec file = waspProjectDir spec file diff --git a/waspc/src/Wasp/Generator/ConfigFile.hs b/waspc/src/Wasp/Generator/ConfigFile.hs index 59cb157810..2e1037af06 100644 --- a/waspc/src/Wasp/Generator/ConfigFile.hs +++ b/waspc/src/Wasp/Generator/ConfigFile.hs @@ -4,9 +4,11 @@ module Wasp.Generator.ConfigFile ) where +import Data.List (find) import Data.Map (fromList) +import Data.Maybe (isJust) import StrongPath (File', Path', Rel, castRel, relfile, ()) -import Wasp.AppSpec (AppSpec, doesConfigFileExist) +import qualified Wasp.AppSpec.ConfigFile as CF import Wasp.ConfigFile (ConfigFileRelocationMap) import Wasp.Generator.Common (ProjectRootDir) import Wasp.Generator.WebAppGenerator.Common (webAppRootDirInProjectRootDir) @@ -24,12 +26,16 @@ asProjectRootDirConfigFile = (webAppRootDirInProjectRootDir ) . castRel -- | Helper that determines if Tailwind used. For our purposes, we allow -- developers to opt-in by creating both a tailwind config file and -- postcss config file in their wasp project dir. -isTailwindUsed :: AppSpec -> Bool -isTailwindUsed spec = - doesConfigFileExist spec tailwindConfigFile - && doesConfigFileExist spec postcssConfigFile +isTailwindUsed :: [CF.ConfigFileRelocator] -> Bool +isTailwindUsed configFileRelocators = + doesConfigFileExist tailwindConfigFile + && doesConfigFileExist postcssConfigFile + where + doesConfigFileExist :: Path' (Rel WaspProjectDir) File' -> Bool + doesConfigFileExist file = + isJust $ find ((==) file . CF._pathInWaspProjectDir) configFileRelocators --- | Establishes the mapping of what config files to copy and where from/to. +-- Establishes the mapping of what config files to copy and where from/to. -- NOTE: In the future, we could allow devs to configure what files we look for and where we copy them. configFileRelocationMap :: ConfigFileRelocationMap configFileRelocationMap = diff --git a/waspc/src/Wasp/Generator/ExternalConfig/PackageJson.hs b/waspc/src/Wasp/Generator/ExternalConfig/PackageJson.hs index f435502614..2f29812c51 100644 --- a/waspc/src/Wasp/Generator/ExternalConfig/PackageJson.hs +++ b/waspc/src/Wasp/Generator/ExternalConfig/PackageJson.hs @@ -7,22 +7,29 @@ import qualified Data.Map as M import qualified Wasp.ExternalConfig.PackageJson as P import Wasp.Generator.Common (prismaVersion) import Wasp.Generator.ExternalConfig.Common (ErrorMsg) +import Wasp.Generator.SdkGenerator.Common (tailwindCssVersion) import Wasp.Generator.WebAppGenerator.Common (reactRouterVersion, reactVersion) -validatePackageJson :: P.PackageJson -> [ErrorMsg] -validatePackageJson packageJson = +validatePackageJson :: Bool -> P.PackageJson -> [ErrorMsg] +validatePackageJson isTailwindUsed packageJson = concat - [ validate ("wasp", "file:.wasp/out/sdk/wasp") IsListedWithExactVersion, - validate ("prisma", show prismaVersion) IsListedAsDevWithExactVersion, - -- Installing the wrong version of "react-router-dom" can make users believe that they - -- can use features that are not available in the version that Wasp supports. - validate ("react-router-dom", show reactRouterVersion) IsListedWithExactVersion, - validate ("react", show reactVersion) IsListedWithExactVersion, - validate ("react-dom", show reactVersion) IsListedWithExactVersion - ] + ( [ validate ("wasp", "file:.wasp/out/sdk/wasp") IsListedWithExactVersion, + validate ("prisma", show prismaVersion) IsListedAsDevWithExactVersion, + -- Installing the wrong version of "react-router-dom" can make users believe that they + -- can use features that are not available in the version that Wasp supports. + validate ("react-router-dom", show reactRouterVersion) IsListedWithExactVersion, + validate ("react", show reactVersion) IsListedWithExactVersion, + validate ("react-dom", show reactVersion) IsListedWithExactVersion + ] + ++ tailwindValidations + ) where validate = validateDep packageJson + tailwindValidations = + [ validate ("tailwindcss", show tailwindCssVersion) IsListedWithExactVersion | isTailwindUsed + ] + data PackageValidationType = IsListedWithExactVersion | IsListedAsDevWithExactVersion | HasExactVersionIfListed validateDep :: P.PackageJson -> (P.PackageName, P.PackageVersion) -> PackageValidationType -> [String] diff --git a/waspc/src/Wasp/Generator/SdkGenerator.hs b/waspc/src/Wasp/Generator/SdkGenerator.hs index 26906464c6..e595e54dd4 100644 --- a/waspc/src/Wasp/Generator/SdkGenerator.hs +++ b/waspc/src/Wasp/Generator/SdkGenerator.hs @@ -44,6 +44,7 @@ import Wasp.Generator.SdkGenerator.Client.AuthG (genNewClientAuth) import Wasp.Generator.SdkGenerator.Client.CrudG (genNewClientCrudApi) import qualified Wasp.Generator.SdkGenerator.Client.OperationsGenerator as ClientOpsGen import Wasp.Generator.SdkGenerator.Client.RouterGenerator (genNewClientRouterApi) +import Wasp.Generator.SdkGenerator.Common (tailwindCssVersion) import qualified Wasp.Generator.SdkGenerator.Common as C import Wasp.Generator.SdkGenerator.CrudG (genCrud) import Wasp.Generator.SdkGenerator.EnvValidation (depsRequiredByEnvValidation, genEnvValidation) @@ -279,10 +280,10 @@ depsRequiredForAuth spec = maybe [] (const authDeps) maybeAuth depsRequiredByTailwind :: AppSpec -> [AS.Dependency.Dependency] depsRequiredByTailwind spec = - if G.CF.isTailwindUsed spec + if G.CF.isTailwindUsed $ AS.configFiles spec then AS.Dependency.fromList - [ ("tailwindcss", "^3.2.7"), + [ ("tailwindcss", show tailwindCssVersion), ("postcss", "^8.4.21"), ("autoprefixer", "^10.4.13") ] diff --git a/waspc/src/Wasp/Generator/SdkGenerator/Common.hs b/waspc/src/Wasp/Generator/SdkGenerator/Common.hs index 5a0311e13f..87fd5f5e85 100644 --- a/waspc/src/Wasp/Generator/SdkGenerator/Common.hs +++ b/waspc/src/Wasp/Generator/SdkGenerator/Common.hs @@ -10,6 +10,7 @@ import Wasp.Generator.ExternalCodeGenerator.Common (GeneratedExternalCodeDir) import Wasp.Generator.FileDraft (FileDraft, createTemplateFileDraft) import Wasp.Generator.Templates (TemplatesDir) import Wasp.Project.Common (generatedCodeDirInDotWaspDir) +import qualified Wasp.SemanticVersion as SV import Wasp.Util (toUpperFirst) data SdkRootDir @@ -84,3 +85,6 @@ serverTemplatesDirInSdkTemplatesDir = [reldir|server|] getOperationTypeName :: AS.Operation.Operation -> String getOperationTypeName operation = toUpperFirst (AS.Operation.getName operation) ++ "_ext" + +tailwindCssVersion :: SV.ComparatorSet +tailwindCssVersion = SV.backwardsCompatibleWith $ SV.Version 3 2 7 diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 235c29df26..cf12939d5c 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -14,6 +14,7 @@ import StrongPath fromAbsDir, ) import qualified Wasp.AppSpec as AS +import qualified Wasp.AppSpec.ConfigFile as CF import Wasp.AppSpec.Core.Decl.JSON () import qualified Wasp.AppSpec.Valid as ASV import Wasp.CompileOptions (CompileOptions) @@ -51,6 +52,10 @@ analyzeWaspProject :: IO (Either [CompileError] AS.AppSpec, [CompileWarning]) analyzeWaspProject waspDir options = do waspFilePathOrError <- left (: []) <$> findWaspFile waspDir + configFiles <- CF.discoverConfigFiles waspDir G.CF.configFileRelocationMap + + let isTailwindUsed = G.CF.isTailwindUsed configFiles + case waspFilePathOrError of Left err -> return (Left err, []) Right waspFilePath -> @@ -61,25 +66,25 @@ analyzeWaspProject waspDir options = do analyzeWaspFile waspDir prismaSchemaAst waspFilePath >>= \case Left errors -> return (Left errors, []) Right declarations -> - EC.analyzeExternalConfigs waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case + EC.analyzeExternalConfigs isTailwindUsed waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case Left errors -> return (Left errors, []) - Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations + Right externalConfigs -> constructAppSpec waspDir options externalConfigs configFiles prismaSchemaAst declarations constructAppSpec :: Path' Abs (Dir WaspProjectDir) -> CompileOptions -> EC.ExternalConfigs -> + [CF.ConfigFileRelocator] -> Psl.Schema.Schema -> [AS.Decl] -> IO (Either [CompileError] AS.AppSpec, [CompileWarning]) -constructAppSpec waspDir options externalConfigs parsedPrismaSchema decls = do +constructAppSpec waspDir options externalConfigs configFiles parsedPrismaSchema decls = do externalCodeFiles <- ExternalFiles.readCodeFiles waspDir externalPublicFiles <- ExternalFiles.readPublicFiles waspDir customViteConfigPath <- findCustomViteConfigPath waspDir maybeMigrationsDir <- findMigrationsDir waspDir maybeUserDockerfileContents <- loadUserDockerfileContents waspDir - configFiles <- CF.discoverConfigFiles waspDir G.CF.configFileRelocationMap let dbSystem = getValidDbSystemFromPrismaSchema parsedPrismaSchema let devDbUrl = makeDevDatabaseUrl waspDir dbSystem decls serverEnvVars <- readDotEnvServer waspDir diff --git a/waspc/src/Wasp/Project/ExternalConfig.hs b/waspc/src/Wasp/Project/ExternalConfig.hs index 742d67285d..8a1effb462 100644 --- a/waspc/src/Wasp/Project/ExternalConfig.hs +++ b/waspc/src/Wasp/Project/ExternalConfig.hs @@ -23,11 +23,12 @@ data ExternalConfigs = ExternalConfigs deriving (Show) analyzeExternalConfigs :: + Bool -> Path' Abs (Dir WaspProjectDir) -> Path' (Rel WaspProjectDir) (File SrcTsConfigFile) -> IO (Either [CompileError] ExternalConfigs) -analyzeExternalConfigs waspDir srcTsConfigFile = runExceptT $ do - packageJsonContent <- ExceptT $ analyzePackageJsonFile waspDir +analyzeExternalConfigs isTailwindUsed waspDir srcTsConfigFile = runExceptT $ do + packageJsonContent <- ExceptT $ analyzePackageJsonFile isTailwindUsed waspDir tsConfigContent <- ExceptT $ analyzeSrcTsConfigFile waspDir srcTsConfigFile return $ diff --git a/waspc/src/Wasp/Project/ExternalConfig/PackageJson.hs b/waspc/src/Wasp/Project/ExternalConfig/PackageJson.hs index 562285a8b6..e1f5d50d84 100644 --- a/waspc/src/Wasp/Project/ExternalConfig/PackageJson.hs +++ b/waspc/src/Wasp/Project/ExternalConfig/PackageJson.hs @@ -18,11 +18,11 @@ import Wasp.Project.Common ) import qualified Wasp.Util.IO as IOUtil -analyzePackageJsonFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either [String] P.PackageJson) -analyzePackageJsonFile waspProjectDir = runExceptT $ do +analyzePackageJsonFile :: Bool -> Path' Abs (Dir WaspProjectDir) -> IO (Either [String] P.PackageJson) +analyzePackageJsonFile isTailwindUsed waspProjectDir = runExceptT $ do packageJsonFile <- ExceptT findPackageJsonFileOrError packageJson <- ExceptT $ readPackageJsonFile packageJsonFile - case validatePackageJson packageJson of + case validatePackageJson isTailwindUsed packageJson of [] -> return packageJson errors -> throwError errors where diff --git a/waspc/waspc.cabal b/waspc/waspc.cabal index d8af354554..a70ea00b5a 100644 --- a/waspc/waspc.cabal +++ b/waspc/waspc.cabal @@ -304,7 +304,6 @@ library Wasp.Generator.NpmInstall Wasp.Generator.NpmInstall.Common Wasp.Generator.NpmInstall.InstalledNpmDepsLog - Wasp.Generator.ImportPathAlias Wasp.Generator.SdkGenerator Wasp.Generator.SdkGenerator.Auth.AuthFormsG Wasp.Generator.SdkGenerator.Auth.EmailAuthG