From 1d2282665cd65dc281e69e50fc17f9be902cd407 Mon Sep 17 00:00:00 2001 From: "Max Cantor (MBPr)" Date: Mon, 17 Mar 2014 23:14:17 -0700 Subject: [PATCH 1/4] added hacky, ugly, multi path support --- Yesod/Routes/Typescript/Generator.hs | 31 ++++++++++++++++++++-------- yesod-routes-typescript.cabal | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Yesod/Routes/Typescript/Generator.hs b/Yesod/Routes/Typescript/Generator.hs index 041f21b..c8ad0d0 100644 --- a/Yesod/Routes/Typescript/Generator.hs +++ b/Yesod/Routes/Typescript/Generator.hs @@ -1,10 +1,11 @@ module Yesod.Routes.Typescript.Generator (genTypeScriptRoutes) where -import ClassyPrelude +import ClassyPrelude hiding (last) import Data.Text (dropWhileEnd) import qualified Data.Text as DT import Filesystem (createTree) import Data.Char (isUpper) +import Data.List (findIndices, last) import Yesod.Routes.TH -- ( ResourceTree(..), -- Piece(Dynamic, Static), @@ -18,8 +19,9 @@ import Yesod.Routes.TH genTypeScriptRoutes :: [ResourceTree String] -> FilePath -> IO () genTypeScriptRoutes resourcesApp fp = do createTree $ directory fp - writeFile fp routesCs + writeFile fp $ marshallFxn <> routesCs where + marshallFxn = "var __mrshl = (p:any) => (typeof p === 'array' ? p.join('/') : p.toString())\n" routesCs = let res = (resToCoffeeString Nothing "" $ ResourceParent "paths" [] hackedTree) in either id id (snd res) @@ -41,7 +43,16 @@ genTypeScriptRoutes resourcesApp fp = do cleanName = uncapitalize . dropWhileEnd isUpper where uncapitalize t = (toLower $ take 1 t) <> drop 1 t - renderRoutePieces pieces = intercalate "/" $ map renderRoutePiece pieces + renderRoutePieces pieces isMulti = + intercalate "/" $ map renderCheckingIdx $ zip [0..] pieces + where + renderCheckingIdx (idx, piece) | isMulti && idx == lastVarIdx = renderRoutePiece piece <> "[]" + | otherwise = renderRoutePiece piece + isDyn (_, Static _) = False + isDyn _ = True + lastVarIdx = case findIndices isDyn pieces of + [] -> error "Expected multipiece, didn't find a last var" + l -> last l renderRoutePiece p = case p of (_, Static st) -> pack st :: Text (_, Dynamic "Text") -> ":string" @@ -49,7 +60,7 @@ genTypeScriptRoutes resourcesApp fp = do (_, Dynamic d) -> ":" <> pack (if isSuffixOf "Id" d then "string" else pack d) isVariable r = length r > 1 && DT.head r == ':' - resRoute res = renderRoutePieces $ resourcePieces res + resRoute res = renderRoutePieces (resourcePieces res) (isJust $ methodsMulti (resourceDispatch res)) resName res = cleanName . pack $ resourceName res lastName res = fromMaybe (resName res) . find (not . isVariable) @@ -72,17 +83,19 @@ genTypeScriptRoutes resourcesApp fp = do else [DT.replace "." "" $ lastName res] in ([], Right $ intercalate "\n" $ map mkLine jsNames) where + pieces :: [Text] pieces = DT.splitOn "/" routeString + variables :: [(Text, Text)] variables = snd $ foldl' (\(i,prev) typ -> (i+1, prev <> [("a" <> tshow i, typ)])) (0::Int, []) - (filter isVariable pieces) + (filter isVariable pieces) mkLine jsName = " public " <> jsName <> "(" <> csvArgs variables <> "):string { return " <> quote (routeStr variables variablePieces) <> "; }" routeStr vars ((Left p):rest) | null p = routeStr vars rest | otherwise = "/" <> p <> routeStr vars rest - routeStr (v:vars) ((Right _):rest) = "/' + " <> fst v <> " + '" <> routeStr vars rest + routeStr (v:vars) ((Right _):rest) = "/' + __mrshl(" <> fst v <> ") + '" <> routeStr vars rest routeStr [] [] = "" routeStr _ [] = error "extra vars!" routeStr [] _ = error "no more vars!" @@ -99,7 +112,7 @@ genTypeScriptRoutes resourcesApp fp = do resToCoffeeString parent routePrefix (ResourceParent "ApiH" pieces children) = (concatMap fst res, Left $ intercalate "\n" (map (either id id . snd) res)) where - fxn = resToCoffeeString parent (routePrefix <> "/" <> renderRoutePieces pieces <> "/") + fxn = resToCoffeeString parent (routePrefix <> "/" <> renderRoutePieces pieces False<> "/") res = map fxn children resToCoffeeString parent routePrefix (ResourceParent name pieces children) = @@ -114,7 +127,7 @@ genTypeScriptRoutes resourcesApp fp = do <> intercalate "\n" childMembers <> " " <> parentMembers memberLinkFromParent <> "\n\n" - <> " constructor(){\n " + <> " constructor(){\n" <> parentMembers memberInitFromParent <> "\n }\n" <> "}\n\n" @@ -123,7 +136,7 @@ genTypeScriptRoutes resourcesApp fp = do childTypescript = map fxn children jsName = maybe "" (<> "_") parent <> pref fxn = resToCoffeeString (Just jsName) - (routePrefix <> "/" <> renderRoutePieces pieces <> "/") + (routePrefix <> "/" <> renderRoutePieces pieces False <> "/") pref = cleanName $ pack name resourceClassName = "PATHS_TYPE_" <> jsName diff --git a/yesod-routes-typescript.cabal b/yesod-routes-typescript.cabal index 08abef3..9c6a3ab 100644 --- a/yesod-routes-typescript.cabal +++ b/yesod-routes-typescript.cabal @@ -2,7 +2,7 @@ -- further documentation, see http://haskell.org/cabal/users-guide/ name: yesod-routes-typescript -version: 0.1.0.0 +version: 0.2.0.0 -- synopsis: -- description: homepage: https://github.com/docmunch/yesod-routes-typescript From 18b610fdaaff0b171148b29868de859bf22a2a54 Mon Sep 17 00:00:00 2001 From: Greg Weber Date: Tue, 18 Mar 2014 10:46:23 -0700 Subject: [PATCH 2/4] use zipWith --- Yesod/Routes/Typescript/Generator.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Yesod/Routes/Typescript/Generator.hs b/Yesod/Routes/Typescript/Generator.hs index c8ad0d0..983ea67 100644 --- a/Yesod/Routes/Typescript/Generator.hs +++ b/Yesod/Routes/Typescript/Generator.hs @@ -44,10 +44,11 @@ genTypeScriptRoutes resourcesApp fp = do where uncapitalize t = (toLower $ take 1 t) <> drop 1 t renderRoutePieces pieces isMulti = - intercalate "/" $ map renderCheckingIdx $ zip [0..] pieces + intercalate "/" $ zipWith renderCheckingIdx [0..] pieces where - renderCheckingIdx (idx, piece) | isMulti && idx == lastVarIdx = renderRoutePiece piece <> "[]" - | otherwise = renderRoutePiece piece + renderCheckingIdx idx piece = renderRoutePiece piece <> arrayType + where arrayType | isMulti && idx == lastVarIdx = "[]" + | otherwise = "" isDyn (_, Static _) = False isDyn _ = True lastVarIdx = case findIndices isDyn pieces of From f6261e200174c7209b9825046370ce2a83055edd Mon Sep 17 00:00:00 2001 From: "Max Cantor (MBPr)" Date: Tue, 18 Mar 2014 16:38:40 -0700 Subject: [PATCH 3/4] cross browser safe array detection. thanks @gregwebs --- Yesod/Routes/Typescript/Generator.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Yesod/Routes/Typescript/Generator.hs b/Yesod/Routes/Typescript/Generator.hs index c8ad0d0..90f1c14 100644 --- a/Yesod/Routes/Typescript/Generator.hs +++ b/Yesod/Routes/Typescript/Generator.hs @@ -21,7 +21,9 @@ genTypeScriptRoutes resourcesApp fp = do createTree $ directory fp writeFile fp $ marshallFxn <> routesCs where - marshallFxn = "var __mrshl = (p:any) => (typeof p === 'array' ? p.join('/') : p.toString())\n" + -- referenced from http://stackoverflow.com/questions/4775722/check-if-object-is-array + marshallFxn = + "var __mrshl = (p:any) => (Object.prototype.toString.call( someVar ) === '[object Array]' ? p.join('/') : p.toString())\n" routesCs = let res = (resToCoffeeString Nothing "" $ ResourceParent "paths" [] hackedTree) in either id id (snd res) From ab50edd99e06192b2f33989b19acc9a18e5bd690 Mon Sep 17 00:00:00 2001 From: "Max Cantor (MBPr)" Date: Wed, 19 Mar 2014 11:10:39 -0700 Subject: [PATCH 4/4] fixed incorrect isArray check --- Yesod/Routes/Typescript/Generator.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Yesod/Routes/Typescript/Generator.hs b/Yesod/Routes/Typescript/Generator.hs index aa6c8e8..9d22278 100644 --- a/Yesod/Routes/Typescript/Generator.hs +++ b/Yesod/Routes/Typescript/Generator.hs @@ -23,7 +23,7 @@ genTypeScriptRoutes resourcesApp fp = do where -- referenced from http://stackoverflow.com/questions/4775722/check-if-object-is-array marshallFxn = - "var __mrshl = (p:any) => (Object.prototype.toString.call( someVar ) === '[object Array]' ? p.join('/') : p.toString())\n" + "var __mrshl = (p:any) => (Object.prototype.toString.call(p) === '[object Array]' ? p.join('/') : p.toString())\n" routesCs = let res = (resToCoffeeString Nothing "" $ ResourceParent "paths" [] hackedTree) in either id id (snd res)