From 4db3c801d8e82ef75e5151873b28ac00199629d2 Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 09:20:55 -0300 Subject: [PATCH 1/9] Install.Function: split insert and replace functionalities --- src/Install/Function/InsertFunction.elm | 159 ++++++++++++++++++ .../ReplaceFunction.elm} | 122 ++++---------- src/Install/Library.elm | 23 +++ 3 files changed, 218 insertions(+), 86 deletions(-) create mode 100644 src/Install/Function/InsertFunction.elm rename src/Install/{Function.elm => Function/ReplaceFunction.elm} (57%) diff --git a/src/Install/Function/InsertFunction.elm b/src/Install/Function/InsertFunction.elm new file mode 100644 index 0000000..4cd65de --- /dev/null +++ b/src/Install/Function/InsertFunction.elm @@ -0,0 +1,159 @@ +module Install.Function.InsertFunction exposing (makeRule, init, Config, CustomError, withInsertAfter) + +{-| Add a function definition in a given module if it is not present. + + -- code for ReviewConfig.elm: + rule = + Install.Function.InsertFunction.init + "Frontend" + "view" + """view model = + +Html.text "This is a test"""" +|> Install.Function.InsertFunction.makeRule + +Running this rule will insert the function `view` in the module `Frontend` with the provided implementation. + +The form of the rule is the same for nested modules: + + rule = + Install.Function.InsertFunction.init + "Foo.Bar" + "earnInterest" + "hoho model = { model | interest = 1.03 * model.interest }" + |> Install.Function.InsertFunction.makeRule + +@docs makeRule, init, Config, CustomError, withInsertAfter + +-} + +import Elm.Syntax.Declaration exposing (Declaration(..)) +import Elm.Syntax.Expression exposing (Expression) +import Elm.Syntax.ModuleName exposing (ModuleName) +import Elm.Syntax.Node as Node exposing (Node) +import Elm.Syntax.Range as Range exposing (Range) +import Install.Infer as Infer +import Install.Library +import Install.Normalize as Normalize +import Review.Fix as Fix +import Review.ModuleNameLookupTable exposing (ModuleNameLookupTable) +import Review.Rule as Rule exposing (Error, Rule) + + +{-| Configuration for makeRule: add a function in a specified module if it does not already exist. +-} +type Config + = Config + { moduleName : String + , functionName : String + , functionImplementation : String + , theFunctionNodeExpression : Maybe (Node Expression) + , customErrorMessage : CustomError + , insertAt : InsertAt + } + + +{-| Custom error message to be displayed when running `elm-review --fix` or `elm-review --fix-all` +-} +type CustomError + = CustomError { message : String, details : List String } + + +type InsertAt + = After String + | AtEnd + + +{-| Add the function after a specified declaration. Just give the name of a function, type, type alias or port and the function will be added after that declaration. Only work if the function is being added and not replaced. +-} +withInsertAfter : String -> Config -> Config +withInsertAfter previousDeclaration (Config config) = + Config { config | insertAt = After previousDeclaration } + + +{-| Initialize the configuration for the rule. +-} +init : String -> String -> String -> Config +init moduleNaeme functionName functionImplementation = + Config + { moduleName = moduleNaeme + , functionName = functionName + , functionImplementation = functionImplementation + , theFunctionNodeExpression = Install.Library.maybeNodeExpressionFromString { moduleName = String.split "." moduleNaeme } functionImplementation + , customErrorMessage = CustomError { message = "Add function \"" ++ functionName ++ "\".", details = [ "" ] } + , insertAt = AtEnd + } + + +{-| Create a rule that adds a function in a given module if it is not present. +-} +makeRule : Config -> Rule +makeRule config = + let + visitor : Node Declaration -> Context -> ( List (Error {}), Context ) + visitor declaration context = + declarationVisitor context config declaration + in + Rule.newModuleRuleSchemaUsingContextCreator "Install.Function.InsertFunction" initialContext + |> Rule.withDeclarationEnterVisitor visitor + |> Rule.withFinalModuleEvaluation (finalEvaluation config) + |> Rule.providesFixesForModuleRule + |> Rule.fromModuleRuleSchema + + +type alias Context = + { moduleName : ModuleName + , lookupTable : ModuleNameLookupTable + , lastDeclarationRange : Range + } + + +initialContext : Rule.ContextCreator () Context +initialContext = + Rule.initContextCreator + (\lookupTable moduleName () -> { lookupTable = lookupTable, moduleName = moduleName, lastDeclarationRange = Range.empty }) + |> Rule.withModuleNameLookupTable + |> Rule.withModuleName + + +declarationVisitor : Context -> Config -> Node Declaration -> ( List (Rule.Error {}), Context ) +declarationVisitor context (Config config) declaration = + let + contextWithLastDeclarationRange = + case config.insertAt of + After previousDeclaration -> + if Install.Library.getDeclarationName declaration == previousDeclaration then + { context | lastDeclarationRange = Node.range declaration } + + else + context + + AtEnd -> + { context | lastDeclarationRange = Node.range declaration } + in + ( [], contextWithLastDeclarationRange ) + + +finalEvaluation : Config -> Context -> List (Rule.Error {}) +finalEvaluation (Config config) context = + if Install.Library.isInCorrectModule config.moduleName context then + addFunction { range = context.lastDeclarationRange, functionName = config.functionName, functionImplementation = config.functionImplementation } + + else + [] + + +type alias FixConfig = + { range : Range + , functionName : String + , functionImplementation : String + } + + +addFunction : FixConfig -> List (Error {}) +addFunction fixConfig = + [ Rule.errorWithFix + { message = "Add function \"" ++ fixConfig.functionName ++ "\"", details = [ "" ] } + fixConfig.range + [ Fix.insertAt { row = fixConfig.range.end.row + 1, column = 0 } fixConfig.functionImplementation ] + ] diff --git a/src/Install/Function.elm b/src/Install/Function/ReplaceFunction.elm similarity index 57% rename from src/Install/Function.elm rename to src/Install/Function/ReplaceFunction.elm index 3692c57..1de21eb 100644 --- a/src/Install/Function.elm +++ b/src/Install/Function/ReplaceFunction.elm @@ -1,28 +1,29 @@ -module Install.Function exposing (makeRule, init, Config, CustomError, withInsertAfter) +module Install.Function.ReplaceFunction exposing (makeRule, init, Config, CustomError) -{-| Replace a function in a given module with a new implementation or -add that function definition if it is not present in the module. +{-| Replace a function in a given module with a new implementation. -- code for ReviewConfig.elm: rule = - Install.Function.init + Install.Function.ReplaceFunction.init "Frontend" "view" """view model = - Html.text "This is a test\"""" - |> Install.Function.makeRule -Running this rule will insert or replace the function `view` in the module `Frontend` with the new implementation. +Html.text "This is a test"""" +|> Install.Function.ReplaceFunction.makeRule + +Running this rule will replace the function `view` in the module `Frontend` with the provided implementation. + The form of the rule is the same for nested modules: rule = - Install.Function.init + Install.Function.ReplaceFunction.init "Foo.Bar" "earnInterest" "hoho model = { model | interest = 1.03 * model.interest }" - |> Install.Function.makeRule + |> Install.Function.ReplaceFunction.makeRule -@docs makeRule, init, Config, CustomError, withInsertAfter +@docs makeRule, init, Config, CustomError -} @@ -39,7 +40,7 @@ import Review.ModuleNameLookupTable exposing (ModuleNameLookupTable) import Review.Rule as Rule exposing (Error, Rule) -{-| Configuration for makeRule: add (or replace if function already exists) a function in a specified module. +{-| Configuration for makeRule: replace a function in a specified module with a new implementation. -} type Config = Config @@ -48,7 +49,6 @@ type Config , functionImplementation : String , theFunctionNodeExpression : Maybe (Node Expression) , customErrorMessage : CustomError - , insertAt : InsertAt } @@ -58,18 +58,6 @@ type CustomError = CustomError { message : String, details : List String } -type InsertAt - = After String - | AtEnd - - -{-| Add the function after a specified declaration. Just give the name of a function, type, type alias or port and the function will be added after that declaration. Only work if the function is being added and not replaced. --} -withInsertAfter : String -> Config -> Config -withInsertAfter previousDeclaration (Config config) = - Config { config | insertAt = After previousDeclaration } - - {-| Initialize the configuration for the rule. -} init : String -> String -> String -> Config @@ -80,12 +68,10 @@ init moduleNaeme functionName functionImplementation = , functionImplementation = functionImplementation , theFunctionNodeExpression = Install.Library.maybeNodeExpressionFromString { moduleName = String.split "." moduleNaeme } functionImplementation , customErrorMessage = CustomError { message = "Replace function \"" ++ functionName ++ "\" with new code.", details = [ "" ] } - , insertAt = AtEnd } -{-| Create a rule that replaces a function in a given module with a new implementation or -creates it if it is not present. +{-| Create a rule that replaces a function in a given module with a new implementation. -} makeRule : Config -> Rule makeRule config = @@ -94,9 +80,8 @@ makeRule config = visitor declaration context = declarationVisitor context config declaration in - Rule.newModuleRuleSchemaUsingContextCreator "Install.Function" initialContext + Rule.newModuleRuleSchemaUsingContextCreator "Install.Function.ReplaceFunction" initialContext |> Rule.withDeclarationEnterVisitor visitor - |> Rule.withFinalModuleEvaluation (finalEvaluation config) |> Rule.providesFixesForModuleRule |> Rule.fromModuleRuleSchema @@ -104,34 +89,19 @@ makeRule config = type alias Context = { moduleName : ModuleName , lookupTable : ModuleNameLookupTable - , lastDeclarationRange : Range - , appliedFix : Bool } initialContext : Rule.ContextCreator () Context initialContext = Rule.initContextCreator - (\lookupTable moduleName () -> { lookupTable = lookupTable, moduleName = moduleName, lastDeclarationRange = Range.empty, appliedFix = False }) + (\lookupTable moduleName () -> { lookupTable = lookupTable, moduleName = moduleName }) |> Rule.withModuleNameLookupTable |> Rule.withModuleName declarationVisitor : Context -> Config -> Node Declaration -> ( List (Rule.Error {}), Context ) declarationVisitor context (Config config) declaration = - let - contextWithLastDeclarationRange = - case config.insertAt of - After previousDeclaration -> - if getDeclarationName declaration == previousDeclaration then - { context | lastDeclarationRange = Node.range declaration } - - else - context - - AtEnd -> - { context | lastDeclarationRange = Node.range declaration } - in case Node.value declaration of FunctionDeclaration function -> let @@ -145,45 +115,27 @@ declarationVisitor context (Config config) declaration = resources = { lookupTable = context.lookupTable, inferredConstants = ( Infer.empty, [] ) } - -- isNotImplemented returns True if the values of the current function expression and the replacement expression are different + isInCorrectFunction = + isInCorrectModule && name == config.functionName + isNotImplemented : Function -> { a | functionImplementation : String } -> Bool isNotImplemented f confg = - Maybe.map2 (Normalize.compare resources) - (f.declaration |> Node.value |> .expression |> Just) - (Install.Library.getExpressionFromString context confg.functionImplementation) - == Just Normalize.ConfirmedEquality - |> not - - isImplemented = - not (isNotImplemented function config) + isInCorrectFunction + && (Maybe.map2 (Normalize.compare resources) + (f.declaration |> Node.value |> .expression |> Just) + (Install.Library.getExpressionFromString context confg.functionImplementation) + == Just Normalize.ConfirmedEquality + |> not + ) in - if isImplemented then - ( [], { contextWithLastDeclarationRange | appliedFix = True } ) - - else if name == config.functionName && isInCorrectModule && isNotImplemented function config then + if isNotImplemented function config then replaceFunction { range = Node.range declaration, functionName = config.functionName, functionImplementation = config.functionImplementation } context else - ( [], contextWithLastDeclarationRange ) + ( [], context ) _ -> - ( [], contextWithLastDeclarationRange ) - - -type alias FixConfig = - { range : Range - , functionName : String - , functionImplementation : String - } - - -finalEvaluation : Config -> Context -> List (Rule.Error {}) -finalEvaluation (Config config) context = - if not context.appliedFix && Install.Library.isInCorrectModule config.moduleName context then - addFunction { range = context.lastDeclarationRange, functionName = config.functionName, functionImplementation = config.functionImplementation } - - else - [] + ( [], context ) replaceFunction : FixConfig -> Context -> ( List (Error {}), Context ) @@ -193,19 +145,10 @@ replaceFunction fixConfig context = fixConfig.range [ Fix.replaceRangeBy fixConfig.range fixConfig.functionImplementation ] ] - , { context | appliedFix = True } + , context ) -addFunction : FixConfig -> List (Error {}) -addFunction fixConfig = - [ Rule.errorWithFix - { message = "Add function \"" ++ fixConfig.functionName ++ "\"", details = [ "" ] } - fixConfig.range - [ Fix.insertAt { row = fixConfig.range.end.row + 1, column = 0 } fixConfig.functionImplementation ] - ] - - getDeclarationName : Node Declaration -> String getDeclarationName declaration = let @@ -227,3 +170,10 @@ getDeclarationName declaration = _ -> "" + + +type alias FixConfig = + { range : Range + , functionName : String + , functionImplementation : String + } diff --git a/src/Install/Library.elm b/src/Install/Library.elm index 8878dcd..d5ac5d6 100644 --- a/src/Install/Library.elm +++ b/src/Install/Library.elm @@ -254,3 +254,26 @@ isInCorrectModule moduleName context = context.moduleName |> String.join "." |> (==) moduleName + + +getDeclarationName : Node Declaration -> String +getDeclarationName declaration = + let + getName declaration_ = + declaration_ |> .name >> Node.value + in + case Node.value declaration of + FunctionDeclaration function -> + getName (Node.value function.declaration) + + AliasDeclaration alias_ -> + getName alias_ + + CustomTypeDeclaration customType -> + getName customType + + PortDeclaration port_ -> + getName port_ + + _ -> + "" From ecd6cee05dbc7f666301c335e2421952bd7d5f54 Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 09:21:40 -0300 Subject: [PATCH 2/9] change tests to use new api --- tests/Install/FunctionTest.elm | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tests/Install/FunctionTest.elm b/tests/Install/FunctionTest.elm index a48a61d..5707981 100644 --- a/tests/Install/FunctionTest.elm +++ b/tests/Install/FunctionTest.elm @@ -1,6 +1,7 @@ module Install.FunctionTest exposing (all) -import Install.Function +import Install.Function.InsertFunction as InsertFunction +import Install.Function.ReplaceFunction as ReplaceFunction import Review.Rule exposing (Rule) import Run import Test exposing (Test, describe) @@ -36,12 +37,12 @@ test1 = rule1 : Rule rule1 = - Install.Function.init + ReplaceFunction.init "Frontend" "view" """view model = Html.text "This is a test\"""" - |> Install.Function.makeRule + |> ReplaceFunction.makeRule src1 : String @@ -103,12 +104,12 @@ test2 = rule2 : Rule rule2 = - Install.Function.init + InsertFunction.init "Frontend" "newFunction" """newFunction model = Html.text "This is a test\"""" - |> Install.Function.makeRule + |> InsertFunction.makeRule under2 : String @@ -168,12 +169,12 @@ type alias Model = rule3 : Rule rule3 = - Install.Function.init + InsertFunction.init "Frontend" "newFunction" """newFunction model = Html.text "This is a test\"""" - |> Install.Function.makeRule + |> InsertFunction.makeRule under3 : String @@ -212,13 +213,13 @@ test4 = rule4 : Rule rule4 = - Install.Function.init + InsertFunction.init "Frontend" "newFunction" """newFunction model = Html.text "This is a test\"""" - |> Install.Function.withInsertAfter "view" - |> Install.Function.makeRule + |> InsertFunction.withInsertAfter "view" + |> InsertFunction.makeRule under4 : String @@ -259,13 +260,13 @@ test4a = rule4a : Rule rule4a = - Install.Function.init + InsertFunction.init "Frontend" "newFunction" """newFunction model = Html.text "This is a test\"""" - |> Install.Function.withInsertAfter "Model" - |> Install.Function.makeRule + |> InsertFunction.withInsertAfter "Model" + |> InsertFunction.makeRule under4a : String @@ -305,13 +306,13 @@ test4b = rule4b : Rule rule4b = - Install.Function.init + InsertFunction.init "Frontend" "newFunction" """newFunction model = Html.text "This is a test\"""" - |> Install.Function.withInsertAfter "Model" - |> Install.Function.makeRule + |> InsertFunction.withInsertAfter "Model" + |> InsertFunction.makeRule under4b : String From 0d3b241bad0c3a36c7d1f8c765f04560876208d4 Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 09:22:20 -0300 Subject: [PATCH 3/9] change preview to use new api and add problematic example --- preview/src/ReviewConfig.elm | 330 +++++++++++++++++++++-------------- 1 file changed, 199 insertions(+), 131 deletions(-) diff --git a/preview/src/ReviewConfig.elm b/preview/src/ReviewConfig.elm index e4a66c8..dfadda5 100644 --- a/preview/src/ReviewConfig.elm +++ b/preview/src/ReviewConfig.elm @@ -11,34 +11,36 @@ when inside the directory containing this file. -} -import Install.Import -import Install.TypeVariant +import Install.ClauseInCase import Install.FieldInTypeAlias -import Install.Type +import Install.Function.InsertFunction +import Install.Function.ReplaceFunction +import Install.Import import Install.Initializer -import Install.ClauseInCase -import Install.Function +import Install.Type +import Install.TypeVariant import Review.Rule exposing (Rule) -config = config1 + +config = + createModal config1 : List Rule config1 = - [ - Install.TypeVariant.makeRule "Types" "ToBackend" "CounterReset" - , Install.TypeVariant.makeRule "Types" "FrontendMsg" "Reset" - , Install.ClauseInCase.init "Frontend" "update" "Reset" "( { model | counter = 0 }, sendToBackend CounterReset )" + [ Install.TypeVariant.makeRule "Types" "ToBackend" "CounterReset" + , Install.TypeVariant.makeRule "Types" "FrontendMsg" "Reset" + , Install.ClauseInCase.init "Frontend" "update" "Reset" "( { model | counter = 0 }, sendToBackend CounterReset )" |> Install.ClauseInCase.withInsertAfter "Increment" |> Install.ClauseInCase.makeRule - , Install.ClauseInCase.init "Backend" "updateFromFrontend" "CounterReset" "( { model | counter = 0 }, broadcast (CounterNewValue 0 clientId) )" + , Install.ClauseInCase.init "Backend" "updateFromFrontend" "CounterReset" "( { model | counter = 0 }, broadcast (CounterNewValue 0 clientId) )" |> Install.ClauseInCase.makeRule - , Install.Function.init "Frontend" "view" viewFunction |>Install.Function.makeRule - + , Install.Function.ReplaceFunction.init "Frontend" "view" viewFunction |> Install.Function.ReplaceFunction.makeRule ] -viewFunction = """view model = +viewFunction = + """view model = Html.div [ style "padding" "50px" ] [ Html.button [ onClick Increment ] [ text "+" ] , Html.div [ style "padding" "10px" ] [ Html.text (String.fromInt model.counter) ] @@ -47,7 +49,9 @@ viewFunction = """view model = , Html.button [ onClick Reset ] [ text "Reset" ] ]""" -viewFunction2 = """view model = + +viewFunction2 = + """view model = Html.div [ style "padding" "50px" ] [ Html.button [ onClick Increment ] [ text "+" ] , Html.div [ style "padding" "10px" ] [ Html.text (String.fromInt model.counter) ] @@ -56,7 +60,9 @@ Html.div [ style "padding" "50px" ] , Html.button [ onClick Reset ] [ text "Reset" ] ]""" -viewFunction3 = """view model = + +viewFunction3 = + """view model = Html.div [ style "padding" "50px" ] [ Html.button [ onClick Increment ] [ text "+" ] , Html.div [ style "padding" "10px" ] [ Html.text (String.fromInt model.counter) ] @@ -66,142 +72,204 @@ viewFunction3 = """view model = ]""" - config2 : List Rule config2 = - [ - -- TYPES - Install.Type.makeRule "Types" "SignInState" [ "SignedOut", "SignUp", "SignedIn" ] - , Install.Type.makeRule "Types" "BackendDataStatus" [ "Sunny", "LoadedBackendData" ] - -- TYPES IMPORTS - , Install.Import.initSimple "Types" ["Auth.Common", "MagicLink.Types", "User", "Session", "Dict", "AssocList"] |>Install.Import.makeRule - , Install.Import.init "Types" [{moduleToImport = "Url", alias_ = Nothing, exposedValues = Just ["Url"] }] |>Install.Import.makeRule - -- Type Frontend, MagicLink - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "authFlow : Auth.Common.Flow" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "authRedirectBaseUrl : Url" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "signinForm : MagicLink.Types.SigninForm" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "loginErrorMessage : Maybe String" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "signInStatus : MagicLink.Types.SignInStatus" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "currentUserData : Maybe User.LoginData" - -- Type Frontend, User - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "currentUser : Maybe User.User" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "signInState : SignInState" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "realname : String" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "username : String" - , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "email : String" - -- Type BackendModel - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "pendingAuths : Dict Lamdera.SessionId Auth.Common.PendingAuth" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "pendingEmailAuths : Dict Lamdera.SessionId Auth.Common.PendingEmailAuth" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "sessions : Dict SessionId Auth.Common.UserInfo" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "secretCounter : Int" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "sessionDict : AssocList.Dict SessionId String" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "pendingLogins: MagicLink.Types.PendingLogins" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "log : MagicLink.Types.Log" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "users: Dict.Dict User.EmailString User.User" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "userNameToEmailString : Dict.Dict User.Username User.EmailString" - , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "sessionInfo : Session.SessionInfo" - -- Type ToBackend - , Install.TypeVariant.makeRule "Types" "ToBackend" "AuthToBackend Auth.Common.ToBackend" - , Install.TypeVariant.makeRule "Types" "ToBackend" "AddUser String String String" - , Install.TypeVariant.makeRule "Types" "ToBackend" "RequestSignup String String String" - -- Type BackendMsg - , Install.TypeVariant.makeRule "Types" "BackendMsg" "AuthBackendMsg Auth.Common.BackendMsg" - , Install.TypeVariant.makeRule "Types" "BackendMsg" "AutoLogin SessionId User.LoginData" - -- Type ToFrontend - , Install.TypeVariant.makeRule "Types" "ToFrontend" "AuthToFrontend Auth.Common.ToFrontend" - , Install.TypeVariant.makeRule "Types" "ToFrontend" "AuthSuccess Auth.Common.UserInfo" - , Install.TypeVariant.makeRule "Types" "ToFrontend" "UserInfoMsg (Maybe Auth.Common.UserInfo)" - , Install.TypeVariant.makeRule "Types" "ToFrontend" "CheckSignInResponse (Result BackendDataStatus User.LoginData)" - , Install.TypeVariant.makeRule "Types" "ToFrontend" "GetLoginTokenRateLimited" - , Install.TypeVariant.makeRule "Types" "ToFrontend" "RegistrationError String" - , Install.TypeVariant.makeRule "Types" "ToFrontend" "SignInError String" - , Install.TypeVariant.makeRule "Types" "ToFrontend" "UserSignedIn (Maybe User.User)" - -- Initialize BackendModel - , Install.Initializer.makeRule "Backend" "init" "users" "Dict.empty" - , Install.Initializer.makeRule "Backend" "init" "sessions" "Dict.empty" - , Install.Initializer.makeRule "Backend" "init" "time" "Time.millisToPosix 0" - , Install.Initializer.makeRule "Backend" "init" "time" "Time.millisToPosix 0" - , Install.Initializer.makeRule "Backend" "init" "randomAtmosphericNumbers" "Nothing" - , Install.Initializer.makeRule "Backend" "init" "localUuidData" "Dict.empty" - , Install.Initializer.makeRule "Backend" "init" "pendingAuths" "Nothing" - , Install.Initializer.makeRule "Backend" "init" "localUuidData" "Nothing" - , Install.Initializer.makeRule "Backend" "init" "secretCounter" "0" - , Install.Initializer.makeRule "Backend" "init" "pendingAuths" "Dict.empty" - , Install.Initializer.makeRule "Backend" "init" "pendingEmailAuths" "Dict.empty" - , Install.Initializer.makeRule "Backend" "init" "sessionDict" "AssocList.empty" - , Install.Initializer.makeRule "Backend" "init" "sessionDict" "AssocList.empty" - , Install.Initializer.makeRule "Backend" "init" "log" "[]" - -- Backend import - , Install.Import.initSimple "Backend" - ["Auth.Common", "AssocList", "Auth.Flow" , "Dict", "Helper", "LocalUUID", - "MagicLink.Auth", "Process", "Task", "Time", "User"] - |>Install.Import.makeRule - , Install.Import.init "Backend" [{moduleToImport = "Lamdera", alias_ = Nothing, exposedValues = Just ["ClientId", "SessionId"]}] |>Install.Import.makeRule - --- - , Install.ClauseInCase.init - "Frontend" "updateFromBacked" - "AuthToFrontend authToFrontendMsg" - "MagicLink.Auth.updateFromBackend authToFrontendMsg model" - |> Install.ClauseInCase.makeRule - + [ -- TYPES + Install.Type.makeRule "Types" "SignInState" [ "SignedOut", "SignUp", "SignedIn" ] + , Install.Type.makeRule "Types" "BackendDataStatus" [ "Sunny", "LoadedBackendData" ] + + -- TYPES IMPORTS + , Install.Import.initSimple "Types" [ "Auth.Common", "MagicLink.Types", "User", "Session", "Dict", "AssocList" ] |> Install.Import.makeRule + , Install.Import.init "Types" [ { moduleToImport = "Url", alias_ = Nothing, exposedValues = Just [ "Url" ] } ] |> Install.Import.makeRule + + -- Type Frontend, MagicLink + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "authFlow : Auth.Common.Flow" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "authRedirectBaseUrl : Url" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "signinForm : MagicLink.Types.SigninForm" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "loginErrorMessage : Maybe String" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "signInStatus : MagicLink.Types.SignInStatus" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "currentUserData : Maybe User.LoginData" + + -- Type Frontend, User + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "currentUser : Maybe User.User" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "signInState : SignInState" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "realname : String" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "username : String" + , Install.FieldInTypeAlias.makeRule "Types" "FrontendModel" "email : String" + + -- Type BackendModel + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "pendingAuths : Dict Lamdera.SessionId Auth.Common.PendingAuth" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "pendingEmailAuths : Dict Lamdera.SessionId Auth.Common.PendingEmailAuth" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "sessions : Dict SessionId Auth.Common.UserInfo" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "secretCounter : Int" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "sessionDict : AssocList.Dict SessionId String" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "pendingLogins: MagicLink.Types.PendingLogins" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "log : MagicLink.Types.Log" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "users: Dict.Dict User.EmailString User.User" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "userNameToEmailString : Dict.Dict User.Username User.EmailString" + , Install.FieldInTypeAlias.makeRule "Types" "BackendModel" "sessionInfo : Session.SessionInfo" + + -- Type ToBackend + , Install.TypeVariant.makeRule "Types" "ToBackend" "AuthToBackend Auth.Common.ToBackend" + , Install.TypeVariant.makeRule "Types" "ToBackend" "AddUser String String String" + , Install.TypeVariant.makeRule "Types" "ToBackend" "RequestSignup String String String" + + -- Type BackendMsg + , Install.TypeVariant.makeRule "Types" "BackendMsg" "AuthBackendMsg Auth.Common.BackendMsg" + , Install.TypeVariant.makeRule "Types" "BackendMsg" "AutoLogin SessionId User.LoginData" + + -- Type ToFrontend + , Install.TypeVariant.makeRule "Types" "ToFrontend" "AuthToFrontend Auth.Common.ToFrontend" + , Install.TypeVariant.makeRule "Types" "ToFrontend" "AuthSuccess Auth.Common.UserInfo" + , Install.TypeVariant.makeRule "Types" "ToFrontend" "UserInfoMsg (Maybe Auth.Common.UserInfo)" + , Install.TypeVariant.makeRule "Types" "ToFrontend" "CheckSignInResponse (Result BackendDataStatus User.LoginData)" + , Install.TypeVariant.makeRule "Types" "ToFrontend" "GetLoginTokenRateLimited" + , Install.TypeVariant.makeRule "Types" "ToFrontend" "RegistrationError String" + , Install.TypeVariant.makeRule "Types" "ToFrontend" "SignInError String" + , Install.TypeVariant.makeRule "Types" "ToFrontend" "UserSignedIn (Maybe User.User)" + + -- Initialize BackendModel + , Install.Initializer.makeRule "Backend" "init" "users" "Dict.empty" + , Install.Initializer.makeRule "Backend" "init" "sessions" "Dict.empty" + , Install.Initializer.makeRule "Backend" "init" "time" "Time.millisToPosix 0" + , Install.Initializer.makeRule "Backend" "init" "time" "Time.millisToPosix 0" + , Install.Initializer.makeRule "Backend" "init" "randomAtmosphericNumbers" "Nothing" + , Install.Initializer.makeRule "Backend" "init" "localUuidData" "Dict.empty" + , Install.Initializer.makeRule "Backend" "init" "pendingAuths" "Nothing" + , Install.Initializer.makeRule "Backend" "init" "localUuidData" "Nothing" + , Install.Initializer.makeRule "Backend" "init" "secretCounter" "0" + , Install.Initializer.makeRule "Backend" "init" "pendingAuths" "Dict.empty" + , Install.Initializer.makeRule "Backend" "init" "pendingEmailAuths" "Dict.empty" + , Install.Initializer.makeRule "Backend" "init" "sessionDict" "AssocList.empty" + , Install.Initializer.makeRule "Backend" "init" "sessionDict" "AssocList.empty" + , Install.Initializer.makeRule "Backend" "init" "log" "[]" + + -- Backend import + , Install.Import.initSimple "Backend" + [ "Auth.Common" + , "AssocList" + , "Auth.Flow" + , "Dict" + , "Helper" + , "LocalUUID" + , "MagicLink.Auth" + , "Process" + , "Task" + , "Time" + , "User" + ] + |> Install.Import.makeRule + , Install.Import.init "Backend" [ { moduleToImport = "Lamdera", alias_ = Nothing, exposedValues = Just [ "ClientId", "SessionId" ] } ] |> Install.Import.makeRule + + --- + , Install.ClauseInCase.init + "Frontend" + "updateFromBacked" + "AuthToFrontend authToFrontendMsg" + "MagicLink.Auth.updateFromBackend authToFrontendMsg model" + |> Install.ClauseInCase.makeRule ] + + {- - updateFromBackendLoaded : ToFrontend -> LoadedModel -> ( LoadedModel, Cmd msg ) - updateFromBackendLoaded msg model = - case msg of - AuthToFrontend authToFrontendMsg -> - MagicLink.Auth.updateFromBackend authToFrontendMsg model + updateFromBackendLoaded : ToFrontend -> LoadedModel -> ( LoadedModel, Cmd msg ) + updateFromBackendLoaded msg model = + case msg of + AuthToFrontend authToFrontendMsg -> + MagicLink.Auth.updateFromBackend authToFrontendMsg model - GotBackendModel beModel -> - ( { model | backendModel = Just beModel }, Cmd.none ) + GotBackendModel beModel -> + ( { model | backendModel = Just beModel }, Cmd.none ) - -- MAGICLINK - AuthSuccess userInfo -> - -- TODO (placholder) - case userInfo.username of - Just username -> - ( { model | authFlow = Auth.Common.Authorized userInfo.email username }, Cmd.none ) + -- MAGICLINK + AuthSuccess userInfo -> + -- TODO (placholder) + case userInfo.username of + Just username -> + ( { model | authFlow = Auth.Common.Authorized userInfo.email username }, Cmd.none ) - Nothing -> - ( model, Cmd.none ) + Nothing -> + ( model, Cmd.none ) - UserInfoMsg _ -> - -- TODO (placholder) - ( model, Cmd.none ) + UserInfoMsg _ -> + -- TODO (placholder) + ( model, Cmd.none ) - SignInError message -> - MagicLink.Frontend.handleSignInError model message + SignInError message -> + MagicLink.Frontend.handleSignInError model message - RegistrationError str -> - MagicLink.Frontend.handleRegistrationError model str + RegistrationError str -> + MagicLink.Frontend.handleRegistrationError model str - CheckSignInResponse _ -> - ( model, Cmd.none ) + CheckSignInResponse _ -> + ( model, Cmd.none ) - GetLoginTokenRateLimited -> - ( model, Cmd.none ) + GetLoginTokenRateLimited -> + ( model, Cmd.none ) - UserRegistered user -> - MagicLink.Frontend.userRegistered model user + UserRegistered user -> + MagicLink.Frontend.userRegistered model user - UserSignedIn maybeUser -> - ( { model | signInStatus = MagicLink.Types.NotSignedIn }, Cmd.none ) + UserSignedIn maybeUser -> + ( { model | signInStatus = MagicLink.Types.NotSignedIn }, Cmd.none ) - GotMessage message -> - ( { model | message = message }, Cmd.none ) + GotMessage message -> + ( { model | message = message }, Cmd.none ) - AdminInspectResponse backendModel -> - ( { model | backendModel = Just backendModel }, Cmd.none ) + AdminInspectResponse backendModel -> + ( { model | backendModel = Just backendModel }, Cmd.none ) - , Cmd.batch - [ Time.now |> Task.perform GotFastTick - , Helper.getAtmosphericRandomNumbers - ] - ) + , Cmd.batch + [ Time.now |> Task.perform GotFastTick + , Helper.getAtmosphericRandomNumbers + ] + ) -} +createModal : List Rule +createModal = + let + toParentMsgName = + "Got" ++ modalConfig.alias ++ "Msg" + in + [ addModalExtMsgInParent toParentMsgName ] + + +type alias ModalConfig = + { moduleName : String + , parentModuleName : String + , alias : String + } + + +modalConfig : ModalConfig +modalConfig = + { moduleName = "Pages.Notification.List" + , parentModuleName = "Frontend" + , alias = "NotificationList" + } + + +addModalExtMsgInParent : String -> Rule +addModalExtMsgInParent toParentMsgName = + let + functionName = + "update" ++ modalConfig.alias ++ "ExtMsg" + + closeModalBranch = + modalConfig.alias ++ ".ClosedModal" + in + Install.Function.InsertFunction.init + modalConfig.parentModuleName + functionName + (functionName ++ """ extMsg ({ model } as uResult) = + case extMsg of + """ ++ closeModalBranch ++ """ -> + closeModal uResult""") + |> Install.Function.InsertFunction.withInsertAfter "update" + |> Install.Function.InsertFunction.makeRule From 9ae26e0f9a32db1341751a8bf1aa1c26146dd972 Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 09:22:40 -0300 Subject: [PATCH 4/9] commit forgotten code --- src/Install/Function/ReplaceFunction.elm | 25 +----------------------- 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/Install/Function/ReplaceFunction.elm b/src/Install/Function/ReplaceFunction.elm index 1de21eb..b4cf45a 100644 --- a/src/Install/Function/ReplaceFunction.elm +++ b/src/Install/Function/ReplaceFunction.elm @@ -107,7 +107,7 @@ declarationVisitor context (Config config) declaration = let name : String name = - getDeclarationName declaration + Install.Library.getDeclarationName declaration isInCorrectModule = Install.Library.isInCorrectModule config.moduleName context @@ -149,29 +149,6 @@ replaceFunction fixConfig context = ) -getDeclarationName : Node Declaration -> String -getDeclarationName declaration = - let - getName declaration_ = - declaration_ |> .name >> Node.value - in - case Node.value declaration of - FunctionDeclaration function -> - getName (Node.value function.declaration) - - AliasDeclaration alias_ -> - getName alias_ - - CustomTypeDeclaration customType -> - getName customType - - PortDeclaration port_ -> - getName port_ - - _ -> - "" - - type alias FixConfig = { range : Range , functionName : String From 9313d9a40f18f6ac69e7bb1d0d4a7f98a8fa2fcb Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 12:20:35 -0300 Subject: [PATCH 5/9] change metadata to reflect new module structure --- README.md | 3 ++- elm.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e68f99d..d6fa57d 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,8 @@ update msg model = - **Install.FieldInTypeAlias**: Add a field to a specified type alias in a specified module. For more details, see the [docs](https://package.elm-lang.org/packages/jxxcarlson/elm-review-codeinstaller/latest/Install-FieldInTypeAlias). - **Install.Initializer**: Add a field to the body of an initializer function where the return value is of the form `( Model, Cmd msg )`. For more details, see the [docs](https://package.elm-lang.org/packages/jxxcarlson/elm-review-codeinstaller/latest/Install-Initializer). - **Install.TypeVariant**: Add a variant to a specified type in a specified module. For more details, see the [docs](https://package.elm-lang.org/packages/jxxcarlson/elm-review-codeinstaller/latest/Install-TypeVariant). -- **Install.Function**: Replace a function in a given module with a new implementation or add that function definition if it is not present in the module. For more details, see the [docs](https://package.elm-lang.org/packages/jxxcarlson/elm-review-codeinstaller/latest/Install-Function). +- **Install.Function.ReplaceFunction**: Replace a function in a given module with a new implementation. For more details, see the [docs](https://package.elm-lang.org/packages/jxxcarlson/elm-review-codeinstaller/latest/Install-Function-ReplaceFunction). +- **Install.Function.InsertFunction**: Add a function in a given module if it is not present. For more details, see the [docs](https://package.elm-lang.org/packages/jxxcarlson/elm-review-codeinstaller/latest/Install-Function-InsertFunction). - **Install.Import**: Add import statements to a given module. For more details, see the [docs](https://package.elm-lang.org/packages/jxxcarlson/elm-review-codeinstaller/latest/Install-Import). ## Try it out diff --git a/elm.json b/elm.json index 0fb1aa1..9578612 100644 --- a/elm.json +++ b/elm.json @@ -9,7 +9,8 @@ "Install.FieldInTypeAlias", "Install.Initializer", "Install.TypeVariant", - "Install.Function", + "Install.Function.InsertFunction", + "Install.Function.ReplaceFunction", "Install.Import", "Install.Type" ], From 7b59aa9f9fb66a279e8c0b06e0bbd3dc7b780253 Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 12:20:50 -0300 Subject: [PATCH 6/9] upgrade elm-review --- review/elm.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/review/elm.json b/review/elm.json index 364253d..7fd1552 100644 --- a/review/elm.json +++ b/review/elm.json @@ -9,7 +9,7 @@ "elm/core": "1.0.5", "elm/json": "1.1.3", "elm/project-metadata-utils": "1.0.2", - "jfmengels/elm-review": "2.13.2", + "jfmengels/elm-review": "2.14.0", "jfmengels/elm-review-debug": "1.0.8", "jfmengels/elm-review-unused": "1.2.3", "jxxcarlson/elm-review-codeinstaller": "1.0.0", @@ -20,11 +20,11 @@ "elm/html": "1.0.0", "elm/parser": "1.1.0", "elm/random": "1.0.0", + "elm/regex": "1.0.0", "elm/time": "1.0.0", "elm/virtual-dom": "1.0.3", "elm-explorations/test": "2.2.0", "miniBill/elm-unicode": "1.1.1", - "pzp1997/assoc-list": "1.0.0", "rtfeldman/elm-hex": "1.0.0", "stil4m/structured-writer": "1.0.3" } @@ -33,9 +33,6 @@ "direct": { "elm-explorations/test": "2.2.0" }, - "indirect": { - "elm/regex": "1.0.0", - "pzp1997/assoc-list": "1.0.0" - } + "indirect": {} } } From 2855e23c6f3f9983125ec5072fbce4538ef8262a Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 12:22:10 -0300 Subject: [PATCH 7/9] add verification to avoid loop when inserting new function --- src/Install/Function/InsertFunction.elm | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Install/Function/InsertFunction.elm b/src/Install/Function/InsertFunction.elm index 4cd65de..3f669ce 100644 --- a/src/Install/Function/InsertFunction.elm +++ b/src/Install/Function/InsertFunction.elm @@ -1,6 +1,6 @@ module Install.Function.InsertFunction exposing (makeRule, init, Config, CustomError, withInsertAfter) -{-| Add a function definition in a given module if it is not present. +{-| Add a function in a given module if it is not present. -- code for ReviewConfig.elm: rule = @@ -8,9 +8,8 @@ module Install.Function.InsertFunction exposing (makeRule, init, Config, CustomE "Frontend" "view" """view model = - -Html.text "This is a test"""" -|> Install.Function.InsertFunction.makeRule + Html.text "This is a test\"""" + |> Install.Function.InsertFunction.makeRule Running this rule will insert the function `view` in the module `Frontend` with the provided implementation. @@ -27,14 +26,12 @@ The form of the rule is the same for nested modules: -} -import Elm.Syntax.Declaration exposing (Declaration(..)) +import Elm.Syntax.Declaration exposing (Declaration) import Elm.Syntax.Expression exposing (Expression) import Elm.Syntax.ModuleName exposing (ModuleName) import Elm.Syntax.Node as Node exposing (Node) import Elm.Syntax.Range as Range exposing (Range) -import Install.Infer as Infer import Install.Library -import Install.Normalize as Normalize import Review.Fix as Fix import Review.ModuleNameLookupTable exposing (ModuleNameLookupTable) import Review.Rule as Rule exposing (Error, Rule) @@ -105,13 +102,14 @@ type alias Context = { moduleName : ModuleName , lookupTable : ModuleNameLookupTable , lastDeclarationRange : Range + , appliedFix : Bool } initialContext : Rule.ContextCreator () Context initialContext = Rule.initContextCreator - (\lookupTable moduleName () -> { lookupTable = lookupTable, moduleName = moduleName, lastDeclarationRange = Range.empty }) + (\lookupTable moduleName () -> { lookupTable = lookupTable, moduleName = moduleName, lastDeclarationRange = Range.empty, appliedFix = False }) |> Rule.withModuleNameLookupTable |> Rule.withModuleName @@ -119,6 +117,9 @@ initialContext = declarationVisitor : Context -> Config -> Node Declaration -> ( List (Rule.Error {}), Context ) declarationVisitor context (Config config) declaration = let + declarationName = + Install.Library.getDeclarationName declaration + contextWithLastDeclarationRange = case config.insertAt of After previousDeclaration -> @@ -131,12 +132,16 @@ declarationVisitor context (Config config) declaration = AtEnd -> { context | lastDeclarationRange = Node.range declaration } in - ( [], contextWithLastDeclarationRange ) + if declarationName == config.functionName then + ( [], { context | appliedFix = True } ) + + else + ( [], contextWithLastDeclarationRange ) finalEvaluation : Config -> Context -> List (Rule.Error {}) finalEvaluation (Config config) context = - if Install.Library.isInCorrectModule config.moduleName context then + if not context.appliedFix && Install.Library.isInCorrectModule config.moduleName context then addFunction { range = context.lastDeclarationRange, functionName = config.functionName, functionImplementation = config.functionImplementation } else From 8d56cdefd5fd63ca41be3da32f470646da7ec082 Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 12:22:20 -0300 Subject: [PATCH 8/9] improve docs --- src/Install/Function/ReplaceFunction.elm | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Install/Function/ReplaceFunction.elm b/src/Install/Function/ReplaceFunction.elm index b4cf45a..c7087e2 100644 --- a/src/Install/Function/ReplaceFunction.elm +++ b/src/Install/Function/ReplaceFunction.elm @@ -4,13 +4,12 @@ module Install.Function.ReplaceFunction exposing (makeRule, init, Config, Custom -- code for ReviewConfig.elm: rule = - Install.Function.ReplaceFunction.init + Install.Function.InsertFunction.init "Frontend" "view" """view model = - -Html.text "This is a test"""" -|> Install.Function.ReplaceFunction.makeRule + Html.text "This is a test\"""" + |> Install.Function.InsertFunction.makeRule Running this rule will replace the function `view` in the module `Frontend` with the provided implementation. @@ -31,7 +30,7 @@ import Elm.Syntax.Declaration exposing (Declaration(..)) import Elm.Syntax.Expression exposing (Expression, Function) import Elm.Syntax.ModuleName exposing (ModuleName) import Elm.Syntax.Node as Node exposing (Node) -import Elm.Syntax.Range as Range exposing (Range) +import Elm.Syntax.Range exposing (Range) import Install.Infer as Infer import Install.Library import Install.Normalize as Normalize From dd247f01f20b8d63d92dc2debc11176ec7ab7c1e Mon Sep 17 00:00:00 2001 From: Mateus Date: Fri, 21 Jun 2024 12:24:22 -0300 Subject: [PATCH 9/9] remove external examples from preview --- preview/src/ReviewConfig.elm | 46 +----------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/preview/src/ReviewConfig.elm b/preview/src/ReviewConfig.elm index dfadda5..8e6c2c1 100644 --- a/preview/src/ReviewConfig.elm +++ b/preview/src/ReviewConfig.elm @@ -23,7 +23,7 @@ import Review.Rule exposing (Rule) config = - createModal + config1 config1 : List Rule @@ -229,47 +229,3 @@ config2 = ] ) -} - - -createModal : List Rule -createModal = - let - toParentMsgName = - "Got" ++ modalConfig.alias ++ "Msg" - in - [ addModalExtMsgInParent toParentMsgName ] - - -type alias ModalConfig = - { moduleName : String - , parentModuleName : String - , alias : String - } - - -modalConfig : ModalConfig -modalConfig = - { moduleName = "Pages.Notification.List" - , parentModuleName = "Frontend" - , alias = "NotificationList" - } - - -addModalExtMsgInParent : String -> Rule -addModalExtMsgInParent toParentMsgName = - let - functionName = - "update" ++ modalConfig.alias ++ "ExtMsg" - - closeModalBranch = - modalConfig.alias ++ ".ClosedModal" - in - Install.Function.InsertFunction.init - modalConfig.parentModuleName - functionName - (functionName ++ """ extMsg ({ model } as uResult) = - case extMsg of - """ ++ closeModalBranch ++ """ -> - closeModal uResult""") - |> Install.Function.InsertFunction.withInsertAfter "update" - |> Install.Function.InsertFunction.makeRule