From 01c3dc62312c500f29cba1100e02d08e585f258a Mon Sep 17 00:00:00 2001 From: Francesco Mazzoli Date: Tue, 9 Mar 2021 16:37:58 +0100 Subject: [PATCH] Allow to export types easily In some cases, we'd like to use the generated types in a typescript module instead of a declaration file. When used in a module, the types need to be explicitely exported to be re-used elsewhere. Adding a new exportTypes FormattingOption in charge of prefixing the generated types with "export". --- src/Data/Aeson/TypeScript/Formatting.hs | 11 ++++++++--- src/Data/Aeson/TypeScript/Types.hs | 13 +++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index 909a8ba..e61339e 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -10,7 +10,7 @@ import qualified Data.Text as T import Data.Monoid #endif - + -- | Same as 'formatTSDeclarations'', but uses default formatting options. formatTSDeclarations :: [TSDeclaration] -> String formatTSDeclarations = formatTSDeclarations' defaultFormattingOptions @@ -18,17 +18,22 @@ formatTSDeclarations = formatTSDeclarations' defaultFormattingOptions -- | Format a single TypeScript declaration. This version accepts a FormattingOptions object in case you want more control over the output. formatTSDeclaration :: FormattingOptions -> TSDeclaration -> String formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVariables names) = - [i|type #{typeNameModifier name}#{getGenericBrackets genericVariables} = #{alternatives};|] + [i|#{exportPrefix exportMode}type #{typeNameModifier name}#{getGenericBrackets genericVariables} = #{alternatives};|] where alternatives = T.intercalate " | " (fmap T.pack names) + formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables members) = - [i|interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { + [i|#{exportPrefix exportMode}interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { #{ls} }|] where ls = T.intercalate "\n" $ fmap T.pack [(replicate numIndentSpaces ' ') <> formatTSField member <> ";"| member <- members] modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName formatTSDeclaration (FormattingOptions {..}) (TSRawDeclaration text) = text +exportPrefix :: ExportMode -> String +exportPrefix ExportEach = "export " +exportPrefix ExportNone = "" + -- | Format a list of TypeScript declarations into a string, suitable for putting directly into a @.d.ts@ file. formatTSDeclarations' :: FormattingOptions -> [TSDeclaration] -> String formatTSDeclarations' options declarations = T.unpack $ T.intercalate "\n\n" (fmap (T.pack . formatTSDeclaration options) declarations) diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index 1127be7..e74dcb6 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -58,7 +58,7 @@ class (Typeable a) => TypeScript a where isGenericVariable :: Proxy a -> Bool -- ^ Special flag to indicate whether this type corresponds to a template variable. isGenericVariable _ = False - + -- | An existential wrapper for any TypeScript instance. data TSType = forall a. (Typeable a, TypeScript a) => TSType { unTSType :: Proxy a } @@ -91,6 +91,12 @@ instance IsString (TSString a) where -- * Formatting options +data ExportMode = + ExportEach + -- ^ Prefix every declaration with the "export" keyword (suitable for putting in a TypeScripe module) + | ExportNone + -- ^ No exporting (suitable for putting in a .d.ts file) + data FormattingOptions = FormattingOptions { numIndentSpaces :: Int -- ^ How many spaces to indent TypeScript blocks @@ -98,6 +104,8 @@ data FormattingOptions = FormattingOptions -- ^ Function applied to generated interface names , typeNameModifier :: String -> String -- ^ Function applied to generated type names + , exportMode :: ExportMode + -- ^ Prefix the generated types with "export" if set to 'True'. } defaultFormattingOptions :: FormattingOptions @@ -105,6 +113,7 @@ defaultFormattingOptions = FormattingOptions { numIndentSpaces = 2 , interfaceNameModifier = id , typeNameModifier = id + , exportMode = ExportNone } -- | Convenience typeclass class you can use to "attach" a set of Aeson encoding options to a type. @@ -136,7 +145,7 @@ instance TypeScript T9 where getTypeScriptType _ = "T9"; isGenericVariable _ = T instance TypeScript T10 where getTypeScriptType _ = "T10"; isGenericVariable _ = True allStarConstructors :: [Type] -allStarConstructors = [ConT ''T1, ConT ''T2, ConT ''T3, ConT ''T4, ConT ''T5, ConT ''T6, ConT ''T7, ConT ''T8, ConT ''T9, ConT ''T10] +allStarConstructors = [ConT ''T1, ConT ''T2, ConT ''T3, ConT ''T4, ConT ''T5, ConT ''T6, ConT ''T7, ConT ''T8, ConT ''T9, ConT ''T10] allStarConstructors' :: [Name] allStarConstructors' = [''T1, ''T2, ''T3, ''T4, ''T5, ''T6, ''T7, ''T8, ''T9, ''T10]