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

Start making ext-src SDK imports relative #2225

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions waspc/src/FilePath/Extra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ reversePosixPath :: FilePath -> FilePath
reversePosixPath path
| null parts = "."
| otherwise =
assert (".." `notElem` parts) $
FPP.joinPath $ map (const "..") parts
assert (".." `notElem` parts) $
FPP.joinPath $ map (const "..") parts
where
parts :: [String]
parts = filter (/= ".") $ FPP.splitDirectories path
18 changes: 14 additions & 4 deletions waspc/src/Wasp/Generator/SdkGenerator/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import qualified Data.Aeson as Aeson
import Data.Maybe (fromJust)
import StrongPath
import qualified StrongPath as SP
import qualified Wasp.AppSpec.ExtImport as EI
import qualified Wasp.AppSpec.Operation as AS.Operation
import Wasp.Generator.Common (ProjectRootDir)
import Wasp.Generator.Common (GeneratedSrcDir, ProjectRootDir)
import Wasp.Generator.ExternalCodeGenerator.Common (GeneratedExternalCodeDir)
import Wasp.Generator.FileDraft (FileDraft, createTemplateFileDraft)
import qualified Wasp.Generator.JsImport as GJI
import Wasp.Generator.Templates (TemplatesDir)
import Wasp.JsImport (JsImport)
import Wasp.Project.Common (generatedCodeDirInDotWaspDir)
import Wasp.Util (toUpperFirst)

Expand All @@ -20,6 +23,8 @@ data ClientTemplatesDir

data ServerTemplatesDir

instance GeneratedSrcDir SdkRootDir

asTmplFile :: Path' (Rel d) File' -> Path' (Rel SdkTemplatesDir) File'
asTmplFile = SP.castRel

Expand Down Expand Up @@ -65,6 +70,14 @@ sdkTemplatesDirInTemplatesDir = [reldir|sdk/wasp|]
extSrcDirInSdkRootDir :: Path' (Rel SdkRootDir) (Dir GeneratedExternalCodeDir)
extSrcDirInSdkRootDir = [reldir|ext-src|]

extImportToJsImport ::
Path Posix (Rel importLocation) (Dir SdkRootDir) ->
EI.ExtImport ->
JsImport
extImportToJsImport = GJI.extImportToJsImport extSrcDirP
where
extSrcDirP = fromJust $ SP.relDirToPosix extSrcDirInSdkRootDir

relDirToRelFileP :: Path Posix (Rel d) Dir' -> Path Posix (Rel d) File'
relDirToRelFileP path = fromJust $ SP.parseRelFileP $ removeTrailingSlash $ SP.fromRelDirP path
where
Expand All @@ -73,9 +86,6 @@ relDirToRelFileP path = fromJust $ SP.parseRelFileP $ removeTrailingSlash $ SP.f
makeSdkImportPath :: Path Posix (Rel SdkRootDir) File' -> Path Posix (Rel s) File'
makeSdkImportPath path = [reldirP|wasp|] </> path

extCodeDirInSdkRootDir :: Path' (Rel SdkRootDir) Dir'
extCodeDirInSdkRootDir = [reldir|ext-src|]

clientTemplatesDirInSdkTemplatesDir :: Path' (Rel SdkTemplatesDir) (Dir ClientTemplatesDir)
clientTemplatesDirInSdkTemplatesDir = [reldir|client|]

Expand Down
14 changes: 10 additions & 4 deletions waspc/src/Wasp/Generator/SdkGenerator/CrudG.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ where

import Data.Aeson (KeyValue ((.=)), object)
import qualified Data.Aeson.Types as Aeson.Types
import Data.Maybe (fromJust)
import StrongPath
( reldir,
reldirP,
relfile,
(</>),
)
import qualified StrongPath as SP
import Wasp.AppSpec (AppSpec, getCruds)
import qualified Wasp.AppSpec as AS
import qualified Wasp.AppSpec.App as AS.App
Expand All @@ -20,8 +23,9 @@ import Wasp.Generator.Crud (crudDeclarationToOperationsList, getCrudFilePath, ge
import Wasp.Generator.FileDraft (FileDraft)
import qualified Wasp.Generator.JsImport as GJI
import Wasp.Generator.Monad (Generator)
import Wasp.Generator.SdkGenerator.Common (extImportToJsImport)
import qualified Wasp.Generator.SdkGenerator.Common as C
import Wasp.Generator.SdkGenerator.Server.OperationsGenerator (extImportToJsImport)
import qualified Wasp.Util.StrongPath as SP

genCrud :: AppSpec -> Generator [FileDraft]
genCrud spec =
Expand All @@ -38,8 +42,8 @@ genCrudServerOperations spec cruds = return $ map genCrudOperation cruds
genCrudOperation :: (String, AS.Crud.Crud) -> FileDraft
genCrudOperation (name, crud) = C.mkTmplFdWithDstAndData tmplPath destPath (Just tmplData)
where
tmplPath = [relfile|server/crud/_operationTypes.ts|]
destPath = [reldir|server/crud|] </> getCrudFilePath name "ts"
tmplPath = crudDirInSdkRootDir </> [relfile|_operationTypes.ts|]
destPath = crudDirInSdkRootDir </> getCrudFilePath name "ts"
tmplData =
object
[ "crud" .= getCrudOperationJson name crud idField,
Expand Down Expand Up @@ -67,4 +71,6 @@ genCrudServerOperations spec cruds = return $ map genCrudOperation cruds
operationToOverrideImport :: (AS.Crud.CrudOperation, AS.Crud.CrudOperationOptions) -> Aeson.Types.Pair
operationToOverrideImport (operation, options) = makeCrudOperationKeyAndJsonPair operation importJson
where
importJson = GJI.jsImportToImportJson $ extImportToJsImport <$> AS.Crud.overrideFn options
importJson = GJI.jsImportToImportJson $ extImportToJsImport sdkRootDirFromCrudDir <$> AS.Crud.overrideFn options
crudDirInSdkRootDir = [reldir|server/crud|]
sdkRootDirFromCrudDir = SP.reversePosixPath $ fromJust $ SP.relDirToPosix crudDirInSdkRootDir
43 changes: 21 additions & 22 deletions waspc/src/Wasp/Generator/SdkGenerator/Server/OperationsGenerator.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{-# LANGUAGE TypeApplications #-}

module Wasp.Generator.SdkGenerator.Server.OperationsGenerator
( extImportToJsImport,
serverOperationsDirInSdkRootDir,
( serverOperationsDirInSdkRootDir,
genOperations,
)
where
Expand All @@ -21,21 +20,27 @@ import Wasp.AppSpec.Operation (getName)
import qualified Wasp.AppSpec.Operation as AS.Operation
import qualified Wasp.AppSpec.Query as AS.Query
import Wasp.AppSpec.Valid (isAuthEnabled)
import Wasp.Generator.Common (dropExtensionFromImportPath, makeJsonWithEntityData)
import Wasp.Generator.Common (makeJsonWithEntityData)
import Wasp.Generator.FileDraft (FileDraft)
import qualified Wasp.Generator.JsImport as GJI
import Wasp.Generator.Monad (Generator)
import Wasp.Generator.SdkGenerator.Common (SdkTemplatesDir, getOperationTypeName, mkTmplFdWithData, serverTemplatesDirInSdkTemplatesDir)
import Wasp.Generator.SdkGenerator.Common (SdkRootDir, SdkTemplatesDir, extImportToJsImport, getOperationTypeName, mkTmplFdWithData, serverTemplatesDirInSdkTemplatesDir)
import qualified Wasp.Generator.SdkGenerator.Common as C
import Wasp.JsImport (JsImport (..), JsImportPath (..))
import Wasp.JsImport (JsImport (..))
import qualified Wasp.JsImport as JI
import Wasp.Util (toUpperFirst)
import qualified Wasp.Util.StrongPath as SP

data ServerOpsTemplatesDir

data ServerOpsSrcDir

serverOpsDirInSdkTemplatesDir :: Path' (Rel SdkTemplatesDir) (Dir ServerOpsTemplatesDir)
serverOpsDirInSdkTemplatesDir = serverTemplatesDirInSdkTemplatesDir </> [reldir|operations|]

serverOpsDirInSdkRootDir :: Path' (Rel C.SdkRootDir) (Dir ServerOpsSrcDir)
serverOpsDirInSdkRootDir = SP.castRel $ SP.castDir serverOpsDirInSdkTemplatesDir

genOperations :: AppSpec -> Generator [FileDraft]
genOperations spec =
sequence
Expand Down Expand Up @@ -139,40 +144,34 @@ genOperationTypesFile tmplFile operations isAuthEnabledGlobally =

serverOperationsDirInSdkRootDir :: AS.Operation.Operation -> Path' (Rel C.SdkRootDir) Dir'
serverOperationsDirInSdkRootDir =
SP.castRel . (serverOpsDirInSdkTemplatesDir </>) . \case
(serverOpsDirInSdkRootDir </>) . \case
(AS.Operation.QueryOp _ _) -> [reldir|queries|]
(AS.Operation.ActionOp _ _) -> [reldir|actions|]

getOperationTmplData :: Bool -> AS.Operation.Operation -> Aeson.Value
getOperationTmplData isAuthEnabledGlobally operation =
object
[ "jsFn" .= extOperationImportToImportJson (AS.Operation.getFn operation),
[ "jsFn" .= importJson,
"operationName" .= getName operation,
"operationTypeName" .= getOperationTypeName operation,
"entities"
.= maybe [] (map (makeJsonWithEntityData . AS.refName)) (AS.Operation.getEntities operation),
"usesAuth" .= fromMaybe isAuthEnabledGlobally (AS.Operation.getAuth operation)
]
where
importJson = extOperationImportToImportJson operationDir operationFn
operationDir = serverOperationsDirInSdkRootDir operation
operationFn = AS.Operation.getFn operation

extOperationImportToImportJson :: EI.ExtImport -> Aeson.Value
extOperationImportToImportJson =
extOperationImportToImportJson :: Path' (Rel SdkRootDir) (Dir d) -> EI.ExtImport -> Aeson.Value
extOperationImportToImportJson importLocationDir =
GJI.jsImportToImportJson
. Just
. applyExtImportAlias
. extImportToJsImport
. extImportToJsImport (SP.reversePosixPath sdkRotoDirFromImportLocationDir)
where
sdkRotoDirFromImportLocationDir = fromJust $ SP.relDirToPosix importLocationDir

applyExtImportAlias :: JsImport -> JsImport
applyExtImportAlias jsImport =
jsImport {_importAlias = Just $ JI.getImportIdentifier jsImport ++ "_ext"}

extImportToJsImport :: EI.ExtImport -> JsImport
extImportToJsImport extImport@(EI.ExtImport extImportName extImportPath) =
JsImport
{ _path = ModuleImportPath importPath,
_name = importName,
_importAlias = Just $ EI.importIdentifier extImport ++ "_ext"
}
where
importPath = C.makeSdkImportPath $ dropExtensionFromImportPath $ extCodeDirP </> SP.castRel extImportPath
extCodeDirP = fromJust $ SP.relDirToPosix C.extCodeDirInSdkRootDir
importName = GJI.extImportNameToJsImportName extImportName
25 changes: 16 additions & 9 deletions waspc/src/Wasp/Generator/SdkGenerator/WebSocketGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ where

import Data.Aeson (object, (.=))
import Data.Char (toLower)
import StrongPath (relfile)
import Data.Maybe (fromJust)
import StrongPath (reldir, relfile)
import qualified StrongPath as SP
import StrongPath.Operations ((</>))
import Wasp.AppSpec (AppSpec)
import qualified Wasp.AppSpec as AS
import qualified Wasp.AppSpec.App as AS.App
Expand All @@ -17,33 +20,37 @@ import Wasp.Generator.Common (makeJsonWithEntityData)
import Wasp.Generator.FileDraft (FileDraft)
import qualified Wasp.Generator.JsImport as GJI
import Wasp.Generator.Monad (Generator)
import Wasp.Generator.SdkGenerator.Common (extImportToJsImport)
import qualified Wasp.Generator.SdkGenerator.Common as C
import Wasp.Generator.SdkGenerator.Server.OperationsGenerator (extImportToJsImport)
import qualified Wasp.Generator.WebSocket as AS.WS
import qualified Wasp.Util.StrongPath as SP

genWebSockets :: AppSpec -> Generator [FileDraft]
genWebSockets spec
| AS.WS.areWebSocketsUsed spec =
sequence
[ genWebSocketServerIndex spec,
genFileCopy [relfile|client/webSocket/index.ts|],
genWebSocketProvider spec
]
sequence
[ genWebSocketServerIndex spec,
genFileCopy [relfile|client/webSocket/index.ts|],
genWebSocketProvider spec
]
| otherwise = return []
where
genFileCopy = return . C.mkTmplFd

genWebSocketServerIndex :: AppSpec -> Generator FileDraft
genWebSocketServerIndex spec = return $ C.mkTmplFdWithData [relfile|server/webSocket/index.ts|] tmplData
genWebSocketServerIndex spec = return $ C.mkTmplFdWithData relIndexTsPath tmplData
where
tmplData =
object
[ "isAuthEnabled" .= isAuthEnabled spec,
"userWebSocketFn" .= GJI.jsImportToImportJson (extImportToJsImport <$> mayebWebSocketFn),
"userWebSocketFn" .= GJI.jsImportToImportJson (extImportToJsImport sdkRootDirFromWebsocketsDir <$> mayebWebSocketFn),
"allEntities" .= map (makeJsonWithEntityData . fst) (AS.getEntities spec)
]
maybeWebSocket = AS.App.webSocket $ snd $ getApp spec
mayebWebSocketFn = AS.App.WS.fn <$> maybeWebSocket
relServerWebsocketsDirPath = [reldir|server/webSocket|]
relIndexTsPath = relServerWebsocketsDirPath </> [relfile|index.ts|]
sdkRootDirFromWebsocketsDir = SP.reversePosixPath $ fromJust $ SP.relDirToPosix relServerWebsocketsDirPath

genWebSocketProvider :: AppSpec -> Generator FileDraft
genWebSocketProvider spec = return $ C.mkTmplFdWithData [relfile|client/webSocket/WebSocketProvider.tsx|] tmplData
Expand Down
17 changes: 8 additions & 9 deletions waspc/src/Wasp/Generator/ServerGenerator/JsImport.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
module Wasp.Generator.ServerGenerator.JsImport where
module Wasp.Generator.ServerGenerator.JsImport
( extImportToImportJson,
extImportToAliasedImportJson,
getAliasedJsImportStmtAndIdentifier,
)
where

import qualified Data.Aeson as Aeson
import StrongPath (Dir, Path, Posix, Rel)
Expand Down Expand Up @@ -32,19 +37,13 @@ extImportToAliasedImportJson importAlias pathFromImportLocationToSrcDir maybeExt
jsImport = extImportToJsImport pathFromImportLocationToSrcDir <$> maybeExtImport
aliasedJsImport = JI.applyJsImportAlias (Just importAlias) <$> jsImport

getJsImportStmtAndIdentifier ::
Path Posix (Rel importLocation) (Dir ServerSrcDir) ->
EI.ExtImport ->
(JsImportStatement, JsImportIdentifier)
getJsImportStmtAndIdentifier pathFromImportLocationToExtCodeDir = JI.getJsImportStmtAndIdentifier . extImportToJsImport pathFromImportLocationToExtCodeDir

getAliasedJsImportStmtAndIdentifier ::
JsImportAlias ->
Path Posix (Rel importLocation) (Dir ServerSrcDir) ->
EI.ExtImport ->
(JsImportStatement, JsImportIdentifier)
getAliasedJsImportStmtAndIdentifier importAlias pathFromImportLocationToExtCodeDir =
JI.getJsImportStmtAndIdentifier . JI.applyJsImportAlias (Just importAlias) . extImportToJsImport pathFromImportLocationToExtCodeDir
getAliasedJsImportStmtAndIdentifier importAlias pathFromImportLocationToSrcDir =
JI.getJsImportStmtAndIdentifier . JI.applyJsImportAlias (Just importAlias) . extImportToJsImport pathFromImportLocationToSrcDir

extImportToJsImport ::
Path Posix (Rel importLocation) (Dir ServerSrcDir) ->
Expand Down
12 changes: 8 additions & 4 deletions waspc/src/Wasp/Generator/WebAppGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import qualified Wasp.Node.Version as NodeVersion
import Wasp.Project.Common (dotWaspDirInWaspProjectDir, generatedCodeDirInDotWaspDir)
import qualified Wasp.Project.Common as Project
import Wasp.Util ((<++>))
import qualified Wasp.Util.StrongPath as SP

genWebApp :: AppSpec -> Generator [FileDraft]
genWebApp spec = do
Expand Down Expand Up @@ -263,9 +264,12 @@ genViteConfig spec = return $ C.mkTmplFdWithData tmplFile tmplData

relPathFromWebAppRootDirWaspProjectDir :: Path Posix (Rel C.WebAppRootDir) (Dir Project.WaspProjectDir)
relPathFromWebAppRootDirWaspProjectDir =
fromJust $
SP.parseRelDirP $
FP.Extra.reversePosixPath $
SP.fromRelDir (Project.dotWaspDirInWaspProjectDir </> Project.generatedCodeDirInDotWaspDir </> C.webAppRootDirInProjectRootDir)
SP.reversePosixPath $
fromJust $
SP.relDirToPosix
( Project.dotWaspDirInWaspProjectDir
</> Project.generatedCodeDirInDotWaspDir
</> C.webAppRootDirInProjectRootDir
)

importName = JsImportModule "customViteConfig"
6 changes: 6 additions & 0 deletions waspc/src/Wasp/Util/StrongPath.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ module Wasp.Util.StrongPath
stripProperPrefix,
splitAbsExtension,
splitRelExtension,
reversePosixPath,
)
where

import Control.Arrow (first)
import Control.Monad.Catch (MonadThrow)
import Data.Maybe (fromJust)
import qualified FilePath.Extra as FP.Extra
import qualified Path as P
import qualified StrongPath as SP
import qualified StrongPath.Path as SP
Expand All @@ -33,3 +36,6 @@ splitAbsExtension path =
splitRelExtension :: MonadThrow m => SP.Path' (SP.Rel b) (SP.File a) -> m (SP.Path' (SP.Rel b) (SP.File c), String)
splitRelExtension path =
first SP.fromPathRelFile <$> P.splitExtension (SP.toPathRelFile path)

reversePosixPath :: SP.Path SP.Posix (SP.Rel d1) (SP.Dir d2) -> SP.Path SP.Posix (SP.Rel d2) (SP.Dir d1)
reversePosixPath = fromJust . SP.parseRelDirP . FP.Extra.reversePosixPath . SP.fromRelDirP
Loading