diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index aead56b..139cbd6 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -1,6 +1,6 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.1. +-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack @@ -67,6 +67,7 @@ library build-depends: aeson , base >=4.7 && <5 + , bytestring , containers , mtl , string-interpolate diff --git a/package.yaml b/package.yaml index 3821c55..a1e476d 100644 --- a/package.yaml +++ b/package.yaml @@ -35,6 +35,7 @@ tested-with: dependencies: - aeson - base >= 4.7 && < 5 +- bytestring - containers - mtl - string-interpolate diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index 5590433..fea6941 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -2,7 +2,9 @@ module Data.Aeson.TypeScript.Formatting where +import Data.Aeson as A import Data.Aeson.TypeScript.Types +import qualified Data.ByteString.Lazy.Char8 as BL8 import Data.Function ((&)) import qualified Data.List as L import Data.Maybe @@ -23,15 +25,31 @@ formatTSDeclaration :: FormattingOptions -> TSDeclaration -> String formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVariables names maybeDoc) = makeDocPrefix maybeDoc <> mainDeclaration where - mainDeclaration = case typeAlternativesFormat of + mainDeclaration = case chooseTypeAlternativesFormat typeAlternativesFormat of Enum -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnum} }|] + where + alternativesEnum = T.intercalate ", " $ [toEnumName entry | entry <- T.pack <$> names] EnumWithType -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name}Enum { #{alternativesEnumWithType} }#{enumType}|] + where + alternativesEnumWithType = T.intercalate ", " $ [toEnumName entry <> "=" <> entry | entry <- T.pack <$> names] + enumType = [i|\n\ntype #{name} = keyof typeof #{typeNameModifier name}Enum;|] :: T.Text TypeAlias -> [i|#{exportPrefix exportMode}type #{typeNameModifier name}#{getGenericBrackets genericVariables} = #{alternatives};|] + where + alternatives = T.intercalate " | " (fmap T.pack names) + + -- Only allow certain formats if some checks pass + chooseTypeAlternativesFormat Enum + | all isDoubleQuotedString names = Enum + | otherwise = TypeAlias + chooseTypeAlternativesFormat EnumWithType + | all isDoubleQuotedString names = EnumWithType + | otherwise = TypeAlias + chooseTypeAlternativesFormat x = x + + isDoubleQuotedString s = case A.eitherDecode (BL8.pack s) of + Right (A.String _) -> True + _ -> False - alternatives = T.intercalate " | " (fmap T.pack names) - alternativesEnum = T.intercalate ", " $ [toEnumName entry | entry <- T.pack <$> names] - alternativesEnumWithType = T.intercalate ", " $ [toEnumName entry <> "=" <> entry | entry <- T.pack <$> names] - enumType = [i|\n\ntype #{name} = keyof typeof #{typeNameModifier name}Enum;|] :: T.Text toEnumName = T.replace "\"" "" formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables (filter (not . isNoEmitTypeScriptField) -> members) maybeDoc) = diff --git a/test/Formatting.hs b/test/Formatting.hs index 35ab299..ab3c770 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -5,7 +5,6 @@ module Formatting (tests) where import Control.Exception import Data.Aeson (defaultOptions) -import Data.Aeson.TH import Data.Aeson.TypeScript.TH import Data.Proxy import Data.String.Interpolate @@ -20,7 +19,6 @@ $(deriveTypeScript defaultOptions ''D2) data Unit = U deriving (Eq, Show) $(deriveTypeScript defaultOptions ''Unit) -$(deriveJSON defaultOptions ''Unit) data PrimeInType' = PrimeInType $(deriveTypeScript defaultOptions ''PrimeInType') @@ -66,9 +64,11 @@ tests = describe "Formatting" $ do enum D2 { S2, F2 }|] - -- it "should generate a TS Enum from unit" $ - -- formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @Unit Proxy) `shouldBe` - -- [__i|enum Unit { U }|] + it "should generate a TS Enum from unit" $ + formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @Unit Proxy) `shouldBe` + [__i|type Unit = IU; + + type IU = void[];|] describe "and the EnumWithType format option is set" $ it "should generate a TS Enum with a type declaration" $