Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using TS SDK from waspc #2276

Merged
merged 41 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e228263
Successfully get spec from stdout
sodic Sep 6, 2024
664eafe
Successfully read spec from file
sodic Sep 6, 2024
1b75ab9
Clean up code in Analyze.hs
sodic Sep 10, 2024
0c7b901
Move outDir source of truth into Haskell
sodic Sep 10, 2024
b7c4800
Add extra context to Analyze.hs
sodic Sep 11, 2024
68bfe30
Improve TS SDK analysis
sodic Sep 11, 2024
0758747
Put config dir back in .wasp dir
sodic Sep 11, 2024
b7ecab4
Add more comments
sodic Sep 12, 2024
e2e802e
Update Analyze.hs
sodic Sep 18, 2024
2d27900
Merge branch 'main' into filip-ts-sdk
sodic Sep 25, 2024
987243d
Remove todo for duplication
sodic Sep 25, 2024
15e3e68
Remove the duplication in templating
sodic Sep 25, 2024
7600288
Rearrange analyze.hs
sodic Sep 25, 2024
2b0c0ff
Remove todo after adding it to GitHub
sodic Sep 25, 2024
7ec9356
Remove one more todo
sodic Sep 25, 2024
1597f4b
Remove todo after adding it to GitHub
sodic Sep 25, 2024
b887cd8
Resolve some more todos
sodic Sep 25, 2024
1bdc871
Remove another todo
sodic Sep 25, 2024
52378c4
Send prisma models to JS runtime
sodic Sep 26, 2024
115dce5
Merge branch 'main' into filip-ts-sdk
sodic Sep 26, 2024
2617b6f
Properly parse decls.json
sodic Sep 26, 2024
32275e5
Improve error messages
sodic Sep 26, 2024
b673308
Merge branch 'main' into filip-ts-sdk
sodic Sep 30, 2024
3513b68
Fix ext import parsing and inject entities
sodic Oct 5, 2024
e9ef283
Fail if you find both wasp files
sodic Oct 7, 2024
0dc7435
Change tsconfig file name
sodic Oct 7, 2024
3e9efc8
Clean up imports
sodic Oct 7, 2024
24f65ec
Fix some more imports
sodic Oct 7, 2024
edd7a85
Change type name
sodic Oct 7, 2024
ae76820
Implement review changes
sodic Oct 7, 2024
7eab0bc
Fix failing tests
sodic Oct 7, 2024
8c8cb4f
Remove duplication when parsing ext imports
sodic Oct 7, 2024
d0ba9e5
Remove redundant variable
sodic Oct 7, 2024
4eec3c1
Remove trailling space
sodic Oct 7, 2024
1699df2
Revert Show instance for Decl
sodic Oct 7, 2024
5a6719e
Add module to package.json and remove mts
sodic Oct 8, 2024
3f48b98
Merge branch 'main' into filip-ts-sdk
sodic Oct 8, 2024
67f1f9e
Differentiate between different tsconfigs
sodic Oct 9, 2024
522e131
Fix tsconfig stuff
sodic Oct 9, 2024
8ab0b3f
Update e2e tests
sodic Oct 9, 2024
d90b235
Rename tsconfig constants and refactor
sodic Oct 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion waspc/cli/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ main = withUtf8 . (`E.catch` handleInternalErrors) $ do

handleInternalErrors :: E.ErrorCall -> IO ()
handleInternalErrors e = do
putStrLn $ "\nInternal Wasp error (bug in compiler):\n" ++ indent 2 (show e)
putStrLn $ "\nInternal Wasp error (bug in the compiler):\n" ++ indent 2 (show e)
exitFailure

-- | Sets env variables that are visible to the commands run by the CLI.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (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
Expand All @@ -26,8 +26,11 @@ replaceTemplatePlaceholdersInWaspFile ::
NewProjectAppName -> NewProjectName -> Path' Abs (Dir WaspProjectDir) -> IO ()
replaceTemplatePlaceholdersInWaspFile appName projectName projectDir =
findWaspFile projectDir >>= \case
Nothing -> return ()
Just absMainWaspFile -> replaceTemplatePlaceholdersInFileOnDisk appName projectName absMainWaspFile
Left _error -> return ()
Right (WaspLang absMainWaspFile) -> replaceTemplatePlaceholders absMainWaspFile
Right (WaspTs absMainTsFile) -> replaceTemplatePlaceholders absMainTsFile
where
replaceTemplatePlaceholders = replaceTemplatePlaceholdersInFileOnDisk appName projectName

-- | Template file for package.json file has placeholders in it that we want to replace
-- in the package.json file we have written to the disk.
Expand Down
1 change: 1 addition & 0 deletions waspc/data/Cli/templates/basic/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "__waspAppName__",
"type": "module",
"dependencies": {
"wasp": "file:.wasp/out/sdk/wasp",
"react": "^18.2.0"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions waspc/src/Wasp/Analyzer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ module Wasp.Analyzer

-- * API
analyze,
getEntityDecls,
takeDecls,
AnalyzeError (..),
getErrorMessageAndCtx,
Expand All @@ -127,8 +128,9 @@ import Wasp.Analyzer.AnalyzeError
)
import Wasp.Analyzer.Evaluator (Decl, evaluate, takeDecls)
import Wasp.Analyzer.Parser (parseStatements)
import qualified Wasp.Analyzer.Parser as Parser
import Wasp.Analyzer.Parser.Valid (validateAst)
import Wasp.Analyzer.Prisma (injectEntitiesFromPrismaSchema)
import Wasp.Analyzer.Prisma (injectEntitiesFromPrismaSchema, parseEntityStatements)
import Wasp.Analyzer.StdTypeDefinitions (stdTypes)
import Wasp.Analyzer.TypeChecker (typeCheck)
import qualified Wasp.Psl.Ast.Schema as Psl.Schema
Expand Down Expand Up @@ -157,7 +159,17 @@ analyze prismaSchemaAst =
^ disallow entities here
^ inject entities here
--}
>=> (left ((: []) . ValidationError) . validateAst)
>=> wrapAnalyzerError ValidationError . validateAst
>=> injectEntitiesFromPrismaSchema prismaSchemaAst
>=> (left ((: []) . TypeError) . typeCheck stdTypes)
>=> (left ((: []) . EvaluationError) . evaluate stdTypes)
>=> (wrapAnalyzerError TypeError . typeCheck stdTypes)
>=> (wrapAnalyzerError EvaluationError . evaluate stdTypes)

getEntityDecls :: Psl.Schema.Schema -> Either [AnalyzeError] [Decl]
getEntityDecls schema =
wrapAnalyzerError TypeError (typeCheck stdTypes astWithEntitiesOnly)
>>= (wrapAnalyzerError EvaluationError . evaluate stdTypes)
where
astWithEntitiesOnly = Parser.AST $ parseEntityStatements schema
Comment on lines +167 to +172
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Martinsos This is what we discussed on Discord: sending only the entity statements through the compilation pipeline to get their declarations.

Should I document the idea behind it?


wrapAnalyzerError :: (e -> AnalyzeError) -> Either e a -> Either [AnalyzeError] a
wrapAnalyzerError makeError = left ((: []) . makeError)
Original file line number Diff line number Diff line change
Expand Up @@ -156,33 +156,18 @@ tuple4 eval1 eval2 eval3 eval4 = evaluation $ \(typeDefs, bindings) -> withCtx $
extImport :: TypedExprEvaluation AppSpec.ExtImport.ExtImport
extImport = evaluation' . withCtx $ \ctx -> \case
TypedAST.ExtImport name extImportPath ->
-- NOTE(martin): This parsing here could instead be done in Parser.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this

-- 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
Comment on lines +165 to +167
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed this for FromJSON so I moved it.

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
Expand Down
6 changes: 5 additions & 1 deletion waspc/src/Wasp/Analyzer/Prisma.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Wasp.Analyzer.Prisma
( injectEntitiesFromPrismaSchema,
parseEntityStatements,
)
where

Expand All @@ -11,9 +12,12 @@ import qualified Wasp.Psl.Generator.Model as Psl.Model.Generator
injectEntitiesFromPrismaSchema :: Psl.Schema.Schema -> Parser.AST -> Either a Parser.AST
injectEntitiesFromPrismaSchema schema ast = Right $ ast {Parser.astStmts = stmts ++ entityStmts}
where
entityStmts = makeEntityStmt <$> generatePrismaModelSources schema
entityStmts = parseEntityStatements schema
stmts = Parser.astStmts ast

parseEntityStatements :: Psl.Schema.Schema -> [WithCtx Parser.Stmt]
parseEntityStatements schema = makeEntityStmt <$> generatePrismaModelSources schema

type ModelName = String

type ModelBody = String
Expand Down
34 changes: 28 additions & 6 deletions waspc/src/Wasp/AppSpec/ExtImport.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ 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)

data ExtImport = ExtImport
Expand All @@ -30,18 +34,16 @@ instance FromJSON ExtImport where
nameStr <- o .: "name"
pathStr <- o .: "path"
extImportName <- parseExtImportName kindStr nameStr
extImportPath <- parseExtImportPath pathStr
extImportPath <- case parseExtImportPath pathStr of
Right path' -> pure path'
Left err -> fail err
Comment on lines +37 to +39
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Martinsos Any helper function for this? I can't use left because of fail.

return $ ExtImport extImportName extImportPath
where
parseExtImportName kindStr nameStr = case kindStr of
"default" -> pure $ ExtImportModule nameStr
"named" -> pure $ ExtImportField nameStr
_ -> fail $ "Failed to parse import kind: " <> kindStr

parseExtImportPath pathStr = case parseRelFileP pathStr of
Just path' -> pure path'
Nothing -> fail $ "Failed to parse relative posix path to file: " <> pathStr

type ExtImportPath = Path Posix (Rel SourceExternalCodeDir) File'

type Identifier = String
Expand All @@ -57,3 +59,23 @@ importIdentifier :: ExtImport -> Identifier
importIdentifier (ExtImport importName _) = case importName of
ExtImportModule n -> n
ExtImportField n -> n

parseExtImportPath :: String -> Either String ExtImportPath
parseExtImportPath extImportPath = case stripImportPrefix extImportPath of
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
-- todo (filip): Do we still want to know which 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/"
5 changes: 3 additions & 2 deletions waspc/src/Wasp/Error.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module Wasp.Error (showCompilerErrorForTerminal) where

import Data.List (intercalate)
import StrongPath (Abs, File', Path')
import StrongPath (Abs, Path')
import qualified StrongPath as SP
import StrongPath.Types (File)
import Wasp.Analyzer.Parser.Ctx (Ctx, getCtxRgn)
import Wasp.Analyzer.Parser.SourcePosition (SourcePosition (..))
import Wasp.Analyzer.Parser.SourceRegion (SourceRegion (..))
Expand All @@ -12,7 +13,7 @@ import qualified Wasp.Util.Terminal as T
-- | Transforms compiler error (error with parse context) into an informative, pretty String that
-- can be printed directly into the terminal. It uses terminal features like escape codes
-- (colors, styling, ...).
showCompilerErrorForTerminal :: (Path' Abs File', String) -> (String, Ctx) -> String
showCompilerErrorForTerminal :: (Path' Abs (File f), String) -> (String, Ctx) -> String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have something like data WaspFile, so that we could do Path' Abs (File WaspFile)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. We didn't before, but we'll have it now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take care of this later. It requires dealing with cyclic dependencies.

showCompilerErrorForTerminal (waspFilePath, waspFileContent) (errMsg, errCtx) =
let srcRegion = getCtxRgn errCtx
in intercalate
Expand Down
6 changes: 3 additions & 3 deletions waspc/src/Wasp/Generator/ExternalConfig/TsConfig.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{-# LANGUAGE FlexibleInstances #-}

module Wasp.Generator.ExternalConfig.TsConfig
( validateTsConfig,
( validateSrcTsConfig,
)
where

Expand All @@ -23,8 +23,8 @@ instance IsJavascriptValue Bool where

type FieldName = String

validateTsConfig :: T.TsConfig -> [ErrorMsg]
validateTsConfig tsConfig =
validateSrcTsConfig :: T.TsConfig -> [ErrorMsg]
validateSrcTsConfig tsConfig =
concat
[ validateRequiredFieldInCompilerOptions "module" "esnext" T._module,
validateRequiredFieldInCompilerOptions "target" "esnext" T.target,
Expand Down
Loading
Loading