From cbfa1e1fcce21a2449ab9de4bc48eb418ba95ebb Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 14 Aug 2021 17:52:23 -0700 Subject: [PATCH 001/123] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ec9a7f..a44f577 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Encode maps as mapped types (allows you to have unions as keys) * Support mapping open type families to lookup types (+ progress on handling promoted types) * Improve propagation of T variables in declarations +* Add support for "key types", in case you have custom implementations of FromJSONKey/ToJSONKey ## 0.3.0.1 From f9c3d801870f51dd2c49f94b8179737014e96cc5 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 21 Aug 2021 18:34:54 -0700 Subject: [PATCH 002/123] Fix deriveTypeScript' calls --- dev/Live.hs | 2 +- dev/Live4.hs | 2 +- test/ClosedTypeFamilies.hs | 4 ++-- test/OpenTypeFamilies.hs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/Live.hs b/dev/Live.hs index 3a61420..496486b 100644 --- a/dev/Live.hs +++ b/dev/Live.hs @@ -69,7 +69,7 @@ data Complex3 k = Complex3 { } deriving (Show) -deriveTypeScript' A.defaultOptions ''UserT (ExtraTypeScriptOptions [''DeployEnvironment]) +deriveTypeScript' A.defaultOptions ''UserT (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment] }) main :: IO () main = getTypeScriptDeclarationsRecursively (Proxy :: Proxy (UserT T Identity)) diff --git a/dev/Live4.hs b/dev/Live4.hs index 294f0e8..3a8e354 100644 --- a/dev/Live4.hs +++ b/dev/Live4.hs @@ -25,7 +25,7 @@ type instance DeployEnvironment2 SingleNodeEnvironment = SingleDE type instance DeployEnvironment2 K8SEnvironment = K8SDE type instance DeployEnvironment2 T = () newtype Simple env = Simple (DeployEnvironment2 env) -$(deriveTypeScript' A.defaultOptions ''Simple (ExtraTypeScriptOptions [''DeployEnvironment2])) +$(deriveTypeScript' A.defaultOptions ''Simple (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment2] })) main :: IO () main = getTypeScriptDeclarationsRecursively (Proxy @(Simple T)) diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 122f94f..9038c21 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -38,14 +38,14 @@ data UserT env f = User { , _userCreatedAt :: Columnar f Int , _userDeployEnvironment :: Columnar f (DeployEnvironment env) } -$(deriveTypeScript' A.defaultOptions ''UserT (ExtraTypeScriptOptions [''DeployEnvironment])) +$(deriveTypeScript' A.defaultOptions ''UserT (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment] })) type family DeployEnvironment2 env = result | result -> env where DeployEnvironment2 SingleNodeEnvironment = SingleDE DeployEnvironment2 K8SEnvironment = K8SDE DeployEnvironment2 T = () newtype Simple env = Simple (DeployEnvironment2 env) -$(deriveTypeScript' A.defaultOptions ''Simple (ExtraTypeScriptOptions [''DeployEnvironment2])) +$(deriveTypeScript' A.defaultOptions ''Simple (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment2] })) tests :: SpecWith () tests = describe "Type families" $ do diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index 222ef15..d0c1c74 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -38,14 +38,14 @@ data UserT env f = User { , _userCreatedAt :: Columnar f Int , _userDeployEnvironment :: Columnar f (DeployEnvironment env) } -$(deriveTypeScript' A.defaultOptions ''UserT (ExtraTypeScriptOptions [''DeployEnvironment])) +$(deriveTypeScript' A.defaultOptions ''UserT (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment] })) type family DeployEnvironment2 env = result | result -> env type instance DeployEnvironment2 SingleNodeEnvironment = SingleDE type instance DeployEnvironment2 K8SEnvironment = K8SDE type instance DeployEnvironment2 T = () newtype Simple env = Simple (DeployEnvironment2 env) -$(deriveTypeScript' A.defaultOptions ''Simple (ExtraTypeScriptOptions [''DeployEnvironment2])) +$(deriveTypeScript' A.defaultOptions ''Simple (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment2] })) tests :: SpecWith () tests = describe "Type families" $ do From 29db9bf4d8e3d2957261b0104f8c0852060dbfbb Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 21 Aug 2021 18:44:33 -0700 Subject: [PATCH 003/123] Add failing test for unwrapUnaryRecords --- aeson-typescript.cabal | 2 +- src/Data/Aeson/TypeScript/TH.hs | 8 ++++++ test/LiveLogging.hs | 32 ----------------------- test/NoOmitNothingFields.hs | 39 +++++++++++++++------------- test/Spec.hs | 4 ++- test/UnwrapUnaryRecords.hs | 45 +++++++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 52 deletions(-) delete mode 100644 test/LiveLogging.hs create mode 100644 test/UnwrapUnaryRecords.hs diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 3354443..a93c213 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -68,7 +68,6 @@ test-suite aeson-typescript-tests Formatting Generic HigherKind - LiveLogging NoOmitNothingFields ObjectWithSingleFieldNoTagSingleConstructors ObjectWithSingleFieldTagSingleConstructors @@ -81,6 +80,7 @@ test-suite aeson-typescript-tests TwoElemArrayTagSingleConstructors UntaggedNoTagSingleConstructors UntaggedTagSingleConstructors + UnwrapUnaryRecords Util Data.Aeson.TypeScript.Formatting Data.Aeson.TypeScript.Instances diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 273e950..4209d04 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -284,6 +284,12 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do | constructorVariant ci == NormalConstructor -> do encoding <- tupleEncoding tell [ExtraDecl encoding] + +#if MIN_VERSION_aeson(0,10,0) + | unwrapUnaryRecords options && (isSingleRecordConstructor ci) -> do + undefined +#endif + | otherwise -> do tsFields <- getTSFields decl <- lift $ assembleInterfaceDeclaration (ListE tsFields) @@ -309,6 +315,8 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do _ -> ( , ) <$> getTypeAsStringExp typ <*> getOptionalAsBoolExp typ lift $ [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) |] + isSingleRecordConstructor (constructorVariant -> RecordConstructor [x]) = True + isSingleRecordConstructor _ = False -- * Convenience functions diff --git a/test/LiveLogging.hs b/test/LiveLogging.hs deleted file mode 100644 index 44f9ae5..0000000 --- a/test/LiveLogging.hs +++ /dev/null @@ -1,32 +0,0 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilies #-} - -module LiveLogging where - -import Data.Kind -import Prelude hiding (Double) - - -data LoggingSource = SGeneral - -data LoggingSourceTagged s where - General :: LoggingSourceTagged 'SGeneral - -type family ParamsFamily (q :: LoggingSource) :: Type where - ParamsFamily 'SGeneral = String - -data HigherKindWithTypeFamily s = TapMessageParams { params :: ParamsFamily s } --- $(deriveTypeScript A.defaultOptions ''HigherKindWithTypeFamily) - --- main = do --- putStrLn $(stringE . pprint =<< (deriveTypeScript A.defaultOptions ''TestT)) diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index fbd5636..fa03d99 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -1,17 +1,17 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE MonoLocalBinds #-} +{-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -module NoOmitNothingFields (main, tests) where +module NoOmitNothingFields (allTests) where import Data.Aeson as A import Data.Aeson.TypeScript.TH @@ -20,21 +20,24 @@ import Data.Proxy import Test.Hspec import TestBoilerplate -$(testDeclarations "NoOmitNothingFields" (A.defaultOptions {omitNothingFields=False})) +$(testDeclarations "NoOmitNothingFields" (A.defaultOptions {omitNothingFields = False})) -main :: IO () -main = hspec $ describe "NoOmitNothingFields" $ do +allTests :: SpecWith () +allTests = describe "NoOmitNothingFields" $ do it "encodes as expected" $ do let decls = getTypeScriptDeclarations (Proxy :: Proxy Optional) - decls `shouldBe` [TSInterfaceDeclaration { - interfaceName = "Optional" + decls `shouldBe` [TSTypeAlternatives { + typeName = "Optional" + , typeGenericVariables = [] + , alternativeTypes = ["IOptional"] + } + , TSInterfaceDeclaration { + interfaceName = "IOptional" , interfaceGenericVariables = [] - , interfaceMembers = [ - TSField {fieldOptional = False - , fieldName = "optionalInt" - , fieldType = "number | null"} - ] + , interfaceMembers = [TSField {fieldOptional = False + , fieldName = "optionalInt" + , fieldType = "number | null"}] }] tests diff --git a/test/Spec.hs b/test/Spec.hs index cdff2a1..611fc36 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -18,6 +18,7 @@ import qualified UntaggedNoTagSingleConstructors import qualified UntaggedTagSingleConstructors import qualified OmitNothingFields import qualified NoOmitNothingFields +import qualified UnwrapUnaryRecords main :: IO () @@ -36,4 +37,5 @@ main = hspec $ do UntaggedTagSingleConstructors.tests UntaggedNoTagSingleConstructors.tests OmitNothingFields.tests - NoOmitNothingFields.tests + NoOmitNothingFields.allTests + UnwrapUnaryRecords.allTests diff --git a/test/UnwrapUnaryRecords.hs b/test/UnwrapUnaryRecords.hs new file mode 100644 index 0000000..e4cbbde --- /dev/null +++ b/test/UnwrapUnaryRecords.hs @@ -0,0 +1,45 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE MonoLocalBinds #-} +{-# OPTIONS_GHC -fno-warn-orphans #-} + +module UnwrapUnaryRecords (allTests) where + +import Data.Aeson as A +import Data.Aeson.TypeScript.TH +import Data.Proxy +import Test.Hspec +import TestBoilerplate +import Util + +-- Between Aeson 0.11.3.0 and 1.0.0.0, UntaggedValue was added +-- Disable these tests if it's not present +#if MIN_VERSION_aeson(0,10,0) +$(testDeclarations "UnwrapUnaryRecords" (setTagSingleConstructors $ A.defaultOptions {unwrapUnaryRecords = True})) + +allTests = describe "NoOmitNothingFields" $ do + it "encodes as expected" $ do + let decls = getTypeScriptDeclarations (Proxy :: Proxy OneField) + + decls `shouldBe` [] + + tests + + +#else +tests :: SpecWith () +tests = describe "UnwrapUnaryRecords" $ it "tests are disabled for this Aeson version" $ 2 `shouldBe` 2 + +allTests = tests +#endif + +main :: IO () +main = hspec allTests From 7e4c7b1d108280147a6eb5fdfae94e18fcdcb60b Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sat, 21 Aug 2021 19:35:03 -0700 Subject: [PATCH 004/123] Working on unwrapUnaryRecords --- src/Data/Aeson/TypeScript/TH.hs | 9 ++++++++- test/UnwrapUnaryRecords.hs | 21 +++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 4209d04..6dbfe92 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -287,7 +287,14 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do #if MIN_VERSION_aeson(0,10,0) | unwrapUnaryRecords options && (isSingleRecordConstructor ci) -> do - undefined + let [typ] = constructorFields ci + stringExp <- lift $ case typ of + (AppT (ConT name) t) | name == ''Maybe && not (omitNothingFields options) -> [|$(getTypeAsStringExp t) <> " | null"|] + _ -> getTypeAsStringExp typ + alternatives <- lift [|TSTypeAlternatives $(TH.stringE interfaceName) + $(genericVariablesListExpr True genericVariables) + [$(return stringExp)]|] + tell [ExtraDecl alternatives] #endif | otherwise -> do diff --git a/test/UnwrapUnaryRecords.hs b/test/UnwrapUnaryRecords.hs index e4cbbde..2b93486 100644 --- a/test/UnwrapUnaryRecords.hs +++ b/test/UnwrapUnaryRecords.hs @@ -15,25 +15,26 @@ module UnwrapUnaryRecords (allTests) where import Data.Aeson as A import Data.Aeson.TypeScript.TH +import Data.Aeson.TypeScript.Types import Data.Proxy import Test.Hspec import TestBoilerplate -import Util --- Between Aeson 0.11.3.0 and 1.0.0.0, UntaggedValue was added --- Disable these tests if it's not present + #if MIN_VERSION_aeson(0,10,0) -$(testDeclarations "UnwrapUnaryRecords" (setTagSingleConstructors $ A.defaultOptions {unwrapUnaryRecords = True})) +$(testDeclarations "UnwrapUnaryRecords" (A.defaultOptions {unwrapUnaryRecords = True})) -allTests = describe "NoOmitNothingFields" $ do +allTests :: SpecWith () +allTests = describe "UnwrapUnaryRecords" $ do it "encodes as expected" $ do let decls = getTypeScriptDeclarations (Proxy :: Proxy OneField) - decls `shouldBe` [] + decls `shouldBe` [ + TSTypeAlternatives {typeName = "OneField", typeGenericVariables = [], alternativeTypes = ["IOneField"]} + ,TSTypeAlternatives {typeName = "IOneField", typeGenericVariables = [], alternativeTypes = ["string"]} + ] tests - - #else tests :: SpecWith () tests = describe "UnwrapUnaryRecords" $ it "tests are disabled for this Aeson version" $ 2 `shouldBe` 2 @@ -41,5 +42,5 @@ tests = describe "UnwrapUnaryRecords" $ it "tests are disabled for this Aeson ve allTests = tests #endif -main :: IO () -main = hspec allTests +-- main :: IO () +-- main = hspec allTests From 5cea17855d0142be2527f363d3948dfcaa2ca100 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sun, 12 Sep 2021 19:40:13 -0700 Subject: [PATCH 005/123] Add recursivelyDeriveMissingTypeScriptInstancesFor etc. --- CHANGELOG.md | 3 +- aeson-typescript.cabal | 2 + package.yaml | 1 + src/Data/Aeson/TypeScript/Recursive.hs | 123 ++++++++++++++++++++++++- 4 files changed, 123 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a44f577..a6093d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change log -## 0.4.0.0 +## 0.4.0.0 (unreleased) * Add new built-in instances (Word8, Int32, Int64, Map, HashSet) * Export TSField in the Internal module @@ -9,6 +9,7 @@ * Support mapping open type families to lookup types (+ progress on handling promoted types) * Improve propagation of T variables in declarations * Add support for "key types", in case you have custom implementations of FromJSONKey/ToJSONKey +* Add ability to recursively derive missing instances (fragile) ## 0.3.0.1 diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index a93c213..291198b 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -56,6 +56,7 @@ library , template-haskell , text , th-abstraction + , transformers , unordered-containers default-language: Haskell2010 @@ -120,5 +121,6 @@ test-suite aeson-typescript-tests , temporary , text , th-abstraction + , transformers , unordered-containers default-language: Haskell2010 diff --git a/package.yaml b/package.yaml index f08c29a..d6aa63f 100644 --- a/package.yaml +++ b/package.yaml @@ -34,6 +34,7 @@ dependencies: - template-haskell - text - th-abstraction +- transformers - unordered-containers library: diff --git a/src/Data/Aeson/TypeScript/Recursive.hs b/src/Data/Aeson/TypeScript/Recursive.hs index a67ecee..9b724db 100755 --- a/src/Data/Aeson/TypeScript/Recursive.hs +++ b/src/Data/Aeson/TypeScript/Recursive.hs @@ -1,22 +1,53 @@ -{-# LANGUAGE QuasiQuotes, OverloadedStrings, TemplateHaskell, RecordWildCards, ScopedTypeVariables, ExistentialQuantification, FlexibleInstances, NamedFieldPuns, MultiWayIf, ViewPatterns, LambdaCase, PolyKinds #-} +{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE PolyKinds #-} module Data.Aeson.TypeScript.Recursive ( + -- * Getting declarations recursively getTransitiveClosure , getTypeScriptDeclarationsRecursively + + -- * Deriving missing instances recursively + , recursivelyDeriveMissingTypeScriptInstancesFor + , recursivelyDeriveMissingInstancesFor + , deriveInstanceIfNecessary + , doesTypeScriptInstanceExist + , getAllParentTypes ) where +import Control.Monad.State +import Control.Monad.Trans.Maybe +import Control.Monad.Writer import Data.Aeson.TypeScript.Instances () import Data.Aeson.TypeScript.TH +import Data.Bifunctor import Data.Function +import qualified Data.List as L +import Data.Maybe import Data.Proxy import qualified Data.Set as S +import Data.String.Interpolate +import Language.Haskell.TH as TH +import Language.Haskell.TH.Datatype +import Language.Haskell.TH.Syntax hiding (lift) getTransitiveClosure :: S.Set TSType -> S.Set TSType -getTransitiveClosure initialTypes = fix (\loop items -> let items' = S.unions (items : [getMore x | x <- S.toList items]) in - if | items' == items -> items - | otherwise -> loop items' - ) initialTypes +getTransitiveClosure = fix $ \loop items -> + let items' = S.unions (items : [getMore x | x <- S.toList items]) + in if + | items' == items -> items + | otherwise -> loop items' + where getMore :: TSType -> S.Set TSType getMore (TSType x) = S.fromList $ getParentTypes x @@ -25,3 +56,85 @@ getTypeScriptDeclarationsRecursively initialType = S.toList $ S.fromList declara where closure = getTransitiveClosure (S.fromList [TSType initialType]) declarations = mconcat [getTypeScriptDeclarations x | TSType x <- S.toList closure] + + +-- * Recursively deriving missing TypeScript interfaces + +recursivelyDeriveMissingTypeScriptInstancesFor :: (Monoid w) => Name -> (Name -> Q w) -> Q w +recursivelyDeriveMissingTypeScriptInstancesFor = recursivelyDeriveMissingInstancesFor doesTypeScriptInstanceExist + +recursivelyDeriveMissingInstancesFor :: (Monoid w) => (Name -> Q Bool) -> Name -> (Name -> Q w) -> Q w +recursivelyDeriveMissingInstancesFor doesInstanceExist name deriveFn = execWriterT $ do + deriveInstanceIfNecessary name deriveFn + + names <- lift $ getAllParentTypes name doesInstanceExist + forM_ names $ \n -> deriveInstanceIfNecessary n deriveFn + +deriveInstanceIfNecessary :: (Monoid w) => Name -> (Name -> Q w) -> WriterT w Q () +deriveInstanceIfNecessary name deriveFn = do + lift (doesTypeScriptInstanceExist name) >>= \case + True -> return () + False -> do + (lift $ nothingOnFail (deriveFn name)) >>= \case + Nothing -> lift $ reportWarning [i|Failed to derive decls for name '#{name}'|] + Just x -> tell x + +doesTypeScriptInstanceExist :: Name -> Q Bool +doesTypeScriptInstanceExist name = do + result :: Maybe Bool <- runMaybeT $ do + (DatatypeInfo {..}) <- MaybeT $ nothingOnFail $ reifyDatatype name + + -- Skip names with type parameters for now + when (datatypeVars /= []) $ fail "" + + MaybeT $ nothingOnFail $ isInstance ''TypeScript [ConT name] + + return $ fromMaybe True result + +getAllParentTypes :: Name -> (Name -> Q Bool) -> Q [Name] +getAllParentTypes name pruneFn = reverse <$> execStateT (getAllParentTypes' name pruneFn) [] + where + getAllParentTypes' :: Name -> (Name -> Q Bool) -> StateT [Name] Q () + getAllParentTypes' nm pfn = (lift $ nothingOnFail $ pfn nm) >>= \case + Nothing -> return () + Just True -> return () + Just False -> (lift $ nothingOnFail (reifyDatatype nm)) >>= \case + Nothing -> do + lift $ reportWarning [i|Failed to reify: '#{nm}'|] + Just (DatatypeInfo {..}) -> do + let parentTypes = mconcat $ fmap constructorFields datatypeCons + + let maybeRecurse n = do + st <- get + unless (n `L.elem` st) $ do + modify (n :) + getAllParentTypes' n pfn + + forM_ parentTypes $ \typ -> do + let names :: [Name] = fst $ execState (getNamesFromType typ) ([], [typ]) + forM_ names maybeRecurse + + getNamesFromType :: Type -> State ([Name], [Type]) () + getNamesFromType (ConT n) = modify (first $ addIfNotPresent n) + getNamesFromType (AppT t1 t2) = handleTwoTypes t1 t2 + getNamesFromType (InfixT t1 _ t2) = handleTwoTypes t1 t2 + getNamesFromType (UInfixT t1 _ t2) = handleTwoTypes t1 t2 + getNamesFromType _ = return () + + handleTwoTypes t1 t2 = do + (_, visitedTypes) <- get + unless (t1 `L.elem` visitedTypes) $ do + modify (second (t1 :)) + getNamesFromType t1 + + (_, visitedTypes') <- get + unless (t2 `L.elem` visitedTypes') $ do + modify (second (t2 :)) + getNamesFromType t2 + + addIfNotPresent :: (Eq a) => a -> [a] -> [a] + addIfNotPresent x xs | x `L.elem` xs = xs + addIfNotPresent x xs = x : xs + +nothingOnFail :: Q a -> Q (Maybe a) +nothingOnFail action = recover (return Nothing) (Just <$> action) From 8985dcfef73873382b5ee05137673053ada12b20 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sun, 12 Sep 2021 19:46:12 -0700 Subject: [PATCH 006/123] Bump version number in preparation for next release --- aeson-typescript.cabal | 2 +- package.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 291198b..7617056 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.3.0.1 +version: 0.4.0.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index d6aa63f..3627dc5 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.3.0.1 +version: 0.4.0.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From 16d6c2a40730fdc72784ca70391b68c5086d78a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= Date: Mon, 4 Oct 2021 21:38:07 +0200 Subject: [PATCH 007/123] Export `defaultFormattingOptions`. No point having a default when the user cannot access to override it! This was forgotten in PR #22 when extracting it from PR #17. --- src/Data/Aeson/TypeScript/TH.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 6dbfe92..8731584 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -126,6 +126,7 @@ module Data.Aeson.TypeScript.TH ( , formatTSDeclarations' , formatTSDeclaration , FormattingOptions(..) + , defaultFormattingOptions , SumTypeFormat(..) , ExportMode(..) From 305cd581fce927ec3a5792ee2cf8b0e7208d901e Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 7 Feb 2022 22:02:40 -0800 Subject: [PATCH 008/123] Sort type family interface keys so they're deterministic --- src/Data/Aeson/TypeScript/Lookup.hs | 4 +++- stack.yaml | 3 +-- stack.yaml.lock | 8 ++++---- test/ClosedTypeFamilies.hs | 10 +++++----- test/OpenTypeFamilies.hs | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Lookup.hs b/src/Data/Aeson/TypeScript/Lookup.hs index ccb1f32..29c254b 100644 --- a/src/Data/Aeson/TypeScript/Lookup.hs +++ b/src/Data/Aeson/TypeScript/Lookup.hs @@ -18,6 +18,8 @@ module Data.Aeson.TypeScript.Lookup where import Control.Monad import Data.Aeson.TypeScript.Instances () import Data.Aeson.TypeScript.Types +import Data.Function +import qualified Data.List as L import Data.Proxy import Data.String.Interpolate import Language.Haskell.TH hiding (stringE) @@ -53,7 +55,7 @@ getClosedTypeFamilyInterfaceDecl name eqns = do #endif x -> fail [i|aeson-typescript doesn't know yet how to handle this type family equation: '#{x}'|] - [| TSInterfaceDeclaration $(TH.stringE $ nameBase name) [] $(listE $ fmap return fields) |] + [| TSInterfaceDeclaration $(TH.stringE $ nameBase name) [] (L.sortBy (compare `on` fieldName) $(listE $ fmap return fields)) |] getClosedTypeFamilyImage :: [TySynEqn] -> Q [Type] getClosedTypeFamilyImage eqns = do diff --git a/stack.yaml b/stack.yaml index 2b993a4..9da7a42 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,6 +1,5 @@ -resolver: lts-18.3 -compiler: ghc-8.10.5 +resolver: nightly-2022-01-15 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index 7940767..d224fde 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - size: 585603 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/3.yaml - sha256: 694573e96dca34db5636edb1fe6c96bb233ca0f9fb96c1ead1671cdfa9bd73e9 - original: lts-18.3 + size: 621914 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/1/15.yaml + sha256: da9648bb5bf30143b3b45c0daeb2c06ee09fa2af08d362672acf318c6eac1724 + original: nightly-2022-01-15 diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 9038c21..45548c2 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -48,13 +48,13 @@ newtype Simple env = Simple (DeployEnvironment2 env) $(deriveTypeScript' A.defaultOptions ''Simple (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment2] })) tests :: SpecWith () -tests = describe "Type families" $ do +tests = describe "Closed type families" $ do describe "simple newtype" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Simple T))) `shouldBe` ([ TSInterfaceDeclaration "DeployEnvironment2" [] [ - TSField False "\"single_node_env\"" "\"single\"" - , TSField False "\"k8s_env\"" "\"k8s\"" + TSField False "\"k8s_env\"" "\"k8s\"" + , TSField False "\"single_node_env\"" "\"single\"" , TSField False "T" "void" ] , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] @@ -75,8 +75,8 @@ tests = describe "Type families" $ do it [i|get the declarations recursively|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (UserT T Identity))) `shouldBe` ([ TSInterfaceDeclaration "DeployEnvironment" [] [ - TSField False "\"single_node_env\"" "\"single\"" - , TSField False "\"k8s_env\"" "\"k8s\"" + TSField False "\"k8s_env\"" "\"k8s\"" + , TSField False "\"single_node_env\"" "\"single\"" , TSField False "T" "void" ] , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index d0c1c74..810154f 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -48,7 +48,7 @@ newtype Simple env = Simple (DeployEnvironment2 env) $(deriveTypeScript' A.defaultOptions ''Simple (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment2] })) tests :: SpecWith () -tests = describe "Type families" $ do +tests = describe "Open type families" $ do describe "simple newtype" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Simple T))) `shouldBe` ([ From c0cd1226aa5a8fc1ebc9f11b21ae25c8f1b8fc1e Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 17 Mar 2022 18:28:00 -0700 Subject: [PATCH 009/123] Prepare for 0.4.0.0 release --- CHANGELOG.md | 2 +- LICENSE | 2 +- aeson-typescript.cabal | 2 +- package.yaml | 2 +- src/Data/Aeson/TypeScript/TH.hs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6093d3..cb2be46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change log -## 0.4.0.0 (unreleased) +## 0.4.0.0 * Add new built-in instances (Word8, Int32, Int64, Map, HashSet) * Export TSField in the Internal module diff --git a/LICENSE b/LICENSE index 5dfaa25..9ff54f5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright Tom McLaughlin (c) 2021 +Copyright Tom McLaughlin (c) 2022 All rights reserved. diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 7617056..72f4945 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -13,7 +13,7 @@ homepage: https://github.com/codedownio/aeson-typescript#readme bug-reports: https://github.com/codedownio/aeson-typescript/issues author: Tom McLaughlin maintainer: tom@codedown.io -copyright: 2021 CodeDown +copyright: 2022 CodeDown license: BSD3 license-file: LICENSE build-type: Simple diff --git a/package.yaml b/package.yaml index 3627dc5..437c2dc 100644 --- a/package.yaml +++ b/package.yaml @@ -5,7 +5,7 @@ license: BSD3 category: Text, Web, JSON author: "Tom McLaughlin" maintainer: "tom@codedown.io" -copyright: "2021 CodeDown" +copyright: "2022 CodeDown" extra-source-files: - README.md diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 8731584..2925c16 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -15,7 +15,7 @@ {-| Module: Data.Aeson.TypeScript.TH -Copyright: (c) 2021 Tom McLaughlin +Copyright: (c) 2022 Tom McLaughlin License: BSD3 Stability: experimental Portability: portable From 6bff8f9e046a2ca4e1affd110d0a634d42ca004b Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 25 Apr 2022 03:28:18 -0700 Subject: [PATCH 010/123] Add TypeScript Int16 --- src/Data/Aeson/TypeScript/Instances.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 8310c54..d4f650c 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -53,6 +53,9 @@ instance TypeScript Bool where instance TypeScript Int where getTypeScriptType _ = "number" +instance TypeScript Int16 where + getTypeScriptType _ = "number" + instance TypeScript Int32 where getTypeScriptType _ = "number" From 1066fb8d72e642bfd4e2317e3a1f31be049e11ab Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 20 May 2022 23:26:51 -0700 Subject: [PATCH 011/123] Add TypeScript (A.KeyMap a) instance for aeson 2 --- src/Data/Aeson/TypeScript/Instances.hs | 20 +++++++++++++++++++- stack.yaml | 4 +++- stack.yaml.lock | 8 ++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index d4f650c..13dcbfe 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -1,4 +1,12 @@ -{-# LANGUAGE QuasiQuotes, OverloadedStrings, TemplateHaskell, RecordWildCards, ScopedTypeVariables, ExistentialQuantification, FlexibleInstances, OverlappingInstances, CPP #-} +{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE OverlappingInstances #-} +{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- Note: the OverlappingInstances pragma is only here so the overlapping instances in this file @@ -25,6 +33,10 @@ import GHC.Int import Data.Monoid #endif +#if MIN_VERSION_aeson(2,0,0) +import qualified Data.Aeson.KeyMap as A +#endif + instance TypeScript () where getTypeScriptType _ = "void" @@ -122,6 +134,12 @@ instance (TypeScript a, TypeScript b) => TypeScript (HashMap a b) where getTypeScriptType _ = [i|{[k in #{getTypeScriptKeyType (Proxy :: Proxy a)}]?: #{getTypeScriptType (Proxy :: Proxy b)}}|] getParentTypes _ = L.nub [TSType (Proxy :: Proxy a), TSType (Proxy :: Proxy b)] +#if MIN_VERSION_aeson(2,0,0) +instance (TypeScript a) => TypeScript (A.KeyMap a) where + getTypeScriptType _ = [i|{[k]?: #{getTypeScriptType (Proxy :: Proxy a)}}|] + getParentTypes _ = L.nub [TSType (Proxy :: Proxy a)] +#endif + instance (TypeScript a) => TypeScript (Set a) where getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) <> "[]"; getParentTypes _ = [TSType (Proxy :: Proxy a)] diff --git a/stack.yaml b/stack.yaml index 9da7a42..78cc250 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,5 +1,7 @@ -resolver: nightly-2022-01-15 +resolver: lts-19.7 +# resolver: nightly-2022-02-07 +# resolver: nightly-2022-01-15 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index d224fde..8787e19 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - size: 621914 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/1/15.yaml - sha256: da9648bb5bf30143b3b45c0daeb2c06ee09fa2af08d362672acf318c6eac1724 - original: nightly-2022-01-15 + size: 618884 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/7.yaml + sha256: 57d4ce67cc097fea2058446927987bc1f7408890e3a6df0da74e5e318f051c20 + original: lts-19.7 From 2f0d7a850f4d7f94f37d64213e470dc520434480 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sun, 16 Oct 2022 21:10:42 -0600 Subject: [PATCH 012/123] Update CHANGELOG --- CHANGELOG.md | 5 +++++ aeson-typescript.cabal | 4 ++-- package.yaml | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb2be46..5b30661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change log +## 0.4.1.0 + +* Add TypeScript Int16 +* Add TypeScript (A.KeyMap a) instance for aeson 2 + ## 0.4.0.0 * Add new built-in instances (Word8, Int32, Int64, Map, HashSet) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 72f4945..b6ad8bc 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.34.4. +-- This file has been generated from package.yaml by hpack version 0.35.0. -- -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.4.0.0 +version: 0.4.1.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index 437c2dc..82cc5a7 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.4.0.0 +version: 0.4.1.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From d4ff690d9618ffa5e118e540ba1085a7119d0d96 Mon Sep 17 00:00:00 2001 From: Tanya Bouman Date: Tue, 18 Oct 2022 20:21:10 -0400 Subject: [PATCH 013/123] README: fix getTypeScriptDeclarations name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cba6b71..d7c2fa3 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ $(deriveTypeScript (defaultOptions {fieldLabelModifier = drop 4, constructorTagM Now we can use the newly created instances. ```haskell ->>> putStrLn $ formatTSDeclarations $ getTypeScriptDeclaration (Proxy :: Proxy (D T)) +>>> putStrLn $ formatTSDeclarations $ getTypeScriptDeclarations (Proxy :: Proxy (D T)) type D = "nullary" | IUnary | IProduct | IRecord; From 1214f1ce30a4bb3b36d21ab454a6aedb620f1392 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 18 Oct 2022 17:31:07 -0700 Subject: [PATCH 014/123] Test GHC 9.2.4 in CI --- .github/workflows/aeson-typescript.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index f3002a9..9c2d5ad 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -16,8 +16,9 @@ jobs: ghc: - "8.6.5" - "8.8.4" - - "8.10.4" - - "9.0.1" + - "8.10.7" + - "9.0.2" + - "9.2.4" # exclude: # - os: macOS-latest # ghc: 8.8.3 @@ -68,8 +69,9 @@ jobs: matrix: ghc: - "8.8.4" - - "8.10.4" - - "9.0.1" + - "8.10.7" + - "9.0.2" + - "9.2.4" steps: - uses: actions/checkout@v2 From 477a8834a1e0116f8076b8fe865710d133d6cd46 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 18 Oct 2022 17:35:10 -0700 Subject: [PATCH 015/123] Remove accidentally checked in dev folder --- .gitignore | 1 + dev/Live.hs | 77 -------------------------------------------------- dev/Live2.hs | 28 ------------------ dev/Live3.hs | 27 ------------------ dev/Live4.hs | 33 ---------------------- dev/Live5.hs | 80 ---------------------------------------------------- dev/Live6.hs | 39 ------------------------- 7 files changed, 1 insertion(+), 284 deletions(-) delete mode 100644 dev/Live.hs delete mode 100644 dev/Live2.hs delete mode 100644 dev/Live3.hs delete mode 100644 dev/Live4.hs delete mode 100644 dev/Live5.hs delete mode 100644 dev/Live6.hs diff --git a/.gitignore b/.gitignore index 70115df..938bf2c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *~ dist-newstyle *.hie +dev/ diff --git a/dev/Live.hs b/dev/Live.hs deleted file mode 100644 index 496486b..0000000 --- a/dev/Live.hs +++ /dev/null @@ -1,77 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilyDependencies #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} - -module Live where - -import Data.Aeson as A -import Data.Aeson.TypeScript.Recursive -import Data.Aeson.TypeScript.TH -import Data.Function -import Data.Functor.Identity -import Data.Kind -import Data.Map -import Data.Proxy -import Data.String.Interpolate -import qualified Data.Text as T -import Prelude hiding (Double) - - -instance TypeScript Identity where getTypeScriptType _ = "any" - -data SingleDE = SingleDE -instance TypeScript SingleDE where getTypeScriptType _ = [i|"single"|] - -data K8SDE = K8SDE -instance TypeScript K8SDE where getTypeScriptType _ = [i|"k8s"|] - -data SingleNodeEnvironment = SingleNodeEnvironment - deriving (Eq, Show) -instance TypeScript SingleNodeEnvironment where getTypeScriptType _ = [i|"single_node_env"|] - -data K8SEnvironment = K8SEnvironment - deriving (Eq, Show) -instance TypeScript K8SEnvironment where getTypeScriptType _ = [i|"k8s_env"|] - -data Nullable (c :: Type -> Type) x -data Exposed x -type family Columnar (f :: Type -> Type) x where - Columnar Exposed x = Exposed x - Columnar Identity x = x - Columnar (Nullable c) x = Columnar c (Maybe x) - Columnar f x = f x - -type family DeployEnvironment env = result | result -> env where - DeployEnvironment SingleNodeEnvironment = SingleDE - DeployEnvironment K8SEnvironment = K8SDE - DeployEnvironment T = () - --- * The main type - -data UserT env f = User { - _userDeployEnv :: Columnar f (DeployEnvironment env) - } - -data Complex3 k = Complex3 { - bulkCommandNoArgKeys :: Map T.Text k - } deriving (Show) - - -deriveTypeScript' A.defaultOptions ''UserT (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment] }) - -main :: IO () -main = getTypeScriptDeclarationsRecursively (Proxy :: Proxy (UserT T Identity)) - & formatTSDeclarations - & putStrLn diff --git a/dev/Live2.hs b/dev/Live2.hs deleted file mode 100644 index e8f4741..0000000 --- a/dev/Live2.hs +++ /dev/null @@ -1,28 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilyDependencies #-} - -module Live2 where - -import Data.Aeson as A -import Data.Aeson.TypeScript.TH -import Data.Function -import Data.Proxy - - -data TestT a = TestT { - listOfA :: [a] - , maybeA :: Maybe a - } -$(deriveTypeScript A.defaultOptions ''TestT) - -main :: IO () -main = getTypeScriptDeclarations (Proxy :: Proxy (TestT Int)) - & formatTSDeclarations - & putStrLn diff --git a/dev/Live3.hs b/dev/Live3.hs deleted file mode 100644 index d8673df..0000000 --- a/dev/Live3.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilyDependencies #-} - -module Live3 where - -import Data.Aeson as A -import Data.Aeson.TypeScript.TH -import Data.Function -import Data.Proxy - - -data Test = TestBlah {x :: Int, y :: Bool} - -$(deriveTypeScript (A.defaultOptions { A.tagSingleConstructors = True }) ''Test) - -main :: IO () -main = getTypeScriptDeclarations (Proxy @Test) - & formatTSDeclarations - & putStrLn diff --git a/dev/Live4.hs b/dev/Live4.hs deleted file mode 100644 index 3a8e354..0000000 --- a/dev/Live4.hs +++ /dev/null @@ -1,33 +0,0 @@ -{-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilyDependencies #-} - -module Live4 where - -import Data.Aeson as A -import Data.Aeson.TypeScript.Recursive -import Data.Aeson.TypeScript.TH -import Data.Function -import Data.Proxy -import TestBoilerplate - - -type family DeployEnvironment2 env = result | result -> env -type instance DeployEnvironment2 SingleNodeEnvironment = SingleDE -type instance DeployEnvironment2 K8SEnvironment = K8SDE -type instance DeployEnvironment2 T = () -newtype Simple env = Simple (DeployEnvironment2 env) -$(deriveTypeScript' A.defaultOptions ''Simple (defaultExtraTypeScriptOptions { typeFamiliesToMapToTypeScript = [''DeployEnvironment2] })) - -main :: IO () -main = getTypeScriptDeclarationsRecursively (Proxy @(Simple T)) - & formatTSDeclarations - & putStrLn diff --git a/dev/Live5.hs b/dev/Live5.hs deleted file mode 100644 index 31082d3..0000000 --- a/dev/Live5.hs +++ /dev/null @@ -1,80 +0,0 @@ -{-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeInType #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilyDependencies #-} -{-# LANGUAGE DeriveGeneric #-} - -module Live5 where - -import Data.Aeson as A -import Data.Aeson.TypeScript.Recursive -import Data.Aeson.TypeScript.TH -import Data.Function -import Data.Kind as Kind -import Data.Proxy -import qualified Data.Text as T -import Data.Typeable -import Data.Void -import GHC.Generics -import TestBoilerplate - - --- data From = FromServer | FromClient --- data MethodType = Notification | Request - --- data Method (f :: From) (t :: MethodType) where --- Login :: Method 'FromClient 'Request --- ReportClick :: Method 'FromClient 'Notification - --- instance TypeScript Login where getTypeScriptType _ = "asdf" --- instance TypeScript ReportClick where getTypeScriptType _ = "fdsa" - --- data LoginParams = LoginParams { --- loginUsername :: T.Text --- , loginPassword :: T.Text --- } --- $(deriveJSONAndTypeScript A.defaultOptions ''LoginParams) - - --- data ReportClickParams = ReportClickParams { --- reportClickX :: Int --- , reportClickY :: Int --- } --- $(deriveJSONAndTypeScript A.defaultOptions ''ReportClickParams) - --- type family MessageParams (m :: Method f t) :: Kind.Type where --- MessageParams 'Login = LoginParams --- MessageParams 'ReportClick = ReportClickParams - --- data SMethod (m :: Method f t) where --- SLogin :: SMethod 'Login --- SReportClick :: SMethod 'ReportClick - --- data RequestMessage (m :: Method f 'Request) = --- RequestMessage { --- _id :: T.Text --- , _method :: SMethod m --- , _params :: MessageParams m --- } - --- data LoginResult = LoginResult { profilePicture :: T.Text } --- $(deriveJSONAndTypeScript A.defaultOptions ''LoginResult) - --- type family ResponseResult (m :: Method f 'Request) :: Kind.Type where --- ResponseResult 'Login = LoginResult --- ResponseResult _ = Void - --- deriveTypeScript' A.defaultOptions ''RequestMessage (ExtraTypeScriptOptions [''MessageParams]) - --- -- main :: IO () --- -- main = getTypeScriptDeclarationsRecursively (Proxy @(RequestMessage (Method FromClient Request))) --- -- & formatTSDeclarations --- -- & putStrLn diff --git a/dev/Live6.hs b/dev/Live6.hs deleted file mode 100644 index c0fdf90..0000000 --- a/dev/Live6.hs +++ /dev/null @@ -1,39 +0,0 @@ -{-# LANGUAGE UndecidableInstances #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeInType #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilyDependencies #-} -{-# LANGUAGE DeriveGeneric #-} - -module Live6 where - -import Data.Aeson as A -import Data.Aeson.TypeScript.TH -import Data.Function -import Data.Map -import Data.Proxy -import Data.Text - - -data Complex a = Product Int a | Unary Int deriving Eq - -data Complex2 a = Product2 Int a - -data Complex3 k = Complex3 { - bulkCommandNoArgKeys :: Map Text k - } deriving (Show) -$(deriveTypeScript defaultOptions ''Complex3) - -main :: IO () --- main = printThing (Proxy @(BulkCommandNoArg Int)) -main = printThing (Proxy @(Complex3 Double)) - -printThing x = getTypeScriptDeclarations x - & formatTSDeclarations - & putStrLn From 85200a0c17e78fa6eddeedcea73d0afb53daadf2 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 18 Oct 2022 17:35:38 -0700 Subject: [PATCH 016/123] Bump Stackage in stack.yaml --- stack.yaml | 6 +++--- stack.yaml.lock | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/stack.yaml b/stack.yaml index 78cc250..e41ff87 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,7 +1,7 @@ -resolver: lts-19.7 -# resolver: nightly-2022-02-07 -# resolver: nightly-2022-01-15 +resolver: nightly-2022-10-18 +# resolver: lts-19.7 +# resolver: nightly-2022-02-07 # End of aeson 1 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index 8787e19..38eee5b 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - size: 618884 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/7.yaml - sha256: 57d4ce67cc097fea2058446927987bc1f7408890e3a6df0da74e5e318f051c20 - original: lts-19.7 + sha256: 895204e9116cba1f32047525ec5bad7423216587706e5df044c4a7c191a5d8cb + size: 644482 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/10/18.yaml + original: nightly-2022-10-18 From 8311cdffa00b52506d6563ae2c5a281a06faef7b Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 18 Oct 2022 18:11:22 -0700 Subject: [PATCH 017/123] Add failing test for bad type of Aeson map --- aeson-typescript.cabal | 2 ++ package.yaml | 1 + test/TestBoilerplate.hs | 15 +++++++++++++-- test/Util/Aeson.hs | 13 +++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 test/Util/Aeson.hs diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index b6ad8bc..e3f2d62 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -83,6 +83,7 @@ test-suite aeson-typescript-tests UntaggedTagSingleConstructors UnwrapUnaryRecords Util + Util.Aeson Data.Aeson.TypeScript.Formatting Data.Aeson.TypeScript.Instances Data.Aeson.TypeScript.Internal @@ -123,4 +124,5 @@ test-suite aeson-typescript-tests , th-abstraction , transformers , unordered-containers + , vector default-language: Haskell2010 diff --git a/package.yaml b/package.yaml index 82cc5a7..75a5929 100644 --- a/package.yaml +++ b/package.yaml @@ -64,3 +64,4 @@ tests: - hspec - process - temporary + - vector diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index fc99e87..322f21f 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -22,9 +22,11 @@ import Data.Functor.Identity import Data.Kind import Data.Proxy import Data.String.Interpolate +import qualified Data.Vector as V import Language.Haskell.TH hiding (Type) import Test.Hspec import Util +import Util.Aeson data Unit = Unit data OneFieldRecordless = OneFieldRecordless Int @@ -35,6 +37,7 @@ data Hybrid = HybridSimple Int | HybridRecord { hybridString :: String } data TwoConstructor = Con1 { con1String :: String } | Con2 { con2String :: String, con2Int :: Int } data Complex a = Nullary | Unary Int | Product String Char a | Record { testOne :: Int, testTwo :: Bool, testThree :: Complex a} deriving Eq data Optional = Optional {optionalInt :: Maybe Int} +data AesonTypes = AesonTypes { aesonValue :: A.Value, aesonObject :: A.Object } -- * For testing type families @@ -74,6 +77,7 @@ testDeclarations testName aesonOptions = do deriveInstances ''TwoConstructor deriveInstances ''Complex deriveInstances ''Optional + deriveInstances ''AesonTypes typesAndValues :: Exp <- [e|[(getTypeScriptType (Proxy :: Proxy Unit), A.encode Unit) @@ -95,9 +99,15 @@ testDeclarations testName aesonOptions = do , (getTypeScriptType (Proxy :: Proxy (Complex Int)), A.encode (Unary 42 :: Complex Int)) , (getTypeScriptType (Proxy :: Proxy (Complex Int)), A.encode (Product "asdf" 'g' 42 :: Complex Int)) , (getTypeScriptType (Proxy :: Proxy (Complex Int)), A.encode ((Record { testOne = 3, testTwo = True, testThree = Product "test" 'A' 123}) :: Complex Int)) + , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Nothing })) - , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Just 1 }))] - |] + , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Just 1 })) + + , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (AesonTypes { + aesonValue = A.object [("foo" :: A.Key, A.Number 42)] + , aesonObject = aesonFromList [("foo", A.Number 42)] + })) + ]|] declarations :: Exp <- [e|getTypeScriptDeclarations (Proxy :: Proxy Unit) <> getTypeScriptDeclarations (Proxy :: Proxy OneFieldRecordless) @@ -108,6 +118,7 @@ testDeclarations testName aesonOptions = do <> getTypeScriptDeclarations (Proxy :: Proxy TwoConstructor) <> getTypeScriptDeclarations (Proxy :: Proxy (Complex T)) <> getTypeScriptDeclarations (Proxy :: Proxy Optional) + <> getTypeScriptDeclarations (Proxy :: Proxy AesonTypes) |] tests <- [d|tests :: SpecWith () diff --git a/test/Util/Aeson.hs b/test/Util/Aeson.hs new file mode 100644 index 0000000..68cf681 --- /dev/null +++ b/test/Util/Aeson.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE CPP #-} + +module Util.Aeson where + +#if MIN_VERSION_aeson(2,0,0) +import qualified Data.Aeson.KeyMap as KM + +aesonFromList = KM.fromList +#else +import Data.HashMap.Strict as HM + +aesonFromList = HM.fromList +#endif From a70a8c3889c12f2775ad0cab8a547c36fc186a70 Mon Sep 17 00:00:00 2001 From: Tanya Bouman Date: Tue, 18 Oct 2022 20:11:08 -0400 Subject: [PATCH 018/123] Fix Typescript instance for KeyMap This makes `KeyMap a` generate the same type as `HashMap Text a`, so that the old and new Aeson representations of an Object have the same typescript type. --- src/Data/Aeson/TypeScript/Instances.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 13dcbfe..98c2e49 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -136,7 +136,7 @@ instance (TypeScript a, TypeScript b) => TypeScript (HashMap a b) where #if MIN_VERSION_aeson(2,0,0) instance (TypeScript a) => TypeScript (A.KeyMap a) where - getTypeScriptType _ = [i|{[k]?: #{getTypeScriptType (Proxy :: Proxy a)}}|] + getTypeScriptType _ = [i|{[k: string]: #{getTypeScriptType (Proxy :: Proxy a)}}|] getParentTypes _ = L.nub [TSType (Proxy :: Proxy a)] #endif From 3c7f78bdcaf7f99155ace833d11546abacf93058 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 18 Oct 2022 18:31:59 -0700 Subject: [PATCH 019/123] Fix TestBoilerplate --- aeson-typescript.cabal | 1 - package.yaml | 1 - test/TestBoilerplate.hs | 9 ++++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index e3f2d62..eb9cb3a 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -124,5 +124,4 @@ test-suite aeson-typescript-tests , th-abstraction , transformers , unordered-containers - , vector default-language: Haskell2010 diff --git a/package.yaml b/package.yaml index 75a5929..82cc5a7 100644 --- a/package.yaml +++ b/package.yaml @@ -64,4 +64,3 @@ tests: - hspec - process - temporary - - vector diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 322f21f..062c0e0 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -22,7 +22,6 @@ import Data.Functor.Identity import Data.Kind import Data.Proxy import Data.String.Interpolate -import qualified Data.Vector as V import Language.Haskell.TH hiding (Type) import Test.Hspec import Util @@ -103,10 +102,10 @@ testDeclarations testName aesonOptions = do , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Nothing })) , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Just 1 })) - , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (AesonTypes { - aesonValue = A.object [("foo" :: A.Key, A.Number 42)] - , aesonObject = aesonFromList [("foo", A.Number 42)] - })) + , (getTypeScriptType (Proxy :: Proxy AesonTypes), A.encode (AesonTypes { + aesonValue = A.object [("foo" :: A.Key, A.Number 42)] + , aesonObject = aesonFromList [("foo", A.Number 42)] + })) ]|] declarations :: Exp <- [e|getTypeScriptDeclarations (Proxy :: Proxy Unit) From c4958f9c4d94c0464472baba0d72eb50aa8af3a0 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 18 Oct 2022 18:35:29 -0700 Subject: [PATCH 020/123] Also remove dev as a source dir --- aeson-typescript.cabal | 7 ------- package.yaml | 1 - 2 files changed, 8 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index eb9cb3a..9e478dc 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -94,17 +94,10 @@ test-suite aeson-typescript-tests Data.Aeson.TypeScript.TypeManipulation Data.Aeson.TypeScript.Types Data.Aeson.TypeScript.Util - Live - Live2 - Live3 - Live4 - Live5 - Live6 Paths_aeson_typescript hs-source-dirs: test src - dev ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N build-depends: aeson diff --git a/package.yaml b/package.yaml index 82cc5a7..f8be48e 100644 --- a/package.yaml +++ b/package.yaml @@ -50,7 +50,6 @@ tests: source-dirs: - test - src - - dev ghc-options: - -Wall - -threaded From c982c7ccd7693769fcb2bcbd03fa7af84970fa4f Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 28 Oct 2022 20:24:23 -0700 Subject: [PATCH 021/123] Update CHANGELOG for 0.4.2.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b30661..455de03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change log +## 0.4.2.0 + +* Fix TypeScript (A.KeyMap a) instance + ## 0.4.1.0 * Add TypeScript Int16 From 5f71db93a30ddf102ff4336ed94a4a7544fdb9e6 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 10 Nov 2022 17:02:32 -0800 Subject: [PATCH 022/123] Release 0.4.2.0 --- aeson-typescript.cabal | 2 +- package.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 9e478dc..c03bc69 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.4.1.0 +version: 0.4.2.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index f8be48e..53c2e6a 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.4.1.0 +version: 0.4.2.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From ba5d99812384a361b3988e133d4763748e49752a Mon Sep 17 00:00:00 2001 From: parsonsmatt Date: Thu, 27 Oct 2022 12:49:43 -0600 Subject: [PATCH 023/123] check for illegal characters --- CHANGELOG.md | 7 ++++ aeson-typescript.cabal | 3 ++ package.yaml | 1 + src/Data/Aeson/TypeScript/LegalName.hs | 39 +++++++++++++++++++++ src/Data/Aeson/TypeScript/TH.hs | 1 + src/Data/Aeson/TypeScript/Types.hs | 24 +++++++++++-- test/Data/Aeson/TypeScript/LegalNameSpec.hs | 23 ++++++++++++ test/Formatting.hs | 23 +++++++++++- test/Spec.hs | 4 ++- 9 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 src/Data/Aeson/TypeScript/LegalName.hs create mode 100644 test/Data/Aeson/TypeScript/LegalNameSpec.hs diff --git a/CHANGELOG.md b/CHANGELOG.md index 455de03..f0610c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change log + +## (unreleased) + +* [#35](https://github.com/codedownio/aeson-typescript/pull/35) + * Add `Data.Aeson.TypeScript.LegalName` module for checking whether a name is a legal JavaScript name or not. + * The `defaultFormatter` will `error` if the name contains illegal characters. + ## 0.4.2.0 * Fix TypeScript (A.KeyMap a) instance diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index c03bc69..54e8557 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -36,6 +36,7 @@ library Data.Aeson.TypeScript.TH Data.Aeson.TypeScript.Internal Data.Aeson.TypeScript.Recursive + Data.Aeson.TypeScript.LegalName other-modules: Data.Aeson.TypeScript.Formatting Data.Aeson.TypeScript.Instances @@ -66,6 +67,7 @@ test-suite aeson-typescript-tests other-modules: Basic ClosedTypeFamilies + Data.Aeson.TypeScript.LegalNameSpec Formatting Generic HigherKind @@ -87,6 +89,7 @@ test-suite aeson-typescript-tests Data.Aeson.TypeScript.Formatting Data.Aeson.TypeScript.Instances Data.Aeson.TypeScript.Internal + Data.Aeson.TypeScript.LegalName Data.Aeson.TypeScript.Lookup Data.Aeson.TypeScript.Recursive Data.Aeson.TypeScript.TH diff --git a/package.yaml b/package.yaml index 53c2e6a..49a963e 100644 --- a/package.yaml +++ b/package.yaml @@ -43,6 +43,7 @@ library: - Data.Aeson.TypeScript.TH - Data.Aeson.TypeScript.Internal - Data.Aeson.TypeScript.Recursive + - Data.Aeson.TypeScript.LegalName tests: aeson-typescript-tests: diff --git a/src/Data/Aeson/TypeScript/LegalName.hs b/src/Data/Aeson/TypeScript/LegalName.hs new file mode 100644 index 0000000..06201ad --- /dev/null +++ b/src/Data/Aeson/TypeScript/LegalName.hs @@ -0,0 +1,39 @@ +-- | This module defines functions which are useful for determining if +-- a given name is a legal JavaScript name according to . +module Data.Aeson.TypeScript.LegalName where + +import qualified Data.Set as Set +import Language.Haskell.TH +import Data.List.NonEmpty (NonEmpty (..)) +import qualified Data.List.NonEmpty as NonEmpty +import Data.Char +import Data.Foldable + +-- | The return type is the illegal characters that are in the name. If the +-- input has no illegal characters, then you have 'Nothing'. +checkIllegalNameChars :: NonEmpty Char -> Maybe (NonEmpty Char) +checkIllegalNameChars (firstChar :| restChars) = NonEmpty.nonEmpty $ + let + legalFirstCategories = + Set.fromList + [ UppercaseLetter + , LowercaseLetter + , TitlecaseLetter + , ModifierLetter + , OtherLetter + , LetterNumber + ] + legalRestCategories = + Set.fromList + [ NonSpacingMark + , SpacingCombiningMark + , DecimalNumber + , ConnectorPunctuation + ] + `Set.union` legalFirstCategories + isIllegalFirstChar c = not $ + c `elem` ['$', '_'] || generalCategory c `Set.member` legalFirstCategories + isIllegalRestChar c = not $ + generalCategory c `Set.member` legalRestCategories + in + filter isIllegalFirstChar [firstChar] <> filter isIllegalRestChar restChars diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 2925c16..f7ec6bc 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -127,6 +127,7 @@ module Data.Aeson.TypeScript.TH ( , formatTSDeclaration , FormattingOptions(..) , defaultFormattingOptions + , defaultNameFormatter , SumTypeFormat(..) , ExportMode(..) diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index e3c7c6c..3398ffa 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -9,11 +9,13 @@ module Data.Aeson.TypeScript.Types where +import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Aeson as A import Data.Proxy import Data.String import Data.Typeable import Language.Haskell.TH +import Data.Aeson.TypeScript.LegalName -- | The typeclass that defines how a type is turned into TypeScript. -- @@ -131,12 +133,30 @@ data SumTypeFormat = defaultFormattingOptions :: FormattingOptions defaultFormattingOptions = FormattingOptions { numIndentSpaces = 2 - , interfaceNameModifier = id - , typeNameModifier = id + , interfaceNameModifier = defaultNameFormatter + , typeNameModifier = defaultNameFormatter , exportMode = ExportNone , typeAlternativesFormat = TypeAlias } +-- | The 'defaultNameFormatter' in the 'FormattingOptions' checks to see if +-- the name is a legal TypeScript name. If it is not, then it throws +-- a runtime error. +defaultNameFormatter :: String -> String +defaultNameFormatter str = + case NonEmpty.nonEmpty str of + Nothing -> + error "Name cannot be empty" + Just nameChars -> + case checkIllegalNameChars nameChars of + Just badChars -> + error $ concat + [ "The name ", str, " contains illegal characters: ", NonEmpty.toList badChars + , "\nConsider setting a default name formatter that replaces these characters, or renaming the type." + ] + Nothing -> + str + -- | Convenience typeclass class you can use to "attach" a set of Aeson encoding options to a type. class HasJSONOptions a where getJSONOptions :: (Proxy a) -> A.Options diff --git a/test/Data/Aeson/TypeScript/LegalNameSpec.hs b/test/Data/Aeson/TypeScript/LegalNameSpec.hs new file mode 100644 index 0000000..dda1429 --- /dev/null +++ b/test/Data/Aeson/TypeScript/LegalNameSpec.hs @@ -0,0 +1,23 @@ +module Data.Aeson.TypeScript.LegalNameSpec where + +import Test.Hspec +import Data.List.NonEmpty (NonEmpty (..)) +import Data.Aeson.TypeScript.LegalName + +tests :: Spec +tests = describe "Data.Aeson.TypeScript.LegalName" $ do + describe "checkIllegalNameChars" $ do + describe "legal Haskell names" $ do + it "allows an uppercase letter" $ do + checkIllegalNameChars ('A' :| []) + `shouldBe` Nothing + it "allows an underscore" $ do + checkIllegalNameChars ('_' :| "asdf") + `shouldBe` Nothing + it "reports that ' is illegal" $ do + checkIllegalNameChars ('F' :| "oo'") + `shouldBe` Just ('\'' :| []) + describe "illegal Haskell names" $ do + it "allows a $" $ do + checkIllegalNameChars ('$' :| "asdf") + `shouldBe` Nothing diff --git a/test/Formatting.hs b/test/Formatting.hs index 136751d..4f10865 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -5,6 +5,7 @@ module Formatting (tests) where +import Control.Exception import Data.Aeson (defaultOptions) import Data.Aeson.TypeScript.TH import Data.Aeson.TypeScript.Types @@ -16,9 +17,17 @@ data D = S | F deriving (Eq, Show) $(deriveTypeScript defaultOptions ''D) +data PrimeInType' = PrimeInType + +$(deriveTypeScript defaultOptions ''PrimeInType') + +data PrimeInConstr = PrimeInConstr' + +$(deriveTypeScript defaultOptions ''PrimeInConstr) + tests :: Spec tests = do - describe "Formatting" $ + describe "Formatting" $ do describe "when given a Sum Type" $ do describe "and the TypeAlias format option is set" $ it "should generate a TS string literal type" $ @@ -32,3 +41,15 @@ tests = do it "should generate a TS Enum with a type declaration" $ formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = EnumWithType }) (getTypeScriptDeclarations @D Proxy) `shouldBe` [i|enum DEnum { S="S", F="F" }\n\ntype D = keyof typeof DEnum;|] + describe "when the name has an apostrophe" $ do + describe "in the type" $ do + it "throws an error" $ do + evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInType' Proxy)) + `shouldThrow` + anyErrorCall + describe "in the constructor" $ do + it "throws an error" $ do + evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInConstr Proxy)) + `shouldThrow` + anyErrorCall + diff --git a/test/Spec.hs b/test/Spec.hs index 611fc36..83ee5fa 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -19,14 +19,16 @@ import qualified UntaggedTagSingleConstructors import qualified OmitNothingFields import qualified NoOmitNothingFields import qualified UnwrapUnaryRecords +import qualified Data.Aeson.TypeScript.LegalNameSpec as LegalNameSpec main :: IO () -main = hspec $ do +main = hspec $ parallel $ do Formatting.tests Generic.tests HigherKind.tests ClosedTypeFamilies.tests + LegalNameSpec.tests ObjectWithSingleFieldTagSingleConstructors.tests ObjectWithSingleFieldNoTagSingleConstructors.tests From cc1545e706a3fa94cd8927b0e51d8deecf41044c Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 22 Dec 2022 19:44:42 -0700 Subject: [PATCH 024/123] Formatting and tweaks following pull #35 --- aeson-typescript.cabal | 2 +- src/Data/Aeson/TypeScript/LegalName.hs | 10 ++++----- src/Data/Aeson/TypeScript/Types.hs | 4 ++-- test/Formatting.hs | 6 +---- .../Aeson/TypeScript => }/LegalNameSpec.hs | 6 ++--- test/Spec.hs | 22 +++++++++---------- 6 files changed, 23 insertions(+), 27 deletions(-) rename test/{Data/Aeson/TypeScript => }/LegalNameSpec.hs (93%) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 54e8557..e3095bf 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -67,10 +67,10 @@ test-suite aeson-typescript-tests other-modules: Basic ClosedTypeFamilies - Data.Aeson.TypeScript.LegalNameSpec Formatting Generic HigherKind + LegalNameSpec NoOmitNothingFields ObjectWithSingleFieldNoTagSingleConstructors ObjectWithSingleFieldTagSingleConstructors diff --git a/src/Data/Aeson/TypeScript/LegalName.hs b/src/Data/Aeson/TypeScript/LegalName.hs index 06201ad..3f15900 100644 --- a/src/Data/Aeson/TypeScript/LegalName.hs +++ b/src/Data/Aeson/TypeScript/LegalName.hs @@ -1,13 +1,13 @@ -- | This module defines functions which are useful for determining if --- a given name is a legal JavaScript name according to . +-- a given name is a legal JavaScript name according to +-- . module Data.Aeson.TypeScript.LegalName where -import qualified Data.Set as Set -import Language.Haskell.TH +import Data.Char import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NonEmpty -import Data.Char -import Data.Foldable +import qualified Data.Set as Set + -- | The return type is the illegal characters that are in the name. If the -- input has no illegal characters, then you have 'Nothing'. diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index 3398ffa..9af55a6 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -9,13 +9,13 @@ module Data.Aeson.TypeScript.Types where -import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Aeson as A +import Data.Aeson.TypeScript.LegalName +import qualified Data.List.NonEmpty as NonEmpty import Data.Proxy import Data.String import Data.Typeable import Language.Haskell.TH -import Data.Aeson.TypeScript.LegalName -- | The typeclass that defines how a type is turned into TypeScript. -- diff --git a/test/Formatting.hs b/test/Formatting.hs index 4f10865..0ad964b 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -8,21 +8,18 @@ module Formatting (tests) where import Control.Exception import Data.Aeson (defaultOptions) import Data.Aeson.TypeScript.TH -import Data.Aeson.TypeScript.Types import Data.Proxy import Data.String.Interpolate import Test.Hspec -data D = S | F deriving (Eq, Show) +data D = S | F deriving (Eq, Show) $(deriveTypeScript defaultOptions ''D) data PrimeInType' = PrimeInType - $(deriveTypeScript defaultOptions ''PrimeInType') data PrimeInConstr = PrimeInConstr' - $(deriveTypeScript defaultOptions ''PrimeInConstr) tests :: Spec @@ -52,4 +49,3 @@ tests = do evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInConstr Proxy)) `shouldThrow` anyErrorCall - diff --git a/test/Data/Aeson/TypeScript/LegalNameSpec.hs b/test/LegalNameSpec.hs similarity index 93% rename from test/Data/Aeson/TypeScript/LegalNameSpec.hs rename to test/LegalNameSpec.hs index dda1429..f657092 100644 --- a/test/Data/Aeson/TypeScript/LegalNameSpec.hs +++ b/test/LegalNameSpec.hs @@ -1,8 +1,8 @@ -module Data.Aeson.TypeScript.LegalNameSpec where +module LegalNameSpec where -import Test.Hspec -import Data.List.NonEmpty (NonEmpty (..)) import Data.Aeson.TypeScript.LegalName +import Data.List.NonEmpty (NonEmpty (..)) +import Test.Hspec tests :: Spec tests = describe "Data.Aeson.TypeScript.LegalName" $ do diff --git a/test/Spec.hs b/test/Spec.hs index 83ee5fa..f645327 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -8,36 +8,36 @@ import qualified Generic import qualified HigherKind import qualified ClosedTypeFamilies +import qualified LegalNameSpec +import qualified NoOmitNothingFields import qualified ObjectWithSingleFieldNoTagSingleConstructors import qualified ObjectWithSingleFieldTagSingleConstructors +import qualified OmitNothingFields import qualified TaggedObjectNoTagSingleConstructors import qualified TaggedObjectTagSingleConstructors import qualified TwoElemArrayNoTagSingleConstructors import qualified TwoElemArrayTagSingleConstructors import qualified UntaggedNoTagSingleConstructors import qualified UntaggedTagSingleConstructors -import qualified OmitNothingFields -import qualified NoOmitNothingFields import qualified UnwrapUnaryRecords -import qualified Data.Aeson.TypeScript.LegalNameSpec as LegalNameSpec main :: IO () main = hspec $ parallel $ do + ClosedTypeFamilies.tests Formatting.tests Generic.tests HigherKind.tests - ClosedTypeFamilies.tests - LegalNameSpec.tests - ObjectWithSingleFieldTagSingleConstructors.tests + LegalNameSpec.tests + NoOmitNothingFields.allTests ObjectWithSingleFieldNoTagSingleConstructors.tests - TaggedObjectTagSingleConstructors.tests + ObjectWithSingleFieldTagSingleConstructors.tests + OmitNothingFields.tests TaggedObjectNoTagSingleConstructors.tests - TwoElemArrayTagSingleConstructors.tests + TaggedObjectTagSingleConstructors.tests TwoElemArrayNoTagSingleConstructors.tests - UntaggedTagSingleConstructors.tests + TwoElemArrayTagSingleConstructors.tests UntaggedNoTagSingleConstructors.tests - OmitNothingFields.tests - NoOmitNothingFields.allTests + UntaggedTagSingleConstructors.tests UnwrapUnaryRecords.allTests From a30807d8f5e3b607992259574d26031c78e96e07 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 18:24:33 -0800 Subject: [PATCH 025/123] Bump stack.yaml to lts-20.12 --- stack.yaml | 4 +--- stack.yaml.lock | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/stack.yaml b/stack.yaml index e41ff87..812491d 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,7 +1,5 @@ -resolver: nightly-2022-10-18 -# resolver: lts-19.7 -# resolver: nightly-2022-02-07 # End of aeson 1 +resolver: lts-20.12 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index 38eee5b..b1d5d3a 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 895204e9116cba1f32047525ec5bad7423216587706e5df044c4a7c191a5d8cb - size: 644482 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/10/18.yaml - original: nightly-2022-10-18 + sha256: af5d667f6096e535b9c725a72cffe0f6c060e0568d9f9eeda04caee70d0d9d2d + size: 649133 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/12.yaml + original: lts-20.12 From 5d10208ebfd099a83da4bf2e0fea8b58544e81af Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 18:24:13 -0800 Subject: [PATCH 026/123] Piping through haddocks using getDoc --- src/Data/Aeson/TypeScript/Formatting.hs | 15 ++++++++++++--- src/Data/Aeson/TypeScript/Instances.hs | 4 ++-- src/Data/Aeson/TypeScript/Lookup.hs | 6 +++--- src/Data/Aeson/TypeScript/TH.hs | 11 +++++++++-- src/Data/Aeson/TypeScript/Types.hs | 10 +++++++--- test/ClosedTypeFamilies.hs | 24 ++++++++++++------------ test/HigherKind.hs | 10 +++++----- test/OpenTypeFamilies.hs | 24 ++++++++++++------------ 8 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index 1edb6bf..f956b3b 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -32,11 +32,16 @@ formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVar formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables members) = [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 +}|] where + ls = T.intercalate "\n" $ fmap T.pack [indentTo numIndentSpaces (formatTSField member <> ";") | member <- members] + modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName formatTSDeclaration _ (TSRawDeclaration text) = text +-- | TODO: handle multiple lines +indentTo :: Int -> String -> String +indentTo numIndentSpaces s = replicate numIndentSpaces ' ' <> s + exportPrefix :: ExportMode -> String exportPrefix ExportEach = "export " exportPrefix ExportNone = "" @@ -60,7 +65,11 @@ validateFormattingOptions options@FormattingOptions{..} decls isPlainSumType ds = (not . any isInterface $ ds) && length ds == 1 formatTSField :: TSField -> String -formatTSField (TSField optional name typ) = [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] +formatTSField (TSField optional name typ maybeDoc) = docPrefix <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] + where + docPrefix = case maybeDoc of + Nothing -> "" + Just doc -> "/* " <> doc <> " */\n" getGenericBrackets :: [String] -> String getGenericBrackets [] = "" diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 98c2e49..ee566be 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -90,8 +90,8 @@ instance {-# OVERLAPPING #-} TypeScript [Char] where instance (TypeScript a, TypeScript b) => TypeScript (Either a b) where getTypeScriptType _ = [i|Either<#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}>|] getTypeScriptDeclarations _ = [TSTypeAlternatives "Either" ["T1", "T2"] ["Left", "Right"] - , TSInterfaceDeclaration "Left" ["T"] [TSField False "Left" "T"] - , TSInterfaceDeclaration "Right" ["T"] [TSField False "Right" "T"] + , TSInterfaceDeclaration "Left" ["T"] [TSField False "Left" "T" Nothing] + , TSInterfaceDeclaration "Right" ["T"] [TSField False "Right" "T" Nothing] ] getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) , (TSType (Proxy :: Proxy b)) diff --git a/src/Data/Aeson/TypeScript/Lookup.hs b/src/Data/Aeson/TypeScript/Lookup.hs index 29c254b..8c245c8 100644 --- a/src/Data/Aeson/TypeScript/Lookup.hs +++ b/src/Data/Aeson/TypeScript/Lookup.hs @@ -46,12 +46,12 @@ getClosedTypeFamilyInterfaceDecl name eqns = do fields <- forM eqns $ \case #if MIN_VERSION_template_haskell(2,15,0) TySynEqn Nothing (AppT (ConT _) (ConT arg)) result -> do - [| TSField False (getTypeScriptType (Proxy :: Proxy $(conT arg))) (getTypeScriptType (Proxy :: Proxy $(return result))) |] + [| TSField False (getTypeScriptType (Proxy :: Proxy $(conT arg))) (getTypeScriptType (Proxy :: Proxy $(return result))) Nothing |] TySynEqn Nothing (AppT (ConT _) (PromotedT arg)) result -> do - [| TSField False (getTypeScriptType (Proxy :: Proxy $(promotedT arg))) (getTypeScriptType (Proxy :: Proxy $(return result))) |] + [| TSField False (getTypeScriptType (Proxy :: Proxy $(promotedT arg))) (getTypeScriptType (Proxy :: Proxy $(return result))) Nothing |] #else TySynEqn [ConT arg] result -> do - [| TSField False (getTypeScriptType (Proxy :: Proxy $(conT arg))) (getTypeScriptType (Proxy :: Proxy $(return result))) |] + [| TSField False (getTypeScriptType (Proxy :: Proxy $(conT arg))) (getTypeScriptType (Proxy :: Proxy $(return result))) Nothing |] #endif x -> fail [i|aeson-typescript doesn't know yet how to handle this type family equation: '#{x}'|] diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index f7ec6bc..33d6bc5 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -270,7 +270,7 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do lift [|$(TH.stringE interfaceName) <> $(return brackets)|] | otherwise -> do tagField :: [Exp] <- lift $ case sumEncoding options of - TaggedObject tagFieldName _ -> (: []) <$> [|TSField False $(TH.stringE tagFieldName) $(TH.stringE [i|"#{constructorNameToUse options ci}"|])|] + TaggedObject tagFieldName _ -> (: []) <$> [|TSField False $(TH.stringE tagFieldName) $(TH.stringE [i|"#{constructorNameToUse options ci}"|]) Nothing|] _ -> return [] tsFields <- getTSFields @@ -322,7 +322,14 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do (AppT (ConT name) t) | name == ''Maybe && not (omitNothingFields options) -> ( , ) <$> [|$(getTypeAsStringExp t) <> " | null"|] <*> getOptionalAsBoolExp t _ -> ( , ) <$> getTypeAsStringExp typ <*> getOptionalAsBoolExp typ - lift $ [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) |] + +#if MIN_VERSION_template_haskell(2,18,0) + maybeDoc <- lift $ getDoc (DeclDoc (mkName nameString)) +#else + let maybeDoc = Nothing +#endif + + lift $ [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) Nothing |] -- TODO isSingleRecordConstructor (constructorVariant -> RecordConstructor [x]) = True isSingleRecordConstructor _ = False diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index 9af55a6..c42af91 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -93,9 +93,13 @@ data TSDeclaration = TSInterfaceDeclaration { interfaceName :: String | TSRawDeclaration { text :: String } deriving (Show, Eq, Ord) -data TSField = TSField { fieldOptional :: Bool - , fieldName :: String - , fieldType :: String } deriving (Show, Eq, Ord) +data TSField = TSField + { fieldOptional :: Bool + , fieldName :: String + , fieldType :: String + , fieldDoc :: Maybe String + -- ^ Haddock documentation for the field, if present + } deriving (Show, Eq, Ord) newtype TSString a = TSString { unpackTSString :: String } deriving Show diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 45548c2..29fa686 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -53,9 +53,9 @@ tests = describe "Closed type families" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Simple T))) `shouldBe` ([ TSInterfaceDeclaration "DeployEnvironment2" [] [ - TSField False "\"k8s_env\"" "\"k8s\"" - , TSField False "\"single_node_env\"" "\"single\"" - , TSField False "T" "void" + TSField False "\"k8s_env\"" "\"k8s\"" Nothing + , TSField False "\"single_node_env\"" "\"single\"" Nothing + , TSField False "T" "void" Nothing ] , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] @@ -66,23 +66,23 @@ tests = describe "Closed type families" $ do (getTypeScriptDeclarations (Proxy :: Proxy (UserT T Identity))) `shouldBe` ([ TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ - TSField False "_userUsername" "string" - , TSField False "_userCreatedAt" "number" - , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" + TSField False "_userUsername" "string" Nothing + , TSField False "_userCreatedAt" "number" Nothing + , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing ] ]) it [i|get the declarations recursively|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (UserT T Identity))) `shouldBe` ([ TSInterfaceDeclaration "DeployEnvironment" [] [ - TSField False "\"k8s_env\"" "\"k8s\"" - , TSField False "\"single_node_env\"" "\"single\"" - , TSField False "T" "void" + TSField False "\"k8s_env\"" "\"k8s\"" Nothing + , TSField False "\"single_node_env\"" "\"single\"" Nothing + , TSField False "T" "void" Nothing ] , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ - TSField False "_userUsername" "string" - , TSField False "_userCreatedAt" "number" - , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" + TSField False "_userUsername" "string" Nothing + , TSField False "_userCreatedAt" "number" Nothing + , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing ] , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] ]) diff --git a/test/HigherKind.hs b/test/HigherKind.hs index 63fe4e8..20afa6b 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -51,7 +51,7 @@ tests = describe "Higher kinds" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (HigherKind T))) `shouldBe` ([ TSTypeAlternatives "HigherKind" ["T"] ["IHigherKind"], - TSInterfaceDeclaration "IHigherKind" ["T"] [TSField False "higherKindList" "T[]"] + TSInterfaceDeclaration "IHigherKind" ["T"] [TSField False "higherKindList" "T[]" Nothing] ]) (getTypeScriptType (Proxy :: Proxy (HigherKind Int))) `shouldBe` "HigherKind" @@ -60,8 +60,8 @@ tests = describe "Higher kinds" $ do it [i|works when referenced in another type|] $ do (getTypeScriptDeclarations (Proxy :: Proxy Foo)) `shouldBe` ([ TSTypeAlternatives "Foo" [] ["IFoo"], - TSInterfaceDeclaration "IFoo" [] [TSField False "fooString" "string" - , TSField False "fooHigherKindReference" "HigherKind"] + TSInterfaceDeclaration "IFoo" [] [TSField False "fooString" "string" Nothing + , TSField False "fooHigherKindReference" "HigherKind" Nothing] ]) it [i|works with an interface inside|] $ do @@ -74,8 +74,8 @@ tests = describe "Higher kinds" $ do it [i|makes the declaration and type correctly|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (DoubleHigherKind T1 T2))) `shouldBe` ([ TSTypeAlternatives "DoubleHigherKind" ["T1","T2"] ["IDoubleHigherKind"], - TSInterfaceDeclaration "IDoubleHigherKind" ["T1","T2"] [TSField False "someList" "T2[]" - , TSField False "higherKindThing" "HigherKind"] + TSInterfaceDeclaration "IDoubleHigherKind" ["T1","T2"] [TSField False "someList" "T2[]" Nothing + , TSField False "higherKindThing" "HigherKind" Nothing] ]) (getTypeScriptType (Proxy :: Proxy (DoubleHigherKind Int String))) `shouldBe` "DoubleHigherKind" diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index 810154f..e860277 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -53,9 +53,9 @@ tests = describe "Open type families" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Simple T))) `shouldBe` ([ TSInterfaceDeclaration "DeployEnvironment2" [] [ - TSField False "\"single_node_env\"" "\"single\"" - , TSField False "\"k8s_env\"" "\"k8s\"" - , TSField False "T" "void" + TSField False "\"single_node_env\"" "\"single\"" Nothing + , TSField False "\"k8s_env\"" "\"k8s\"" Nothing + , TSField False "T" "void" Nothing ] , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] @@ -66,23 +66,23 @@ tests = describe "Open type families" $ do (getTypeScriptDeclarations (Proxy :: Proxy (UserT T Identity))) `shouldBe` ([ TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ - TSField False "_userUsername" "string" - , TSField False "_userCreatedAt" "number" - , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" + TSField False "_userUsername" "string" Nothing + , TSField False "_userCreatedAt" "number" Nothing + , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing ] ]) it [i|get the declarations recursively|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (UserT T Identity))) `shouldBe` ([ TSInterfaceDeclaration "DeployEnvironment" [] [ - TSField False "\"single_node_env\"" "\"single\"" - , TSField False "\"k8s_env\"" "\"k8s\"" - , TSField False "T" "void" + TSField False "\"single_node_env\"" "\"single\"" Nothing + , TSField False "\"k8s_env\"" "\"k8s\"" Nothing + , TSField False "T" "void" Nothing ] , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ - TSField False "_userUsername" "string" - , TSField False "_userCreatedAt" "number" - , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" + TSField False "_userUsername" "string" Nothing + , TSField False "_userCreatedAt" "number" Nothing + , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing ] , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] ]) From 8a5bb23dc79d9f18ee7462f9a38882acd37bbaae Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 19:04:05 -0800 Subject: [PATCH 027/123] Recover from getDoc failure --- src/Data/Aeson/TypeScript/Recursive.hs | 4 +--- src/Data/Aeson/TypeScript/TH.hs | 4 ++-- src/Data/Aeson/TypeScript/Util.hs | 3 +++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Recursive.hs b/src/Data/Aeson/TypeScript/Recursive.hs index 9b724db..e525bf6 100755 --- a/src/Data/Aeson/TypeScript/Recursive.hs +++ b/src/Data/Aeson/TypeScript/Recursive.hs @@ -29,6 +29,7 @@ import Control.Monad.Trans.Maybe import Control.Monad.Writer import Data.Aeson.TypeScript.Instances () import Data.Aeson.TypeScript.TH +import Data.Aeson.TypeScript.Util (nothingOnFail) import Data.Bifunctor import Data.Function import qualified Data.List as L @@ -135,6 +136,3 @@ getAllParentTypes name pruneFn = reverse <$> execStateT (getAllParentTypes' name addIfNotPresent :: (Eq a) => a -> [a] -> [a] addIfNotPresent x xs | x `L.elem` xs = xs addIfNotPresent x xs = x : xs - -nothingOnFail :: Q a -> Q (Maybe a) -nothingOnFail action = recover (return Nothing) (Just <$> action) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 33d6bc5..353180e 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -324,12 +324,12 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do _ -> ( , ) <$> getTypeAsStringExp typ <*> getOptionalAsBoolExp typ #if MIN_VERSION_template_haskell(2,18,0) - maybeDoc <- lift $ getDoc (DeclDoc (mkName nameString)) + maybeDoc <- lift $ nothingOnFail $ getDoc (DeclDoc (mkName nameString)) #else let maybeDoc = Nothing #endif - lift $ [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) Nothing |] -- TODO + lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) Nothing |] -- TODO isSingleRecordConstructor (constructorVariant -> RecordConstructor [x]) = True isSingleRecordConstructor _ = False diff --git a/src/Data/Aeson/TypeScript/Util.hs b/src/Data/Aeson/TypeScript/Util.hs index 89c771b..7e39892 100644 --- a/src/Data/Aeson/TypeScript/Util.hs +++ b/src/Data/Aeson/TypeScript/Util.hs @@ -224,3 +224,6 @@ genericVariablesListExpr includeSuffix genericVariables = listE (fmap (\((_, (su isStarType :: Type -> Maybe Name isStarType (SigT (VarT n) StarT) = Just n isStarType _ = Nothing + +nothingOnFail :: Q a -> Q (Maybe a) +nothingOnFail action = recover (return Nothing) (Just <$> action) From 5bfb857119f436f54b87d3b583177ac871122193 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 19:16:17 -0800 Subject: [PATCH 028/123] Add getDoc tests and fix Basic tests --- aeson-typescript.cabal | 3 ++- test/Basic.hs | 4 +++- test/Generic.hs | 10 +++++----- test/GetDoc.hs | 40 +++++++++++++++++++++++++++++++++++++ test/NoOmitNothingFields.hs | 4 +--- test/OmitNothingFields.hs | 4 +--- test/Spec.hs | 4 ++++ 7 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 test/GetDoc.hs diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index e3095bf..8c0a9b3 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.0. +-- This file has been generated from package.yaml by hpack version 0.35.1. -- -- see: https://github.com/sol/hpack @@ -69,6 +69,7 @@ test-suite aeson-typescript-tests ClosedTypeFamilies Formatting Generic + GetDoc HigherKind LegalNameSpec NoOmitNothingFields diff --git a/test/Basic.hs b/test/Basic.hs index d018fb0..ec66cb5 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -41,7 +41,9 @@ tests = describe "Basic tests" $ do ]) it [i|Works with a unit with constructorTagModifier|] $ do - (getTypeScriptDeclarations (Proxy :: Proxy Unit2)) `shouldBe` ([]) + (getTypeScriptDeclarations (Proxy :: Proxy Unit2)) `shouldBe` ([ + TSTypeAlternatives "Unit2" [] ["\"foo\""] + ]) main :: IO () diff --git a/test/Generic.hs b/test/Generic.hs index 60e1a20..13ada57 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -44,8 +44,8 @@ tests :: SpecWith () tests = describe "Generic instances" $ do it [i|Complex makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex String))) `shouldBe` [ - TSInterfaceDeclaration {interfaceName = "IProduct", interfaceGenericVariables = ["T"], interfaceMembers = [TSField {fieldOptional = False, fieldName = "tag", fieldType = "\"Product\""},TSField {fieldOptional = False, fieldName = "contents", fieldType = "[number, T]"}]} - ,TSInterfaceDeclaration {interfaceName = "IUnary", interfaceGenericVariables = ["T"], interfaceMembers = [TSField {fieldOptional = False, fieldName = "tag", fieldType = "\"Unary\""},TSField {fieldOptional = False, fieldName = "contents", fieldType = "number"}]} + TSInterfaceDeclaration {interfaceName = "IProduct", interfaceGenericVariables = ["T"], interfaceMembers = [TSField False "tag" "\"Product\"" Nothing, TSField False "contents" "[number, T]" Nothing]} + ,TSInterfaceDeclaration {interfaceName = "IUnary", interfaceGenericVariables = ["T"], interfaceMembers = [TSField False "tag" "\"Unary\"" Nothing, TSField False "contents" "number" Nothing]} ,TSTypeAlternatives {typeName = "Complex", typeGenericVariables = ["T"], alternativeTypes = ["IProduct","IUnary"]} ] @@ -58,14 +58,14 @@ tests = describe "Generic instances" $ do it [i|Complex3 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex3 String))) `shouldBe` [ TSInterfaceDeclaration {interfaceName = "IProduct3", interfaceGenericVariables = ["T"], interfaceMembers = [ - TSField {fieldOptional = False, fieldName = "record3", fieldType = "T[]"} + TSField False "record3" "T[]" Nothing ]} ,TSTypeAlternatives {typeName = "Complex3", typeGenericVariables = ["T"], alternativeTypes = ["IProduct3"]} ] (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex3 Int))) `shouldBe` [ TSInterfaceDeclaration {interfaceName = "IProduct3", interfaceGenericVariables = ["T"], interfaceMembers = [ - TSField {fieldOptional = False, fieldName = "record3", fieldType = "T[]"} + TSField False "record3" "T[]" Nothing ]} ,TSTypeAlternatives {typeName = "Complex3", typeGenericVariables = ["T"], alternativeTypes = ["IProduct3"]} ] @@ -73,7 +73,7 @@ tests = describe "Generic instances" $ do it [i|Complex4 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex4 String))) `shouldBe` [ TSInterfaceDeclaration {interfaceName = "IProduct4", interfaceGenericVariables = ["T"], interfaceMembers = [ - TSField {fieldOptional = False, fieldName = "record4", fieldType = "{[k in string]?: T}"} + TSField False "record4" "{[k in string]?: T}" Nothing ]} ,TSTypeAlternatives {typeName = "Complex4", typeGenericVariables = ["T"], alternativeTypes = ["IProduct4"]} ] diff --git a/test/GetDoc.hs b/test/GetDoc.hs new file mode 100644 index 0000000..bda2e5d --- /dev/null +++ b/test/GetDoc.hs @@ -0,0 +1,40 @@ +{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} + +module GetDoc (tests) where + +import Data.Aeson as A +import Data.Aeson.TypeScript.TH +import Data.Aeson.TypeScript.Types +import Data.Proxy +import Data.String.Interpolate +import Prelude hiding (Double) +import Test.Hspec + + +data OneField = OneField { + -- | This is a simple string. + simpleString :: String + } +$(deriveTypeScript A.defaultOptions ''OneField) + +tests :: SpecWith () +tests = describe "getDoc tests" $ do + it [i|Works with a simple record type|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy OneField)) `shouldBe` ([]) + + +main :: IO () +main = hspec tests diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index fa03d99..2a8158f 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -35,9 +35,7 @@ allTests = describe "NoOmitNothingFields" $ do , TSInterfaceDeclaration { interfaceName = "IOptional" , interfaceGenericVariables = [] - , interfaceMembers = [TSField {fieldOptional = False - , fieldName = "optionalInt" - , fieldType = "number | null"}] + , interfaceMembers = [TSField False "optionalInt" "number | null" Nothing] }] tests diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index 39886ea..55918fd 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -31,9 +31,7 @@ main = hspec $ describe "OmitNothingFields" $ do interfaceName = "Optional" , interfaceGenericVariables = [] , interfaceMembers = [ - TSField {fieldOptional = True - , fieldName = "optionalInt" - , fieldType = "number"} + TSField True "optionalInt" "number" Nothing ] }] diff --git a/test/Spec.hs b/test/Spec.hs index f645327..3424fef 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -3,8 +3,10 @@ module Main where import Test.Hspec +import qualified Basic import qualified Formatting import qualified Generic +import qualified GetDoc import qualified HigherKind import qualified ClosedTypeFamilies @@ -24,9 +26,11 @@ import qualified UnwrapUnaryRecords main :: IO () main = hspec $ parallel $ do + Basic.tests ClosedTypeFamilies.tests Formatting.tests Generic.tests + GetDoc.tests HigherKind.tests LegalNameSpec.tests From b284178928cf2e2c11d7fd6a7c68c1f5f76d35a7 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 19:48:09 -0800 Subject: [PATCH 029/123] Use the actual getDoc result; not working yet --- src/Data/Aeson/TypeScript/TH.hs | 2 +- test/GetDoc.hs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 353180e..603a85f 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -329,7 +329,7 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do let maybeDoc = Nothing #endif - lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) Nothing |] -- TODO + lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) $(case maybeDoc of Just (Just doc) -> [|Just $(TH.stringE doc)|]; _ -> [|Nothing|]) |] isSingleRecordConstructor (constructorVariant -> RecordConstructor [x]) = True isSingleRecordConstructor _ = False diff --git a/test/GetDoc.hs b/test/GetDoc.hs index bda2e5d..7cc231c 100644 --- a/test/GetDoc.hs +++ b/test/GetDoc.hs @@ -24,9 +24,10 @@ import Prelude hiding (Double) import Test.Hspec +-- | OneField is a type with a single field data OneField = OneField { - -- | This is a simple string. simpleString :: String + -- ^ This is a simple string. } $(deriveTypeScript A.defaultOptions ''OneField) From b773b8c9e12ff2de50e51225668dc045ad810649 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 21:47:09 -0800 Subject: [PATCH 030/123] Small tweaks --- src/Data/Aeson/TypeScript/TH.hs | 2 +- test/Util/Aeson.hs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 603a85f..e1495b0 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -331,7 +331,7 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) $(case maybeDoc of Just (Just doc) -> [|Just $(TH.stringE doc)|]; _ -> [|Nothing|]) |] - isSingleRecordConstructor (constructorVariant -> RecordConstructor [x]) = True + isSingleRecordConstructor (constructorVariant -> RecordConstructor [_]) = True isSingleRecordConstructor _ = False -- * Convenience functions diff --git a/test/Util/Aeson.hs b/test/Util/Aeson.hs index 68cf681..b38b900 100644 --- a/test/Util/Aeson.hs +++ b/test/Util/Aeson.hs @@ -3,8 +3,10 @@ module Util.Aeson where #if MIN_VERSION_aeson(2,0,0) +import qualified Data.Aeson.Key as K import qualified Data.Aeson.KeyMap as KM +aesonFromList :: [(K.Key, v)] -> KM.KeyMap v aesonFromList = KM.fromList #else import Data.HashMap.Strict as HM From cbc75951e36c9a0f40e1feb8864903730fc727e4 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 21:47:38 -0800 Subject: [PATCH 031/123] GetDoc.hs test passing + start to clean up test extensions --- aeson-typescript.cabal | 2 +- package.yaml | 2 ++ test/Basic.hs | 1 - test/ClosedTypeFamilies.hs | 1 - test/Generic.hs | 1 - test/GetDoc.hs | 21 +++++++-------------- test/HigherKind.hs | 1 - test/OpenTypeFamilies.hs | 1 - test/UntaggedTagSingleConstructors.hs | 5 ----- test/UnwrapUnaryRecords.hs | 9 ++------- 10 files changed, 12 insertions(+), 32 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 8c0a9b3..5b91721 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -102,7 +102,7 @@ test-suite aeson-typescript-tests hs-source-dirs: test src - ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N + ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds build-depends: aeson , aeson-typescript diff --git a/package.yaml b/package.yaml index 49a963e..3728830 100644 --- a/package.yaml +++ b/package.yaml @@ -56,6 +56,8 @@ tests: - -threaded - -rtsopts - -with-rtsopts=-N + - -haddock + - -fno-warn-unused-top-binds dependencies: - aeson-typescript - bytestring diff --git a/test/Basic.hs b/test/Basic.hs index ec66cb5..7ccfee9 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -11,7 +11,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module Basic (tests) where diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 29fa686..986cf0a 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -12,7 +12,6 @@ {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module ClosedTypeFamilies (tests) where diff --git a/test/Generic.hs b/test/Generic.hs index 13ada57..1d2ea09 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -12,7 +12,6 @@ {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module Generic (tests) where diff --git a/test/GetDoc.hs b/test/GetDoc.hs index 7cc231c..c953f80 100644 --- a/test/GetDoc.hs +++ b/test/GetDoc.hs @@ -1,17 +1,6 @@ {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module GetDoc (tests) where @@ -26,16 +15,20 @@ import Test.Hspec -- | OneField is a type with a single field data OneField = OneField { + -- | This is a simple string simpleString :: String - -- ^ This is a simple string. } $(deriveTypeScript A.defaultOptions ''OneField) tests :: SpecWith () tests = describe "getDoc tests" $ do it [i|Works with a simple record type|] $ do - (getTypeScriptDeclarations (Proxy :: Proxy OneField)) `shouldBe` ([]) - + (getTypeScriptDeclarations (Proxy :: Proxy OneField)) `shouldBe` ([ + TSTypeAlternatives "OneField" [] ["IOneField"] + , TSInterfaceDeclaration "IOneField" [] [ + TSField False "simpleString" "string" (Just " This is a simple string") + ] + ]) main :: IO () main = hspec tests diff --git a/test/HigherKind.hs b/test/HigherKind.hs index 20afa6b..4f55473 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -11,7 +11,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module HigherKind (tests) where diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index e860277..9f13e96 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -12,7 +12,6 @@ {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module OpenTypeFamilies (tests) where diff --git a/test/UntaggedTagSingleConstructors.hs b/test/UntaggedTagSingleConstructors.hs index 5970c5e..da8e9bb 100644 --- a/test/UntaggedTagSingleConstructors.hs +++ b/test/UntaggedTagSingleConstructors.hs @@ -1,14 +1,9 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module UntaggedTagSingleConstructors (main, tests) where diff --git a/test/UnwrapUnaryRecords.hs b/test/UnwrapUnaryRecords.hs index 2b93486..7764fb8 100644 --- a/test/UnwrapUnaryRecords.hs +++ b/test/UnwrapUnaryRecords.hs @@ -1,14 +1,9 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module UnwrapUnaryRecords (allTests) where @@ -42,5 +37,5 @@ tests = describe "UnwrapUnaryRecords" $ it "tests are disabled for this Aeson ve allTests = tests #endif --- main :: IO () --- main = hspec allTests +main :: IO () +main = hspec allTests From 332ff83fd512dca9a81a69f0ec57ae33e04a7e4a Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 21:47:50 -0800 Subject: [PATCH 032/123] Update github CI --- .github/workflows/aeson-typescript.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 9c2d5ad..2fc03f6 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -18,7 +18,8 @@ jobs: - "8.8.4" - "8.10.7" - "9.0.2" - - "9.2.4" + - "9.2.6" + - "9.4.4" # exclude: # - os: macOS-latest # ghc: 8.8.3 @@ -71,7 +72,8 @@ jobs: - "8.8.4" - "8.10.7" - "9.0.2" - - "9.2.4" + - "9.2.6" + - "9.4.4" steps: - uses: actions/checkout@v2 From ba10af7287cd67e578b51f084bde3629ccee546a Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 21:50:56 -0800 Subject: [PATCH 033/123] Run CI on all branches --- .github/workflows/aeson-typescript.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 2fc03f6..55ce756 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -3,7 +3,6 @@ name: aeson-typescript on: pull_request: push: - branches: [master] jobs: cabal: From 68c56eaafa6b05ca4da6acc0da98cb55359f14b7 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 21:54:42 -0800 Subject: [PATCH 034/123] Cleaning up test extensions --- aeson-typescript.cabal | 5 +++++ package.yaml | 5 +++++ test/Basic.hs | 3 --- test/ClosedTypeFamilies.hs | 3 --- test/Generic.hs | 3 --- test/HigherKind.hs | 3 --- test/NoOmitNothingFields.hs | 3 --- test/ObjectWithSingleFieldNoTagSingleConstructors.hs | 3 --- test/ObjectWithSingleFieldTagSingleConstructors.hs | 3 --- test/OmitNothingFields.hs | 3 --- test/OpenTypeFamilies.hs | 3 --- test/TaggedObjectNoTagSingleConstructors.hs | 3 --- test/TaggedObjectTagSingleConstructors.hs | 3 --- test/TestBoilerplate.hs | 3 --- test/TwoElemArrayNoTagSingleConstructors.hs | 3 --- test/TwoElemArrayTagSingleConstructors.hs | 3 --- test/UntaggedNoTagSingleConstructors.hs | 3 --- test/UntaggedTagSingleConstructors.hs | 3 --- test/UnwrapUnaryRecords.hs | 3 --- 19 files changed, 10 insertions(+), 51 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 5b91721..4ed8e89 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -102,6 +102,11 @@ test-suite aeson-typescript-tests hs-source-dirs: test src + default-extensions: + OverloadedStrings + ScopedTypeVariables + KindSignatures + FlexibleContexts ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds build-depends: aeson diff --git a/package.yaml b/package.yaml index 3728830..18fea5d 100644 --- a/package.yaml +++ b/package.yaml @@ -58,6 +58,11 @@ tests: - -with-rtsopts=-N - -haddock - -fno-warn-unused-top-binds + default-extensions: + - OverloadedStrings + - ScopedTypeVariables + - KindSignatures + - FlexibleContexts dependencies: - aeson-typescript - bytestring diff --git a/test/Basic.hs b/test/Basic.hs index 7ccfee9..edd589a 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -1,15 +1,12 @@ {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} module Basic (tests) where diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 986cf0a..24c3008 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -1,16 +1,13 @@ {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilyDependencies #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} module ClosedTypeFamilies (tests) where diff --git a/test/Generic.hs b/test/Generic.hs index 1d2ea09..27494cb 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -1,16 +1,13 @@ {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilyDependencies #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} module Generic (tests) where diff --git a/test/HigherKind.hs b/test/HigherKind.hs index 4f55473..f076032 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -1,15 +1,12 @@ {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} module HigherKind (tests) where diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index 2a8158f..a65bb38 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -1,10 +1,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} diff --git a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs index 310b5d0..7e72a0b 100644 --- a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/ObjectWithSingleFieldTagSingleConstructors.hs b/test/ObjectWithSingleFieldTagSingleConstructors.hs index 7251aac..fa15288 100644 --- a/test/ObjectWithSingleFieldTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldTagSingleConstructors.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index 55918fd..ea61e60 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index 9f13e96..2d4f1f7 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -1,16 +1,13 @@ {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilyDependencies #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} module OpenTypeFamilies (tests) where diff --git a/test/TaggedObjectNoTagSingleConstructors.hs b/test/TaggedObjectNoTagSingleConstructors.hs index 8a942a5..160a452 100644 --- a/test/TaggedObjectNoTagSingleConstructors.hs +++ b/test/TaggedObjectNoTagSingleConstructors.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TaggedObjectTagSingleConstructors.hs b/test/TaggedObjectTagSingleConstructors.hs index f86621d..8806672 100644 --- a/test/TaggedObjectTagSingleConstructors.hs +++ b/test/TaggedObjectTagSingleConstructors.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 062c0e0..0c0d7bd 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} diff --git a/test/TwoElemArrayNoTagSingleConstructors.hs b/test/TwoElemArrayNoTagSingleConstructors.hs index f25b3b8..abcbb7c 100644 --- a/test/TwoElemArrayNoTagSingleConstructors.hs +++ b/test/TwoElemArrayNoTagSingleConstructors.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TwoElemArrayTagSingleConstructors.hs b/test/TwoElemArrayTagSingleConstructors.hs index 6b0d4b7..ca8d29d 100644 --- a/test/TwoElemArrayTagSingleConstructors.hs +++ b/test/TwoElemArrayTagSingleConstructors.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/UntaggedNoTagSingleConstructors.hs b/test/UntaggedNoTagSingleConstructors.hs index 8ca4738..8a1d4f9 100644 --- a/test/UntaggedNoTagSingleConstructors.hs +++ b/test/UntaggedNoTagSingleConstructors.hs @@ -1,12 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/UntaggedTagSingleConstructors.hs b/test/UntaggedTagSingleConstructors.hs index da8e9bb..c2a3004 100644 --- a/test/UntaggedTagSingleConstructors.hs +++ b/test/UntaggedTagSingleConstructors.hs @@ -1,9 +1,6 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module UntaggedTagSingleConstructors (main, tests) where diff --git a/test/UnwrapUnaryRecords.hs b/test/UnwrapUnaryRecords.hs index 7764fb8..2221e68 100644 --- a/test/UnwrapUnaryRecords.hs +++ b/test/UnwrapUnaryRecords.hs @@ -1,9 +1,6 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module UnwrapUnaryRecords (allTests) where From d17d4573fed9cb355b9e618572ac056b3cd2d77c Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 21:56:18 -0800 Subject: [PATCH 035/123] Bump haskell setup actions --- .github/workflows/aeson-typescript.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 55ce756..8325ada 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -78,7 +78,7 @@ jobs: - uses: actions/checkout@v2 if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' - - uses: haskell/actions/setup@v1 + - uses: haskell/actions/setup@v2 name: Setup Haskell Stack with: ghc-version: ${{ matrix.ghc }} From 724db4dac237db522084bce59731471d71749933 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 21:59:50 -0800 Subject: [PATCH 036/123] More test extension cleanup --- aeson-typescript.cabal | 2 ++ package.yaml | 2 ++ test/Basic.hs | 5 ----- test/ClosedTypeFamilies.hs | 5 ----- test/Formatting.hs | 3 --- test/Generic.hs | 5 ----- test/GetDoc.hs | 3 --- test/HigherKind.hs | 5 ----- test/NoOmitNothingFields.hs | 5 ----- test/ObjectWithSingleFieldNoTagSingleConstructors.hs | 5 ----- test/ObjectWithSingleFieldTagSingleConstructors.hs | 5 ----- test/OmitNothingFields.hs | 5 ----- test/OpenTypeFamilies.hs | 5 ----- test/TaggedObjectNoTagSingleConstructors.hs | 5 ----- test/TaggedObjectTagSingleConstructors.hs | 5 ----- test/TestBoilerplate.hs | 5 ----- test/TwoElemArrayNoTagSingleConstructors.hs | 5 ----- test/TwoElemArrayTagSingleConstructors.hs | 5 ----- test/UntaggedNoTagSingleConstructors.hs | 5 ----- test/UntaggedTagSingleConstructors.hs | 2 -- test/UnwrapUnaryRecords.hs | 2 -- 21 files changed, 4 insertions(+), 85 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 4ed8e89..a1a7ea6 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -107,6 +107,8 @@ test-suite aeson-typescript-tests ScopedTypeVariables KindSignatures FlexibleContexts + QuasiQuotes + TemplateHaskell ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds build-depends: aeson diff --git a/package.yaml b/package.yaml index 18fea5d..e9e9a28 100644 --- a/package.yaml +++ b/package.yaml @@ -63,6 +63,8 @@ tests: - ScopedTypeVariables - KindSignatures - FlexibleContexts + - QuasiQuotes + - TemplateHaskell dependencies: - aeson-typescript - bytestring diff --git a/test/Basic.hs b/test/Basic.hs index edd589a..ec98b84 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -1,8 +1,3 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 24c3008..d947ace 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -1,8 +1,3 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} diff --git a/test/Formatting.hs b/test/Formatting.hs index 0ad964b..c4fec32 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -1,7 +1,4 @@ -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-} -{-# LANGUAGE QuasiQuotes #-} module Formatting (tests) where diff --git a/test/Generic.hs b/test/Generic.hs index 27494cb..e206bf0 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -1,8 +1,3 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} diff --git a/test/GetDoc.hs b/test/GetDoc.hs index c953f80..0f91f82 100644 --- a/test/GetDoc.hs +++ b/test/GetDoc.hs @@ -1,6 +1,3 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE ScopedTypeVariables #-} module GetDoc (tests) where diff --git a/test/HigherKind.hs b/test/HigherKind.hs index f076032..d0a588f 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -1,8 +1,3 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index a65bb38..3d9a7f0 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -1,11 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module NoOmitNothingFields (allTests) where diff --git a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs index 7e72a0b..63ab976 100644 --- a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/ObjectWithSingleFieldTagSingleConstructors.hs b/test/ObjectWithSingleFieldTagSingleConstructors.hs index fa15288..014daab 100644 --- a/test/ObjectWithSingleFieldTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldTagSingleConstructors.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index ea61e60..52f665b 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index 2d4f1f7..8e96307 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -1,8 +1,3 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} diff --git a/test/TaggedObjectNoTagSingleConstructors.hs b/test/TaggedObjectNoTagSingleConstructors.hs index 160a452..f4181c0 100644 --- a/test/TaggedObjectNoTagSingleConstructors.hs +++ b/test/TaggedObjectNoTagSingleConstructors.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TaggedObjectTagSingleConstructors.hs b/test/TaggedObjectTagSingleConstructors.hs index 8806672..65e6ec4 100644 --- a/test/TaggedObjectTagSingleConstructors.hs +++ b/test/TaggedObjectTagSingleConstructors.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 0c0d7bd..5f0b438 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} diff --git a/test/TwoElemArrayNoTagSingleConstructors.hs b/test/TwoElemArrayNoTagSingleConstructors.hs index abcbb7c..d634a5e 100644 --- a/test/TwoElemArrayNoTagSingleConstructors.hs +++ b/test/TwoElemArrayNoTagSingleConstructors.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TwoElemArrayTagSingleConstructors.hs b/test/TwoElemArrayTagSingleConstructors.hs index ca8d29d..b3943d3 100644 --- a/test/TwoElemArrayTagSingleConstructors.hs +++ b/test/TwoElemArrayTagSingleConstructors.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/UntaggedNoTagSingleConstructors.hs b/test/UntaggedNoTagSingleConstructors.hs index 8a1d4f9..76c39a9 100644 --- a/test/UntaggedNoTagSingleConstructors.hs +++ b/test/UntaggedNoTagSingleConstructors.hs @@ -1,9 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/UntaggedTagSingleConstructors.hs b/test/UntaggedTagSingleConstructors.hs index c2a3004..dc049b1 100644 --- a/test/UntaggedTagSingleConstructors.hs +++ b/test/UntaggedTagSingleConstructors.hs @@ -1,6 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module UntaggedTagSingleConstructors (main, tests) where diff --git a/test/UnwrapUnaryRecords.hs b/test/UnwrapUnaryRecords.hs index 2221e68..37f398d 100644 --- a/test/UnwrapUnaryRecords.hs +++ b/test/UnwrapUnaryRecords.hs @@ -1,6 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module UnwrapUnaryRecords (allTests) where From c7175f81444223d3215f490e8faff43b7a85b633 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:02:02 -0800 Subject: [PATCH 037/123] Always do checkout --- .github/workflows/aeson-typescript.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 8325ada..c215331 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -76,7 +76,6 @@ jobs: steps: - uses: actions/checkout@v2 - if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' - uses: haskell/actions/setup@v2 name: Setup Haskell Stack From bf1f5821c853dc1791337eec84ac784688556696 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:02:13 -0800 Subject: [PATCH 038/123] More extension cleanup --- test/Basic.hs | 1 - test/ClosedTypeFamilies.hs | 1 - test/Generic.hs | 1 - test/HigherKind.hs | 1 - test/NoOmitNothingFields.hs | 1 - test/ObjectWithSingleFieldNoTagSingleConstructors.hs | 1 - test/ObjectWithSingleFieldTagSingleConstructors.hs | 1 - test/OmitNothingFields.hs | 1 - test/OpenTypeFamilies.hs | 1 - test/TaggedObjectNoTagSingleConstructors.hs | 1 - test/TaggedObjectTagSingleConstructors.hs | 1 - test/TestBoilerplate.hs | 1 - test/TwoElemArrayNoTagSingleConstructors.hs | 1 - test/TwoElemArrayTagSingleConstructors.hs | 1 - test/UntaggedNoTagSingleConstructors.hs | 1 - 15 files changed, 15 deletions(-) diff --git a/test/Basic.hs b/test/Basic.hs index ec98b84..1d82527 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index d947ace..b9b2302 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} diff --git a/test/Generic.hs b/test/Generic.hs index e206bf0..c5c2081 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} diff --git a/test/HigherKind.hs b/test/HigherKind.hs index d0a588f..c26e6a1 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index 3d9a7f0..ef42939 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs index 63ab976..77aeb6f 100644 --- a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/ObjectWithSingleFieldTagSingleConstructors.hs b/test/ObjectWithSingleFieldTagSingleConstructors.hs index 014daab..d05f416 100644 --- a/test/ObjectWithSingleFieldTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index 52f665b..f58836d 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index 8e96307..961ea5e 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TypeFamilies #-} diff --git a/test/TaggedObjectNoTagSingleConstructors.hs b/test/TaggedObjectNoTagSingleConstructors.hs index f4181c0..a81f925 100644 --- a/test/TaggedObjectNoTagSingleConstructors.hs +++ b/test/TaggedObjectNoTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TaggedObjectTagSingleConstructors.hs b/test/TaggedObjectTagSingleConstructors.hs index 65e6ec4..d5e37c8 100644 --- a/test/TaggedObjectTagSingleConstructors.hs +++ b/test/TaggedObjectTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 5f0b438..591f44b 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TwoElemArrayNoTagSingleConstructors.hs b/test/TwoElemArrayNoTagSingleConstructors.hs index d634a5e..974be7f 100644 --- a/test/TwoElemArrayNoTagSingleConstructors.hs +++ b/test/TwoElemArrayNoTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TwoElemArrayTagSingleConstructors.hs b/test/TwoElemArrayTagSingleConstructors.hs index b3943d3..b3fc9a1 100644 --- a/test/TwoElemArrayTagSingleConstructors.hs +++ b/test/TwoElemArrayTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/UntaggedNoTagSingleConstructors.hs b/test/UntaggedNoTagSingleConstructors.hs index 76c39a9..39c308a 100644 --- a/test/UntaggedNoTagSingleConstructors.hs +++ b/test/UntaggedNoTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} From 3117bfc66736d0d9e2b7e4a87f94509b58e60e00 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:05:10 -0800 Subject: [PATCH 039/123] More CI fixups --- .github/workflows/aeson-typescript.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index c215331..669806a 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -25,9 +25,8 @@ jobs: steps: - uses: actions/checkout@v2 - if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master' - - uses: haskell/actions/setup@v1 + - uses: haskell/actions/setup@v2 id: setup-haskell-cabal name: Setup Haskell with: From 0bb53c0e5cf6a78e5e714cf7be3247406f651037 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:06:12 -0800 Subject: [PATCH 040/123] More extension cleanup --- aeson-typescript.cabal | 1 + package.yaml | 1 + test/Basic.hs | 2 -- test/ClosedTypeFamilies.hs | 2 -- test/Generic.hs | 3 --- test/HigherKind.hs | 2 -- test/OpenTypeFamilies.hs | 2 -- test/TestBoilerplate.hs | 1 - 8 files changed, 2 insertions(+), 12 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index a1a7ea6..2b55ef7 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -109,6 +109,7 @@ test-suite aeson-typescript-tests FlexibleContexts QuasiQuotes TemplateHaskell + TypeFamilies ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds build-depends: aeson diff --git a/package.yaml b/package.yaml index e9e9a28..982f957 100644 --- a/package.yaml +++ b/package.yaml @@ -65,6 +65,7 @@ tests: - FlexibleContexts - QuasiQuotes - TemplateHaskell + - TypeFamilies dependencies: - aeson-typescript - bytestring diff --git a/test/Basic.hs b/test/Basic.hs index 1d82527..6facfcb 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -1,6 +1,4 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module Basic (tests) where diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index b9b2302..50191d2 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -1,6 +1,4 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} diff --git a/test/Generic.hs b/test/Generic.hs index c5c2081..e1c33d3 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -1,7 +1,4 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} module Generic (tests) where diff --git a/test/HigherKind.hs b/test/HigherKind.hs index c26e6a1..7c1430d 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -1,6 +1,4 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module HigherKind (tests) where diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index 961ea5e..b6bc6d5 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -1,6 +1,4 @@ {-# LANGUAGE DataKinds #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 591f44b..3cf77b5 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} From 85c11ec20b24ad7adac55f9063a01da99e3c21d1 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:08:25 -0800 Subject: [PATCH 041/123] More extension cleanup --- test/Basic.hs | 2 -- test/ClosedTypeFamilies.hs | 1 - test/Generic.hs | 2 -- test/HigherKind.hs | 2 -- test/OpenTypeFamilies.hs | 1 - 5 files changed, 8 deletions(-) diff --git a/test/Basic.hs b/test/Basic.hs index 6facfcb..eec08ea 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE UndecidableInstances #-} module Basic (tests) where diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 50191d2..d8381db 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} diff --git a/test/Generic.hs b/test/Generic.hs index e1c33d3..889ac8d 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE UndecidableInstances #-} module Generic (tests) where diff --git a/test/HigherKind.hs b/test/HigherKind.hs index 7c1430d..b272ecc 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE UndecidableInstances #-} module HigherKind (tests) where diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index b6bc6d5..f668757 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilyDependencies #-} {-# LANGUAGE UndecidableInstances #-} From 62882d05be682b8d5bca8d961b608a2e15eef5fb Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:11:44 -0800 Subject: [PATCH 042/123] More extension cleanup --- aeson-typescript.cabal | 1 + package.yaml | 1 + test/LegalNameSpec.hs | 1 + test/NoOmitNothingFields.hs | 2 -- test/ObjectWithSingleFieldNoTagSingleConstructors.hs | 2 -- test/ObjectWithSingleFieldTagSingleConstructors.hs | 2 -- test/OmitNothingFields.hs | 2 -- test/TaggedObjectNoTagSingleConstructors.hs | 2 -- test/TaggedObjectTagSingleConstructors.hs | 2 -- test/TestBoilerplate.hs | 1 - test/TwoElemArrayNoTagSingleConstructors.hs | 2 -- test/TwoElemArrayTagSingleConstructors.hs | 2 -- test/UntaggedNoTagSingleConstructors.hs | 1 - test/Util.hs | 2 +- 14 files changed, 4 insertions(+), 19 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 2b55ef7..71176a2 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -110,6 +110,7 @@ test-suite aeson-typescript-tests QuasiQuotes TemplateHaskell TypeFamilies + LambdaCase ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds build-depends: aeson diff --git a/package.yaml b/package.yaml index 982f957..c86a44f 100644 --- a/package.yaml +++ b/package.yaml @@ -66,6 +66,7 @@ tests: - QuasiQuotes - TemplateHaskell - TypeFamilies + - LambdaCase dependencies: - aeson-typescript - bytestring diff --git a/test/LegalNameSpec.hs b/test/LegalNameSpec.hs index f657092..638f314 100644 --- a/test/LegalNameSpec.hs +++ b/test/LegalNameSpec.hs @@ -1,3 +1,4 @@ + module LegalNameSpec where import Data.Aeson.TypeScript.LegalName diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index ef42939..eb9d993 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module NoOmitNothingFields (allTests) where diff --git a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs index 77aeb6f..f69464a 100644 --- a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module ObjectWithSingleFieldNoTagSingleConstructors (main, tests) where diff --git a/test/ObjectWithSingleFieldTagSingleConstructors.hs b/test/ObjectWithSingleFieldTagSingleConstructors.hs index d05f416..9920e0c 100644 --- a/test/ObjectWithSingleFieldTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldTagSingleConstructors.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module ObjectWithSingleFieldTagSingleConstructors (main, tests) where diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index f58836d..1107f70 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module OmitNothingFields (main, tests) where diff --git a/test/TaggedObjectNoTagSingleConstructors.hs b/test/TaggedObjectNoTagSingleConstructors.hs index a81f925..6993d5f 100644 --- a/test/TaggedObjectNoTagSingleConstructors.hs +++ b/test/TaggedObjectNoTagSingleConstructors.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module TaggedObjectNoTagSingleConstructors (main, tests) where diff --git a/test/TaggedObjectTagSingleConstructors.hs b/test/TaggedObjectTagSingleConstructors.hs index d5e37c8..3a1ee31 100644 --- a/test/TaggedObjectTagSingleConstructors.hs +++ b/test/TaggedObjectTagSingleConstructors.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module TaggedObjectTagSingleConstructors (main, tests) where diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 3cf77b5..d8957a4 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} diff --git a/test/TwoElemArrayNoTagSingleConstructors.hs b/test/TwoElemArrayNoTagSingleConstructors.hs index 974be7f..35a2ae5 100644 --- a/test/TwoElemArrayNoTagSingleConstructors.hs +++ b/test/TwoElemArrayNoTagSingleConstructors.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module TwoElemArrayNoTagSingleConstructors (main, tests) where diff --git a/test/TwoElemArrayTagSingleConstructors.hs b/test/TwoElemArrayTagSingleConstructors.hs index b3fc9a1..e21ea3b 100644 --- a/test/TwoElemArrayTagSingleConstructors.hs +++ b/test/TwoElemArrayTagSingleConstructors.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module TwoElemArrayTagSingleConstructors (main, tests) where diff --git a/test/UntaggedNoTagSingleConstructors.hs b/test/UntaggedNoTagSingleConstructors.hs index 39c308a..8e3148d 100644 --- a/test/UntaggedNoTagSingleConstructors.hs +++ b/test/UntaggedNoTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module UntaggedNoTagSingleConstructors (main, tests) where diff --git a/test/Util.hs b/test/Util.hs index ea6dfe4..180f657 100644 --- a/test/Util.hs +++ b/test/Util.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE CPP, QuasiQuotes, OverloadedStrings, TemplateHaskell, RecordWildCards, ScopedTypeVariables, NamedFieldPuns, LambdaCase #-} +{-# LANGUAGE CPP #-} module Util where From d0aa202e07ae789b94b6cc1d6118e1f457409794 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:13:02 -0800 Subject: [PATCH 043/123] More extension cleanup --- aeson-typescript.cabal | 2 +- package.yaml | 1 + test/NoOmitNothingFields.hs | 1 - test/ObjectWithSingleFieldNoTagSingleConstructors.hs | 1 - test/ObjectWithSingleFieldTagSingleConstructors.hs | 1 - test/OmitNothingFields.hs | 1 - test/TaggedObjectNoTagSingleConstructors.hs | 1 - test/TaggedObjectTagSingleConstructors.hs | 1 - test/TestBoilerplate.hs | 1 - test/TwoElemArrayNoTagSingleConstructors.hs | 1 - test/TwoElemArrayTagSingleConstructors.hs | 1 - test/UntaggedNoTagSingleConstructors.hs | 1 - test/UntaggedTagSingleConstructors.hs | 1 - test/UnwrapUnaryRecords.hs | 1 - 14 files changed, 2 insertions(+), 13 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 71176a2..2837766 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -111,7 +111,7 @@ test-suite aeson-typescript-tests TemplateHaskell TypeFamilies LambdaCase - ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds + ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds -fno-warn-orphans build-depends: aeson , aeson-typescript diff --git a/package.yaml b/package.yaml index c86a44f..4626235 100644 --- a/package.yaml +++ b/package.yaml @@ -58,6 +58,7 @@ tests: - -with-rtsopts=-N - -haddock - -fno-warn-unused-top-binds + - -fno-warn-orphans default-extensions: - OverloadedStrings - ScopedTypeVariables diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index eb9d993..4f5da71 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module NoOmitNothingFields (allTests) where diff --git a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs index f69464a..c075759 100644 --- a/test/ObjectWithSingleFieldNoTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldNoTagSingleConstructors.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module ObjectWithSingleFieldNoTagSingleConstructors (main, tests) where diff --git a/test/ObjectWithSingleFieldTagSingleConstructors.hs b/test/ObjectWithSingleFieldTagSingleConstructors.hs index 9920e0c..42807f0 100644 --- a/test/ObjectWithSingleFieldTagSingleConstructors.hs +++ b/test/ObjectWithSingleFieldTagSingleConstructors.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module ObjectWithSingleFieldTagSingleConstructors (main, tests) where diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index 1107f70..9993e3b 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module OmitNothingFields (main, tests) where diff --git a/test/TaggedObjectNoTagSingleConstructors.hs b/test/TaggedObjectNoTagSingleConstructors.hs index 6993d5f..91266e5 100644 --- a/test/TaggedObjectNoTagSingleConstructors.hs +++ b/test/TaggedObjectNoTagSingleConstructors.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module TaggedObjectNoTagSingleConstructors (main, tests) where diff --git a/test/TaggedObjectTagSingleConstructors.hs b/test/TaggedObjectTagSingleConstructors.hs index 3a1ee31..b5dba98 100644 --- a/test/TaggedObjectTagSingleConstructors.hs +++ b/test/TaggedObjectTagSingleConstructors.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module TaggedObjectTagSingleConstructors (main, tests) where diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index d8957a4..ac4afd0 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -1,5 +1,4 @@ {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} module TestBoilerplate where diff --git a/test/TwoElemArrayNoTagSingleConstructors.hs b/test/TwoElemArrayNoTagSingleConstructors.hs index 35a2ae5..cc0bd2c 100644 --- a/test/TwoElemArrayNoTagSingleConstructors.hs +++ b/test/TwoElemArrayNoTagSingleConstructors.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module TwoElemArrayNoTagSingleConstructors (main, tests) where diff --git a/test/TwoElemArrayTagSingleConstructors.hs b/test/TwoElemArrayTagSingleConstructors.hs index e21ea3b..7bff5f1 100644 --- a/test/TwoElemArrayTagSingleConstructors.hs +++ b/test/TwoElemArrayTagSingleConstructors.hs @@ -1,4 +1,3 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} module TwoElemArrayTagSingleConstructors (main, tests) where diff --git a/test/UntaggedNoTagSingleConstructors.hs b/test/UntaggedNoTagSingleConstructors.hs index 8e3148d..d4862e6 100644 --- a/test/UntaggedNoTagSingleConstructors.hs +++ b/test/UntaggedNoTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} module UntaggedNoTagSingleConstructors (main, tests) where diff --git a/test/UntaggedTagSingleConstructors.hs b/test/UntaggedTagSingleConstructors.hs index dc049b1..d94b811 100644 --- a/test/UntaggedTagSingleConstructors.hs +++ b/test/UntaggedTagSingleConstructors.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} module UntaggedTagSingleConstructors (main, tests) where diff --git a/test/UnwrapUnaryRecords.hs b/test/UnwrapUnaryRecords.hs index 37f398d..99c702d 100644 --- a/test/UnwrapUnaryRecords.hs +++ b/test/UnwrapUnaryRecords.hs @@ -1,5 +1,4 @@ {-# LANGUAGE CPP #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} module UnwrapUnaryRecords (allTests) where From 91b7205aa0ef931241595ead3a753751bd167fde Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:42:21 -0800 Subject: [PATCH 044/123] Fix getDoc call to use actual name, not transformed one --- src/Data/Aeson/TypeScript/TH.hs | 6 +++--- src/Data/Aeson/TypeScript/Util.hs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index e1495b0..73c764e 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -195,7 +195,7 @@ deriveTypeScript' options name extraOptions = do xs -> zip xs allStarConstructors'' genericVariablesAndSuffixes <- forM varsAndTVars $ \(var, tvar) -> do (_, genericInfos) <- runWriterT $ forM_ (datatypeCons datatypeInfo') $ \ci -> - forM_ (namesAndTypes options [] ci) $ \(_, typ) -> do + forM_ (namesAndTypes options [] ci) $ \(_, _, typ) -> do searchForConstraints extraOptions typ var return (var, (unifyGenericVariable genericInfos, tvar)) @@ -317,14 +317,14 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do $(return members)|] getTSFields :: WriterT [ExtraDeclOrGenericInfo] Q [Exp] - getTSFields = forM (namesAndTypes options genericVariables ci) $ \(nameString, typ) -> do + getTSFields = forM (namesAndTypes options genericVariables ci) $ \(name, nameString, typ) -> do (fieldTyp, optAsBool) <- lift $ case typ of (AppT (ConT name) t) | name == ''Maybe && not (omitNothingFields options) -> ( , ) <$> [|$(getTypeAsStringExp t) <> " | null"|] <*> getOptionalAsBoolExp t _ -> ( , ) <$> getTypeAsStringExp typ <*> getOptionalAsBoolExp typ #if MIN_VERSION_template_haskell(2,18,0) - maybeDoc <- lift $ nothingOnFail $ getDoc (DeclDoc (mkName nameString)) + maybeDoc <- lift $ nothingOnFail $ getDoc (DeclDoc name) #else let maybeDoc = Nothing #endif diff --git a/src/Data/Aeson/TypeScript/Util.hs b/src/Data/Aeson/TypeScript/Util.hs index 7e39892..74b2c29 100644 --- a/src/Data/Aeson/TypeScript/Util.hs +++ b/src/Data/Aeson/TypeScript/Util.hs @@ -148,14 +148,14 @@ mkInstance = InstanceD Nothing mkInstance = InstanceD #endif -namesAndTypes :: Options -> [(Name, (Suffix, Var))] -> ConstructorInfo -> [(String, Type)] +namesAndTypes :: Options -> [(Name, (Suffix, Var))] -> ConstructorInfo -> [(Name, String, Type)] namesAndTypes options genericVariables ci = case constructorVariant ci of - RecordConstructor names -> zip (fmap ((fieldLabelModifier options) . lastNameComponent') names) (constructorFields ci) + RecordConstructor names -> zip3 names (fmap ((fieldLabelModifier options) . lastNameComponent') names) (constructorFields ci) _ -> case sumEncoding options of TaggedObject _ contentsFieldName | isConstructorNullary ci -> [] - | otherwise -> [(contentsFieldName, contentsTupleTypeSubstituted genericVariables ci)] - _ -> [(constructorNameToUse options ci, contentsTupleTypeSubstituted genericVariables ci)] + | otherwise -> [(mkName "", contentsFieldName, contentsTupleTypeSubstituted genericVariables ci)] + _ -> [(constructorName ci, constructorNameToUse options ci, contentsTupleTypeSubstituted genericVariables ci)] constructorNameToUse :: Options -> ConstructorInfo -> String constructorNameToUse options ci = (constructorTagModifier options) $ lastNameComponent' (constructorName ci) From 40b5750af8495f9548ad2f538d786f39ead9590c Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:42:47 -0800 Subject: [PATCH 045/123] Add docstring example to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d7c2fa3..4cdf469 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ data D a = Nullary | Product String Char a | Record { testOne :: Double , testTwo :: Bool + -- | This docstring will go into the generated TypeScript! , testThree :: D a } deriving Eq ``` @@ -41,6 +42,7 @@ interface IRecord { tag: "record"; One: number; Two: boolean; + // This docstring will go into the generated TypeScript! Three: D; } ``` From 02da0c6ddc2e20be0a424c2b0322e7327c08e194 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:42:58 -0800 Subject: [PATCH 046/123] Improve docstring formatting --- src/Data/Aeson/TypeScript/Formatting.hs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index f956b3b..eec3e7d 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -3,6 +3,7 @@ module Data.Aeson.TypeScript.Formatting where import Data.Aeson.TypeScript.Types +import qualified Data.List as L import Data.String.Interpolate import qualified Data.Text as T @@ -33,14 +34,14 @@ formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceNa [i|#{exportPrefix exportMode}interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { #{ls} }|] where - ls = T.intercalate "\n" $ fmap T.pack [indentTo numIndentSpaces (formatTSField member <> ";") | member <- members] + ls = T.intercalate "\n" $ [indentTo numIndentSpaces (T.pack (formatTSField member <> ";")) | member <- members] modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName formatTSDeclaration _ (TSRawDeclaration text) = text --- | TODO: handle multiple lines -indentTo :: Int -> String -> String -indentTo numIndentSpaces s = replicate numIndentSpaces ' ' <> s +indentTo :: Int -> T.Text -> T.Text +indentTo numIndentSpaces input = T.intercalate "\n" [padding <> line | line <- T.splitOn "\n" input] + where padding = T.replicate numIndentSpaces " " exportPrefix :: ExportMode -> String exportPrefix ExportEach = "export " @@ -69,7 +70,10 @@ formatTSField (TSField optional name typ maybeDoc) = docPrefix <> [i|#{name}#{if where docPrefix = case maybeDoc of Nothing -> "" - Just doc -> "/* " <> doc <> " */\n" + Just doc | '\n' `L.elem` doc -> "/* " <> (deleteLeadingWhitespace doc) <> " */\n" + Just doc -> "// " <> (deleteLeadingWhitespace doc) <> "\n" + + deleteLeadingWhitespace = L.dropWhile (== ' ') getGenericBrackets :: [String] -> String getGenericBrackets [] = "" From 32f5672dac4da8fd16b9e258454c3671b93ca628 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 28 Feb 2023 22:44:37 -0800 Subject: [PATCH 047/123] Don't try to run GetDoc tests when not supported --- test/Spec.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/Spec.hs b/test/Spec.hs index 3424fef..d7f7548 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} module Main where @@ -30,7 +31,9 @@ main = hspec $ parallel $ do ClosedTypeFamilies.tests Formatting.tests Generic.tests +#if MIN_VERSION_template_haskell(2,18,0) GetDoc.tests +#endif HigherKind.tests LegalNameSpec.tests From 431d8543ae997f155ee0a01768be4f78b605d5be Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 00:27:38 -0800 Subject: [PATCH 048/123] Get docs on interface names --- src/Data/Aeson/TypeScript/Formatting.hs | 12 +++++++++--- src/Data/Aeson/TypeScript/Instances.hs | 4 ++-- src/Data/Aeson/TypeScript/TH.hs | 23 +++++++++++++++-------- src/Data/Aeson/TypeScript/Types.hs | 3 ++- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index eec3e7d..2869f2c 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -30,10 +30,15 @@ formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVar enumType = [i|\n\ntype #{name} = keyof typeof #{typeNameModifier name};|] :: T.Text toEnumName = T.replace "\"" "" -formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables members) = - [i|#{exportPrefix exportMode}interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { +formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables members maybeDoc) = + docPrefix <> [i|#{exportPrefix exportMode}interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { #{ls} }|] where + docPrefix = case maybeDoc of + Nothing -> "" + Just doc | '\n' `L.elem` doc -> "/* " <> (deleteLeadingWhitespace doc) <> " */\n" + Just doc -> "// " <> (deleteLeadingWhitespace doc) <> "\n" + ls = T.intercalate "\n" $ [indentTo numIndentSpaces (T.pack (formatTSField member <> ";")) | member <- members] modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName @@ -73,7 +78,8 @@ formatTSField (TSField optional name typ maybeDoc) = docPrefix <> [i|#{name}#{if Just doc | '\n' `L.elem` doc -> "/* " <> (deleteLeadingWhitespace doc) <> " */\n" Just doc -> "// " <> (deleteLeadingWhitespace doc) <> "\n" - deleteLeadingWhitespace = L.dropWhile (== ' ') +deleteLeadingWhitespace :: String -> String +deleteLeadingWhitespace = L.dropWhile (== ' ') getGenericBrackets :: [String] -> String getGenericBrackets [] = "" diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index ee566be..6d50c5b 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -90,8 +90,8 @@ instance {-# OVERLAPPING #-} TypeScript [Char] where instance (TypeScript a, TypeScript b) => TypeScript (Either a b) where getTypeScriptType _ = [i|Either<#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}>|] getTypeScriptDeclarations _ = [TSTypeAlternatives "Either" ["T1", "T2"] ["Left", "Right"] - , TSInterfaceDeclaration "Left" ["T"] [TSField False "Left" "T" Nothing] - , TSInterfaceDeclaration "Right" ["T"] [TSField False "Right" "T" Nothing] + , TSInterfaceDeclaration "Left" ["T"] [TSField False "Left" "T" Nothing] Nothing + , TSInterfaceDeclaration "Right" ["T"] [TSField False "Right" "T" Nothing] Nothing ] getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) , (TSType (Proxy :: Proxy b)) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 73c764e..773e634 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -314,7 +314,20 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do assembleInterfaceDeclaration members = [|TSInterfaceDeclaration $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) - $(return members)|] + $(return members) + $(tryGetDoc (constructorName ci))|] + + tryGetDoc :: Name -> Q Exp + tryGetDoc n = do +#if MIN_VERSION_template_haskell(2,18,0) + maybeDoc <- nothingOnFail $ getDoc (DeclDoc n) +#else + let maybeDoc = Nothing +#endif + + case maybeDoc of + Just (Just doc) -> [|Just $(TH.stringE doc)|] + _ -> [|Nothing|] getTSFields :: WriterT [ExtraDeclOrGenericInfo] Q [Exp] getTSFields = forM (namesAndTypes options genericVariables ci) $ \(name, nameString, typ) -> do @@ -323,13 +336,7 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do ( , ) <$> [|$(getTypeAsStringExp t) <> " | null"|] <*> getOptionalAsBoolExp t _ -> ( , ) <$> getTypeAsStringExp typ <*> getOptionalAsBoolExp typ -#if MIN_VERSION_template_haskell(2,18,0) - maybeDoc <- lift $ nothingOnFail $ getDoc (DeclDoc name) -#else - let maybeDoc = Nothing -#endif - - lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) $(case maybeDoc of Just (Just doc) -> [|Just $(TH.stringE doc)|]; _ -> [|Nothing|]) |] + lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) $(tryGetDoc name) |] isSingleRecordConstructor (constructorVariant -> RecordConstructor [_]) = True isSingleRecordConstructor _ = False diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index c42af91..ec23d1c 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -86,7 +86,8 @@ instance Show TSType where data TSDeclaration = TSInterfaceDeclaration { interfaceName :: String , interfaceGenericVariables :: [String] - , interfaceMembers :: [TSField] } + , interfaceMembers :: [TSField] + , interfaceDoc :: Maybe String } | TSTypeAlternatives { typeName :: String , typeGenericVariables :: [String] , alternativeTypes :: [String]} From 856370007867e013d2499c5a6570ffa917f47a9c Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 00:37:08 -0800 Subject: [PATCH 049/123] Update tests to use docs on interface names --- src/Data/Aeson/TypeScript/Lookup.hs | 2 +- test/ClosedTypeFamilies.hs | 8 ++++---- test/Generic.hs | 16 +++++----------- test/HigherKind.hs | 6 +++--- test/NoOmitNothingFields.hs | 1 + test/OmitNothingFields.hs | 1 + test/OpenTypeFamilies.hs | 8 ++++---- 7 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Lookup.hs b/src/Data/Aeson/TypeScript/Lookup.hs index 8c245c8..ef0e9a8 100644 --- a/src/Data/Aeson/TypeScript/Lookup.hs +++ b/src/Data/Aeson/TypeScript/Lookup.hs @@ -55,7 +55,7 @@ getClosedTypeFamilyInterfaceDecl name eqns = do #endif x -> fail [i|aeson-typescript doesn't know yet how to handle this type family equation: '#{x}'|] - [| TSInterfaceDeclaration $(TH.stringE $ nameBase name) [] (L.sortBy (compare `on` fieldName) $(listE $ fmap return fields)) |] + [| TSInterfaceDeclaration $(TH.stringE $ nameBase name) [] (L.sortBy (compare `on` fieldName) $(listE $ fmap return fields)) Nothing |] getClosedTypeFamilyImage :: [TySynEqn] -> Q [Type] getClosedTypeFamilyImage eqns = do diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index d8381db..606a0cf 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -43,7 +43,7 @@ tests = describe "Closed type families" $ do TSField False "\"k8s_env\"" "\"k8s\"" Nothing , TSField False "\"single_node_env\"" "\"single\"" Nothing , TSField False "T" "void" Nothing - ] + ] Nothing , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] ]) @@ -56,7 +56,7 @@ tests = describe "Closed type families" $ do TSField False "_userUsername" "string" Nothing , TSField False "_userCreatedAt" "number" Nothing , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing - ] + ] Nothing ]) it [i|get the declarations recursively|] $ do @@ -65,12 +65,12 @@ tests = describe "Closed type families" $ do TSField False "\"k8s_env\"" "\"k8s\"" Nothing , TSField False "\"single_node_env\"" "\"single\"" Nothing , TSField False "T" "void" Nothing - ] + ] Nothing , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ TSField False "_userUsername" "string" Nothing , TSField False "_userCreatedAt" "number" Nothing , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing - ] + ] Nothing , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] ]) diff --git a/test/Generic.hs b/test/Generic.hs index 889ac8d..fa36a3e 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -29,8 +29,8 @@ tests :: SpecWith () tests = describe "Generic instances" $ do it [i|Complex makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex String))) `shouldBe` [ - TSInterfaceDeclaration {interfaceName = "IProduct", interfaceGenericVariables = ["T"], interfaceMembers = [TSField False "tag" "\"Product\"" Nothing, TSField False "contents" "[number, T]" Nothing]} - ,TSInterfaceDeclaration {interfaceName = "IUnary", interfaceGenericVariables = ["T"], interfaceMembers = [TSField False "tag" "\"Unary\"" Nothing, TSField False "contents" "number" Nothing]} + TSInterfaceDeclaration "IProduct" ["T"] [TSField False "tag" "\"Product\"" Nothing, TSField False "contents" "[number, T]" Nothing] Nothing + ,TSInterfaceDeclaration "IUnary" ["T"] [TSField False "tag" "\"Unary\"" Nothing, TSField False "contents" "number" Nothing] Nothing ,TSTypeAlternatives {typeName = "Complex", typeGenericVariables = ["T"], alternativeTypes = ["IProduct","IUnary"]} ] @@ -42,24 +42,18 @@ tests = describe "Generic instances" $ do it [i|Complex3 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex3 String))) `shouldBe` [ - TSInterfaceDeclaration {interfaceName = "IProduct3", interfaceGenericVariables = ["T"], interfaceMembers = [ - TSField False "record3" "T[]" Nothing - ]} + TSInterfaceDeclaration "IProduct3" ["T"] [TSField False "record3" "T[]" Nothing] Nothing ,TSTypeAlternatives {typeName = "Complex3", typeGenericVariables = ["T"], alternativeTypes = ["IProduct3"]} ] (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex3 Int))) `shouldBe` [ - TSInterfaceDeclaration {interfaceName = "IProduct3", interfaceGenericVariables = ["T"], interfaceMembers = [ - TSField False "record3" "T[]" Nothing - ]} + TSInterfaceDeclaration "IProduct3" ["T"] [TSField False "record3" "T[]" Nothing] Nothing ,TSTypeAlternatives {typeName = "Complex3", typeGenericVariables = ["T"], alternativeTypes = ["IProduct3"]} ] it [i|Complex4 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex4 String))) `shouldBe` [ - TSInterfaceDeclaration {interfaceName = "IProduct4", interfaceGenericVariables = ["T"], interfaceMembers = [ - TSField False "record4" "{[k in string]?: T}" Nothing - ]} + TSInterfaceDeclaration "IProduct4" ["T"] [TSField False "record4" "{[k in string]?: T}" Nothing] Nothing ,TSTypeAlternatives {typeName = "Complex4", typeGenericVariables = ["T"], alternativeTypes = ["IProduct4"]} ] diff --git a/test/HigherKind.hs b/test/HigherKind.hs index b272ecc..00aeac5 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -37,7 +37,7 @@ tests = describe "Higher kinds" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (HigherKind T))) `shouldBe` ([ TSTypeAlternatives "HigherKind" ["T"] ["IHigherKind"], - TSInterfaceDeclaration "IHigherKind" ["T"] [TSField False "higherKindList" "T[]" Nothing] + TSInterfaceDeclaration "IHigherKind" ["T"] [TSField False "higherKindList" "T[]" Nothing] Nothing ]) (getTypeScriptType (Proxy :: Proxy (HigherKind Int))) `shouldBe` "HigherKind" @@ -47,7 +47,7 @@ tests = describe "Higher kinds" $ do (getTypeScriptDeclarations (Proxy :: Proxy Foo)) `shouldBe` ([ TSTypeAlternatives "Foo" [] ["IFoo"], TSInterfaceDeclaration "IFoo" [] [TSField False "fooString" "string" Nothing - , TSField False "fooHigherKindReference" "HigherKind" Nothing] + , TSField False "fooHigherKindReference" "HigherKind" Nothing] Nothing ]) it [i|works with an interface inside|] $ do @@ -61,7 +61,7 @@ tests = describe "Higher kinds" $ do (getTypeScriptDeclarations (Proxy :: Proxy (DoubleHigherKind T1 T2))) `shouldBe` ([ TSTypeAlternatives "DoubleHigherKind" ["T1","T2"] ["IDoubleHigherKind"], TSInterfaceDeclaration "IDoubleHigherKind" ["T1","T2"] [TSField False "someList" "T2[]" Nothing - , TSField False "higherKindThing" "HigherKind" Nothing] + , TSField False "higherKindThing" "HigherKind" Nothing] Nothing ]) (getTypeScriptType (Proxy :: Proxy (DoubleHigherKind Int String))) `shouldBe` "DoubleHigherKind" diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index 4f5da71..36c5d39 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -24,6 +24,7 @@ allTests = describe "NoOmitNothingFields" $ do interfaceName = "IOptional" , interfaceGenericVariables = [] , interfaceMembers = [TSField False "optionalInt" "number | null" Nothing] + , interfaceDoc = Nothing }] tests diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index 9993e3b..360f2a1 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -21,6 +21,7 @@ main = hspec $ describe "OmitNothingFields" $ do , interfaceMembers = [ TSField True "optionalInt" "number" Nothing ] + , interfaceDoc = Nothing }] tests diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index f668757..1b1aeaa 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -43,7 +43,7 @@ tests = describe "Open type families" $ do TSField False "\"single_node_env\"" "\"single\"" Nothing , TSField False "\"k8s_env\"" "\"k8s\"" Nothing , TSField False "T" "void" Nothing - ] + ] Nothing , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] ]) @@ -56,7 +56,7 @@ tests = describe "Open type families" $ do TSField False "_userUsername" "string" Nothing , TSField False "_userCreatedAt" "number" Nothing , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing - ] + ] Nothing ]) it [i|get the declarations recursively|] $ do @@ -65,12 +65,12 @@ tests = describe "Open type families" $ do TSField False "\"single_node_env\"" "\"single\"" Nothing , TSField False "\"k8s_env\"" "\"k8s\"" Nothing , TSField False "T" "void" Nothing - ] + ] Nothing , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ TSField False "_userUsername" "string" Nothing , TSField False "_userCreatedAt" "number" Nothing , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing - ] + ] Nothing , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] ]) From 01ec42f268ff0c2e4a48fb55cac5e78324777aed Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 00:37:16 -0800 Subject: [PATCH 050/123] Fix warning in test/Util.hs --- test/Util.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Util.hs b/test/Util.hs index 180f657..88a088d 100644 --- a/test/Util.hs +++ b/test/Util.hs @@ -14,7 +14,8 @@ import System.Environment import System.Exit import System.FilePath import System.IO.Temp -import System.Process +import System.Process hiding (cwd) + npmInstallScript, yarnInstallScript, localTSC :: String npmInstallScript = "test/assets/npm_install.sh" From 8cba46725d7761ef7b061652b57290bf5b6317f7 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 00:47:23 -0800 Subject: [PATCH 051/123] Add haddockModifier to ExtraTypeScriptOptions --- src/Data/Aeson/TypeScript/Formatting.hs | 21 +++++++-------------- src/Data/Aeson/TypeScript/TH.hs | 10 ++++++---- src/Data/Aeson/TypeScript/Types.hs | 11 ++++++++++- test/GetDoc.hs | 16 +++++++++------- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index 2869f2c..7990790 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -31,14 +31,9 @@ formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVar toEnumName = T.replace "\"" "" formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables members maybeDoc) = - docPrefix <> [i|#{exportPrefix exportMode}interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { + makeDocPrefix maybeDoc <> [i|#{exportPrefix exportMode}interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { #{ls} }|] where - docPrefix = case maybeDoc of - Nothing -> "" - Just doc | '\n' `L.elem` doc -> "/* " <> (deleteLeadingWhitespace doc) <> " */\n" - Just doc -> "// " <> (deleteLeadingWhitespace doc) <> "\n" - ls = T.intercalate "\n" $ [indentTo numIndentSpaces (T.pack (formatTSField member <> ";")) | member <- members] modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName @@ -71,15 +66,13 @@ validateFormattingOptions options@FormattingOptions{..} decls isPlainSumType ds = (not . any isInterface $ ds) && length ds == 1 formatTSField :: TSField -> String -formatTSField (TSField optional name typ maybeDoc) = docPrefix <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] - where - docPrefix = case maybeDoc of - Nothing -> "" - Just doc | '\n' `L.elem` doc -> "/* " <> (deleteLeadingWhitespace doc) <> " */\n" - Just doc -> "// " <> (deleteLeadingWhitespace doc) <> "\n" +formatTSField (TSField optional name typ maybeDoc) = makeDocPrefix maybeDoc <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] -deleteLeadingWhitespace :: String -> String -deleteLeadingWhitespace = L.dropWhile (== ' ') +makeDocPrefix :: Maybe String -> String +makeDocPrefix maybeDoc = case maybeDoc of + Nothing -> "" + Just doc | '\n' `L.elem` doc -> "/* " <> doc <> " */\n" + Just doc -> "// " <> doc <> "\n" getGenericBrackets :: [String] -> String getGenericBrackets [] = "" diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 773e634..0207026 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -217,7 +217,7 @@ deriveTypeScript' options name extraOptions = do let typeVariablePreds :: [Pred] = [AppT (ConT ''TypeScript) x | x <- getDataTypeVars dti] -- Build the declarations - (types, (extraDeclsOrGenericInfosInitial <>) -> extraDeclsOrGenericInfos) <- runWriterT $ mapM (handleConstructor options dti genericVariablesAndSuffixes) (datatypeCons dti) + (types, (extraDeclsOrGenericInfosInitial <>) -> extraDeclsOrGenericInfos) <- runWriterT $ mapM (handleConstructor extraOptions options dti genericVariablesAndSuffixes) (datatypeCons dti) typeDeclaration <- [|TSTypeAlternatives $(TH.stringE $ getTypeName (datatypeName dti)) $(genericVariablesListExpr True genericVariablesAndSuffixes) $(listE $ fmap return types)|] @@ -244,8 +244,8 @@ deriveTypeScript' options name extraOptions = do return (mconcat [x | ExtraTopLevelDecs x <- extraDeclsOrGenericInfos] <> inst) -- | Return a string to go in the top-level type declaration, plus an optional expression containing a declaration -handleConstructor :: Options -> DatatypeInfo -> [(Name, (Suffix, Var))] -> ConstructorInfo -> WriterT [ExtraDeclOrGenericInfo] Q Exp -handleConstructor options (DatatypeInfo {..}) genericVariables ci = do +handleConstructor :: ExtraTypeScriptOptions -> Options -> DatatypeInfo -> [(Name, (Suffix, Var))] -> ConstructorInfo -> WriterT [ExtraDeclOrGenericInfo] Q Exp +handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) genericVariables ci = do if | (length datatypeCons == 1) && not (getTagSingleConstructors options) -> do writeSingleConstructorEncoding brackets <- lift $ getBracketsExpression False genericVariables @@ -320,7 +320,9 @@ handleConstructor options (DatatypeInfo {..}) genericVariables ci = do tryGetDoc :: Name -> Q Exp tryGetDoc n = do #if MIN_VERSION_template_haskell(2,18,0) - maybeDoc <- nothingOnFail $ getDoc (DeclDoc n) + maybeDoc <- nothingOnFail (getDoc (DeclDoc n)) >>= \case + Just (Just doc) -> return $ Just $ Just $ haddockModifier doc + x -> return x #else let maybeDoc = Nothing #endif diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index ec23d1c..4b98999 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -11,6 +11,7 @@ module Data.Aeson.TypeScript.Types where import qualified Data.Aeson as A import Data.Aeson.TypeScript.LegalName +import qualified Data.List as L import qualified Data.List.NonEmpty as NonEmpty import Data.Proxy import Data.String @@ -203,11 +204,19 @@ allStarConstructors'' = ["T1", "T2", "T3", "T4", "T5", "T6", "T7", "T8", "T9", " data ExtraTypeScriptOptions = ExtraTypeScriptOptions { typeFamiliesToMapToTypeScript :: [Name] + , keyType :: Maybe String + + -- | Function which is applied to all Haddocks we read in. + -- By default, just drops leading whitespace. + , haddockModifier :: String -> String } defaultExtraTypeScriptOptions :: ExtraTypeScriptOptions -defaultExtraTypeScriptOptions = ExtraTypeScriptOptions [] Nothing +defaultExtraTypeScriptOptions = ExtraTypeScriptOptions [] Nothing deleteLeadingWhitespace + where + deleteLeadingWhitespace :: String -> String + deleteLeadingWhitespace = L.dropWhile (== ' ') data ExtraDeclOrGenericInfo = ExtraDecl Exp | ExtraGeneric GenericInfo diff --git a/test/GetDoc.hs b/test/GetDoc.hs index 0f91f82..8ee8f80 100644 --- a/test/GetDoc.hs +++ b/test/GetDoc.hs @@ -10,11 +10,13 @@ import Prelude hiding (Double) import Test.Hspec --- | OneField is a type with a single field -data OneField = OneField { - -- | This is a simple string - simpleString :: String - } +-- | OneField type doc +data OneField = + -- | OneField constructor doc + OneField { + -- | This is a simple string + simpleString :: String + } $(deriveTypeScript A.defaultOptions ''OneField) tests :: SpecWith () @@ -23,8 +25,8 @@ tests = describe "getDoc tests" $ do (getTypeScriptDeclarations (Proxy :: Proxy OneField)) `shouldBe` ([ TSTypeAlternatives "OneField" [] ["IOneField"] , TSInterfaceDeclaration "IOneField" [] [ - TSField False "simpleString" "string" (Just " This is a simple string") - ] + TSField False "simpleString" "string" (Just "This is a simple string") + ] (Just "OneField constructor doc") ]) main :: IO () From 68be59f818391d7b5f1259698b96bdeb819ccd4c Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 00:56:52 -0800 Subject: [PATCH 052/123] Working on TSTypeAlternatives docs and cleaning up extensions --- aeson-typescript.cabal | 10 +++++++ package.yaml | 18 ++++++++--- src/Data/Aeson/TypeScript/Formatting.hs | 12 ++++---- src/Data/Aeson/TypeScript/Instances.hs | 6 +--- src/Data/Aeson/TypeScript/Lookup.hs | 9 ------ src/Data/Aeson/TypeScript/Recursive.hs | 8 ----- src/Data/Aeson/TypeScript/TH.hs | 30 +++---------------- src/Data/Aeson/TypeScript/Transform.hs | 9 ------ src/Data/Aeson/TypeScript/TypeManipulation.hs | 9 ------ src/Data/Aeson/TypeScript/Types.hs | 7 ++--- src/Data/Aeson/TypeScript/Util.hs | 21 ++++++++----- test/Basic.hs | 6 ++-- 12 files changed, 55 insertions(+), 90 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 2837766..93c2d8b 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -48,6 +48,16 @@ library Paths_aeson_typescript hs-source-dirs: src + default-extensions: + LambdaCase + RecordWildCards + NamedFieldPuns + MultiWayIf + TupleSections + QuasiQuotes + OverloadedStrings + ViewPatterns + ScopedTypeVariables build-depends: aeson , base >=4.7 && <5 diff --git a/package.yaml b/package.yaml index 4626235..07a1080 100644 --- a/package.yaml +++ b/package.yaml @@ -39,11 +39,21 @@ dependencies: library: source-dirs: src + default-extensions: + - LambdaCase + - RecordWildCards + - NamedFieldPuns + - MultiWayIf + - TupleSections + - QuasiQuotes + - OverloadedStrings + - ViewPatterns + - ScopedTypeVariables exposed-modules: - - Data.Aeson.TypeScript.TH - - Data.Aeson.TypeScript.Internal - - Data.Aeson.TypeScript.Recursive - - Data.Aeson.TypeScript.LegalName + - Data.Aeson.TypeScript.TH + - Data.Aeson.TypeScript.Internal + - Data.Aeson.TypeScript.Recursive + - Data.Aeson.TypeScript.LegalName tests: aeson-typescript-tests: diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index 7990790..c099c62 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -18,12 +18,14 @@ 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) = - case typeAlternativesFormat of - Enum -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnum} }|] - EnumWithType -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnumWithType} }#{enumType}|] - TypeAlias -> [i|#{exportPrefix exportMode}type #{typeNameModifier name}#{getGenericBrackets genericVariables} = #{alternatives};|] +formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVariables names maybeDoc) = + makeDocPrefix maybeDoc <> mainDeclaration where + mainDeclaration = case typeAlternativesFormat of + Enum -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnum} }|] + EnumWithType -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnumWithType} }#{enumType}|] + TypeAlias -> [i|#{exportPrefix exportMode}type #{typeNameModifier name}#{getGenericBrackets genericVariables} = #{alternatives};|] + 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] diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 6d50c5b..3833dcc 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -1,8 +1,4 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverlappingInstances #-} @@ -89,7 +85,7 @@ instance {-# OVERLAPPING #-} TypeScript [Char] where instance (TypeScript a, TypeScript b) => TypeScript (Either a b) where getTypeScriptType _ = [i|Either<#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}>|] - getTypeScriptDeclarations _ = [TSTypeAlternatives "Either" ["T1", "T2"] ["Left", "Right"] + getTypeScriptDeclarations _ = [TSTypeAlternatives "Either" ["T1", "T2"] ["Left", "Right"] Nothing , TSInterfaceDeclaration "Left" ["T"] [TSField False "Left" "T" Nothing] Nothing , TSInterfaceDeclaration "Right" ["T"] [TSField False "Right" "T" Nothing] Nothing ] diff --git a/src/Data/Aeson/TypeScript/Lookup.hs b/src/Data/Aeson/TypeScript/Lookup.hs index ef0e9a8..82544fe 100644 --- a/src/Data/Aeson/TypeScript/Lookup.hs +++ b/src/Data/Aeson/TypeScript/Lookup.hs @@ -1,17 +1,8 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE MultiWayIf #-} -{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE LambdaCase #-} module Data.Aeson.TypeScript.Lookup where diff --git a/src/Data/Aeson/TypeScript/Recursive.hs b/src/Data/Aeson/TypeScript/Recursive.hs index e525bf6..b0c7c12 100755 --- a/src/Data/Aeson/TypeScript/Recursive.hs +++ b/src/Data/Aeson/TypeScript/Recursive.hs @@ -1,14 +1,6 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE MultiWayIf #-} -{-# LANGUAGE ViewPatterns #-} -{-# LANGUAGE LambdaCase #-} {-# LANGUAGE PolyKinds #-} module Data.Aeson.TypeScript.Recursive ( diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 0207026..c52c511 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -1,17 +1,8 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE MultiWayIf #-} -{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE LambdaCase #-} {-| Module: Data.Aeson.TypeScript.TH @@ -220,7 +211,8 @@ deriveTypeScript' options name extraOptions = do (types, (extraDeclsOrGenericInfosInitial <>) -> extraDeclsOrGenericInfos) <- runWriterT $ mapM (handleConstructor extraOptions options dti genericVariablesAndSuffixes) (datatypeCons dti) typeDeclaration <- [|TSTypeAlternatives $(TH.stringE $ getTypeName (datatypeName dti)) $(genericVariablesListExpr True genericVariablesAndSuffixes) - $(listE $ fmap return types)|] + $(listE $ fmap return types) + $(tryGetDoc (haddockModifier extraOptions) (datatypeName dti))|] declarationsFunctionBody <- [| $(return typeDeclaration) : $(listE (fmap return [x | ExtraDecl x <- extraDeclsOrGenericInfos])) |] @@ -315,21 +307,7 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene assembleInterfaceDeclaration members = [|TSInterfaceDeclaration $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) $(return members) - $(tryGetDoc (constructorName ci))|] - - tryGetDoc :: Name -> Q Exp - tryGetDoc n = do -#if MIN_VERSION_template_haskell(2,18,0) - maybeDoc <- nothingOnFail (getDoc (DeclDoc n)) >>= \case - Just (Just doc) -> return $ Just $ Just $ haddockModifier doc - x -> return x -#else - let maybeDoc = Nothing -#endif - - case maybeDoc of - Just (Just doc) -> [|Just $(TH.stringE doc)|] - _ -> [|Nothing|] + $(tryGetDoc haddockModifier (constructorName ci))|] getTSFields :: WriterT [ExtraDeclOrGenericInfo] Q [Exp] getTSFields = forM (namesAndTypes options genericVariables ci) $ \(name, nameString, typ) -> do @@ -338,7 +316,7 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene ( , ) <$> [|$(getTypeAsStringExp t) <> " | null"|] <*> getOptionalAsBoolExp t _ -> ( , ) <$> getTypeAsStringExp typ <*> getOptionalAsBoolExp typ - lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) $(tryGetDoc name) |] + lift [| TSField $(return optAsBool) $(TH.stringE nameString) $(return fieldTyp) $(tryGetDoc haddockModifier name) |] isSingleRecordConstructor (constructorVariant -> RecordConstructor [_]) = True isSingleRecordConstructor _ = False diff --git a/src/Data/Aeson/TypeScript/Transform.hs b/src/Data/Aeson/TypeScript/Transform.hs index 259267a..f5494e1 100644 --- a/src/Data/Aeson/TypeScript/Transform.hs +++ b/src/Data/Aeson/TypeScript/Transform.hs @@ -1,17 +1,8 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE MultiWayIf #-} -{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE LambdaCase #-} module Data.Aeson.TypeScript.Transform ( diff --git a/src/Data/Aeson/TypeScript/TypeManipulation.hs b/src/Data/Aeson/TypeScript/TypeManipulation.hs index dc36c11..9462d49 100644 --- a/src/Data/Aeson/TypeScript/TypeManipulation.hs +++ b/src/Data/Aeson/TypeScript/TypeManipulation.hs @@ -1,17 +1,8 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE MultiWayIf #-} -{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE LambdaCase #-} module Data.Aeson.TypeScript.TypeManipulation ( searchForConstraints diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index 4b98999..58f5317 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -1,8 +1,4 @@ -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneDeriving #-} @@ -91,7 +87,8 @@ data TSDeclaration = TSInterfaceDeclaration { interfaceName :: String , interfaceDoc :: Maybe String } | TSTypeAlternatives { typeName :: String , typeGenericVariables :: [String] - , alternativeTypes :: [String]} + , alternativeTypes :: [String] + , typeDoc :: Maybe String } | TSRawDeclaration { text :: String } deriving (Show, Eq, Ord) diff --git a/src/Data/Aeson/TypeScript/Util.hs b/src/Data/Aeson/TypeScript/Util.hs index 74b2c29..cedf0bf 100644 --- a/src/Data/Aeson/TypeScript/Util.hs +++ b/src/Data/Aeson/TypeScript/Util.hs @@ -1,14 +1,7 @@ {-# LANGUAGE CPP #-} -{-# LANGUAGE QuasiQuotes #-} -{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE MultiWayIf #-} -{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE PolyKinds #-} module Data.Aeson.TypeScript.Util where @@ -227,3 +220,17 @@ isStarType _ = Nothing nothingOnFail :: Q a -> Q (Maybe a) nothingOnFail action = recover (return Nothing) (Just <$> action) + +tryGetDoc :: (String -> String) -> Name -> Q Exp +tryGetDoc haddockModifier n = do +#if MIN_VERSION_template_haskell(2,18,0) + maybeDoc <- nothingOnFail (getDoc (DeclDoc n)) >>= \case + Just (Just doc) -> return $ Just $ Just $ haddockModifier doc + x -> return x +#else + let maybeDoc = Nothing +#endif + + case maybeDoc of + Just (Just doc) -> [|Just $(TH.stringE doc)|] + _ -> [|Nothing|] diff --git a/test/Basic.hs b/test/Basic.hs index eec08ea..18c226d 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -22,13 +22,13 @@ tests = describe "Basic tests" $ do describe "tagSingleConstructors and constructorTagModifier" $ do it [i|Works with a normal unit|] $ do (getTypeScriptDeclarations (Proxy :: Proxy Unit1)) `shouldBe` ([ - TSTypeAlternatives "Unit1" [] ["IUnit1"] - , TSTypeAlternatives "IUnit1" [] ["void[]"] + TSTypeAlternatives "Unit1" [] ["IUnit1"] Nothing + , TSTypeAlternatives "IUnit1" [] ["void[]"] Nothing ]) it [i|Works with a unit with constructorTagModifier|] $ do (getTypeScriptDeclarations (Proxy :: Proxy Unit2)) `shouldBe` ([ - TSTypeAlternatives "Unit2" [] ["\"foo\""] + TSTypeAlternatives "Unit2" [] ["\"foo\""] Nothing ]) From e75d17a220bc4e0fa54f6e00dbf9b9a0377d85fd Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 01:10:37 -0800 Subject: [PATCH 053/123] Consolidate extensions and update TSTypeAlternatives in tests --- aeson-typescript.cabal | 21 +++++++++++++-------- package.yaml | 27 ++++++++++++--------------- src/Data/Aeson/TypeScript/TH.hs | 6 ++++-- test/ClosedTypeFamilies.hs | 8 ++++---- test/Generic.hs | 12 ++++++------ test/GetDoc.hs | 2 +- test/HigherKind.hs | 10 +++++----- test/NoOmitNothingFields.hs | 13 ++----------- test/OpenTypeFamilies.hs | 8 ++++---- test/UnwrapUnaryRecords.hs | 4 ++-- 10 files changed, 53 insertions(+), 58 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 93c2d8b..645ac1a 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -50,14 +50,14 @@ library src default-extensions: LambdaCase - RecordWildCards - NamedFieldPuns MultiWayIf - TupleSections - QuasiQuotes + NamedFieldPuns OverloadedStrings - ViewPatterns + QuasiQuotes + RecordWildCards ScopedTypeVariables + TupleSections + ViewPatterns build-depends: aeson , base >=4.7 && <5 @@ -113,14 +113,19 @@ test-suite aeson-typescript-tests test src default-extensions: + LambdaCase + MultiWayIf + NamedFieldPuns OverloadedStrings + QuasiQuotes + RecordWildCards ScopedTypeVariables - KindSignatures + TupleSections + ViewPatterns FlexibleContexts - QuasiQuotes + KindSignatures TemplateHaskell TypeFamilies - LambdaCase ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -haddock -fno-warn-unused-top-binds -fno-warn-orphans build-depends: aeson diff --git a/package.yaml b/package.yaml index 07a1080..c8e44f4 100644 --- a/package.yaml +++ b/package.yaml @@ -37,18 +37,19 @@ dependencies: - transformers - unordered-containers +default-extensions: +- LambdaCase +- MultiWayIf +- NamedFieldPuns +- OverloadedStrings +- QuasiQuotes +- RecordWildCards +- ScopedTypeVariables +- TupleSections +- ViewPatterns + library: source-dirs: src - default-extensions: - - LambdaCase - - RecordWildCards - - NamedFieldPuns - - MultiWayIf - - TupleSections - - QuasiQuotes - - OverloadedStrings - - ViewPatterns - - ScopedTypeVariables exposed-modules: - Data.Aeson.TypeScript.TH - Data.Aeson.TypeScript.Internal @@ -70,14 +71,10 @@ tests: - -fno-warn-unused-top-binds - -fno-warn-orphans default-extensions: - - OverloadedStrings - - ScopedTypeVariables - - KindSignatures - FlexibleContexts - - QuasiQuotes + - KindSignatures - TemplateHaskell - TypeFamilies - - LambdaCase dependencies: - aeson-typescript - bytestring diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index c52c511..7cd0e49 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -287,7 +287,8 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene _ -> getTypeAsStringExp typ alternatives <- lift [|TSTypeAlternatives $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) - [$(return stringExp)]|] + [$(return stringExp)] + $(tryGetDoc haddockModifier (constructorName ci))|] tell [ExtraDecl alternatives] #endif @@ -302,7 +303,8 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene tupleEncoding = lift [|TSTypeAlternatives $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) - [getTypeScriptType (Proxy :: Proxy $(return (contentsTupleTypeSubstituted genericVariables ci)))]|] + [getTypeScriptType (Proxy :: Proxy $(return (contentsTupleTypeSubstituted genericVariables ci)))] + $(tryGetDoc haddockModifier (constructorName ci))|] assembleInterfaceDeclaration members = [|TSInterfaceDeclaration $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) diff --git a/test/ClosedTypeFamilies.hs b/test/ClosedTypeFamilies.hs index 606a0cf..0e75647 100644 --- a/test/ClosedTypeFamilies.hs +++ b/test/ClosedTypeFamilies.hs @@ -44,14 +44,14 @@ tests = describe "Closed type families" $ do , TSField False "\"single_node_env\"" "\"single\"" Nothing , TSField False "T" "void" Nothing ] Nothing - , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] - , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] + , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] Nothing + , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] Nothing ]) describe "Complicated Beam-like user type" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (UserT T Identity))) `shouldBe` ([ - TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] + TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] Nothing , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ TSField False "_userUsername" "string" Nothing , TSField False "_userCreatedAt" "number" Nothing @@ -71,7 +71,7 @@ tests = describe "Closed type families" $ do , TSField False "_userCreatedAt" "number" Nothing , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing ] Nothing - , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] + , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] Nothing ]) main :: IO () diff --git a/test/Generic.hs b/test/Generic.hs index fa36a3e..68f92fb 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -31,30 +31,30 @@ tests = describe "Generic instances" $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex String))) `shouldBe` [ TSInterfaceDeclaration "IProduct" ["T"] [TSField False "tag" "\"Product\"" Nothing, TSField False "contents" "[number, T]" Nothing] Nothing ,TSInterfaceDeclaration "IUnary" ["T"] [TSField False "tag" "\"Unary\"" Nothing, TSField False "contents" "number" Nothing] Nothing - ,TSTypeAlternatives {typeName = "Complex", typeGenericVariables = ["T"], alternativeTypes = ["IProduct","IUnary"]} + ,TSTypeAlternatives "Complex" ["T"] ["IProduct","IUnary"] Nothing ] it [i|Complex2 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex2 String))) `shouldBe` [ - TSTypeAlternatives {typeName = "Complex2", typeGenericVariables = ["T"], alternativeTypes = ["IProduct2"]} - ,TSTypeAlternatives {typeName = "IProduct2", typeGenericVariables = ["T"], alternativeTypes = ["[number, T]"]} + TSTypeAlternatives "Complex2" ["T"] ["IProduct2"] Nothing + ,TSTypeAlternatives "IProduct2" ["T"] ["[number, T]"] Nothing ] it [i|Complex3 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex3 String))) `shouldBe` [ TSInterfaceDeclaration "IProduct3" ["T"] [TSField False "record3" "T[]" Nothing] Nothing - ,TSTypeAlternatives {typeName = "Complex3", typeGenericVariables = ["T"], alternativeTypes = ["IProduct3"]} + ,TSTypeAlternatives "Complex3" ["T"] ["IProduct3"] Nothing ] (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex3 Int))) `shouldBe` [ TSInterfaceDeclaration "IProduct3" ["T"] [TSField False "record3" "T[]" Nothing] Nothing - ,TSTypeAlternatives {typeName = "Complex3", typeGenericVariables = ["T"], alternativeTypes = ["IProduct3"]} + ,TSTypeAlternatives "Complex3" ["T"] ["IProduct3"] Nothing ] it [i|Complex4 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex4 String))) `shouldBe` [ TSInterfaceDeclaration "IProduct4" ["T"] [TSField False "record4" "{[k in string]?: T}" Nothing] Nothing - ,TSTypeAlternatives {typeName = "Complex4", typeGenericVariables = ["T"], alternativeTypes = ["IProduct4"]} + ,TSTypeAlternatives "Complex4" ["T"] ["IProduct4"] Nothing ] main :: IO () diff --git a/test/GetDoc.hs b/test/GetDoc.hs index 8ee8f80..73f25b7 100644 --- a/test/GetDoc.hs +++ b/test/GetDoc.hs @@ -23,7 +23,7 @@ tests :: SpecWith () tests = describe "getDoc tests" $ do it [i|Works with a simple record type|] $ do (getTypeScriptDeclarations (Proxy :: Proxy OneField)) `shouldBe` ([ - TSTypeAlternatives "OneField" [] ["IOneField"] + TSTypeAlternatives "OneField" [] ["IOneField"] (Just "OneField type doc") , TSInterfaceDeclaration "IOneField" [] [ TSField False "simpleString" "string" (Just "This is a simple string") ] (Just "OneField constructor doc") diff --git a/test/HigherKind.hs b/test/HigherKind.hs index 00aeac5..3587785 100644 --- a/test/HigherKind.hs +++ b/test/HigherKind.hs @@ -36,7 +36,7 @@ tests = describe "Higher kinds" $ do describe "Kind * -> *" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (HigherKind T))) `shouldBe` ([ - TSTypeAlternatives "HigherKind" ["T"] ["IHigherKind"], + TSTypeAlternatives "HigherKind" ["T"] ["IHigherKind"] Nothing, TSInterfaceDeclaration "IHigherKind" ["T"] [TSField False "higherKindList" "T[]" Nothing] Nothing ]) @@ -45,21 +45,21 @@ tests = describe "Higher kinds" $ do it [i|works when referenced in another type|] $ do (getTypeScriptDeclarations (Proxy :: Proxy Foo)) `shouldBe` ([ - TSTypeAlternatives "Foo" [] ["IFoo"], + TSTypeAlternatives "Foo" [] ["IFoo"] Nothing, TSInterfaceDeclaration "IFoo" [] [TSField False "fooString" "string" Nothing , TSField False "fooHigherKindReference" "HigherKind" Nothing] Nothing ]) it [i|works with an interface inside|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (HigherKindWithUnary T))) `shouldBe` ([ - TSTypeAlternatives "HigherKindWithUnary" ["T"] ["IUnary"], - TSTypeAlternatives "IUnary" ["T"] ["number"] + TSTypeAlternatives "HigherKindWithUnary" ["T"] ["IUnary"] Nothing, + TSTypeAlternatives "IUnary" ["T"] ["number"] Nothing ]) describe "Kind * -> * -> *" $ do it [i|makes the declaration and type correctly|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (DoubleHigherKind T1 T2))) `shouldBe` ([ - TSTypeAlternatives "DoubleHigherKind" ["T1","T2"] ["IDoubleHigherKind"], + TSTypeAlternatives "DoubleHigherKind" ["T1","T2"] ["IDoubleHigherKind"] Nothing, TSInterfaceDeclaration "IDoubleHigherKind" ["T1","T2"] [TSField False "someList" "T2[]" Nothing , TSField False "higherKindThing" "HigherKind" Nothing] Nothing ]) diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index 36c5d39..148e822 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -15,16 +15,7 @@ allTests = describe "NoOmitNothingFields" $ do it "encodes as expected" $ do let decls = getTypeScriptDeclarations (Proxy :: Proxy Optional) - decls `shouldBe` [TSTypeAlternatives { - typeName = "Optional" - , typeGenericVariables = [] - , alternativeTypes = ["IOptional"] - } - , TSInterfaceDeclaration { - interfaceName = "IOptional" - , interfaceGenericVariables = [] - , interfaceMembers = [TSField False "optionalInt" "number | null" Nothing] - , interfaceDoc = Nothing - }] + decls `shouldBe` [TSTypeAlternatives "Optional" [] ["IOptional"] Nothing + , TSInterfaceDeclaration "IOptional" [] [TSField False "optionalInt" "number | null" Nothing] Nothing] tests diff --git a/test/OpenTypeFamilies.hs b/test/OpenTypeFamilies.hs index 1b1aeaa..52a148e 100644 --- a/test/OpenTypeFamilies.hs +++ b/test/OpenTypeFamilies.hs @@ -44,14 +44,14 @@ tests = describe "Open type families" $ do , TSField False "\"k8s_env\"" "\"k8s\"" Nothing , TSField False "T" "void" Nothing ] Nothing - , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] - , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] + , TSTypeAlternatives "ISimple" ["T extends keyof DeployEnvironment2"] ["DeployEnvironment2[T]"] Nothing + , TSTypeAlternatives "Simple" ["T extends keyof DeployEnvironment2"] ["ISimple"] Nothing ]) describe "Complicated Beam-like user type" $ do it [i|makes the declaration and types correctly|] $ do (getTypeScriptDeclarations (Proxy :: Proxy (UserT T Identity))) `shouldBe` ([ - TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] + TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] Nothing , TSInterfaceDeclaration "IUser" ["T extends keyof DeployEnvironment"] [ TSField False "_userUsername" "string" Nothing , TSField False "_userCreatedAt" "number" Nothing @@ -71,7 +71,7 @@ tests = describe "Open type families" $ do , TSField False "_userCreatedAt" "number" Nothing , TSField False "_userDeployEnvironment" "DeployEnvironment[T]" Nothing ] Nothing - , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] + , TSTypeAlternatives "UserT" ["T extends keyof DeployEnvironment"] ["IUser"] Nothing ]) main :: IO () diff --git a/test/UnwrapUnaryRecords.hs b/test/UnwrapUnaryRecords.hs index 99c702d..1a75fb2 100644 --- a/test/UnwrapUnaryRecords.hs +++ b/test/UnwrapUnaryRecords.hs @@ -19,8 +19,8 @@ allTests = describe "UnwrapUnaryRecords" $ do let decls = getTypeScriptDeclarations (Proxy :: Proxy OneField) decls `shouldBe` [ - TSTypeAlternatives {typeName = "OneField", typeGenericVariables = [], alternativeTypes = ["IOneField"]} - ,TSTypeAlternatives {typeName = "IOneField", typeGenericVariables = [], alternativeTypes = ["string"]} + TSTypeAlternatives "OneField" [] ["IOneField"] Nothing + ,TSTypeAlternatives "IOneField" [] ["string"] Nothing ] tests From b8149881c317ef95ca702747fc74ef5affddff83 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 01:17:33 -0800 Subject: [PATCH 054/123] Change default haddockModifier to stripStart on each line --- src/Data/Aeson/TypeScript/Types.hs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index 58f5317..a96f635 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -7,10 +7,11 @@ module Data.Aeson.TypeScript.Types where import qualified Data.Aeson as A import Data.Aeson.TypeScript.LegalName -import qualified Data.List as L +import Data.Function ((&)) import qualified Data.List.NonEmpty as NonEmpty import Data.Proxy import Data.String +import qualified Data.Text as T import Data.Typeable import Language.Haskell.TH @@ -205,15 +206,20 @@ data ExtraTypeScriptOptions = ExtraTypeScriptOptions { , keyType :: Maybe String -- | Function which is applied to all Haddocks we read in. - -- By default, just drops leading whitespace. + -- By default, just drops leading whitespace from each line. , haddockModifier :: String -> String } defaultExtraTypeScriptOptions :: ExtraTypeScriptOptions -defaultExtraTypeScriptOptions = ExtraTypeScriptOptions [] Nothing deleteLeadingWhitespace +defaultExtraTypeScriptOptions = ExtraTypeScriptOptions [] Nothing stripStartEachLine where - deleteLeadingWhitespace :: String -> String - deleteLeadingWhitespace = L.dropWhile (== ' ') + stripStartEachLine :: String -> String + stripStartEachLine s = s + & T.pack + & T.splitOn "\n" + & fmap T.stripStart + & T.intercalate "\n" + & T.unpack data ExtraDeclOrGenericInfo = ExtraDecl Exp | ExtraGeneric GenericInfo From bab4047f5c551e4f4b48cccf46d6c9ccbf13421d Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 01:17:52 -0800 Subject: [PATCH 055/123] Format haddocks with // comments always --- src/Data/Aeson/TypeScript/Formatting.hs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index c099c62..990971e 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -3,6 +3,7 @@ module Data.Aeson.TypeScript.Formatting where import Data.Aeson.TypeScript.Types +import Data.Function ((&)) import qualified Data.List as L import Data.String.Interpolate import qualified Data.Text as T @@ -73,8 +74,10 @@ formatTSField (TSField optional name typ maybeDoc) = makeDocPrefix maybeDoc <> [ makeDocPrefix :: Maybe String -> String makeDocPrefix maybeDoc = case maybeDoc of Nothing -> "" - Just doc | '\n' `L.elem` doc -> "/* " <> doc <> " */\n" - Just doc -> "// " <> doc <> "\n" + Just (T.pack -> text) -> ["// " <> line | line <- T.splitOn "\n" text] + & T.intercalate "\n" + & (<> "\n") + & T.unpack getGenericBrackets :: [String] -> String getGenericBrackets [] = "" From 4c587754358dad3463ae5e5dd46b4b334408348d Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 03:03:43 -0800 Subject: [PATCH 056/123] Implement @no-emit-typescript annotation address #31 --- CHANGELOG.md | 1 + src/Data/Aeson/TypeScript/Formatting.hs | 39 +++++++++++- test/Formatting.hs | 80 +++++++++++++++++-------- 3 files changed, 91 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0610c1..e817f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [#35](https://github.com/codedownio/aeson-typescript/pull/35) * Add `Data.Aeson.TypeScript.LegalName` module for checking whether a name is a legal JavaScript name or not. * The `defaultFormatter` will `error` if the name contains illegal characters. +* Add support for @no-emit-typescript in Haddocks for constructors and record fields (requires GHC >= 9.2) ## 0.4.2.0 diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index 990971e..b4e4c77 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -1,10 +1,11 @@ -{-# LANGUAGE QuasiQuotes, OverloadedStrings, TemplateHaskell, RecordWildCards, ScopedTypeVariables, NamedFieldPuns, CPP #-} +{-# LANGUAGE CPP #-} module Data.Aeson.TypeScript.Formatting where import Data.Aeson.TypeScript.Types import Data.Function ((&)) import qualified Data.List as L +import Data.Maybe import Data.String.Interpolate import qualified Data.Text as T @@ -33,7 +34,7 @@ formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVar enumType = [i|\n\ntype #{name} = keyof typeof #{typeNameModifier name};|] :: T.Text toEnumName = T.replace "\"" "" -formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables members maybeDoc) = +formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceName genericVariables (filter (not . isNoEmitTypeScriptField) -> members) maybeDoc) = makeDocPrefix maybeDoc <> [i|#{exportPrefix exportMode}interface #{modifiedInterfaceName}#{getGenericBrackets genericVariables} { #{ls} }|] where @@ -52,7 +53,27 @@ 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 (validateFormattingOptions options declarations)) declarations) +formatTSDeclarations' options allDeclarations = + declarations & fmap (T.pack . formatTSDeclaration (validateFormattingOptions options declarations)) + & T.intercalate "\n\n" + & T.unpack + where + removedDeclarations = filter isNoEmitTypeScriptDeclaration allDeclarations + + getDeclarationName :: TSDeclaration -> Maybe String + getDeclarationName (TSInterfaceDeclaration {..}) = Just interfaceName + getDeclarationName (TSTypeAlternatives {..}) = Just typeName + _ = Nothing + + removedDeclarationNames = mapMaybe getDeclarationName removedDeclarations + + removeReferencesToRemovedNames :: [String] -> TSDeclaration -> TSDeclaration + removeReferencesToRemovedNames removedNames decl@(TSTypeAlternatives {..}) = decl { alternativeTypes = [x | x <- alternativeTypes, not (x `L.elem` removedNames)] } + removeReferencesToRemovedNames _ x = x + + declarations = allDeclarations + & filter (not . isNoEmitTypeScriptDeclaration) + & fmap (removeReferencesToRemovedNames removedDeclarationNames) validateFormattingOptions :: FormattingOptions -> [TSDeclaration] -> FormattingOptions validateFormattingOptions options@FormattingOptions{..} decls @@ -82,3 +103,15 @@ makeDocPrefix maybeDoc = case maybeDoc of getGenericBrackets :: [String] -> String getGenericBrackets [] = "" getGenericBrackets xs = [i|<#{T.intercalate ", " (fmap T.pack xs)}>|] + +-- * Support for @no-emit-typescript + +noEmitTypeScriptAnnotation :: String +noEmitTypeScriptAnnotation = "@no-emit-typescript" + +isNoEmitTypeScriptField (TSField {fieldDoc=(Just doc)}) = noEmitTypeScriptAnnotation `L.isInfixOf` doc +isNoEmitTypeScriptField _ = False + +isNoEmitTypeScriptDeclaration (TSInterfaceDeclaration {interfaceDoc=(Just doc)}) = noEmitTypeScriptAnnotation `L.isInfixOf` doc +isNoEmitTypeScriptDeclaration (TSTypeAlternatives {typeDoc=(Just doc)}) = noEmitTypeScriptAnnotation `L.isInfixOf` doc +isNoEmitTypeScriptDeclaration _ = False diff --git a/test/Formatting.hs b/test/Formatting.hs index c4fec32..f9a4906 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -19,30 +19,58 @@ $(deriveTypeScript defaultOptions ''PrimeInType') data PrimeInConstr = PrimeInConstr' $(deriveTypeScript defaultOptions ''PrimeInConstr) +data FooBar = + Foo { + -- | @no-emit-typescript + recordString :: String + , recordInt :: Int + } + | + -- | @no-emit-typescript + Bar { + barInt :: Int + } +$(deriveTypeScript defaultOptions ''FooBar) + +data NormalConstructors = + -- | @no-emit-typescript + Con1 String + | Con2 Int +$(deriveTypeScript defaultOptions ''NormalConstructors) + tests :: Spec -tests = do - describe "Formatting" $ do - describe "when given a Sum Type" $ do - describe "and the TypeAlias format option is set" $ - it "should generate a TS string literal type" $ - formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @D Proxy) `shouldBe` - [i|type D = "S" | "F";|] - describe "and the Enum format option is set" $ - it "should generate a TS Enum" $ - formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @D Proxy) `shouldBe` - [i|enum D { S, F }|] - describe "and the EnumWithType format option is set" $ - it "should generate a TS Enum with a type declaration" $ - formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = EnumWithType }) (getTypeScriptDeclarations @D Proxy) `shouldBe` - [i|enum DEnum { S="S", F="F" }\n\ntype D = keyof typeof DEnum;|] - describe "when the name has an apostrophe" $ do - describe "in the type" $ do - it "throws an error" $ do - evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInType' Proxy)) - `shouldThrow` - anyErrorCall - describe "in the constructor" $ do - it "throws an error" $ do - evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInConstr Proxy)) - `shouldThrow` - anyErrorCall +tests = describe "Formatting" $ do + describe "when given a Sum Type" $ do + describe "and the TypeAlias format option is set" $ + it "should generate a TS string literal type" $ + formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @D Proxy) `shouldBe` + [i|type D = "S" | "F";|] + + describe "and the Enum format option is set" $ + it "should generate a TS Enum" $ + formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @D Proxy) `shouldBe` + [i|enum D { S, F }|] + + describe "and the EnumWithType format option is set" $ + it "should generate a TS Enum with a type declaration" $ + formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = EnumWithType }) (getTypeScriptDeclarations @D Proxy) `shouldBe` + [i|enum DEnum { S="S", F="F" }\n\ntype D = keyof typeof DEnum;|] + + describe "when the name has an apostrophe" $ do + describe "in the type" $ do + it "throws an error" $ do + evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInType' Proxy)) `shouldThrow` anyErrorCall + + describe "in the constructor" $ do + it "throws an error" $ do + evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInConstr Proxy)) `shouldThrow` anyErrorCall + + describe "when @no-emit-typescript is present" $ do + it [i|works on records and constructors of record types|] $ do + formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @FooBar Proxy) `shouldBe` [i|type FooBar = IFoo;\n\ninterface IFoo {\n tag: "Foo";\n recordInt: number;\n}|] + + it [i|works on normal constructors|] $ do + formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @NormalConstructors Proxy) `shouldBe` [i|type NormalConstructors = ICon2;\n\ninterface ICon2 {\n tag: "Con2";\n contents: number;\n}|] + +main :: IO () +main = hspec tests From d6a3addf220d51dcc1199744869beda2b8bb2aa1 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 1 Mar 2023 03:17:19 -0800 Subject: [PATCH 057/123] Check for compatible template-haskell when testing @no-emit-typescript --- test/Formatting.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/Formatting.hs b/test/Formatting.hs index f9a4906..d035c4e 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE TypeApplications #-} module Formatting (tests) where @@ -65,12 +66,14 @@ tests = describe "Formatting" $ do it "throws an error" $ do evaluate (formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @PrimeInConstr Proxy)) `shouldThrow` anyErrorCall +#if MIN_VERSION_template_haskell(2,18,0) describe "when @no-emit-typescript is present" $ do it [i|works on records and constructors of record types|] $ do formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @FooBar Proxy) `shouldBe` [i|type FooBar = IFoo;\n\ninterface IFoo {\n tag: "Foo";\n recordInt: number;\n}|] it [i|works on normal constructors|] $ do formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @NormalConstructors Proxy) `shouldBe` [i|type NormalConstructors = ICon2;\n\ninterface ICon2 {\n tag: "Con2";\n contents: number;\n}|] +#endif main :: IO () main = hspec tests From 6c4cbc9dd5127c6f36faab5ec73df52531a68644 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 22 Mar 2023 21:33:09 -0700 Subject: [PATCH 058/123] GHC 9.2.6 -> 9.2.7 in CI --- .github/workflows/aeson-typescript.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 669806a..5d5b9ee 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -70,7 +70,7 @@ jobs: - "8.8.4" - "8.10.7" - "9.0.2" - - "9.2.6" + - "9.2.7" - "9.4.4" steps: From 6f5803aaa179e11410b4a714b5479d2f84a15b87 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 22 Mar 2023 21:33:24 -0700 Subject: [PATCH 059/123] See if we can test GHC 9.6.1 Cabal in CI --- .github/workflows/aeson-typescript.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 5d5b9ee..3246c6a 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -19,6 +19,7 @@ jobs: - "9.0.2" - "9.2.6" - "9.4.4" + - "9.6.1" # exclude: # - os: macOS-latest # ghc: 8.8.3 From 5ae6687ba09c609c6698ef06ad6b3dac490395d1 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 22 Mar 2023 11:31:00 -0700 Subject: [PATCH 060/123] Enable building with mtl-2.3 --- src/Data/Aeson/TypeScript/Recursive.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Aeson/TypeScript/Recursive.hs b/src/Data/Aeson/TypeScript/Recursive.hs index b0c7c12..8eb673c 100755 --- a/src/Data/Aeson/TypeScript/Recursive.hs +++ b/src/Data/Aeson/TypeScript/Recursive.hs @@ -16,6 +16,7 @@ module Data.Aeson.TypeScript.Recursive ( , getAllParentTypes ) where +import Control.Monad import Control.Monad.State import Control.Monad.Trans.Maybe import Control.Monad.Writer From 1ddb9d529436d804957c52f89a7f6cfbdf5e1a5c Mon Sep 17 00:00:00 2001 From: Langston Barrett Date: Wed, 3 Aug 2022 10:14:40 -0400 Subject: [PATCH 061/123] Add instances for more types from base Specifically: * `Data.Functor.Compose.Compose` * `Data.Functor.Const.Const` * `Data.Functor.Identity.Identity` * `Data.Functor.Product.Product` * `Data.List.NonEmpty.NonEmpty` * `Data.Word.Word` * `Data.Word.Word16` * `Data.Word.Word32` * `Data.Word.Word64` * `Numeric.Natural.Natural` --- src/Data/Aeson/TypeScript/Instances.hs | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 3833dcc..8759207 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -13,9 +13,14 @@ module Data.Aeson.TypeScript.Instances where import qualified Data.Aeson as A import Data.Aeson.TypeScript.Types import Data.Data +import Data.Functor.Compose (Compose) +import Data.Functor.Const (Const) +import Data.Functor.Identity (Identity) +import Data.Functor.Product (Product) import Data.HashMap.Strict import Data.HashSet import qualified Data.List as L +import Data.List.NonEmpty (NonEmpty) import Data.Map.Strict import Data.Set import Data.String.Interpolate @@ -23,6 +28,7 @@ import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Data.Void import Data.Word +import Numeric.Natural (Natural) import GHC.Int #if !MIN_VERSION_base(4,11,0) @@ -49,6 +55,9 @@ instance TypeScript TL.Text where instance TypeScript Integer where getTypeScriptType _ = "number" +instance TypeScript Natural where + getTypeScriptType _ = "number" + instance TypeScript Float where getTypeScriptType _ = "number" @@ -73,13 +82,29 @@ instance TypeScript Int64 where instance TypeScript Char where getTypeScriptType _ = "string" +instance TypeScript Word where + getTypeScriptType _ = "number" + instance TypeScript Word8 where getTypeScriptType _ = "number" +instance TypeScript Word16 where + getTypeScriptType _ = "number" + +instance TypeScript Word32 where + getTypeScriptType _ = "number" + +instance TypeScript Word64 where + getTypeScriptType _ = "number" + instance {-# OVERLAPPABLE #-} (TypeScript a) => TypeScript [a] where getTypeScriptType _ = (getTypeScriptType (Proxy :: Proxy a)) ++ "[]" getParentTypes _ = [TSType (Proxy :: Proxy a)] +instance (TypeScript a) => TypeScript (NonEmpty a) where + getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy [a]) + getParentTypes _ = [TSType (Proxy :: Proxy a)] + instance {-# OVERLAPPING #-} TypeScript [Char] where getTypeScriptType _ = "string" @@ -114,6 +139,24 @@ instance (TypeScript a, TypeScript b, TypeScript c, TypeScript d) => TypeScript , (TSType (Proxy :: Proxy d)) ] +instance (TypeScript a) => TypeScript (Const a) where + getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) + getParentTypes _ = [TSType (Proxy :: Proxy a)] + +instance (TypeScript a) => TypeScript (Identity a) where + getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) + getParentTypes _ = [TSType (Proxy :: Proxy a)] + +instance (Typeable f, Typeable g, Typeable a, TypeScript (f (g a)), TypeScript a) => TypeScript (Compose f g a) where + getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy (f (g a))) + getParentTypes _ = getParentTypes (Proxy :: Proxy (f (g a))) + +instance (Typeable f, Typeable g, Typeable a, TypeScript (f a), TypeScript (g a)) => TypeScript (Product f g a) where + getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy (f a, g a)) + getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy (f a))) + , (TSType (Proxy :: Proxy (g a))) + ] + instance (TypeScript a) => TypeScript (Maybe a) where getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) getTypeScriptOptional _ = True From 0043bb7fd9cfad055fa085be46dfc872485ce3cd Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 22 Mar 2023 23:06:14 -0700 Subject: [PATCH 062/123] Bump dev stack resolver --- stack.yaml | 2 +- stack.yaml.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/stack.yaml b/stack.yaml index 812491d..677d2f3 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,5 +1,5 @@ -resolver: lts-20.12 +resolver: lts-20.15 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index b1d5d3a..79b93cf 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: af5d667f6096e535b9c725a72cffe0f6c060e0568d9f9eeda04caee70d0d9d2d - size: 649133 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/12.yaml - original: lts-20.12 + sha256: 5d1df60a0aaf19ab42eb79d5ca01ab812318a96be3925559e902e1bfd8cac569 + size: 649582 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/15.yaml + original: lts-20.15 From 5ef8e5507cbef37eb89a8e4d2c0c667dec931d16 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 22 Mar 2023 23:07:07 -0700 Subject: [PATCH 063/123] Release 0.5.0.0 --- CHANGELOG.md | 6 +++++- aeson-typescript.cabal | 2 +- package.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e817f8a..0b614a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,14 @@ ## (unreleased) +## 0.5.0.0 + * [#35](https://github.com/codedownio/aeson-typescript/pull/35) * Add `Data.Aeson.TypeScript.LegalName` module for checking whether a name is a legal JavaScript name or not. * The `defaultFormatter` will `error` if the name contains illegal characters. -* Add support for @no-emit-typescript in Haddocks for constructors and record fields (requires GHC >= 9.2) +* Be able to transfer Haddock comments to emitted TypeScript (requires GHC >= 9.2 and `-haddock` flag) +* Add support for @no-emit-typescript in Haddocks for constructors and record fields (requires GHC >= 9.2 and `-haddock` flag) +* Support GHC 9.6.1 ## 0.4.2.0 diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 645ac1a..6416159 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.4.2.0 +version: 0.5.0.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index c8e44f4..a029bb2 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.4.2.0 +version: 0.5.0.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From c8c94fd49b052eb8ac09680cd3dd6efc7661b0a4 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 00:29:31 -0700 Subject: [PATCH 064/123] Try fixing up new instances and add test of the new number ones --- src/Data/Aeson/TypeScript/Instances.hs | 14 ++++++++++---- test/TestBoilerplate.hs | 12 ++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 8759207..97de51c 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverlappingInstances #-} {-# LANGUAGE CPP #-} +{-# LANGUAGE PolyKinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- Note: the OverlappingInstances pragma is only here so the overlapping instances in this file @@ -19,6 +20,7 @@ import Data.Functor.Identity (Identity) import Data.Functor.Product (Product) import Data.HashMap.Strict import Data.HashSet +import Data.Kind (Type) import qualified Data.List as L import Data.List.NonEmpty (NonEmpty) import Data.Map.Strict @@ -28,8 +30,8 @@ import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Data.Void import Data.Word -import Numeric.Natural (Natural) import GHC.Int +import Numeric.Natural (Natural) #if !MIN_VERSION_base(4,11,0) import Data.Monoid @@ -139,7 +141,7 @@ instance (TypeScript a, TypeScript b, TypeScript c, TypeScript d) => TypeScript , (TSType (Proxy :: Proxy d)) ] -instance (TypeScript a) => TypeScript (Const a) where +instance forall a k (b :: k). (Typeable k, Typeable b, TypeScript a) => TypeScript (Const a b) where getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) getParentTypes _ = [TSType (Proxy :: Proxy a)] @@ -147,11 +149,15 @@ instance (TypeScript a) => TypeScript (Identity a) where getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) getParentTypes _ = [TSType (Proxy :: Proxy a)] -instance (Typeable f, Typeable g, Typeable a, TypeScript (f (g a)), TypeScript a) => TypeScript (Compose f g a) where +instance forall k k1 (f :: k -> Type) (g :: k1 -> k) a. ( + Typeable k, Typeable k1, Typeable f, Typeable g, Typeable a, TypeScript (f (g a)), TypeScript a + ) => TypeScript (Compose f g a) where getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy (f (g a))) getParentTypes _ = getParentTypes (Proxy :: Proxy (f (g a))) -instance (Typeable f, Typeable g, Typeable a, TypeScript (f a), TypeScript (g a)) => TypeScript (Product f g a) where +instance forall k (f :: k -> Type) (g :: k -> Type) a. ( + Typeable k, Typeable f, Typeable g, Typeable a, TypeScript (f a), TypeScript (g a) + ) => TypeScript (Product f g a) where getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy (f a, g a)) getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy (f a))) , (TSType (Proxy :: Proxy (g a))) diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index ac4afd0..a642548 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -10,7 +10,9 @@ import Data.Functor.Identity import Data.Kind import Data.Proxy import Data.String.Interpolate +import Data.Word import Language.Haskell.TH hiding (Type) +import Numeric.Natural (Natural) import Test.Hspec import Util import Util.Aeson @@ -25,6 +27,13 @@ data TwoConstructor = Con1 { con1String :: String } | Con2 { con2String :: Strin data Complex a = Nullary | Unary Int | Product String Char a | Record { testOne :: Int, testTwo :: Bool, testThree :: Complex a} deriving Eq data Optional = Optional {optionalInt :: Maybe Int} data AesonTypes = AesonTypes { aesonValue :: A.Value, aesonObject :: A.Object } +data Numbers = Numbers { + natural :: Natural + , word :: Word + , word16 :: Word16 + , word32 :: Word32 + , word64 :: Word64 + } -- * For testing type families @@ -65,6 +74,7 @@ testDeclarations testName aesonOptions = do deriveInstances ''Complex deriveInstances ''Optional deriveInstances ''AesonTypes + deriveInstances ''Numbers typesAndValues :: Exp <- [e|[(getTypeScriptType (Proxy :: Proxy Unit), A.encode Unit) @@ -94,6 +104,8 @@ testDeclarations testName aesonOptions = do aesonValue = A.object [("foo" :: A.Key, A.Number 42)] , aesonObject = aesonFromList [("foo", A.Number 42)] })) + + , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Numbers 42 42 42 42 42)) ]|] declarations :: Exp <- [e|getTypeScriptDeclarations (Proxy :: Proxy Unit) From 7a7fd49bf99ad3462b43468d698b5ceb0a7babed Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 00:31:54 -0700 Subject: [PATCH 065/123] Fix numbers boilerplate --- test/TestBoilerplate.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index a642548..2dbfbb0 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -105,7 +105,7 @@ testDeclarations testName aesonOptions = do , aesonObject = aesonFromList [("foo", A.Number 42)] })) - , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Numbers 42 42 42 42 42)) + , (getTypeScriptType (Proxy :: Proxy Numbers), A.encode (Numbers 42 42 42 42 42)) ]|] declarations :: Exp <- [e|getTypeScriptDeclarations (Proxy :: Proxy Unit) From ba24350b7117ec57f829a95b28ed41d6b8817c7a Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 00:39:32 -0700 Subject: [PATCH 066/123] One more boilerplate fix --- test/TestBoilerplate.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 2dbfbb0..f19112d 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -118,6 +118,7 @@ testDeclarations testName aesonOptions = do <> getTypeScriptDeclarations (Proxy :: Proxy (Complex T)) <> getTypeScriptDeclarations (Proxy :: Proxy Optional) <> getTypeScriptDeclarations (Proxy :: Proxy AesonTypes) + <> getTypeScriptDeclarations (Proxy :: Proxy Numbers) |] tests <- [d|tests :: SpecWith () From aed83abcfee2aecd3399b33c67a308cbd2e340db Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 00:39:39 -0700 Subject: [PATCH 067/123] Fix up package.yaml tested-with --- .github/workflows/aeson-typescript.yml | 2 +- aeson-typescript.cabal | 8 +++++++- package.yaml | 9 ++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 3246c6a..2f60f89 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -17,7 +17,7 @@ jobs: - "8.8.4" - "8.10.7" - "9.0.2" - - "9.2.6" + - "9.2.7" - "9.4.4" - "9.6.1" # exclude: diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 6416159..34423cd 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -18,7 +18,13 @@ license: BSD3 license-file: LICENSE build-type: Simple tested-with: - GHC == 9.0.1, GHC == 8.10.4, GHC == 8.10.3, GHC == 8.8.4, GHC == 8.8.3 + GHC == 9.6.1 + , GHC == 9.4.4 + , GHC == 9.2.7 + , GHC == 9.0.2 + , GHC == 8.10.7 + , GHC == 8.8.4 + , GHC == 8.6.5 extra-source-files: README.md CHANGELOG.md diff --git a/package.yaml b/package.yaml index a029bb2..87ad92c 100644 --- a/package.yaml +++ b/package.yaml @@ -23,7 +23,14 @@ synopsis: Generate TypeScript definition files from your ADTs # common to point users to the README.md file. description: Please see the README on Github at -tested-with: GHC == 9.0.1, GHC == 8.10.4, GHC == 8.10.3, GHC == 8.8.4, GHC == 8.8.3 +tested-with: +- GHC == 9.6.1 +- GHC == 9.4.4 +- GHC == 9.2.7 +- GHC == 9.0.2 +- GHC == 8.10.7 +- GHC == 8.8.4 +- GHC == 8.6.5 dependencies: - aeson From afbf9210ea53f29f70631603f73b51403fa49584 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 00:43:22 -0700 Subject: [PATCH 068/123] Bump CI setup-node version (v2 -> v3) and node (v12 -> v16) --- .github/workflows/aeson-typescript.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 2f60f89..6577565 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -89,10 +89,9 @@ jobs: path: ~/.stack key: ${{ runner.os }}-${{ matrix.ghc }}-stack - # Install TSC - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: - node-version: '12' + node-version: '16' - name: Install TSC run: | npm install -g typescript From 55ed89b0eec31fc01afc81ced236905476781e2f Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 23 Mar 2023 01:54:30 -0700 Subject: [PATCH 069/123] More FancyFunctors fields --- test/TestBoilerplate.hs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index f19112d..5b4ad98 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -6,8 +6,12 @@ import Control.Monad.Writer.Lazy hiding (Product) import qualified Data.Aeson as A import Data.Aeson.TH as A import Data.Aeson.TypeScript.TH +import Data.Functor.Compose +import Data.Functor.Const import Data.Functor.Identity +import Data.Functor.Product import Data.Kind +import Data.List.NonEmpty import Data.Proxy import Data.String.Interpolate import Data.Word @@ -34,6 +38,17 @@ data Numbers = Numbers { , word32 :: Word32 , word64 :: Word64 } +data FancyFunctors = FancyFunctors { + nonEmpty :: NonEmpty Int + , const :: Const Int Int + , product :: Product Identity Identity Int + , compose :: Compose Identity Identity Int + } + +-- * Values + +fancyFunctorsValue :: FancyFunctors +fancyFunctorsValue = FancyFunctors (42 :| []) (Const 42) (Pair 42 42) (Compose 42) -- * For testing type families @@ -75,6 +90,7 @@ testDeclarations testName aesonOptions = do deriveInstances ''Optional deriveInstances ''AesonTypes deriveInstances ''Numbers + deriveInstances ''FancyFunctors typesAndValues :: Exp <- [e|[(getTypeScriptType (Proxy :: Proxy Unit), A.encode Unit) @@ -106,6 +122,7 @@ testDeclarations testName aesonOptions = do })) , (getTypeScriptType (Proxy :: Proxy Numbers), A.encode (Numbers 42 42 42 42 42)) + , (getTypeScriptType (Proxy :: Proxy FancyFunctors), A.encode fancyFunctorsValue) ]|] declarations :: Exp <- [e|getTypeScriptDeclarations (Proxy :: Proxy Unit) @@ -119,6 +136,7 @@ testDeclarations testName aesonOptions = do <> getTypeScriptDeclarations (Proxy :: Proxy Optional) <> getTypeScriptDeclarations (Proxy :: Proxy AesonTypes) <> getTypeScriptDeclarations (Proxy :: Proxy Numbers) + <> getTypeScriptDeclarations (Proxy :: Proxy FancyFunctors) |] tests <- [d|tests :: SpecWith () From 671347e3739b63bf04d5412330dc9a4748c7832e Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 27 Apr 2023 17:15:06 -0700 Subject: [PATCH 070/123] Release 0.6.0.0 --- CHANGELOG.md | 5 ++++- aeson-typescript.cabal | 2 +- package.yaml | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b614a8..0d7aba8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ # Change log -## (unreleased) +## 0.6.0.0 + +* New word instances: Word, Word16, Word32, Word64 +* New instances from Data.Functor: Compose, Const, Identity, Product ## 0.5.0.0 diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 34423cd..aead56b 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.5.0.0 +version: 0.6.0.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index 87ad92c..3821c55 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.5.0.0 +version: 0.6.0.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From 903774c23902adb714662758bfc8b836f26a057e Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 22 Jun 2023 21:05:35 -0700 Subject: [PATCH 071/123] ci: try specifying stack resolver properly --- .github/workflows/aeson-typescript.yml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 6577565..9290bd6 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -67,27 +67,33 @@ jobs: strategy: fail-fast: false matrix: - ghc: - - "8.8.4" - - "8.10.7" - - "9.0.2" - - "9.2.7" - - "9.4.4" + include: + - ghc: "8.8.4" + resolver: "lts-16.31" + - ghc: "8.10.7" + resolver: "lts-18.28" + - ghc: "9.0.2" + resolver: "lts-19.33" + - ghc: "9.2.8" + resolver: "lts-20.26" + - ghc: "9.4.5" + resolver: "lts-21.0" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: haskell/actions/setup@v2 name: Setup Haskell Stack with: ghc-version: ${{ matrix.ghc }} + enable-stack: true stack-version: "latest" - uses: actions/cache@v1 name: Cache ~/.stack with: path: ~/.stack - key: ${{ runner.os }}-${{ matrix.ghc }}-stack + key: ${{ runner.os }}-${{ matrix.ghc }}-${{ matrix.resolver }}-stack - uses: actions/setup-node@v3 with: @@ -98,8 +104,8 @@ jobs: - name: Build run: | - stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks + stack build --resolver ${{matrix.resolver}} --system-ghc --test --bench --no-run-tests --no-run-benchmarks - name: Test run: | - stack test --system-ghc + stack test --resolver ${{matrix.resolver}} --system-ghc From 0f4b0d3f22c95601a99859e712ee2279bd38b948 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 28 Jun 2023 04:43:42 -0700 Subject: [PATCH 072/123] Modernize CI by using explicit stack.yaml files --- .github/workflows/aeson-typescript.yml | 29 +++++++++++--------------- stack-8.10.7.yaml | 5 +++++ stack-8.10.7.yaml.lock | 12 +++++++++++ stack-9.0.2.yaml | 5 +++++ stack-9.0.2.yaml.lock | 12 +++++++++++ stack-9.2.8.yaml | 5 +++++ stack-9.2.8.yaml.lock | 12 +++++++++++ stack-9.4.5.yaml | 5 +++++ stack-9.4.5.yaml.lock | 12 +++++++++++ stack.yaml | 5 +---- stack.yaml.lock | 8 +++---- 11 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 stack-8.10.7.yaml create mode 100644 stack-8.10.7.yaml.lock create mode 100644 stack-9.0.2.yaml create mode 100644 stack-9.0.2.yaml.lock create mode 100644 stack-9.2.8.yaml create mode 100644 stack-9.2.8.yaml.lock create mode 100644 stack-9.4.5.yaml create mode 100644 stack-9.4.5.yaml.lock diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 9290bd6..f660f16 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -13,16 +13,11 @@ jobs: matrix: os: [ubuntu-latest, macOS-latest] ghc: - - "8.6.5" - - "8.8.4" - "8.10.7" - "9.0.2" - - "9.2.7" - - "9.4.4" - - "9.6.1" - # exclude: - # - os: macOS-latest - # ghc: 8.8.3 + - "9.2.8" + - "9.4.5" + - "9.6.2" steps: - uses: actions/checkout@v2 @@ -68,16 +63,16 @@ jobs: fail-fast: false matrix: include: - - ghc: "8.8.4" - resolver: "lts-16.31" - ghc: "8.10.7" - resolver: "lts-18.28" + yaml: "stack-8.10.7" - ghc: "9.0.2" - resolver: "lts-19.33" + yaml: "stack-9.0.2.yaml" - ghc: "9.2.8" - resolver: "lts-20.26" + yaml: "stack-9.2.8.yaml" - ghc: "9.4.5" - resolver: "lts-21.0" + yaml: "stack-9.4.5.yaml" + - ghc: "9.6.2" + yaml: "stack.yaml" steps: - uses: actions/checkout@v3 @@ -93,7 +88,7 @@ jobs: name: Cache ~/.stack with: path: ~/.stack - key: ${{ runner.os }}-${{ matrix.ghc }}-${{ matrix.resolver }}-stack + key: ${{ runner.os }}-${{ matrix.ghc }}-${{ matrix.yaml }} - uses: actions/setup-node@v3 with: @@ -104,8 +99,8 @@ jobs: - name: Build run: | - stack build --resolver ${{matrix.resolver}} --system-ghc --test --bench --no-run-tests --no-run-benchmarks + stack build --stack-yaml ${{matrix.yaml}} --system-ghc --test --bench --no-run-tests --no-run-benchmarks - name: Test run: | - stack test --resolver ${{matrix.resolver}} --system-ghc + stack test --stack-yaml ${{matrix.yaml}} --system-ghc diff --git a/stack-8.10.7.yaml b/stack-8.10.7.yaml new file mode 100644 index 0000000..2b383ea --- /dev/null +++ b/stack-8.10.7.yaml @@ -0,0 +1,5 @@ + +resolver: lts-18.28 + +packages: +- . diff --git a/stack-8.10.7.yaml.lock b/stack-8.10.7.yaml.lock new file mode 100644 index 0000000..da10c3e --- /dev/null +++ b/stack-8.10.7.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 428ec8d5ce932190d3cbe266b9eb3c175cd81e984babf876b64019e2cbe4ea68 + size: 590100 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml + original: lts-18.28 diff --git a/stack-9.0.2.yaml b/stack-9.0.2.yaml new file mode 100644 index 0000000..fe2c91a --- /dev/null +++ b/stack-9.0.2.yaml @@ -0,0 +1,5 @@ + +resolver: lts-19.33 + +packages: +- . diff --git a/stack-9.0.2.yaml.lock b/stack-9.0.2.yaml.lock new file mode 100644 index 0000000..d79c369 --- /dev/null +++ b/stack-9.0.2.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 + size: 619204 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml + original: lts-19.33 diff --git a/stack-9.2.8.yaml b/stack-9.2.8.yaml new file mode 100644 index 0000000..028d2f7 --- /dev/null +++ b/stack-9.2.8.yaml @@ -0,0 +1,5 @@ + +resolver: lts-20.26 + +packages: +- . diff --git a/stack-9.2.8.yaml.lock b/stack-9.2.8.yaml.lock new file mode 100644 index 0000000..ea5a850 --- /dev/null +++ b/stack-9.2.8.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 5a59b2a405b3aba3c00188453be172b85893cab8ebc352b1ef58b0eae5d248a2 + size: 650475 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/26.yaml + original: lts-20.26 diff --git a/stack-9.4.5.yaml b/stack-9.4.5.yaml new file mode 100644 index 0000000..a05c602 --- /dev/null +++ b/stack-9.4.5.yaml @@ -0,0 +1,5 @@ + +resolver: lts-21.0 + +packages: +- . diff --git a/stack-9.4.5.yaml.lock b/stack-9.4.5.yaml.lock new file mode 100644 index 0000000..ad1be6c --- /dev/null +++ b/stack-9.4.5.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 1867d84255dff8c87373f5dd03e5a5cb1c10a99587e26c8793e750c54e83ffdc + size: 639139 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/0.yaml + original: lts-21.0 diff --git a/stack.yaml b/stack.yaml index 677d2f3..4d5471e 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,8 +1,5 @@ -resolver: lts-20.15 +resolver: nightly-2023-06-27 packages: - . - -# ghc-options: -# "$locals": -fwrite-ide-info diff --git a/stack.yaml.lock b/stack.yaml.lock index 79b93cf..204a9e1 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 5d1df60a0aaf19ab42eb79d5ca01ab812318a96be3925559e902e1bfd8cac569 - size: 649582 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/15.yaml - original: lts-20.15 + sha256: 7cb8c85885c204500c43790ea0e7802a6f8bdaf1a27309de33cbd8898f2c1c00 + size: 531943 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2023/6/27.yaml + original: nightly-2023-06-27 From 968a95bc695129209586b5c70ab07cc60003fdd9 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 28 Jun 2023 04:43:57 -0700 Subject: [PATCH 073/123] Fix Aeson CPP --- test/TestBoilerplate.hs | 2 +- test/Util/Aeson.hs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 5b4ad98..3b45997 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -117,7 +117,7 @@ testDeclarations testName aesonOptions = do , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Just 1 })) , (getTypeScriptType (Proxy :: Proxy AesonTypes), A.encode (AesonTypes { - aesonValue = A.object [("foo" :: A.Key, A.Number 42)] + aesonValue = A.object [("foo" :: AesonKey, A.Number 42)] , aesonObject = aesonFromList [("foo", A.Number 42)] })) diff --git a/test/Util/Aeson.hs b/test/Util/Aeson.hs index b38b900..3954546 100644 --- a/test/Util/Aeson.hs +++ b/test/Util/Aeson.hs @@ -8,8 +8,15 @@ import qualified Data.Aeson.KeyMap as KM aesonFromList :: [(K.Key, v)] -> KM.KeyMap v aesonFromList = KM.fromList + +type AesonKey = A.Key #else +import Data.Aeson as A import Data.HashMap.Strict as HM +import Data.Text as T +aesonFromList :: [(T.Text, Value)] -> HM.HashMap Text A.Value aesonFromList = HM.fromList + +type AesonKey = Text #endif From 870982a53f939f29754138ff29da45b395019cc7 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 28 Jun 2023 04:54:10 -0700 Subject: [PATCH 074/123] Fix a yaml path --- .github/workflows/aeson-typescript.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index f660f16..343791a 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -64,7 +64,7 @@ jobs: matrix: include: - ghc: "8.10.7" - yaml: "stack-8.10.7" + yaml: "stack-8.10.7.yaml" - ghc: "9.0.2" yaml: "stack-9.0.2.yaml" - ghc: "9.2.8" From a80b62c1906a82cb9853d0f647b4d6ec6ef19195 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 28 Jun 2023 04:54:35 -0700 Subject: [PATCH 075/123] Another Util/Aeson.hs fix --- test/Util/Aeson.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Util/Aeson.hs b/test/Util/Aeson.hs index 3954546..38aded1 100644 --- a/test/Util/Aeson.hs +++ b/test/Util/Aeson.hs @@ -9,7 +9,7 @@ import qualified Data.Aeson.KeyMap as KM aesonFromList :: [(K.Key, v)] -> KM.KeyMap v aesonFromList = KM.fromList -type AesonKey = A.Key +type AesonKey = K.Key #else import Data.Aeson as A import Data.HashMap.Strict as HM From c8e64b65aec4247d5942d5fe0006ac6d525f4efe Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 28 Jun 2023 05:05:58 -0700 Subject: [PATCH 076/123] Improve output when TSC check fails --- test/Util.hs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/Util.hs b/test/Util.hs index 88a088d..8436f05 100644 --- a/test/Util.hs +++ b/test/Util.hs @@ -70,12 +70,19 @@ testTypeCheckDeclarations tsDeclarations typesAndVals = withSystemTempDirectory writeFile tsFile contents tsc <- getTSC - (code, output, _err) <- readProcessWithExitCode tsc ["--strict", "--noEmit", "--skipLibCheck", "--traceResolution", "--noResolve", tsFile] "" + (code, sout, serr) <- readProcessWithExitCode tsc ["--strict", "--noEmit", "--skipLibCheck", "--traceResolution", "--noResolve", tsFile] "" - when (code /= ExitSuccess) $ do - error [i|TSC check failed: #{output}. File contents were\n\n#{contents}|] + when (code /= ExitSuccess) $ + error [__i|TSC check failed. + File contents: + #{contents} - return () + Stdout: + #{sout} + + Stderr: + #{serr} + |] ensureTSCExists :: IO () From d7deffad3d9f6652ef820be7eca71b8f77b0dee9 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 28 Jun 2023 05:07:56 -0700 Subject: [PATCH 077/123] Try fixing cabal tests in CI --- .github/workflows/aeson-typescript.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 343791a..9d31265 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -33,16 +33,15 @@ jobs: run: | cabal freeze - - uses: actions/cache@v1 + - uses: actions/cache@v3 name: Cache ~/.cabal/store with: path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }} key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }} - # Install TSC - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: - node-version: '12' + node-version: '16' - name: Install TSC run: | npm install -g typescript @@ -84,7 +83,7 @@ jobs: enable-stack: true stack-version: "latest" - - uses: actions/cache@v1 + - uses: actions/cache@v3 name: Cache ~/.stack with: path: ~/.stack From 40674f9628732eb8afd5918373debb4a764bf3d8 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 12 Oct 2023 21:24:27 -0700 Subject: [PATCH 078/123] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cdf469..249e3b5 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,6 @@ Now you can generate the types by running `stack runhaskell tsdef/Main.hs > type # See also -If you want a much more opinionated web framework for generating APIs, check out [servant](http://haskell-servant.readthedocs.io/en/stable/). (Although it doesn't seem to support TypeScript client generation at the moment.) +If you want a more opinionated web framework for generating APIs, check out [servant](http://haskell-servant.readthedocs.io/en/stable/). If you use Servant, you may enjoy [servant-typescript](https://github.com/codedownio/servant-typescript), which is based on `aeson-typescript`! It also has the advantage of magically collecting all the types used in your API, so you don't have to list them out manually. For another very powerful framework that can generate TypeScript client code based on an API specification, see [Swagger/OpenAPI](https://github.com/swagger-api/swagger-codegen). From 0d0f4b2d54f0efa16e0af1e47ef5e6353a6b8250 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 12 Oct 2023 21:25:20 -0700 Subject: [PATCH 079/123] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 249e3b5..227be17 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,6 @@ Now you can generate the types by running `stack runhaskell tsdef/Main.hs > type # See also -If you want a more opinionated web framework for generating APIs, check out [servant](http://haskell-servant.readthedocs.io/en/stable/). If you use Servant, you may enjoy [servant-typescript](https://github.com/codedownio/servant-typescript), which is based on `aeson-typescript`! It also has the advantage of magically collecting all the types used in your API, so you don't have to list them out manually. +If you want a more opinionated web framework for generating APIs, check out [servant](http://haskell-servant.readthedocs.io/en/stable/). If you use Servant, you may enjoy [servant-typescript](https://github.com/codedownio/servant-typescript), which is based on `aeson-typescript`! This companion package also has the advantage of magically collecting all the types used in your API, so you don't have to list them out manually. For another very powerful framework that can generate TypeScript client code based on an API specification, see [Swagger/OpenAPI](https://github.com/swagger-api/swagger-codegen). From 0c62a9291dd5e69e40d0682900a759b5498a9029 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 13 Nov 2023 17:25:32 -0800 Subject: [PATCH 080/123] Apply typeNameModifier to fields within interfaces --- CHANGELOG.md | 3 +++ src/Data/Aeson/TypeScript/Formatting.hs | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d7aba8..720c2c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change log +## Unreleased + +* Apply `typeNameModifier` to type names emitted on the RHS of fields within interfaces, for consistency. ## 0.6.0.0 diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index b4e4c77..c6051fc 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -41,6 +41,9 @@ formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceNa ls = T.intercalate "\n" $ [indentTo numIndentSpaces (T.pack (formatTSField member <> ";")) | member <- members] modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName + formatTSField :: TSField -> String + formatTSField (TSField optional name typ maybeDoc) = makeDocPrefix maybeDoc <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typeNameModifier typ}|] + formatTSDeclaration _ (TSRawDeclaration text) = text indentTo :: Int -> T.Text -> T.Text @@ -89,9 +92,6 @@ validateFormattingOptions options@FormattingOptions{..} decls -- Units (data U = U) contain two declarations, and thus are invalid isPlainSumType ds = (not . any isInterface $ ds) && length ds == 1 -formatTSField :: TSField -> String -formatTSField (TSField optional name typ maybeDoc) = makeDocPrefix maybeDoc <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] - makeDocPrefix :: Maybe String -> String makeDocPrefix maybeDoc = case maybeDoc of Nothing -> "" From 9465d8dea3488450a69220dc919c094fff8a3e07 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 13 Nov 2023 17:33:39 -0800 Subject: [PATCH 081/123] Update stack.yaml files/GHC versions --- .github/workflows/aeson-typescript.yml | 10 +++++----- stack-9.4.5.yaml | 5 ----- stack-9.4.7.yaml | 5 +++++ stack-9.4.5.yaml.lock => stack-9.4.7.yaml.lock | 8 ++++---- stack.yaml | 2 +- stack.yaml.lock | 8 ++++---- 6 files changed, 19 insertions(+), 19 deletions(-) delete mode 100644 stack-9.4.5.yaml create mode 100644 stack-9.4.7.yaml rename stack-9.4.5.yaml.lock => stack-9.4.7.yaml.lock (65%) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 9d31265..9c63d79 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -16,8 +16,8 @@ jobs: - "8.10.7" - "9.0.2" - "9.2.8" - - "9.4.5" - - "9.6.2" + - "9.4.7" + - "9.6.3" steps: - uses: actions/checkout@v2 @@ -68,9 +68,9 @@ jobs: yaml: "stack-9.0.2.yaml" - ghc: "9.2.8" yaml: "stack-9.2.8.yaml" - - ghc: "9.4.5" - yaml: "stack-9.4.5.yaml" - - ghc: "9.6.2" + - ghc: "9.4.7" + yaml: "stack-9.4.7.yaml" + - ghc: "9.6.3" yaml: "stack.yaml" steps: diff --git a/stack-9.4.5.yaml b/stack-9.4.5.yaml deleted file mode 100644 index a05c602..0000000 --- a/stack-9.4.5.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resolver: lts-21.0 - -packages: -- . diff --git a/stack-9.4.7.yaml b/stack-9.4.7.yaml new file mode 100644 index 0000000..13994e4 --- /dev/null +++ b/stack-9.4.7.yaml @@ -0,0 +1,5 @@ + +resolver: lts-21.20 + +packages: +- . diff --git a/stack-9.4.5.yaml.lock b/stack-9.4.7.yaml.lock similarity index 65% rename from stack-9.4.5.yaml.lock rename to stack-9.4.7.yaml.lock index ad1be6c..1b8f599 100644 --- a/stack-9.4.5.yaml.lock +++ b/stack-9.4.7.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 1867d84255dff8c87373f5dd03e5a5cb1c10a99587e26c8793e750c54e83ffdc - size: 639139 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/0.yaml - original: lts-21.0 + sha256: 5921ddc75f5dd3f197fbc32e1e5676895a8e7b971d4f82ef6b556657801dd18a + size: 640054 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/20.yaml + original: lts-21.20 diff --git a/stack.yaml b/stack.yaml index 4d5471e..bfc9a75 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,5 +1,5 @@ -resolver: nightly-2023-06-27 +resolver: nightly-2023-11-14 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index 204a9e1..dd4da80 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 7cb8c85885c204500c43790ea0e7802a6f8bdaf1a27309de33cbd8898f2c1c00 - size: 531943 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2023/6/27.yaml - original: nightly-2023-06-27 + sha256: 0eaacfc9de6b0ab46ab6026166d2ba7718ab06a8612086b3ee21d7667e682df0 + size: 698974 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2023/11/14.yaml + original: nightly-2023-11-14 From 7cd51838d0c69fe299f52b8ce496d94795898a57 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 13 Nov 2023 17:45:44 -0800 Subject: [PATCH 082/123] Undo 0c62a92 --- src/Data/Aeson/TypeScript/Formatting.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index c6051fc..fdaad6e 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -42,7 +42,7 @@ formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceNa modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName formatTSField :: TSField -> String - formatTSField (TSField optional name typ maybeDoc) = makeDocPrefix maybeDoc <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typeNameModifier typ}|] + formatTSField (TSField optional name typ maybeDoc) = makeDocPrefix maybeDoc <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] formatTSDeclaration _ (TSRawDeclaration text) = text From 70af53a251b854c3767e7407226e197716a7f43f Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 13 Nov 2023 17:54:42 -0800 Subject: [PATCH 083/123] Remove changelog entry until we fix this for real --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 720c2c8..79f651a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,6 @@ ## Unreleased -* Apply `typeNameModifier` to type names emitted on the RHS of fields within interfaces, for consistency. - ## 0.6.0.0 * New word instances: Word, Word16, Word32, Word64 From 1afccfe6318bea005f6fe319bcda52ee8d09b7a2 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 30 Nov 2023 20:35:50 -0700 Subject: [PATCH 084/123] Add more enum formatting tests --- test/Formatting.hs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/test/Formatting.hs b/test/Formatting.hs index d035c4e..b4953e2 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -14,6 +14,12 @@ import Test.Hspec data D = S | F deriving (Eq, Show) $(deriveTypeScript defaultOptions ''D) +data D2 = S2 | F2 deriving (Eq, Show) +$(deriveTypeScript defaultOptions ''D2) + +data Unit = U deriving (Eq, Show) +$(deriveTypeScript defaultOptions ''Unit) + data PrimeInType' = PrimeInType $(deriveTypeScript defaultOptions ''PrimeInType') @@ -47,11 +53,21 @@ tests = describe "Formatting" $ do formatTSDeclarations' defaultFormattingOptions (getTypeScriptDeclarations @D Proxy) `shouldBe` [i|type D = "S" | "F";|] - describe "and the Enum format option is set" $ + describe "and the Enum format option is set" $ do it "should generate a TS Enum" $ formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @D Proxy) `shouldBe` [i|enum D { S, F }|] + it "should generate a TS Enum with multiple" $ + formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @D Proxy <> getTypeScriptDeclarations @D2 Proxy) `shouldBe` + [__i|enum D { S, F } + + enum D2 { S2, F2 }|] + + it "should generate a TS Enum from unit" $ + formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @Unit Proxy) `shouldBe` + [__i|enum Unit { U }|] + describe "and the EnumWithType format option is set" $ it "should generate a TS Enum with a type declaration" $ formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = EnumWithType }) (getTypeScriptDeclarations @D Proxy) `shouldBe` From a7d273e80bf6b5aeeb827deab54d1d1f7d4f3213 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 30 Nov 2023 20:36:16 -0700 Subject: [PATCH 085/123] Get rid of validateFormattingOptions --- src/Data/Aeson/TypeScript/Formatting.hs | 34 +++++++------------------ 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index fdaad6e..f2464e4 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -25,13 +25,13 @@ formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVar where mainDeclaration = case typeAlternativesFormat of Enum -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnum} }|] - EnumWithType -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnumWithType} }#{enumType}|] + EnumWithType -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name}Enum { #{alternativesEnumWithType} }#{enumType}|] TypeAlias -> [i|#{exportPrefix exportMode}type #{typeNameModifier name}#{getGenericBrackets genericVariables} = #{alternatives};|] 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};|] :: T.Text + 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) = @@ -57,18 +57,16 @@ 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 allDeclarations = - declarations & fmap (T.pack . formatTSDeclaration (validateFormattingOptions options declarations)) + declarations & fmap (T.pack . formatTSDeclaration options) & T.intercalate "\n\n" & T.unpack where - removedDeclarations = filter isNoEmitTypeScriptDeclaration allDeclarations - - getDeclarationName :: TSDeclaration -> Maybe String - getDeclarationName (TSInterfaceDeclaration {..}) = Just interfaceName - getDeclarationName (TSTypeAlternatives {..}) = Just typeName - _ = Nothing - - removedDeclarationNames = mapMaybe getDeclarationName removedDeclarations + removedDeclarationNames = mapMaybe getDeclarationName (filter isNoEmitTypeScriptDeclaration allDeclarations) + where + getDeclarationName :: TSDeclaration -> Maybe String + getDeclarationName (TSInterfaceDeclaration {..}) = Just interfaceName + getDeclarationName (TSTypeAlternatives {..}) = Just typeName + _ = Nothing removeReferencesToRemovedNames :: [String] -> TSDeclaration -> TSDeclaration removeReferencesToRemovedNames removedNames decl@(TSTypeAlternatives {..}) = decl { alternativeTypes = [x | x <- alternativeTypes, not (x `L.elem` removedNames)] } @@ -78,20 +76,6 @@ formatTSDeclarations' options allDeclarations = & filter (not . isNoEmitTypeScriptDeclaration) & fmap (removeReferencesToRemovedNames removedDeclarationNames) -validateFormattingOptions :: FormattingOptions -> [TSDeclaration] -> FormattingOptions -validateFormattingOptions options@FormattingOptions{..} decls - | typeAlternativesFormat == Enum && isPlainSumType decls = options - | typeAlternativesFormat == EnumWithType && isPlainSumType decls = options { typeNameModifier = flip (<>) "Enum" } - | otherwise = options { typeAlternativesFormat = TypeAlias } - where - isInterface :: TSDeclaration -> Bool - isInterface TSInterfaceDeclaration{} = True - isInterface _ = False - - -- Plain sum types have only one declaration with multiple alternatives - -- Units (data U = U) contain two declarations, and thus are invalid - isPlainSumType ds = (not . any isInterface $ ds) && length ds == 1 - makeDocPrefix :: Maybe String -> String makeDocPrefix maybeDoc = case maybeDoc of Nothing -> "" From 07bc4923850d0b12b14496f132ee8ffdc4d215f3 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 30 Nov 2023 20:39:22 -0700 Subject: [PATCH 086/123] Comment Unit test for now --- test/Formatting.hs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/Formatting.hs b/test/Formatting.hs index b4953e2..35ab299 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -5,6 +5,7 @@ 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 @@ -19,6 +20,7 @@ $(deriveTypeScript defaultOptions ''D2) data Unit = U deriving (Eq, Show) $(deriveTypeScript defaultOptions ''Unit) +$(deriveJSON defaultOptions ''Unit) data PrimeInType' = PrimeInType $(deriveTypeScript defaultOptions ''PrimeInType') @@ -64,9 +66,9 @@ 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|enum Unit { U }|] describe "and the EnumWithType format option is set" $ it "should generate a TS Enum with a type declaration" $ From 5afd1649ac1dcfed2a1a92312c3c182a20b0cf83 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 30 Nov 2023 21:58:59 -0700 Subject: [PATCH 087/123] Fix bug in getDeclarationName --- src/Data/Aeson/TypeScript/Formatting.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index f2464e4..50a9544 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -66,7 +66,7 @@ formatTSDeclarations' options allDeclarations = getDeclarationName :: TSDeclaration -> Maybe String getDeclarationName (TSInterfaceDeclaration {..}) = Just interfaceName getDeclarationName (TSTypeAlternatives {..}) = Just typeName - _ = Nothing + getDeclarationName _ = Nothing removeReferencesToRemovedNames :: [String] -> TSDeclaration -> TSDeclaration removeReferencesToRemovedNames removedNames decl@(TSTypeAlternatives {..}) = decl { alternativeTypes = [x | x <- alternativeTypes, not (x `L.elem` removedNames)] } From 7933c644a485c07b7f0fc90daddd2ee59f6039f1 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 30 Nov 2023 21:59:31 -0700 Subject: [PATCH 088/123] Fix a couple warnings --- src/Data/Aeson/TypeScript/Formatting.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index 50a9544..5590433 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -42,7 +42,7 @@ formatTSDeclaration (FormattingOptions {..}) (TSInterfaceDeclaration interfaceNa modifiedInterfaceName = (\(li, name) -> li <> interfaceNameModifier name) . splitAt 1 $ interfaceName formatTSField :: TSField -> String - formatTSField (TSField optional name typ maybeDoc) = makeDocPrefix maybeDoc <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] + formatTSField (TSField optional name typ maybeDoc') = makeDocPrefix maybeDoc' <> [i|#{name}#{if optional then ("?" :: String) else ""}: #{typ}|] formatTSDeclaration _ (TSRawDeclaration text) = text @@ -93,9 +93,11 @@ getGenericBrackets xs = [i|<#{T.intercalate ", " (fmap T.pack xs)}>|] noEmitTypeScriptAnnotation :: String noEmitTypeScriptAnnotation = "@no-emit-typescript" +isNoEmitTypeScriptField :: TSField -> Bool isNoEmitTypeScriptField (TSField {fieldDoc=(Just doc)}) = noEmitTypeScriptAnnotation `L.isInfixOf` doc isNoEmitTypeScriptField _ = False +isNoEmitTypeScriptDeclaration :: TSDeclaration -> Bool isNoEmitTypeScriptDeclaration (TSInterfaceDeclaration {interfaceDoc=(Just doc)}) = noEmitTypeScriptAnnotation `L.isInfixOf` doc isNoEmitTypeScriptDeclaration (TSTypeAlternatives {typeDoc=(Just doc)}) = noEmitTypeScriptAnnotation `L.isInfixOf` doc isNoEmitTypeScriptDeclaration _ = False From 2e5c1234e770877ce62a18e23a8dc811ade25079 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 30 Nov 2023 21:59:53 -0700 Subject: [PATCH 089/123] Add a better check for enum mode --- aeson-typescript.cabal | 3 ++- package.yaml | 1 + src/Data/Aeson/TypeScript/Formatting.hs | 28 ++++++++++++++++++++----- test/Formatting.hs | 10 ++++----- 4 files changed, 31 insertions(+), 11 deletions(-) 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" $ From e39ae7c19e0a661fac351ec79f00795e45079cde Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 30 Nov 2023 22:08:45 -0700 Subject: [PATCH 090/123] Add CHANGELOG entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79f651a..eaf6f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Fix a bug which caused enum formatting mode to turn off when multiple declarations were provided (#41) + ## 0.6.0.0 * New word instances: Word, Word16, Word32, Word64 From 007e161fb59191010d175479bb8e4e216072db16 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 5 Dec 2023 19:13:45 -0800 Subject: [PATCH 091/123] Always include string in enums to match aeson --- src/Data/Aeson/TypeScript/Formatting.hs | 2 +- test/Formatting.hs | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Formatting.hs b/src/Data/Aeson/TypeScript/Formatting.hs index fea6941..9412b53 100644 --- a/src/Data/Aeson/TypeScript/Formatting.hs +++ b/src/Data/Aeson/TypeScript/Formatting.hs @@ -28,7 +28,7 @@ formatTSDeclaration (FormattingOptions {..}) (TSTypeAlternatives name genericVar mainDeclaration = case chooseTypeAlternativesFormat typeAlternativesFormat of Enum -> [i|#{exportPrefix exportMode}enum #{typeNameModifier name} { #{alternativesEnum} }|] where - alternativesEnum = T.intercalate ", " $ [toEnumName entry | entry <- T.pack <$> names] + alternativesEnum = T.intercalate ", " $ [toEnumName entry <> "=" <> 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] diff --git a/test/Formatting.hs b/test/Formatting.hs index ab3c770..a86f948 100644 --- a/test/Formatting.hs +++ b/test/Formatting.hs @@ -4,7 +4,7 @@ module Formatting (tests) where import Control.Exception -import Data.Aeson (defaultOptions) +import Data.Aeson (SumEncoding(UntaggedValue), defaultOptions, sumEncoding, tagSingleConstructors) import Data.Aeson.TypeScript.TH import Data.Proxy import Data.String.Interpolate @@ -17,9 +17,14 @@ $(deriveTypeScript defaultOptions ''D) data D2 = S2 | F2 deriving (Eq, Show) $(deriveTypeScript defaultOptions ''D2) +-- A.encode U --> "[]" data Unit = U deriving (Eq, Show) $(deriveTypeScript defaultOptions ''Unit) +-- A.encode UTagSingle --> "\"UTagSingle\"" +data UnitTagSingle = UTagSingle deriving (Eq, Show) +$(deriveTypeScript (defaultOptions { tagSingleConstructors = True, sumEncoding = UntaggedValue }) ''UnitTagSingle) + data PrimeInType' = PrimeInType $(deriveTypeScript defaultOptions ''PrimeInType') @@ -56,25 +61,33 @@ tests = describe "Formatting" $ do describe "and the Enum format option is set" $ do it "should generate a TS Enum" $ formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @D Proxy) `shouldBe` - [i|enum D { S, F }|] + [i|enum D { S="S", F="F" }|] it "should generate a TS Enum with multiple" $ formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @D Proxy <> getTypeScriptDeclarations @D2 Proxy) `shouldBe` - [__i|enum D { S, F } + [__i|enum D { S="S", F="F" } - enum D2 { S2, F2 }|] + enum D2 { S2="S2", F2="F2" }|] - it "should generate a TS Enum from unit" $ + it "should generate a normal type from Unit, singe tagSingleConstructors=False by default" $ 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 suitable enum from UnitTagSingle" $ + formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = Enum }) (getTypeScriptDeclarations @UnitTagSingle Proxy) `shouldBe` + [__i|enum UnitTagSingle { UTagSingle="UTagSingle" }|] + + describe "and the EnumWithType format option is set" $ do it "should generate a TS Enum with a type declaration" $ formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = EnumWithType }) (getTypeScriptDeclarations @D Proxy) `shouldBe` [i|enum DEnum { S="S", F="F" }\n\ntype D = keyof typeof DEnum;|] + it "should also work for UnitTagSingle" $ + formatTSDeclarations' (defaultFormattingOptions { typeAlternativesFormat = EnumWithType }) (getTypeScriptDeclarations @UnitTagSingle Proxy) `shouldBe` + [i|enum UnitTagSingleEnum { UTagSingle="UTagSingle" }\n\ntype UnitTagSingle = keyof typeof UnitTagSingleEnum;|] + describe "when the name has an apostrophe" $ do describe "in the type" $ do it "throws an error" $ do From 78bbf423ef445c9b76df4f41dc6a970596a19284 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 6 Dec 2023 15:56:51 -0800 Subject: [PATCH 092/123] Release 0.6.1.0 --- CHANGELOG.md | 3 +++ aeson-typescript.cabal | 2 +- package.yaml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eaf6f71..a5020c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ ## Unreleased +## 0.6.1.0 + * Fix a bug which caused enum formatting mode to turn off when multiple declarations were provided (#41) +* Fix some mismatch issues where an enum value doesn't match the desired string. ## 0.6.0.0 diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 139cbd6..1caf1f6 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.6.0.0 +version: 0.6.1.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index a1e476d..9de924e 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.6.0.0 +version: 0.6.1.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From 5802281709c959a6de339a7883dfd8082c673475 Mon Sep 17 00:00:00 2001 From: jjkv Date: Tue, 9 Jan 2024 15:26:38 -0500 Subject: [PATCH 093/123] export type variables 4 through 10 --- src/Data/Aeson/TypeScript/TH.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 7cd0e49..4663a8f 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -137,6 +137,13 @@ module Data.Aeson.TypeScript.TH ( , T1(..) , T2(..) , T3(..) + , T4(..) + , T5(..) + , T6(..) + , T7(..) + , T8(..) + , T9(..) + , T10(..) , module Data.Aeson.TypeScript.Instances ) where From 02b279563d5780b3d07008a2690bf275c48d7185 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 10 Jan 2024 13:30:51 -0800 Subject: [PATCH 094/123] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5020c4..729808f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.6.2.0 + +* Expose generic type constructors `T4` through `T10`. (We only exposed `T`, `T1`, `T2`, and `T3` before.) + ## 0.6.1.0 * Fix a bug which caused enum formatting mode to turn off when multiple declarations were provided (#41) From b834e60c91295afba6d7f92e87e57de19dc7cc49 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Wed, 10 Jan 2024 14:02:32 -0800 Subject: [PATCH 095/123] Bump version to 0.6.2.0 --- aeson-typescript.cabal | 2 +- package.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 1caf1f6..6ae61ba 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.6.1.0 +version: 0.6.2.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index 9de924e..8b52337 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.6.1.0 +version: 0.6.2.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From 517f14bde9544dbed826f1b7d6470aeb0b1e833e Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 26 Jan 2024 01:57:52 -0800 Subject: [PATCH 096/123] Add GHC 9.8 support and stack.yaml files for 9.8.1, 9.6.3 --- .github/workflows/aeson-typescript.yml | 5 ++++- CHANGELOG.md | 2 ++ src/Data/Aeson/TypeScript/Transform.hs | 4 +++- stack-9.6.3.yaml | 5 +++++ stack-9.6.3.yaml.lock | 12 ++++++++++++ stack-9.8.1.yaml | 5 +++++ stack-9.8.1.yaml.lock | 12 ++++++++++++ stack.yaml | 2 +- stack.yaml.lock | 8 ++++---- 9 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 stack-9.6.3.yaml create mode 100644 stack-9.6.3.yaml.lock create mode 100644 stack-9.8.1.yaml create mode 100644 stack-9.8.1.yaml.lock diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 9c63d79..e719130 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -18,6 +18,7 @@ jobs: - "9.2.8" - "9.4.7" - "9.6.3" + - "9.8.1" steps: - uses: actions/checkout@v2 @@ -71,7 +72,9 @@ jobs: - ghc: "9.4.7" yaml: "stack-9.4.7.yaml" - ghc: "9.6.3" - yaml: "stack.yaml" + yaml: "stack-9.6.3.yaml" + - ghc: "9.8.1" + yaml: "stack-9.8.1.yaml" steps: - uses: actions/checkout@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 729808f..5cecaec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* GHC 9.8 support + ## 0.6.2.0 * Expose generic type constructors `T4` through `T10`. (We only exposed `T`, `T1`, `T2`, and `T3` before.) diff --git a/src/Data/Aeson/TypeScript/Transform.hs b/src/Data/Aeson/TypeScript/Transform.hs index f5494e1..7e02879 100644 --- a/src/Data/Aeson/TypeScript/Transform.hs +++ b/src/Data/Aeson/TypeScript/Transform.hs @@ -45,7 +45,9 @@ transformTypeFamilies eo@(ExtraTypeScriptOptions {..}) (AppT (ConT name) typ) name' <- lift $ newName (nameBase typeFamilyName <> "'") f <- lift $ newName "f" -#if MIN_VERSION_template_haskell(2,17,0) +#if MIN_VERSION_template_haskell(2,21,0) + let inst1 = DataD [] name' [PlainTV f BndrReq] Nothing [] [] +#elif MIN_VERSION_template_haskell(2,17,0) let inst1 = DataD [] name' [PlainTV f ()] Nothing [] [] #else let inst1 = DataD [] name' [PlainTV f] Nothing [] [] diff --git a/stack-9.6.3.yaml b/stack-9.6.3.yaml new file mode 100644 index 0000000..fa1a123 --- /dev/null +++ b/stack-9.6.3.yaml @@ -0,0 +1,5 @@ + +resolver: lts-22.6 + +packages: +- . diff --git a/stack-9.6.3.yaml.lock b/stack-9.6.3.yaml.lock new file mode 100644 index 0000000..1b74b0a --- /dev/null +++ b/stack-9.6.3.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 1b4c2669e26fa828451830ed4725e4d406acc25a1fa24fcc039465dd13d7a575 + size: 714100 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/6.yaml + original: lts-22.6 diff --git a/stack-9.8.1.yaml b/stack-9.8.1.yaml new file mode 100644 index 0000000..2f1a36f --- /dev/null +++ b/stack-9.8.1.yaml @@ -0,0 +1,5 @@ + +resolver: nightly-2024-01-26 + +packages: +- . diff --git a/stack-9.8.1.yaml.lock b/stack-9.8.1.yaml.lock new file mode 100644 index 0000000..3f8e18f --- /dev/null +++ b/stack-9.8.1.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 876a5c75d90718add42e1ad36d66000bf35050ce1c66748119897a32df613186 + size: 563963 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2024/1/26.yaml + original: nightly-2024-01-26 diff --git a/stack.yaml b/stack.yaml index bfc9a75..fa1a123 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,5 +1,5 @@ -resolver: nightly-2023-11-14 +resolver: lts-22.6 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index dd4da80..1b74b0a 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 0eaacfc9de6b0ab46ab6026166d2ba7718ab06a8612086b3ee21d7667e682df0 - size: 698974 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2023/11/14.yaml - original: nightly-2023-11-14 + sha256: 1b4c2669e26fa828451830ed4725e4d406acc25a1fa24fcc039465dd13d7a575 + size: 714100 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/6.yaml + original: lts-22.6 From 1ea2172d9c903d616ed53309a38f136f058dce22 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 29 Jan 2024 14:19:16 -0800 Subject: [PATCH 097/123] Release 0.6.3.0 (GHC 9.8 support) --- CHANGELOG.md | 2 ++ aeson-typescript.cabal | 2 +- package.yaml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cecaec..14b81d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.6.3.0 + * GHC 9.8 support ## 0.6.2.0 diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 6ae61ba..1c8b635 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.6.2.0 +version: 0.6.3.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index 8b52337..cf445d8 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.6.2.0 +version: 0.6.3.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From ac758f277f70e05e8696b34562b9f941e73ec953 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Tue, 29 Oct 2024 11:03:37 -0500 Subject: [PATCH 098/123] Fix type for maps with non-string keys --- src/Data/Aeson/TypeScript/Instances.hs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 97de51c..a3cd144 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -4,6 +4,7 @@ {-# LANGUAGE OverlappingInstances #-} {-# LANGUAGE CPP #-} {-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- Note: the OverlappingInstances pragma is only here so the overlapping instances in this file @@ -171,13 +172,18 @@ instance (TypeScript a) => TypeScript (Maybe a) where instance TypeScript A.Value where getTypeScriptType _ = "any"; -instance (TypeScript a, TypeScript b) => TypeScript (Map a b) where - getTypeScriptType _ = "{[k in " ++ getTypeScriptKeyType (Proxy :: Proxy a) ++ "]?: " ++ getTypeScriptType (Proxy :: Proxy b) ++ "}" - getParentTypes _ = [TSType (Proxy :: Proxy a), TSType (Proxy :: Proxy b)] - -instance (TypeScript a, TypeScript b) => TypeScript (HashMap a b) where - getTypeScriptType _ = [i|{[k in #{getTypeScriptKeyType (Proxy :: Proxy a)}]?: #{getTypeScriptType (Proxy :: Proxy b)}}|] - getParentTypes _ = L.nub [TSType (Proxy :: Proxy a), TSType (Proxy :: Proxy b)] +instance (TypeScript a, TypeScript b, A.ToJSONKey a) => TypeScript (Map a b) where + getTypeScriptType = + let k = getTypeScriptKeyType @a Proxy + v = getTypeScriptType @b Proxy + in const $ case A.toJSONKey @a of + A.ToJSONKeyText{} -> "{[k in " <> k <> "]?: " <> v <> "}" + A.ToJSONKeyValue{} -> getTypeScriptType @[(a, b)] Proxy + getParentTypes = const $ L.nub [TSType @a Proxy, TSType @b Proxy] + +instance (TypeScript a, TypeScript b, A.ToJSONKey a) => TypeScript (HashMap a b) where + getTypeScriptType = const $ getTypeScriptType @(Map a b) Proxy + getParentTypes = const $ getParentTypes @(Map a b) Proxy #if MIN_VERSION_aeson(2,0,0) instance (TypeScript a) => TypeScript (A.KeyMap a) where From 5d6175061c2d6086290f6affb9aa95bcfb1b6ad1 Mon Sep 17 00:00:00 2001 From: thomasjm Date: Tue, 29 Oct 2024 19:08:28 -0700 Subject: [PATCH 099/123] Improve a few error messages --- src/Data/Aeson/TypeScript/Lookup.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Lookup.hs b/src/Data/Aeson/TypeScript/Lookup.hs index 82544fe..f51b2fd 100644 --- a/src/Data/Aeson/TypeScript/Lookup.hs +++ b/src/Data/Aeson/TypeScript/Lookup.hs @@ -30,7 +30,7 @@ deriveTypeScriptLookupType name declNameStr = do interfaceDecl <- getClosedTypeFamilyInterfaceDecl name eqns return [FunD (mkName declNameStr) [Clause [] (NormalB (ListE [interfaceDecl])) []]] - _ -> fail [i|Expected a close type family; got #{info}|] + _ -> fail [i|Expected a closed type family; got #{info}|] getClosedTypeFamilyInterfaceDecl :: Name -> [TySynEqn] -> Q Exp getClosedTypeFamilyInterfaceDecl name eqns = do @@ -44,7 +44,7 @@ getClosedTypeFamilyInterfaceDecl name eqns = do TySynEqn [ConT arg] result -> do [| TSField False (getTypeScriptType (Proxy :: Proxy $(conT arg))) (getTypeScriptType (Proxy :: Proxy $(return result))) Nothing |] #endif - x -> fail [i|aeson-typescript doesn't know yet how to handle this type family equation: '#{x}'|] + x -> fail [i|aeson-typescript doesn't know yet how to handle this type family equation when generating interface declaration: '#{x}'|] [| TSInterfaceDeclaration $(TH.stringE $ nameBase name) [] (L.sortBy (compare `on` fieldName) $(listE $ fmap return fields)) Nothing |] @@ -56,4 +56,4 @@ getClosedTypeFamilyImage eqns = do #else TySynEqn [ConT _] result -> return result #endif - x -> fail [i|aeson-typescript doesn't know yet how to handle this type family equation: '#{x}'|] + x -> fail [i|aeson-typescript doesn't know yet how to handle this type family equation when calculating closed type family image: '#{x}'|] From 10d8056282084b54d53ba638906efbbc9f3796ab Mon Sep 17 00:00:00 2001 From: thomasjm Date: Tue, 29 Oct 2024 19:09:41 -0700 Subject: [PATCH 100/123] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14b81d1..32aa218 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.6.4.0 + +* Fix type for maps with non-string keys (#46, fixes #28, thanks @tfausak!) + ## 0.6.3.0 * GHC 9.8 support From 35a6414c3d7e136d556e355fc86b6a6764171ddd Mon Sep 17 00:00:00 2001 From: thomasjm Date: Fri, 1 Nov 2024 00:11:22 -0700 Subject: [PATCH 101/123] Release 0.6.4.0 --- aeson-typescript.cabal | 4 ++-- package.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index 1c8b635..a448269 100644 --- a/aeson-typescript.cabal +++ b/aeson-typescript.cabal @@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.36.0. +-- This file has been generated from package.yaml by hpack version 0.37.0. -- -- see: https://github.com/sol/hpack name: aeson-typescript -version: 0.6.3.0 +version: 0.6.4.0 synopsis: Generate TypeScript definition files from your ADTs description: Please see the README on Github at category: Text, Web, JSON diff --git a/package.yaml b/package.yaml index cf445d8..0f0fde4 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: aeson-typescript -version: 0.6.3.0 +version: 0.6.4.0 github: "codedownio/aeson-typescript" license: BSD3 category: Text, Web, JSON From 0cf43e7006ad85b5f034226a31c732115efa3fa3 Mon Sep 17 00:00:00 2001 From: thomasjm Date: Fri, 6 Dec 2024 15:35:00 -0800 Subject: [PATCH 102/123] Remove question mark in Data.Map instance --- src/Data/Aeson/TypeScript/Instances.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index a3cd144..988aec0 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -177,8 +177,8 @@ instance (TypeScript a, TypeScript b, A.ToJSONKey a) => TypeScript (Map a b) whe let k = getTypeScriptKeyType @a Proxy v = getTypeScriptType @b Proxy in const $ case A.toJSONKey @a of - A.ToJSONKeyText{} -> "{[k in " <> k <> "]?: " <> v <> "}" - A.ToJSONKeyValue{} -> getTypeScriptType @[(a, b)] Proxy + A.ToJSONKeyText {} -> "{[k in " <> k <> "]: " <> v <> "}" + A.ToJSONKeyValue {} -> getTypeScriptType @[(a, b)] Proxy getParentTypes = const $ L.nub [TSType @a Proxy, TSType @b Proxy] instance (TypeScript a, TypeScript b, A.ToJSONKey a) => TypeScript (HashMap a b) where From 217af9cd361e961d4ba7fdb0edce90db390de0df Mon Sep 17 00:00:00 2001 From: thomasjm Date: Fri, 6 Dec 2024 16:04:28 -0800 Subject: [PATCH 103/123] GHC 9.6.3 -> 9.6.6 --- .github/workflows/aeson-typescript.yml | 6 +++--- stack-9.6.3.yaml | 5 ----- stack-9.6.6.yaml | 5 +++++ stack.yaml | 2 +- stack.yaml.lock | 8 ++++---- 5 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 stack-9.6.3.yaml create mode 100644 stack-9.6.6.yaml diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index e719130..948d0b7 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -17,7 +17,7 @@ jobs: - "9.0.2" - "9.2.8" - "9.4.7" - - "9.6.3" + - "9.6.6" - "9.8.1" steps: @@ -71,8 +71,8 @@ jobs: yaml: "stack-9.2.8.yaml" - ghc: "9.4.7" yaml: "stack-9.4.7.yaml" - - ghc: "9.6.3" - yaml: "stack-9.6.3.yaml" + - ghc: "9.6.6" + yaml: "stack-9.6.6.yaml" - ghc: "9.8.1" yaml: "stack-9.8.1.yaml" diff --git a/stack-9.6.3.yaml b/stack-9.6.3.yaml deleted file mode 100644 index fa1a123..0000000 --- a/stack-9.6.3.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resolver: lts-22.6 - -packages: -- . diff --git a/stack-9.6.6.yaml b/stack-9.6.6.yaml new file mode 100644 index 0000000..da3643b --- /dev/null +++ b/stack-9.6.6.yaml @@ -0,0 +1,5 @@ + +resolver: lts-22.43 + +packages: +- . diff --git a/stack.yaml b/stack.yaml index fa1a123..da3643b 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,5 +1,5 @@ -resolver: lts-22.6 +resolver: lts-22.43 packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index 1b74b0a..f9829eb 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 1b4c2669e26fa828451830ed4725e4d406acc25a1fa24fcc039465dd13d7a575 - size: 714100 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/6.yaml - original: lts-22.6 + sha256: 08bd13ce621b41a8f5e51456b38d5b46d7783ce114a50ab604d6bbab0d002146 + size: 720271 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/43.yaml + original: lts-22.43 From c659b5b3f85e5b1e08d5b303221ecb53cb85ffff Mon Sep 17 00:00:00 2001 From: thomasjm Date: Fri, 6 Dec 2024 16:04:45 -0800 Subject: [PATCH 104/123] Add flake.nix, .envrc --- .envrc | 6 ++++++ .gitignore | 2 ++ flake.nix | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 .envrc create mode 100644 flake.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..ac5cf17 --- /dev/null +++ b/.envrc @@ -0,0 +1,6 @@ + +if ! has nix_direnv_version || ! nix_direnv_version 2.2.0; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.0/direnvrc" "sha256-5EwyKnkJNQeXrRkYbwwRBcXbibosCJqyIUuz9Xq+LRc=" +fi + +use_flake diff --git a/.gitignore b/.gitignore index 938bf2c..b2918f1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ dist-newstyle *.hie dev/ + +.direnv diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..f0f08c1 --- /dev/null +++ b/flake.nix @@ -0,0 +1,32 @@ +{ + description = "aeson-typescript"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-24.05"; + inputs.nixpkgsMaster.url = "github:NixOS/nixpkgs/master"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + + outputs = { self, nixpkgs, nixpkgsMaster, flake-utils }: + flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: + let + pkgs = import nixpkgs { inherit system; }; + pkgsMaster = import nixpkgsMaster { inherit system; }; + in + { + packages = { + inherit (pkgsMaster.haskell.packages.ghc966) weeder; + + test = pkgs.writeShellScriptBin "stack-test" '' + export NIX_PATH=nixpkgs=${pkgs.path} + ${pkgs.stack}/bin/stack test + ''; + + nixpkgsPath = pkgs.writeShellScriptBin "nixpkgsPath.sh" "echo -n ${pkgs.path}"; + }; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + nodejs + ]; + }; + }); +} From 300d44cf2389aa137b95f362805cef50b232e5c3 Mon Sep 17 00:00:00 2001 From: thomasjm Date: Fri, 6 Dec 2024 16:33:41 -0800 Subject: [PATCH 105/123] Update flake.nix and tests to pass with question mark change --- flake.lock | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 2 +- stack.yaml | 3 ++ test/Generic.hs | 2 +- test/Util.hs | 40 ++++++++++++++----------- 5 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 flake.lock diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..649c591 --- /dev/null +++ b/flake.lock @@ -0,0 +1,78 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1733506555, + "narHash": "sha256-2LC74TJ4jh0oGkNRaiLfKvTttjBtBIT7lr9/OJBeb1g=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f11c13edc4ad2bd863c7275a4aa792230bc668f6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgsMaster": { + "locked": { + "lastModified": 1733527277, + "narHash": "sha256-f6a4Zql19fawMRbvAsJ21T4rvBxbsJFhHxHpu9jASLo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a01ee2f7f3e0f33f6738b6f49d24d3653a415682", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "master", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "nixpkgsMaster": "nixpkgsMaster" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index f0f08c1..1ac4a28 100644 --- a/flake.nix +++ b/flake.nix @@ -25,7 +25,7 @@ devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ - nodejs + nodePackages.typescript ]; }; }); diff --git a/stack.yaml b/stack.yaml index da3643b..e6ad164 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,5 +1,8 @@ resolver: lts-22.43 +nix: + pure: false + packages: - . diff --git a/test/Generic.hs b/test/Generic.hs index 68f92fb..ea6d05b 100644 --- a/test/Generic.hs +++ b/test/Generic.hs @@ -53,7 +53,7 @@ tests = describe "Generic instances" $ do it [i|Complex4 makes the declaration and types correctly|] $ do (getTypeScriptDeclarationsRecursively (Proxy :: Proxy (Complex4 String))) `shouldBe` [ - TSInterfaceDeclaration "IProduct4" ["T"] [TSField False "record4" "{[k in string]?: T}" Nothing] Nothing + TSInterfaceDeclaration "IProduct4" ["T"] [TSField False "record4" "{[k in string]: T}" Nothing] Nothing ,TSTypeAlternatives "Complex4" ["T"] ["IProduct4"] Nothing ] diff --git a/test/Util.hs b/test/Util.hs index 8436f05..045672f 100644 --- a/test/Util.hs +++ b/test/Util.hs @@ -1,6 +1,11 @@ {-# LANGUAGE CPP #-} -module Util where +module Util ( + testTypeCheck + , testTypeCheckDeclarations + + , setTagSingleConstructors + ) where import Control.Monad import Data.Aeson as A @@ -17,10 +22,9 @@ import System.IO.Temp import System.Process hiding (cwd) -npmInstallScript, yarnInstallScript, localTSC :: String +npmInstallScript, yarnInstallScript :: String npmInstallScript = "test/assets/npm_install.sh" yarnInstallScript = "test/assets/yarn_install.sh" -localTSC = "test/assets/node_modules/.bin/tsc" isCI :: IO Bool isCI = lookupEnv "CI" >>= (return . (== (Just "true"))) @@ -30,8 +34,22 @@ getTSC = isCI >>= \case True -> do return "tsc" -- Assume it's set up on the path False -> do - ensureTSCExists - return localTSC + -- Check for a global tsc + findExecutable "tsc" >>= \case + Just tsc -> return tsc + Nothing -> do + let localTSC = "test/assets/node_modules/.bin/tsc" + + doesFileExist localTSC >>= \exists -> unless exists $ void $ do + cwd <- getCurrentDirectory + + installScript <- chooseInstallScript + + putStrLn [i|Invoking yarn to install tsc compiler (make sure yarn is installed). CWD is #{cwd}|] + (exitCode, stdout, stderr) <- readProcessWithExitCode installScript [] "" + when (exitCode /= ExitSuccess) $ putStrLn [i|Error installing yarn: '#{stderr}', '#{stdout}'|] + + return localTSC testTypeCheck :: forall a. (TypeScript a, ToJSON a) => a -> IO () testTypeCheck obj = withSystemTempDirectory "typescript_test" $ \folder -> do @@ -84,18 +102,6 @@ testTypeCheckDeclarations tsDeclarations typesAndVals = withSystemTempDirectory #{serr} |] - -ensureTSCExists :: IO () -ensureTSCExists = doesFileExist localTSC >>= \exists -> unless exists $ void $ do - cwd <- getCurrentDirectory - - installScript <- chooseInstallScript - - putStrLn [i|Invoking yarn to install tsc compiler (make sure yarn is installed). CWD is #{cwd}|] - (exitCode, stdout, stderr) <- readProcessWithExitCode installScript [] "" - when (exitCode /= ExitSuccess) $ putStrLn [i|Error installing yarn: '#{stderr}', '#{stdout}'|] - - -- Between Aeson 1.1.2.0 and 1.2.0.0, tagSingleConstructors was added setTagSingleConstructors :: Options -> Options #if MIN_VERSION_aeson(1,2,0) From e1fe0538fe47fb436ba8255485843f0d8bc83c2c Mon Sep 17 00:00:00 2001 From: thomasjm Date: Fri, 6 Dec 2024 16:38:35 -0800 Subject: [PATCH 106/123] GHC 9.4.7 -> 9.4.8, 9.8.1 -> 9.8.2 --- .github/workflows/aeson-typescript.yml | 12 ++++++------ stack-9.4.7.yaml | 5 ----- stack-9.4.8.yaml | 5 +++++ stack-9.4.7.yaml.lock => stack-9.4.8.yaml.lock | 8 ++++---- stack-9.8.1.yaml | 5 ----- stack-9.8.4.yaml | 5 +++++ stack-9.8.1.yaml.lock => stack-9.8.4.yaml.lock | 8 ++++---- 7 files changed, 24 insertions(+), 24 deletions(-) delete mode 100644 stack-9.4.7.yaml create mode 100644 stack-9.4.8.yaml rename stack-9.4.7.yaml.lock => stack-9.4.8.yaml.lock (65%) delete mode 100644 stack-9.8.1.yaml create mode 100644 stack-9.8.4.yaml rename stack-9.8.1.yaml.lock => stack-9.8.4.yaml.lock (63%) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 948d0b7..425c384 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -16,9 +16,9 @@ jobs: - "8.10.7" - "9.0.2" - "9.2.8" - - "9.4.7" + - "9.4.8" - "9.6.6" - - "9.8.1" + - "9.8.2" steps: - uses: actions/checkout@v2 @@ -69,12 +69,12 @@ jobs: yaml: "stack-9.0.2.yaml" - ghc: "9.2.8" yaml: "stack-9.2.8.yaml" - - ghc: "9.4.7" - yaml: "stack-9.4.7.yaml" + - ghc: "9.4.8" + yaml: "stack-9.4.8.yaml" - ghc: "9.6.6" yaml: "stack-9.6.6.yaml" - - ghc: "9.8.1" - yaml: "stack-9.8.1.yaml" + - ghc: "9.8.2" + yaml: "stack-9.8.2.yaml" steps: - uses: actions/checkout@v3 diff --git a/stack-9.4.7.yaml b/stack-9.4.7.yaml deleted file mode 100644 index 13994e4..0000000 --- a/stack-9.4.7.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resolver: lts-21.20 - -packages: -- . diff --git a/stack-9.4.8.yaml b/stack-9.4.8.yaml new file mode 100644 index 0000000..8ff6e94 --- /dev/null +++ b/stack-9.4.8.yaml @@ -0,0 +1,5 @@ + +resolver: lts-21.25 + +packages: +- . diff --git a/stack-9.4.7.yaml.lock b/stack-9.4.8.yaml.lock similarity index 65% rename from stack-9.4.7.yaml.lock rename to stack-9.4.8.yaml.lock index 1b8f599..f823d29 100644 --- a/stack-9.4.7.yaml.lock +++ b/stack-9.4.8.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 5921ddc75f5dd3f197fbc32e1e5676895a8e7b971d4f82ef6b556657801dd18a - size: 640054 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/20.yaml - original: lts-21.20 + sha256: a81fb3877c4f9031e1325eb3935122e608d80715dc16b586eb11ddbff8671ecd + size: 640086 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/25.yaml + original: lts-21.25 diff --git a/stack-9.8.1.yaml b/stack-9.8.1.yaml deleted file mode 100644 index 2f1a36f..0000000 --- a/stack-9.8.1.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resolver: nightly-2024-01-26 - -packages: -- . diff --git a/stack-9.8.4.yaml b/stack-9.8.4.yaml new file mode 100644 index 0000000..995854f --- /dev/null +++ b/stack-9.8.4.yaml @@ -0,0 +1,5 @@ + +resolver: nightly-2024-10-21 + +packages: +- . diff --git a/stack-9.8.1.yaml.lock b/stack-9.8.4.yaml.lock similarity index 63% rename from stack-9.8.1.yaml.lock rename to stack-9.8.4.yaml.lock index 3f8e18f..691f9ca 100644 --- a/stack-9.8.1.yaml.lock +++ b/stack-9.8.4.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 876a5c75d90718add42e1ad36d66000bf35050ce1c66748119897a32df613186 - size: 563963 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2024/1/26.yaml - original: nightly-2024-01-26 + sha256: 867086a789eaf6da9f48a56bb5e8bfd6df27b120023c144cc7bbec5c95717915 + size: 669588 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2024/10/21.yaml + original: nightly-2024-10-21 From de38e594bfa15843da60f2a93ef7ecbe5590f493 Mon Sep 17 00:00:00 2001 From: thomasjm Date: Sat, 7 Dec 2024 00:07:31 -0800 Subject: [PATCH 107/123] Fix stack-9.8.2. file name --- stack-9.8.4.yaml => stack-9.8.2.yaml | 0 stack-9.8.4.yaml.lock => stack-9.8.2.yaml.lock | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename stack-9.8.4.yaml => stack-9.8.2.yaml (100%) rename stack-9.8.4.yaml.lock => stack-9.8.2.yaml.lock (100%) diff --git a/stack-9.8.4.yaml b/stack-9.8.2.yaml similarity index 100% rename from stack-9.8.4.yaml rename to stack-9.8.2.yaml diff --git a/stack-9.8.4.yaml.lock b/stack-9.8.2.yaml.lock similarity index 100% rename from stack-9.8.4.yaml.lock rename to stack-9.8.2.yaml.lock From 4d6c0b414f41a28544e7a5f28fcfe70261fae79d Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 3 Feb 2025 19:53:45 -0800 Subject: [PATCH 108/123] Update stack.yaml files --- .github/workflows/aeson-typescript.yml | 6 +++--- stack-9.8.2.yaml | 5 ----- stack-9.8.4.yaml | 5 +++++ stack-9.8.2.yaml.lock => stack-9.8.4.yaml.lock | 8 ++++---- stack.yaml | 2 +- stack.yaml.lock | 8 ++++---- 6 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 stack-9.8.2.yaml create mode 100644 stack-9.8.4.yaml rename stack-9.8.2.yaml.lock => stack-9.8.4.yaml.lock (63%) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 425c384..fcffabb 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -18,7 +18,7 @@ jobs: - "9.2.8" - "9.4.8" - "9.6.6" - - "9.8.2" + - "9.8.4" steps: - uses: actions/checkout@v2 @@ -73,8 +73,8 @@ jobs: yaml: "stack-9.4.8.yaml" - ghc: "9.6.6" yaml: "stack-9.6.6.yaml" - - ghc: "9.8.2" - yaml: "stack-9.8.2.yaml" + - ghc: "9.8.4" + yaml: "stack-9.8.4.yaml" steps: - uses: actions/checkout@v3 diff --git a/stack-9.8.2.yaml b/stack-9.8.2.yaml deleted file mode 100644 index 995854f..0000000 --- a/stack-9.8.2.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resolver: nightly-2024-10-21 - -packages: -- . diff --git a/stack-9.8.4.yaml b/stack-9.8.4.yaml new file mode 100644 index 0000000..8587184 --- /dev/null +++ b/stack-9.8.4.yaml @@ -0,0 +1,5 @@ + +resolver: lts-23.7 + +packages: +- . diff --git a/stack-9.8.2.yaml.lock b/stack-9.8.4.yaml.lock similarity index 63% rename from stack-9.8.2.yaml.lock rename to stack-9.8.4.yaml.lock index 691f9ca..0e99322 100644 --- a/stack-9.8.2.yaml.lock +++ b/stack-9.8.4.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 867086a789eaf6da9f48a56bb5e8bfd6df27b120023c144cc7bbec5c95717915 - size: 669588 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2024/10/21.yaml - original: nightly-2024-10-21 + sha256: 4ef79c30b9efcf07335cb3de532983a7ac4c5a4180bc17f6212a86b09ce2ff75 + size: 680777 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/7.yaml + original: lts-23.7 diff --git a/stack.yaml b/stack.yaml index e6ad164..dfcce6a 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,5 +1,5 @@ -resolver: lts-22.43 +resolver: lts-23.7 nix: pure: false diff --git a/stack.yaml.lock b/stack.yaml.lock index f9829eb..0e99322 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,7 +6,7 @@ packages: [] snapshots: - completed: - sha256: 08bd13ce621b41a8f5e51456b38d5b46d7783ce114a50ab604d6bbab0d002146 - size: 720271 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/43.yaml - original: lts-22.43 + sha256: 4ef79c30b9efcf07335cb3de532983a7ac4c5a4180bc17f6212a86b09ce2ff75 + size: 680777 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/7.yaml + original: lts-23.7 From 48f5d0dbc5d39ac2cc7ced80b112690b8238deda Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 3 Feb 2025 19:55:04 -0800 Subject: [PATCH 109/123] flake.nix: trying to do windows cross-compile --- flake.lock | 609 ++++++++++++++++++++++++++++++++++++++++++++++++++++- flake.nix | 43 +++- 2 files changed, 635 insertions(+), 17 deletions(-) diff --git a/flake.lock b/flake.lock index 649c591..577cda8 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,105 @@ { "nodes": { + "HTTP": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, + "cabal-32": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, + "cabal-34": { + "flake": false, + "locked": { + "lastModified": 1645834128, + "narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=", + "owner": "haskell", + "repo": "cabal", + "rev": "5ff598c67f53f7c4f48e31d722ba37172230c462", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, + "cabal-36": { + "flake": false, + "locked": { + "lastModified": 1669081697, + "narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=", + "owner": "haskell", + "repo": "cabal", + "rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, + "cardano-shell": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1672831974, + "narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=", + "owner": "input-output-hk", + "repo": "flake-compat", + "rev": "45f2638735f8cdc40fe302742b79f248d23eb368", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "hkm/gitlab-fix", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -18,43 +118,530 @@ "type": "github" } }, + "ghc-8.6.5-iohk": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "hackage": { + "flake": false, + "locked": { + "lastModified": 1738628879, + "narHash": "sha256-fQNlSl5f6MPKLI7RmqLKHdix3YtxVkAyZ0b7XzNn1YQ=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "901791fe0870fc8816fb52665774fb7b4d591ed9", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "haskellNix": { + "inputs": { + "HTTP": "HTTP", + "cabal-32": "cabal-32", + "cabal-34": "cabal-34", + "cabal-36": "cabal-36", + "cardano-shell": "cardano-shell", + "flake-compat": "flake-compat", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", + "hackage": "hackage", + "hls-1.10": "hls-1.10", + "hls-2.0": "hls-2.0", + "hls-2.2": "hls-2.2", + "hls-2.3": "hls-2.3", + "hls-2.4": "hls-2.4", + "hls-2.5": "hls-2.5", + "hls-2.6": "hls-2.6", + "hls-2.7": "hls-2.7", + "hls-2.8": "hls-2.8", + "hls-2.9": "hls-2.9", + "hpc-coveralls": "hpc-coveralls", + "iserv-proxy": "iserv-proxy", + "nixpkgs": [ + "haskellNix", + "nixpkgs-unstable" + ], + "nixpkgs-2003": "nixpkgs-2003", + "nixpkgs-2105": "nixpkgs-2105", + "nixpkgs-2111": "nixpkgs-2111", + "nixpkgs-2205": "nixpkgs-2205", + "nixpkgs-2211": "nixpkgs-2211", + "nixpkgs-2305": "nixpkgs-2305", + "nixpkgs-2311": "nixpkgs-2311", + "nixpkgs-2405": "nixpkgs-2405", + "nixpkgs-2411": "nixpkgs-2411", + "nixpkgs-unstable": "nixpkgs-unstable", + "old-ghc-nix": "old-ghc-nix", + "stackage": "stackage" + }, + "locked": { + "lastModified": 1738630291, + "narHash": "sha256-sT8M2+hNzQl2flJZY0lAD9Ygpr5f4deKecc/OuNRVP0=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "2cb66646461d4388b950621190af3840169fe883", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "hls-1.10": { + "flake": false, + "locked": { + "lastModified": 1680000865, + "narHash": "sha256-rc7iiUAcrHxwRM/s0ErEsSPxOR3u8t7DvFeWlMycWgo=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b08691db779f7a35ff322b71e72a12f6e3376fd9", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "1.10.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.0": { + "flake": false, + "locked": { + "lastModified": 1687698105, + "narHash": "sha256-OHXlgRzs/kuJH8q7Sxh507H+0Rb8b7VOiPAjcY9sM1k=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "783905f211ac63edf982dd1889c671653327e441", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.0.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.2": { + "flake": false, + "locked": { + "lastModified": 1693064058, + "narHash": "sha256-8DGIyz5GjuCFmohY6Fa79hHA/p1iIqubfJUTGQElbNk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b30f4b6cf5822f3112c35d14a0cba51f3fe23b85", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.2.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.3": { + "flake": false, + "locked": { + "lastModified": 1695910642, + "narHash": "sha256-tR58doOs3DncFehHwCLczJgntyG/zlsSd7DgDgMPOkI=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "458ccdb55c9ea22cd5d13ec3051aaefb295321be", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.3.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.4": { + "flake": false, + "locked": { + "lastModified": 1699862708, + "narHash": "sha256-YHXSkdz53zd0fYGIYOgLt6HrA0eaRJi9mXVqDgmvrjk=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "54507ef7e85fa8e9d0eb9a669832a3287ffccd57", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.4.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.5": { + "flake": false, + "locked": { + "lastModified": 1701080174, + "narHash": "sha256-fyiR9TaHGJIIR0UmcCb73Xv9TJq3ht2ioxQ2mT7kVdc=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "27f8c3d3892e38edaef5bea3870161815c4d014c", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.5.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.6": { + "flake": false, + "locked": { + "lastModified": 1705325287, + "narHash": "sha256-+P87oLdlPyMw8Mgoul7HMWdEvWP/fNlo8jyNtwME8E8=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "6e0b342fa0327e628610f2711f8c3e4eaaa08b1e", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.6.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.7": { + "flake": false, + "locked": { + "lastModified": 1708965829, + "narHash": "sha256-LfJ+TBcBFq/XKoiNI7pc4VoHg4WmuzsFxYJ3Fu+Jf+M=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "50322b0a4aefb27adc5ec42f5055aaa8f8e38001", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.7.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.8": { + "flake": false, + "locked": { + "lastModified": 1715153580, + "narHash": "sha256-Vi/iUt2pWyUJlo9VrYgTcbRviWE0cFO6rmGi9rmALw0=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "dd1be1beb16700de59e0d6801957290bcf956a0a", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.8.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.9": { + "flake": false, + "locked": { + "lastModified": 1720003792, + "narHash": "sha256-qnDx8Pk0UxtoPr7BimEsAZh9g2WuTuMB/kGqnmdryKs=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "0c1817cb2babef0765e4e72dd297c013e8e3d12b", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.9.0.1", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hpc-coveralls": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, + "iserv-proxy": { + "flake": false, + "locked": { + "lastModified": 1717479972, + "narHash": "sha256-7vE3RQycHI1YT9LHJ1/fUaeln2vIpYm6Mmn8FTpYeVo=", + "owner": "stable-haskell", + "repo": "iserv-proxy", + "rev": "2ed34002247213fc435d0062350b91bab920626e", + "type": "github" + }, + "original": { + "owner": "stable-haskell", + "ref": "iserv-syms", + "repo": "iserv-proxy", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1733506555, - "narHash": "sha256-2LC74TJ4jh0oGkNRaiLfKvTttjBtBIT7lr9/OJBeb1g=", + "lastModified": 1738633836, + "narHash": "sha256-WqzHCqLdENH6Y44G997EKc8sIO7DrLQf2NMh1Pm0qn4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f11c13edc4ad2bd863c7275a4aa792230bc668f6", + "rev": "c55e1940d4dffcfa2b8d4ea15e864c837e514a77", "type": "github" }, "original": { "owner": "NixOS", - "ref": "release-24.05", + "ref": "release-24.11", "repo": "nixpkgs", "type": "github" } }, - "nixpkgsMaster": { + "nixpkgs-2003": { "locked": { - "lastModified": 1733527277, - "narHash": "sha256-f6a4Zql19fawMRbvAsJ21T4rvBxbsJFhHxHpu9jASLo=", + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a01ee2f7f3e0f33f6738b6f49d24d3653a415682", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", "type": "github" }, "original": { "owner": "NixOS", - "ref": "master", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2105": { + "locked": { + "lastModified": 1659914493, + "narHash": "sha256-lkA5X3VNMKirvA+SUzvEhfA7XquWLci+CGi505YFAIs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "022caabb5f2265ad4006c1fa5b1ebe69fb0c3faf", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111": { + "locked": { + "lastModified": 1659446231, + "narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eabc38219184cc3e04a974fe31857d8e0eac098d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2205": { + "locked": { + "lastModified": 1685573264, + "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "380be19fbd2d9079f677978361792cb25e8a3635", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2211": { + "locked": { + "lastModified": 1688392541, + "narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-22.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2305": { + "locked": { + "lastModified": 1705033721, + "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2311": { + "locked": { + "lastModified": 1719957072, + "narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7144d6241f02d171d25fba3edeaf15e0f2592105", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-23.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2405": { + "locked": { + "lastModified": 1735564410, + "narHash": "sha256-HB/FA0+1gpSs8+/boEavrGJH+Eq08/R2wWNph1sM1Dg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1e7a8f391f1a490460760065fa0630b5520f9cf8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-24.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2411": { + "locked": { + "lastModified": 1737255904, + "narHash": "sha256-r3fxHvh+M/mBgCZXOACzRFPsJdix2QSsKazb7VCXXo0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eacdab35066b0bb1c9413c96898e326b76398a81", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-24.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1737110817, + "narHash": "sha256-DSenga8XjPaUV5KUFW/i3rNkN7jm9XmguW+qQ1ZJTR4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "041c867bad68dfe34b78b2813028a2e2ea70a23c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } }, + "old-ghc-nix": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, "root": { "inputs": { "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "nixpkgsMaster": "nixpkgsMaster" + "gitignore": "gitignore", + "haskellNix": "haskellNix", + "nixpkgs": "nixpkgs" + } + }, + "stackage": { + "flake": false, + "locked": { + "lastModified": 1738627879, + "narHash": "sha256-NqNxhRroKBitD8BxoDTSXJbw9R3pPlsaVkoYqiPbDT0=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "42916147b7e9e8f751cac1881a60bcbb8839ec3d", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" } }, "systems": { diff --git a/flake.nix b/flake.nix index 1ac4a28..4727cfc 100644 --- a/flake.nix +++ b/flake.nix @@ -1,19 +1,50 @@ { description = "aeson-typescript"; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-24.05"; - inputs.nixpkgsMaster.url = "github:NixOS/nixpkgs/master"; inputs.flake-utils.url = "github:numtide/flake-utils"; + inputs.gitignore = { + url = "github:hercules-ci/gitignore.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + inputs.haskellNix.url = "github:input-output-hk/haskell.nix"; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-24.11"; - outputs = { self, nixpkgs, nixpkgsMaster, flake-utils }: + outputs = { self, flake-utils, gitignore, haskellNix, nixpkgs }: flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: let - pkgs = import nixpkgs { inherit system; }; - pkgsMaster = import nixpkgsMaster { inherit system; }; + compiler-nix-name = "ghc984"; + + pkgs = import nixpkgs { + inherit system; + overlays = [haskellNix.overlay]; + inherit (haskellNix) config; + }; + + src = gitignore.lib.gitignoreSource ./.; + + flake = (pkgs.haskell-nix.hix.project { + inherit src compiler-nix-name; + evalSystem = system; + projectFileName = "stack.yaml"; + modules = []; + }).flake {}; + + flakeWindows = (pkgs.pkgsCross.mingwW64.haskell-nix.hix.project { + inherit src compiler-nix-name; + evalSystem = system; + projectFileName = "stack.yaml"; + modules = []; + }).flake {}; + in { packages = { - inherit (pkgsMaster.haskell.packages.ghc966) weeder; + inherit (pkgs.haskell.packages.${compiler-nix-name}) weeder; + + inherit flake; + + normal = flake.packages."aeson-typescript:lib:aeson-typescript"; + windows = flakeWindows.packages."aeson-typescript:lib:aeson-typescript"; test = pkgs.writeShellScriptBin "stack-test" '' export NIX_PATH=nixpkgs=${pkgs.path} From e2c05c937a8e62436e9ca02475e3524cf82e1916 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Mon, 3 Feb 2025 19:55:17 -0800 Subject: [PATCH 110/123] .gitignore result --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b2918f1..346524a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ dist-newstyle dev/ .direnv + +result From 77d515608b8619001691fb7707445a6a7c169db3 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Tue, 4 Feb 2025 05:20:27 -0800 Subject: [PATCH 111/123] More on cross-compiling --- flake.lock | 21 ++++----------------- flake.nix | 9 ++++++--- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/flake.lock b/flake.lock index 577cda8..bf6c88e 100644 --- a/flake.lock +++ b/flake.lock @@ -427,22 +427,6 @@ "type": "github" } }, - "nixpkgs": { - "locked": { - "lastModified": 1738633836, - "narHash": "sha256-WqzHCqLdENH6Y44G997EKc8sIO7DrLQf2NMh1Pm0qn4=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "c55e1940d4dffcfa2b8d4ea15e864c837e514a77", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "release-24.11", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs-2003": { "locked": { "lastModified": 1620055814, @@ -625,7 +609,10 @@ "flake-utils": "flake-utils", "gitignore": "gitignore", "haskellNix": "haskellNix", - "nixpkgs": "nixpkgs" + "nixpkgs": [ + "haskellNix", + "nixpkgs" + ] } }, "stackage": { diff --git a/flake.nix b/flake.nix index 4727cfc..b48a9ff 100644 --- a/flake.nix +++ b/flake.nix @@ -7,11 +7,12 @@ inputs.nixpkgs.follows = "nixpkgs"; }; inputs.haskellNix.url = "github:input-output-hk/haskell.nix"; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-24.11"; + inputs.nixpkgs.follows = "haskellNix/nixpkgs"; outputs = { self, flake-utils, gitignore, haskellNix, nixpkgs }: flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: let + # compiler-nix-name = "ghc966"; compiler-nix-name = "ghc984"; pkgs = import nixpkgs { @@ -32,8 +33,10 @@ flakeWindows = (pkgs.pkgsCross.mingwW64.haskell-nix.hix.project { inherit src compiler-nix-name; evalSystem = system; - projectFileName = "stack.yaml"; - modules = []; + projectFileName = "stack-9.8.4.yaml"; + modules = [{ + reinstallableLibGhc = false; + }]; }).flake {}; in From 03e486680c5de3d0d5edef3b3654f39802166724 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 6 Feb 2025 19:00:33 -0800 Subject: [PATCH 112/123] ci: run latest stack files --- .github/workflows/aeson-typescript.yml | 3 +++ stack-9.10.1.yaml | 5 +++++ stack-9.10.1.yaml.lock | 12 ++++++++++++ stack-9.6.6.yaml.lock | 12 ++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 stack-9.10.1.yaml create mode 100644 stack-9.10.1.yaml.lock create mode 100644 stack-9.6.6.yaml.lock diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index fcffabb..0a45431 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -19,6 +19,7 @@ jobs: - "9.4.8" - "9.6.6" - "9.8.4" + - "9.10.1" steps: - uses: actions/checkout@v2 @@ -75,6 +76,8 @@ jobs: yaml: "stack-9.6.6.yaml" - ghc: "9.8.4" yaml: "stack-9.8.4.yaml" + - ghc: "9.10.1" + yaml: "stack-9.10.1.yaml" steps: - uses: actions/checkout@v3 diff --git a/stack-9.10.1.yaml b/stack-9.10.1.yaml new file mode 100644 index 0000000..db6fede --- /dev/null +++ b/stack-9.10.1.yaml @@ -0,0 +1,5 @@ + +resolver: nightly-2025-02-04 + +packages: +- . diff --git a/stack-9.10.1.yaml.lock b/stack-9.10.1.yaml.lock new file mode 100644 index 0000000..d12fe41 --- /dev/null +++ b/stack-9.10.1.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: a1b6c372b9194401b72c7c707b257215a4bed0649b8114c778d9fa17db15a4cb + size: 650398 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2025/2/4.yaml + original: nightly-2025-02-04 diff --git a/stack-9.6.6.yaml.lock b/stack-9.6.6.yaml.lock new file mode 100644 index 0000000..f9829eb --- /dev/null +++ b/stack-9.6.6.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 08bd13ce621b41a8f5e51456b38d5b46d7783ce114a50ab604d6bbab0d002146 + size: 720271 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/43.yaml + original: lts-22.43 From 7d22ebbbb8cc61e86cd9295d6af5659c1845c405 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 6 Feb 2025 19:00:48 -0800 Subject: [PATCH 113/123] Update some flake stuff and CHANGELOG --- CHANGELOG.md | 2 ++ flake.lock | 18 +++++++++--------- flake.nix | 3 +++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32aa218..aabd8b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Remove question mark in Data.Map instance + ## 0.6.4.0 * Fix type for maps with non-string keys (#46, fixes #28, thanks @tfausak!) diff --git a/flake.lock b/flake.lock index bf6c88e..d658202 100644 --- a/flake.lock +++ b/flake.lock @@ -158,11 +158,11 @@ "hackage": { "flake": false, "locked": { - "lastModified": 1738628879, - "narHash": "sha256-fQNlSl5f6MPKLI7RmqLKHdix3YtxVkAyZ0b7XzNn1YQ=", + "lastModified": 1738715278, + "narHash": "sha256-SI154ShwJ24faTWlV/+phNfwOR7il5LPyRulpsCToHI=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "901791fe0870fc8816fb52665774fb7b4d591ed9", + "rev": "08261aa338ce30b6817ec7ed37b097ef284154e0", "type": "github" }, "original": { @@ -211,11 +211,11 @@ "stackage": "stackage" }, "locked": { - "lastModified": 1738630291, - "narHash": "sha256-sT8M2+hNzQl2flJZY0lAD9Ygpr5f4deKecc/OuNRVP0=", + "lastModified": 1738716891, + "narHash": "sha256-DLK/yKwY19sRRRXQvrPkcUOqYwMBWCt1woiPxOuIYGs=", "owner": "input-output-hk", "repo": "haskell.nix", - "rev": "2cb66646461d4388b950621190af3840169fe883", + "rev": "908d11a14c51adecaa6d5fc6866b450a8fdd8a52", "type": "github" }, "original": { @@ -618,11 +618,11 @@ "stackage": { "flake": false, "locked": { - "lastModified": 1738627879, - "narHash": "sha256-NqNxhRroKBitD8BxoDTSXJbw9R3pPlsaVkoYqiPbDT0=", + "lastModified": 1738714273, + "narHash": "sha256-0X3JlXEcmLCVAM0kxU6ha3dmcoPjAMVs4Rt4zMrbJ0Q=", "owner": "input-output-hk", "repo": "stackage.nix", - "rev": "42916147b7e9e8f751cac1881a60bcbb8839ec3d", + "rev": "23b0d89937dadc38d96a9c0768dfcef0cf8e5a1b", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index b48a9ff..a29bd1f 100644 --- a/flake.nix +++ b/flake.nix @@ -14,6 +14,7 @@ let # compiler-nix-name = "ghc966"; compiler-nix-name = "ghc984"; + # compiler-nix-name = "ghc9101"; pkgs = import nixpkgs { inherit system; @@ -33,7 +34,9 @@ flakeWindows = (pkgs.pkgsCross.mingwW64.haskell-nix.hix.project { inherit src compiler-nix-name; evalSystem = system; + # projectFileName = "stack.yaml"; projectFileName = "stack-9.8.4.yaml"; + # projectFileName = "stack-9.10.1.yaml"; modules = [{ reinstallableLibGhc = false; }]; From 98f57d555ebed5254f3551e06a63c6eca35ea7dd Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 6 Feb 2025 19:10:12 -0800 Subject: [PATCH 114/123] ci: haskell/actions/setup -> haskell-actions/setup --- .github/workflows/aeson-typescript.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 0a45431..e58e3a9 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: haskell/actions/setup@v2 + - uses: haskell-actions/setup@v2 id: setup-haskell-cabal name: Setup Haskell with: @@ -82,7 +82,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: haskell/actions/setup@v2 + - uses: haskell-actions/setup@v2 name: Setup Haskell Stack with: ghc-version: ${{ matrix.ghc }} From 3d8bae393e826b1c7858fb509d320d3f82b82b3a Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 6 Feb 2025 19:37:53 -0800 Subject: [PATCH 115/123] ci: exclude older GHCs on macOS --- .github/workflows/aeson-typescript.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index e58e3a9..ac56835 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -20,6 +20,13 @@ jobs: - "9.6.6" - "9.8.4" - "9.10.1" + exclude: + # These don't work on GitHub CI anymore because they need llvm@13, which became + # disabled on 12/31/2024 + - os: macOS-latest + ghc: 8.10.7 + - os: macOS-latest + ghc: 9.0.2 steps: - uses: actions/checkout@v2 From eb5f6f611e64d83e778c7a1aca42e750fd474469 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 31 Jul 2025 09:29:45 -0700 Subject: [PATCH 116/123] stack-9.10.1.yaml -> stack-9.10.2.yaml --- stack-9.10.1.yaml | 5 ----- stack-9.10.2.yaml | 5 +++++ stack-9.10.1.yaml.lock => stack-9.10.2.yaml.lock | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 stack-9.10.1.yaml create mode 100644 stack-9.10.2.yaml rename stack-9.10.1.yaml.lock => stack-9.10.2.yaml.lock (51%) diff --git a/stack-9.10.1.yaml b/stack-9.10.1.yaml deleted file mode 100644 index db6fede..0000000 --- a/stack-9.10.1.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resolver: nightly-2025-02-04 - -packages: -- . diff --git a/stack-9.10.2.yaml b/stack-9.10.2.yaml new file mode 100644 index 0000000..09bacd7 --- /dev/null +++ b/stack-9.10.2.yaml @@ -0,0 +1,5 @@ + +resolver: lts-24.2 + +packages: +- . diff --git a/stack-9.10.1.yaml.lock b/stack-9.10.2.yaml.lock similarity index 51% rename from stack-9.10.1.yaml.lock rename to stack-9.10.2.yaml.lock index d12fe41..8e22df7 100644 --- a/stack-9.10.1.yaml.lock +++ b/stack-9.10.2.yaml.lock @@ -1,12 +1,12 @@ # This file was autogenerated by Stack. # You should not edit this file by hand. # For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/lock_files +# https://docs.haskellstack.org/en/stable/topics/lock_files packages: [] snapshots: - completed: - sha256: a1b6c372b9194401b72c7c707b257215a4bed0649b8114c778d9fa17db15a4cb - size: 650398 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2025/2/4.yaml - original: nightly-2025-02-04 + sha256: cd28bd74375205718f1d5fa221730a9c17a203059708b1eb95f4b20d68bf82d9 + size: 724943 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/24/2.yaml + original: lts-24.2 From dd6aaaca1723cee7da68848e19e0b9e81bd7d87a Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 31 Jul 2025 09:30:13 -0700 Subject: [PATCH 117/123] dev stack.yaml: bump to GHC 9.12 and use .envrc-provided ghc/HLS --- flake.lock | 245 ++++++++++++++++++++++++++++-------------------- flake.nix | 11 ++- stack.yaml | 6 +- stack.yaml.lock | 10 +- 4 files changed, 159 insertions(+), 113 deletions(-) diff --git a/flake.lock b/flake.lock index d658202..aeb0daf 100644 --- a/flake.lock +++ b/flake.lock @@ -158,11 +158,44 @@ "hackage": { "flake": false, "locked": { - "lastModified": 1738715278, - "narHash": "sha256-SI154ShwJ24faTWlV/+phNfwOR7il5LPyRulpsCToHI=", + "lastModified": 1753922646, + "narHash": "sha256-eVvEjP9s6iQCPQFbb66+Gzd3ZM6BjIqfFzuf/yk9D7U=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "08261aa338ce30b6817ec7ed37b097ef284154e0", + "rev": "224f3770869031c2129c82061aeeabb6b8035aad", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "hackage-for-stackage": { + "flake": false, + "locked": { + "lastModified": 1753921689, + "narHash": "sha256-F7yJ6l+Qb97hCTrBn24JeX4bzg5dEARtQ2HJKy3Vc48=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "b8dbf163f00e329f2090733108b427c03d6976fc", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "for-stackage", + "repo": "hackage.nix", + "type": "github" + } + }, + "hackage-internal": { + "flake": false, + "locked": { + "lastModified": 1750307553, + "narHash": "sha256-iiafNoeLHwlSLQTyvy8nPe2t6g5AV4PPcpMeH/2/DLs=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "f7867baa8817fab296528f4a4ec39d1c7c4da4f3", "type": "github" }, "original": { @@ -181,8 +214,13 @@ "flake-compat": "flake-compat", "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", "hackage": "hackage", + "hackage-for-stackage": "hackage-for-stackage", + "hackage-internal": "hackage-internal", + "hls": "hls", "hls-1.10": "hls-1.10", "hls-2.0": "hls-2.0", + "hls-2.10": "hls-2.10", + "hls-2.11": "hls-2.11", "hls-2.2": "hls-2.2", "hls-2.3": "hls-2.3", "hls-2.4": "hls-2.4", @@ -197,25 +235,21 @@ "haskellNix", "nixpkgs-unstable" ], - "nixpkgs-2003": "nixpkgs-2003", - "nixpkgs-2105": "nixpkgs-2105", - "nixpkgs-2111": "nixpkgs-2111", - "nixpkgs-2205": "nixpkgs-2205", - "nixpkgs-2211": "nixpkgs-2211", "nixpkgs-2305": "nixpkgs-2305", "nixpkgs-2311": "nixpkgs-2311", "nixpkgs-2405": "nixpkgs-2405", "nixpkgs-2411": "nixpkgs-2411", + "nixpkgs-2505": "nixpkgs-2505", "nixpkgs-unstable": "nixpkgs-unstable", "old-ghc-nix": "old-ghc-nix", "stackage": "stackage" }, "locked": { - "lastModified": 1738716891, - "narHash": "sha256-DLK/yKwY19sRRRXQvrPkcUOqYwMBWCt1woiPxOuIYGs=", + "lastModified": 1753923139, + "narHash": "sha256-9LriT9Da9oQ5+PhUBZCHqmzRMv2M2lJ8ts6KgJX2DKQ=", "owner": "input-output-hk", "repo": "haskell.nix", - "rev": "908d11a14c51adecaa6d5fc6866b450a8fdd8a52", + "rev": "758d34c249352818ee786abb06068b8a9e29c098", "type": "github" }, "original": { @@ -224,6 +258,22 @@ "type": "github" } }, + "hls": { + "flake": false, + "locked": { + "lastModified": 1741604408, + "narHash": "sha256-tuq3+Ip70yu89GswZ7DSINBpwRprnWnl6xDYnS4GOsc=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "682d6894c94087da5e566771f25311c47e145359", + "type": "github" + }, + "original": { + "owner": "haskell", + "repo": "haskell-language-server", + "type": "github" + } + }, "hls-1.10": { "flake": false, "locked": { @@ -258,6 +308,40 @@ "type": "github" } }, + "hls-2.10": { + "flake": false, + "locked": { + "lastModified": 1743069404, + "narHash": "sha256-q4kDFyJDDeoGqfEtrZRx4iqMVEC2MOzCToWsFY+TOzY=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "2318c61db3a01e03700bd4b05665662929b7fe8b", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.10.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "hls-2.11": { + "flake": false, + "locked": { + "lastModified": 1747306193, + "narHash": "sha256-/MmtpF8+FyQlwfKHqHK05BdsxC9LHV70d/FiMM7pzBM=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "46ef4523ea4949f47f6d2752476239f1c6d806fe", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "2.11.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, "hls-2.2": { "flake": false, "locked": { @@ -380,11 +464,11 @@ "hls-2.9": { "flake": false, "locked": { - "lastModified": 1720003792, - "narHash": "sha256-qnDx8Pk0UxtoPr7BimEsAZh9g2WuTuMB/kGqnmdryKs=", + "lastModified": 1719993701, + "narHash": "sha256-wy348++MiMm/xwtI9M3vVpqj2qfGgnDcZIGXw8sF1sA=", "owner": "haskell", "repo": "haskell-language-server", - "rev": "0c1817cb2babef0765e4e72dd297c013e8e3d12b", + "rev": "90319a7e62ab93ab65a95f8f2bcf537e34dae76a", "type": "github" }, "original": { @@ -413,11 +497,11 @@ "iserv-proxy": { "flake": false, "locked": { - "lastModified": 1717479972, - "narHash": "sha256-7vE3RQycHI1YT9LHJ1/fUaeln2vIpYm6Mmn8FTpYeVo=", + "lastModified": 1750543273, + "narHash": "sha256-WaswH0Y+Fmupvv8AkIlQBlUy/IdD3Inx9PDuE+5iRYY=", "owner": "stable-haskell", "repo": "iserv-proxy", - "rev": "2ed34002247213fc435d0062350b91bab920626e", + "rev": "a53c57c9a8d22a66a2f0c4c969e806da03f08c28", "type": "github" }, "original": { @@ -427,162 +511,114 @@ "type": "github" } }, - "nixpkgs-2003": { - "locked": { - "lastModified": 1620055814, - "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-20.03-darwin", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-2105": { - "locked": { - "lastModified": 1659914493, - "narHash": "sha256-lkA5X3VNMKirvA+SUzvEhfA7XquWLci+CGi505YFAIs=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "022caabb5f2265ad4006c1fa5b1ebe69fb0c3faf", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-21.05-darwin", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-2111": { - "locked": { - "lastModified": 1659446231, - "narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "eabc38219184cc3e04a974fe31857d8e0eac098d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-21.11-darwin", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-2205": { + "nixpkgs-2305": { "locked": { - "lastModified": 1685573264, - "narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=", + "lastModified": 1705033721, + "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "380be19fbd2d9079f677978361792cb25e8a3635", + "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-22.05-darwin", + "ref": "nixpkgs-23.05-darwin", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-2211": { + "nixpkgs-2311": { "locked": { - "lastModified": 1688392541, - "narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=", + "lastModified": 1719957072, + "narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b", + "rev": "7144d6241f02d171d25fba3edeaf15e0f2592105", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-22.11-darwin", + "ref": "nixpkgs-23.11-darwin", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-2305": { + "nixpkgs-2405": { "locked": { - "lastModified": 1705033721, - "narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=", + "lastModified": 1735564410, + "narHash": "sha256-HB/FA0+1gpSs8+/boEavrGJH+Eq08/R2wWNph1sM1Dg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea", + "rev": "1e7a8f391f1a490460760065fa0630b5520f9cf8", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-23.05-darwin", + "ref": "nixpkgs-24.05-darwin", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-2311": { + "nixpkgs-2411": { "locked": { - "lastModified": 1719957072, - "narHash": "sha256-gvFhEf5nszouwLAkT9nWsDzocUTqLWHuL++dvNjMp9I=", + "lastModified": 1748037224, + "narHash": "sha256-92vihpZr6dwEMV6g98M5kHZIttrWahb9iRPBm1atcPk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7144d6241f02d171d25fba3edeaf15e0f2592105", + "rev": "f09dede81861f3a83f7f06641ead34f02f37597f", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-23.11-darwin", + "ref": "nixpkgs-24.11-darwin", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-2405": { + "nixpkgs-2505": { "locked": { - "lastModified": 1735564410, - "narHash": "sha256-HB/FA0+1gpSs8+/boEavrGJH+Eq08/R2wWNph1sM1Dg=", + "lastModified": 1748852332, + "narHash": "sha256-r/wVJWmLYEqvrJKnL48r90Wn9HWX9SHFt6s4LhuTh7k=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1e7a8f391f1a490460760065fa0630b5520f9cf8", + "rev": "a8167f3cc2f991dd4d0055746df53dae5fd0c953", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-24.05-darwin", + "ref": "nixpkgs-25.05-darwin", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-2411": { + "nixpkgs-unstable": { "locked": { - "lastModified": 1737255904, - "narHash": "sha256-r3fxHvh+M/mBgCZXOACzRFPsJdix2QSsKazb7VCXXo0=", + "lastModified": 1748856973, + "narHash": "sha256-RlTsJUvvr8ErjPBsiwrGbbHYW8XbB/oek0Gi78XdWKg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "eacdab35066b0bb1c9413c96898e326b76398a81", + "rev": "e4b09e47ace7d87de083786b404bf232eb6c89d8", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-24.11-darwin", + "ref": "nixpkgs-unstable", "repo": "nixpkgs", "type": "github" } }, - "nixpkgs-unstable": { + "nixpkgsMaster": { "locked": { - "lastModified": 1737110817, - "narHash": "sha256-DSenga8XjPaUV5KUFW/i3rNkN7jm9XmguW+qQ1ZJTR4=", + "lastModified": 1753975144, + "narHash": "sha256-QsCqY2NnLN+47+j/J8V0PHemua+iA7em8pw1yID1RN0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "041c867bad68dfe34b78b2813028a2e2ea70a23c", + "rev": "63e24fbc205fc7484ac7c90212a94853be116de4", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-unstable", + "ref": "master", "repo": "nixpkgs", "type": "github" } @@ -612,17 +648,18 @@ "nixpkgs": [ "haskellNix", "nixpkgs" - ] + ], + "nixpkgsMaster": "nixpkgsMaster" } }, "stackage": { "flake": false, "locked": { - "lastModified": 1738714273, - "narHash": "sha256-0X3JlXEcmLCVAM0kxU6ha3dmcoPjAMVs4Rt4zMrbJ0Q=", + "lastModified": 1753920846, + "narHash": "sha256-jk2dKSlLgEfwpwocH2GX9mfwLSV0anmyjJ400zqCGq8=", "owner": "input-output-hk", "repo": "stackage.nix", - "rev": "23b0d89937dadc38d96a9c0768dfcef0cf8e5a1b", + "rev": "edb12eda18a509b65576505316a7419ad2dbfb69", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index a29bd1f..268b584 100644 --- a/flake.nix +++ b/flake.nix @@ -8,8 +8,9 @@ }; inputs.haskellNix.url = "github:input-output-hk/haskell.nix"; inputs.nixpkgs.follows = "haskellNix/nixpkgs"; + inputs.nixpkgsMaster.url = "github:NixOS/nixpkgs/master"; - outputs = { self, flake-utils, gitignore, haskellNix, nixpkgs }: + outputs = { self, flake-utils, gitignore, haskellNix, nixpkgs, nixpkgsMaster }: flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: let # compiler-nix-name = "ghc966"; @@ -22,6 +23,10 @@ inherit (haskellNix) config; }; + pkgsMaster = import nixpkgsMaster { + inherit system; + }; + src = gitignore.lib.gitignoreSource ./.; flake = (pkgs.haskell-nix.hix.project { @@ -62,7 +67,9 @@ devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ - nodePackages.typescript + pkgs.nodePackages.typescript + pkgsMaster.haskell.compiler.ghc9122 + (pkgsMaster.haskell-language-server.override { supportedGhcVersions = ["9122"]; }) ]; }; }); diff --git a/stack.yaml b/stack.yaml index dfcce6a..b026e0d 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,8 +1,10 @@ -resolver: lts-23.7 +resolver: nightly-2025-07-31 nix: - pure: false + enable: false + +system-ghc: true packages: - . diff --git a/stack.yaml.lock b/stack.yaml.lock index 0e99322..76ec781 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -1,12 +1,12 @@ # This file was autogenerated by Stack. # You should not edit this file by hand. # For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/lock_files +# https://docs.haskellstack.org/en/stable/topics/lock_files packages: [] snapshots: - completed: - sha256: 4ef79c30b9efcf07335cb3de532983a7ac4c5a4180bc17f6212a86b09ce2ff75 - size: 680777 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/7.yaml - original: lts-23.7 + sha256: 3dec7f4c6dc2dc10047d2941a6bc9ee8fa6a84f6db932096cbd83a0ace83dfa1 + size: 672916 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2025/7/31.yaml + original: nightly-2025-07-31 From a10b1babcaf77e7fd8e6e9794d66451245f931c9 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 31 Jul 2025 09:34:22 -0700 Subject: [PATCH 118/123] Handle Maybe correctly in tuple encodings (fixes #49) --- src/Data/Aeson/TypeScript/TH.hs | 9 +++++++-- test/Basic.hs | 9 +++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 4663a8f..3cd7227 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -307,10 +307,15 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene -- * Type declaration to use interfaceName = "I" <> (lastNameComponent' $ constructorName ci) - tupleEncoding = + tupleEncoding = do + let typ = contentsTupleTypeSubstituted genericVariables ci + stringExp <- lift $ case typ of + (AppT (ConT name) t) | name == ''Maybe -> [|$(getTypeAsStringExp t) <> " | null"|] + _ -> getTypeAsStringExp typ + lift [|TSTypeAlternatives $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) - [getTypeScriptType (Proxy :: Proxy $(return (contentsTupleTypeSubstituted genericVariables ci)))] + [$(return stringExp)] $(tryGetDoc haddockModifier (constructorName ci))|] assembleInterfaceDeclaration members = [|TSInterfaceDeclaration $(TH.stringE interfaceName) diff --git a/test/Basic.hs b/test/Basic.hs index 18c226d..a6c7a86 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -17,6 +17,9 @@ data Unit2 = Unit2 $(deriveTypeScript (A.defaultOptions { A.tagSingleConstructors = True , A.constructorTagModifier = const "foo" }) ''Unit2) +data Test1 = Test1 (Maybe Int) +deriveTypeScript A.defaultOptions ''Test1 + tests :: SpecWith () tests = describe "Basic tests" $ do describe "tagSingleConstructors and constructorTagModifier" $ do @@ -31,6 +34,12 @@ tests = describe "Basic tests" $ do TSTypeAlternatives "Unit2" [] ["\"foo\""] Nothing ]) + it [i|Maybe tuple encoding includes null option|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy Test1)) `shouldBe` ([ + TSTypeAlternatives "Test1" [] ["ITest1"] Nothing + , TSTypeAlternatives "ITest1" [] ["number | null"] Nothing + ]) + main :: IO () main = hspec tests From 5fc225d4c198b932fc7e78247620a3335b083a07 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 31 Jul 2025 11:01:04 -0700 Subject: [PATCH 119/123] stack-9.6.6.yaml -> stack-9.6.7.yaml + update CI --- .github/workflows/aeson-typescript.yml | 8 ++++---- stack-9.6.6.yaml | 5 ----- stack-9.6.7.yaml | 5 +++++ stack-9.6.6.yaml.lock => stack-9.6.7.yaml.lock | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 stack-9.6.6.yaml create mode 100644 stack-9.6.7.yaml rename stack-9.6.6.yaml.lock => stack-9.6.7.yaml.lock (52%) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index ac56835..f5f7830 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -17,9 +17,9 @@ jobs: - "9.0.2" - "9.2.8" - "9.4.8" - - "9.6.6" + - "9.6.7" - "9.8.4" - - "9.10.1" + - "9.10.2" exclude: # These don't work on GitHub CI anymore because they need llvm@13, which became # disabled on 12/31/2024 @@ -83,8 +83,8 @@ jobs: yaml: "stack-9.6.6.yaml" - ghc: "9.8.4" yaml: "stack-9.8.4.yaml" - - ghc: "9.10.1" - yaml: "stack-9.10.1.yaml" + - ghc: "9.10.2" + yaml: "stack-9.10.2.yaml" steps: - uses: actions/checkout@v3 diff --git a/stack-9.6.6.yaml b/stack-9.6.6.yaml deleted file mode 100644 index da3643b..0000000 --- a/stack-9.6.6.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resolver: lts-22.43 - -packages: -- . diff --git a/stack-9.6.7.yaml b/stack-9.6.7.yaml new file mode 100644 index 0000000..e06d1e2 --- /dev/null +++ b/stack-9.6.7.yaml @@ -0,0 +1,5 @@ + +resolver: lts-22.44 + +packages: +- . diff --git a/stack-9.6.6.yaml.lock b/stack-9.6.7.yaml.lock similarity index 52% rename from stack-9.6.6.yaml.lock rename to stack-9.6.7.yaml.lock index f9829eb..8d134eb 100644 --- a/stack-9.6.6.yaml.lock +++ b/stack-9.6.7.yaml.lock @@ -1,12 +1,12 @@ # This file was autogenerated by Stack. # You should not edit this file by hand. # For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/lock_files +# https://docs.haskellstack.org/en/stable/topics/lock_files packages: [] snapshots: - completed: - sha256: 08bd13ce621b41a8f5e51456b38d5b46d7783ce114a50ab604d6bbab0d002146 - size: 720271 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/43.yaml - original: lts-22.43 + sha256: 238fa745b64f91184f9aa518fe04bdde6552533d169b0da5256670df83a0f1a9 + size: 721141 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/44.yaml + original: lts-22.44 From 981defc26a2e6bd4c14c953fd3fba0d416121cf1 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 31 Jul 2025 11:47:33 -0700 Subject: [PATCH 120/123] ci: another update --- .github/workflows/aeson-typescript.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index f5f7830..784ec16 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -79,8 +79,8 @@ jobs: yaml: "stack-9.2.8.yaml" - ghc: "9.4.8" yaml: "stack-9.4.8.yaml" - - ghc: "9.6.6" - yaml: "stack-9.6.6.yaml" + - ghc: "9.6.7" + yaml: "stack-9.6.7.yaml" - ghc: "9.8.4" yaml: "stack-9.8.4.yaml" - ghc: "9.10.2" From 79816488ef338875b3808e69bb4b95a9b60f70da Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 31 Jul 2025 11:59:45 -0700 Subject: [PATCH 121/123] ci: try testing GHC 9.12.2 --- .github/workflows/aeson-typescript.yml | 3 +++ stack-9.12.2.yaml | 10 ++++++++++ stack-9.12.2.yaml.lock | 12 ++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 stack-9.12.2.yaml create mode 100644 stack-9.12.2.yaml.lock diff --git a/.github/workflows/aeson-typescript.yml b/.github/workflows/aeson-typescript.yml index 784ec16..7cd9973 100644 --- a/.github/workflows/aeson-typescript.yml +++ b/.github/workflows/aeson-typescript.yml @@ -20,6 +20,7 @@ jobs: - "9.6.7" - "9.8.4" - "9.10.2" + - "9.12.2" exclude: # These don't work on GitHub CI anymore because they need llvm@13, which became # disabled on 12/31/2024 @@ -85,6 +86,8 @@ jobs: yaml: "stack-9.8.4.yaml" - ghc: "9.10.2" yaml: "stack-9.10.2.yaml" + - ghc: "9.12.2" + yaml: "stack-9.12.2.yaml" steps: - uses: actions/checkout@v3 diff --git a/stack-9.12.2.yaml b/stack-9.12.2.yaml new file mode 100644 index 0000000..b026e0d --- /dev/null +++ b/stack-9.12.2.yaml @@ -0,0 +1,10 @@ + +resolver: nightly-2025-07-31 + +nix: + enable: false + +system-ghc: true + +packages: +- . diff --git a/stack-9.12.2.yaml.lock b/stack-9.12.2.yaml.lock new file mode 100644 index 0000000..76ec781 --- /dev/null +++ b/stack-9.12.2.yaml.lock @@ -0,0 +1,12 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/topics/lock_files + +packages: [] +snapshots: +- completed: + sha256: 3dec7f4c6dc2dc10047d2941a6bc9ee8fa6a84f6db932096cbd83a0ace83dfa1 + size: 672916 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2025/7/31.yaml + original: nightly-2025-07-31 From b02479d9abfe0055c83a9dac411b831afbcbe13a Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Thu, 31 Jul 2025 22:57:34 -0700 Subject: [PATCH 122/123] flake.nix: use eachDefaultSystem --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 268b584..bebda18 100644 --- a/flake.nix +++ b/flake.nix @@ -11,7 +11,7 @@ inputs.nixpkgsMaster.url = "github:NixOS/nixpkgs/master"; outputs = { self, flake-utils, gitignore, haskellNix, nixpkgs, nixpkgsMaster }: - flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: + flake-utils.lib.eachDefaultSystem (system: let # compiler-nix-name = "ghc966"; compiler-nix-name = "ghc984"; From 846f4de8d54278c49456a29803da6f01ab9b87f6 Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Fri, 1 Aug 2025 11:37:33 -0700 Subject: [PATCH 123/123] Fix more issues with Maybes inside tuple encodings (#52) * Add MaybeTuples tests * Add getTypeScriptTypeOrOptionalNull helper to use in tuple instances * Use TH to derive tuple instances up to size 10 * Use getTypeScriptTypeOrOptionalNull to tidy TH.hs * Fix a few warnings * Tighten up a couple haddocks * Add size-1 and size-2 tuples to TestBoilerplate.hs --- aeson-typescript.cabal | 5 +- src/Data/Aeson/TypeScript/Instances.hs | 23 +----- .../Aeson/TypeScript/Instances/TupleGen.hs | 36 +++++++++ src/Data/Aeson/TypeScript/Recursive.hs | 1 - src/Data/Aeson/TypeScript/TH.hs | 10 +-- src/Data/Aeson/TypeScript/Types.hs | 6 ++ src/Data/Aeson/TypeScript/Util.hs | 6 +- test/Basic.hs | 15 ---- test/MaybeTuples.hs | 78 +++++++++++++++++++ test/NoOmitNothingFields.hs | 6 +- test/OmitNothingFields.hs | 4 +- test/Spec.hs | 4 +- test/TestBoilerplate.hs | 22 ++++-- 13 files changed, 159 insertions(+), 57 deletions(-) create mode 100644 src/Data/Aeson/TypeScript/Instances/TupleGen.hs create mode 100644 test/MaybeTuples.hs diff --git a/aeson-typescript.cabal b/aeson-typescript.cabal index a448269..2387dd8 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.37.0. +-- This file has been generated from package.yaml by hpack version 0.38.0. -- -- see: https://github.com/sol/hpack @@ -46,6 +46,7 @@ library other-modules: Data.Aeson.TypeScript.Formatting Data.Aeson.TypeScript.Instances + Data.Aeson.TypeScript.Instances.TupleGen Data.Aeson.TypeScript.Lookup Data.Aeson.TypeScript.Transform Data.Aeson.TypeScript.TypeManipulation @@ -89,6 +90,7 @@ test-suite aeson-typescript-tests GetDoc HigherKind LegalNameSpec + MaybeTuples NoOmitNothingFields ObjectWithSingleFieldNoTagSingleConstructors ObjectWithSingleFieldTagSingleConstructors @@ -106,6 +108,7 @@ test-suite aeson-typescript-tests Util.Aeson Data.Aeson.TypeScript.Formatting Data.Aeson.TypeScript.Instances + Data.Aeson.TypeScript.Instances.TupleGen Data.Aeson.TypeScript.Internal Data.Aeson.TypeScript.LegalName Data.Aeson.TypeScript.Lookup diff --git a/src/Data/Aeson/TypeScript/Instances.hs b/src/Data/Aeson/TypeScript/Instances.hs index 988aec0..2f61ce6 100644 --- a/src/Data/Aeson/TypeScript/Instances.hs +++ b/src/Data/Aeson/TypeScript/Instances.hs @@ -13,6 +13,7 @@ module Data.Aeson.TypeScript.Instances where import qualified Data.Aeson as A +import Data.Aeson.TypeScript.Instances.TupleGen import Data.Aeson.TypeScript.Types import Data.Data import Data.Functor.Compose (Compose) @@ -121,26 +122,8 @@ instance (TypeScript a, TypeScript b) => TypeScript (Either a b) where , (TSType (Proxy :: Proxy b)) ] -instance (TypeScript a, TypeScript b) => TypeScript (a, b) where - getTypeScriptType _ = [i|[#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}]|] - getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) - , (TSType (Proxy :: Proxy b)) - ] - -instance (TypeScript a, TypeScript b, TypeScript c) => TypeScript (a, b, c) where - getTypeScriptType _ = [i|[#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}, #{getTypeScriptType (Proxy :: Proxy c)}]|] - getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) - , (TSType (Proxy :: Proxy b)) - , (TSType (Proxy :: Proxy c)) - ] - -instance (TypeScript a, TypeScript b, TypeScript c, TypeScript d) => TypeScript (a, b, c, d) where - getTypeScriptType _ = [i|[#{getTypeScriptType (Proxy :: Proxy a)}, #{getTypeScriptType (Proxy :: Proxy b)}, #{getTypeScriptType (Proxy :: Proxy c)}, #{getTypeScriptType (Proxy :: Proxy d)}]|] - getParentTypes _ = L.nub [ (TSType (Proxy :: Proxy a)) - , (TSType (Proxy :: Proxy b)) - , (TSType (Proxy :: Proxy c)) - , (TSType (Proxy :: Proxy d)) - ] +-- Derive instance TypeScript (a, b), instance TypeScript (a, b, c), etc. up to size 10 +mkTupleInstances 10 instance forall a k (b :: k). (Typeable k, Typeable b, TypeScript a) => TypeScript (Const a b) where getTypeScriptType _ = getTypeScriptType (Proxy :: Proxy a) diff --git a/src/Data/Aeson/TypeScript/Instances/TupleGen.hs b/src/Data/Aeson/TypeScript/Instances/TupleGen.hs new file mode 100644 index 0000000..e4ca456 --- /dev/null +++ b/src/Data/Aeson/TypeScript/Instances/TupleGen.hs @@ -0,0 +1,36 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE QuasiQuotes #-} + +module Data.Aeson.TypeScript.Instances.TupleGen where + +import Data.Aeson.TypeScript.Types +import Data.Data +import Data.List (intercalate) +import qualified Data.List as L +import Language.Haskell.TH + + +mkTupleInstance :: Int -> Q Dec +mkTupleInstance n = do + let typeVars = take n $ map (mkName . (:[])) ['a'..] + constraints = map (\tv -> AppT (ConT ''TypeScript) (VarT tv)) typeVars + tupleType = foldl AppT (TupleT n) (map VarT typeVars) + instanceHead = AppT (ConT ''TypeScript) tupleType + + getTypeBody <- buildTypeBody typeVars + let getTypeMethod = FunD 'getTypeScriptType [Clause [WildP] (NormalB getTypeBody) []] + + let tsTypes = map (\tv -> AppE (ConE 'TSType) (SigE (ConE 'Proxy) (AppT (ConT ''Proxy) (VarT tv)))) typeVars + getParentsMethod = FunD 'getParentTypes [Clause [WildP] (NormalB (AppE (VarE 'L.nub) (ListE tsTypes))) []] + + return $ InstanceD Nothing constraints instanceHead [getTypeMethod, getParentsMethod] + +buildTypeBody :: [Name] -> Q Exp +buildTypeBody typeVars = do + let calls = map (\tv -> AppE (VarE 'getTypeScriptTypeOrOptionalNull) + (SigE (ConE 'Proxy) (AppT (ConT ''Proxy) (VarT tv)))) typeVars + parts = [LitE (StringL "[")] ++ intercalate [LitE (StringL ", ")] (map (:[]) calls) ++ [LitE (StringL "]")] + return $ foldr1 (\a b -> InfixE (Just a) (VarE '(++)) (Just b)) parts + +mkTupleInstances :: Int -> Q [Dec] +mkTupleInstances maxArity = mapM mkTupleInstance [2..maxArity] diff --git a/src/Data/Aeson/TypeScript/Recursive.hs b/src/Data/Aeson/TypeScript/Recursive.hs index 8eb673c..e5f5daa 100755 --- a/src/Data/Aeson/TypeScript/Recursive.hs +++ b/src/Data/Aeson/TypeScript/Recursive.hs @@ -32,7 +32,6 @@ import qualified Data.Set as S import Data.String.Interpolate import Language.Haskell.TH as TH import Language.Haskell.TH.Datatype -import Language.Haskell.TH.Syntax hiding (lift) getTransitiveClosure :: S.Set TSType -> S.Set TSType diff --git a/src/Data/Aeson/TypeScript/TH.hs b/src/Data/Aeson/TypeScript/TH.hs index 3cd7227..6f926cf 100644 --- a/src/Data/Aeson/TypeScript/TH.hs +++ b/src/Data/Aeson/TypeScript/TH.hs @@ -289,9 +289,7 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene #if MIN_VERSION_aeson(0,10,0) | unwrapUnaryRecords options && (isSingleRecordConstructor ci) -> do let [typ] = constructorFields ci - stringExp <- lift $ case typ of - (AppT (ConT name) t) | name == ''Maybe && not (omitNothingFields options) -> [|$(getTypeAsStringExp t) <> " | null"|] - _ -> getTypeAsStringExp typ + stringExp <- lift $ [|getTypeScriptTypeOrOptionalNull (Proxy :: Proxy $(return typ))|] alternatives <- lift [|TSTypeAlternatives $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) [$(return stringExp)] @@ -309,9 +307,7 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene tupleEncoding = do let typ = contentsTupleTypeSubstituted genericVariables ci - stringExp <- lift $ case typ of - (AppT (ConT name) t) | name == ''Maybe -> [|$(getTypeAsStringExp t) <> " | null"|] - _ -> getTypeAsStringExp typ + stringExp <- lift $ [|getTypeScriptTypeOrOptionalNull (Proxy :: Proxy $(return typ))|] lift [|TSTypeAlternatives $(TH.stringE interfaceName) $(genericVariablesListExpr True genericVariables) @@ -326,7 +322,7 @@ handleConstructor (ExtraTypeScriptOptions {..}) options (DatatypeInfo {..}) gene getTSFields :: WriterT [ExtraDeclOrGenericInfo] Q [Exp] getTSFields = forM (namesAndTypes options genericVariables ci) $ \(name, nameString, typ) -> do (fieldTyp, optAsBool) <- lift $ case typ of - (AppT (ConT name) t) | name == ''Maybe && not (omitNothingFields options) -> + (AppT (ConT name') t) | name' == ''Maybe && not (omitNothingFields options) -> ( , ) <$> [|$(getTypeAsStringExp t) <> " | null"|] <*> getOptionalAsBoolExp t _ -> ( , ) <$> getTypeAsStringExp typ <*> getOptionalAsBoolExp typ diff --git a/src/Data/Aeson/TypeScript/Types.hs b/src/Data/Aeson/TypeScript/Types.hs index a96f635..910ec73 100644 --- a/src/Data/Aeson/TypeScript/Types.hs +++ b/src/Data/Aeson/TypeScript/Types.hs @@ -70,6 +70,12 @@ class (Typeable a) => TypeScript a where -- ^ Special flag to indicate whether this type corresponds to a template variable. isGenericVariable _ = False + +getTypeScriptTypeOrOptionalNull :: TypeScript a => Proxy a -> String +getTypeScriptTypeOrOptionalNull proxy = getTypeScriptType proxy <> extra + where + extra = if getTypeScriptOptional proxy then " | null" else "" + -- | An existential wrapper for any TypeScript instance. data TSType = forall a. (Typeable a, TypeScript a) => TSType { unTSType :: Proxy a } diff --git a/src/Data/Aeson/TypeScript/Util.hs b/src/Data/Aeson/TypeScript/Util.hs index cedf0bf..29bff97 100644 --- a/src/Data/Aeson/TypeScript/Util.hs +++ b/src/Data/Aeson/TypeScript/Util.hs @@ -12,6 +12,7 @@ import Data.Aeson.TypeScript.Instances () import Data.Aeson.TypeScript.Types import qualified Data.List as L import Data.Proxy +import Data.String (IsString) import Data.String.Interpolate import qualified Data.Text as T import Language.Haskell.TH hiding (stringE) @@ -82,12 +83,12 @@ getTypeAsStringExp typ = [|getTypeScriptType (Proxy :: Proxy $(return typ))|] getOptionalAsBoolExp :: Type -> Q Exp getOptionalAsBoolExp typ = [|getTypeScriptOptional (Proxy :: Proxy $(return typ))|] --- | Helper to apply a type constructor to a list of type args +-- | Apply a type constructor to a list of type args applyToArgsT :: Type -> [Type] -> Type applyToArgsT constructor [] = constructor applyToArgsT constructor (x:xs) = applyToArgsT (AppT constructor x) xs --- | Helper to apply a function a list of args +-- | Apply a function to a list of args applyToArgsE :: Exp -> [Exp] -> Exp applyToArgsE f [] = f applyToArgsE f (x:xs) = applyToArgsE (AppE f x) xs @@ -183,6 +184,7 @@ mapType g (ImplicitParamT x typ) = ImplicitParamT x (mapType g typ) #endif mapType _ x = x +tryPromote :: (Eq a1, Eq a2, IsString a2) => Type -> [(a1, (a3, a2))] -> a1 -> Type tryPromote _ genericVariables (flip L.lookup genericVariables -> Just (_, "")) = ConT ''T tryPromote _ genericVariables (flip L.lookup genericVariables -> Just (_, "T")) = ConT ''T tryPromote _ genericVariables (flip L.lookup genericVariables -> Just (_, "T1")) = ConT ''T1 diff --git a/test/Basic.hs b/test/Basic.hs index a6c7a86..a8abb3e 100644 --- a/test/Basic.hs +++ b/test/Basic.hs @@ -17,9 +17,6 @@ data Unit2 = Unit2 $(deriveTypeScript (A.defaultOptions { A.tagSingleConstructors = True , A.constructorTagModifier = const "foo" }) ''Unit2) -data Test1 = Test1 (Maybe Int) -deriveTypeScript A.defaultOptions ''Test1 - tests :: SpecWith () tests = describe "Basic tests" $ do describe "tagSingleConstructors and constructorTagModifier" $ do @@ -29,17 +26,5 @@ tests = describe "Basic tests" $ do , TSTypeAlternatives "IUnit1" [] ["void[]"] Nothing ]) - it [i|Works with a unit with constructorTagModifier|] $ do - (getTypeScriptDeclarations (Proxy :: Proxy Unit2)) `shouldBe` ([ - TSTypeAlternatives "Unit2" [] ["\"foo\""] Nothing - ]) - - it [i|Maybe tuple encoding includes null option|] $ do - (getTypeScriptDeclarations (Proxy :: Proxy Test1)) `shouldBe` ([ - TSTypeAlternatives "Test1" [] ["ITest1"] Nothing - , TSTypeAlternatives "ITest1" [] ["number | null"] Nothing - ]) - - main :: IO () main = hspec tests diff --git a/test/MaybeTuples.hs b/test/MaybeTuples.hs new file mode 100644 index 0000000..d857f97 --- /dev/null +++ b/test/MaybeTuples.hs @@ -0,0 +1,78 @@ + +module MaybeTuples (tests) where + +import Data.Aeson as A +import Data.Aeson.TypeScript.TH +import Data.Aeson.TypeScript.Types +import Data.Proxy +import Data.String.Interpolate +import Prelude hiding (Double) +import Test.Hspec + + +data Maybe1 = Maybe1 (Maybe Int) +deriveTypeScript A.defaultOptions ''Maybe1 + +data Maybe2 = Maybe2 String (Maybe Int) +deriveTypeScript A.defaultOptions ''Maybe2 + +data Maybe3 = Maybe3 String (String, String) (Maybe Int) +deriveTypeScript A.defaultOptions ''Maybe3 + +data Maybe4 = Maybe4 Int Int Int (Maybe Int) +deriveTypeScript A.defaultOptions ''Maybe4 + +data Maybe5 = Maybe5 Int Int Int Int (Maybe Int) +deriveTypeScript A.defaultOptions ''Maybe5 + +data Maybe6 = Maybe6 Int Int Int Int Int (Maybe Int) +deriveTypeScript A.defaultOptions ''Maybe6 + +data MaybeRecord = MaybeRecord { + foo :: String + , bar :: Maybe Int + } +deriveTypeScript A.defaultOptions ''MaybeRecord + +tests :: SpecWith () +tests = describe "Maybes in tuple encodings" $ do + describe "tagSingleConstructors and constructorTagModifier" $ do + it [i|Maybe 1 tuple encoding includes null option|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy Maybe1)) `shouldBe` ([ + TSTypeAlternatives "Maybe1" [] ["IMaybe1"] Nothing + , TSTypeAlternatives "IMaybe1" [] ["number | null"] Nothing + ]) + + it [i|Maybe 2 tuple encoding includes null option|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy Maybe2)) `shouldBe` ([ + TSTypeAlternatives "Maybe2" [] ["IMaybe2"] Nothing + , TSTypeAlternatives "IMaybe2" [] ["[string, number | null]"] Nothing + ]) + + it [i|Maybe 3 tuple encoding includes null option|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy Maybe3)) `shouldBe` ([ + TSTypeAlternatives "Maybe3" [] ["IMaybe3"] Nothing + , TSTypeAlternatives "IMaybe3" [] ["[string, [string, string], number | null]"] Nothing + ]) + + it [i|Maybe 4 tuple encoding includes null option|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy Maybe4)) `shouldBe` ([ + TSTypeAlternatives "Maybe4" [] ["IMaybe4"] Nothing + , TSTypeAlternatives "IMaybe4" [] ["[number, number, number, number | null]"] Nothing + ]) + + it [i|Maybe 5 tuple encoding includes null option|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy Maybe5)) `shouldBe` ([ + TSTypeAlternatives "Maybe5" [] ["IMaybe5"] Nothing + , TSTypeAlternatives "IMaybe5" [] ["[number, number, number, number, number | null]"] Nothing + ]) + + it [i|Maybe 6 tuple encoding includes null option|] $ do + (getTypeScriptDeclarations (Proxy :: Proxy Maybe6)) `shouldBe` ([ + TSTypeAlternatives "Maybe6" [] ["IMaybe6"] Nothing + , TSTypeAlternatives "IMaybe6" [] ["[number, number, number, number, number, number | null]"] Nothing + ]) + + +main :: IO () +main = hspec tests diff --git a/test/NoOmitNothingFields.hs b/test/NoOmitNothingFields.hs index 148e822..4dd6dd8 100644 --- a/test/NoOmitNothingFields.hs +++ b/test/NoOmitNothingFields.hs @@ -13,9 +13,9 @@ $(testDeclarations "NoOmitNothingFields" (A.defaultOptions {omitNothingFields = allTests :: SpecWith () allTests = describe "NoOmitNothingFields" $ do it "encodes as expected" $ do - let decls = getTypeScriptDeclarations (Proxy :: Proxy Optional) + let decls = getTypeScriptDeclarations (Proxy :: Proxy OptionalRecord) - decls `shouldBe` [TSTypeAlternatives "Optional" [] ["IOptional"] Nothing - , TSInterfaceDeclaration "IOptional" [] [TSField False "optionalInt" "number | null" Nothing] Nothing] + decls `shouldBe` [TSTypeAlternatives "OptionalRecord" [] ["IOptionalRecord"] Nothing + , TSInterfaceDeclaration "IOptionalRecord" [] [TSField False "optionalInt" "number | null" Nothing] Nothing] tests diff --git a/test/OmitNothingFields.hs b/test/OmitNothingFields.hs index 360f2a1..f418b6f 100644 --- a/test/OmitNothingFields.hs +++ b/test/OmitNothingFields.hs @@ -13,10 +13,10 @@ $(testDeclarations "OmitNothingFields" (A.defaultOptions {omitNothingFields=True main :: IO () main = hspec $ describe "OmitNothingFields" $ do it "encodes as expected" $ do - let decls = getTypeScriptDeclarations (Proxy :: Proxy Optional) + let decls = getTypeScriptDeclarations (Proxy :: Proxy OptionalRecord) decls `shouldBe` [TSInterfaceDeclaration { - interfaceName = "Optional" + interfaceName = "OptionalRecord" , interfaceGenericVariables = [] , interfaceMembers = [ TSField True "optionalInt" "number" Nothing diff --git a/test/Spec.hs b/test/Spec.hs index d7f7548..11e0626 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -5,11 +5,12 @@ module Main where import Test.Hspec import qualified Basic +import qualified ClosedTypeFamilies import qualified Formatting import qualified Generic import qualified GetDoc import qualified HigherKind -import qualified ClosedTypeFamilies +import qualified MaybeTuples import qualified LegalNameSpec import qualified NoOmitNothingFields @@ -35,6 +36,7 @@ main = hspec $ parallel $ do GetDoc.tests #endif HigherKind.tests + MaybeTuples.tests LegalNameSpec.tests NoOmitNothingFields.allTests diff --git a/test/TestBoilerplate.hs b/test/TestBoilerplate.hs index 3b45997..bd4bd92 100644 --- a/test/TestBoilerplate.hs +++ b/test/TestBoilerplate.hs @@ -29,7 +29,9 @@ data TwoField = TwoField { doubleInt :: Int, doubleString :: String } data Hybrid = HybridSimple Int | HybridRecord { hybridString :: String } data TwoConstructor = Con1 { con1String :: String } | Con2 { con2String :: String, con2Int :: Int } data Complex a = Nullary | Unary Int | Product String Char a | Record { testOne :: Int, testTwo :: Bool, testThree :: Complex a} deriving Eq -data Optional = Optional {optionalInt :: Maybe Int} +data OptionalRecord = OptionalRecord {optionalInt :: Maybe Int} +data OptionalTuple1 = OptionalTuple1 (Maybe Int) +data OptionalTuple2 = OptionalTuple2 String (Maybe Int) data AesonTypes = AesonTypes { aesonValue :: A.Value, aesonObject :: A.Object } data Numbers = Numbers { natural :: Natural @@ -87,7 +89,9 @@ testDeclarations testName aesonOptions = do deriveInstances ''Hybrid deriveInstances ''TwoConstructor deriveInstances ''Complex - deriveInstances ''Optional + deriveInstances ''OptionalRecord + deriveInstances ''OptionalTuple1 + deriveInstances ''OptionalTuple2 deriveInstances ''AesonTypes deriveInstances ''Numbers deriveInstances ''FancyFunctors @@ -113,8 +117,14 @@ testDeclarations testName aesonOptions = do , (getTypeScriptType (Proxy :: Proxy (Complex Int)), A.encode (Product "asdf" 'g' 42 :: Complex Int)) , (getTypeScriptType (Proxy :: Proxy (Complex Int)), A.encode ((Record { testOne = 3, testTwo = True, testThree = Product "test" 'A' 123}) :: Complex Int)) - , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Nothing })) - , (getTypeScriptType (Proxy :: Proxy Optional), A.encode (Optional { optionalInt = Just 1 })) + , (getTypeScriptType (Proxy :: Proxy OptionalRecord), A.encode (OptionalRecord { optionalInt = Nothing })) + , (getTypeScriptType (Proxy :: Proxy OptionalRecord), A.encode (OptionalRecord { optionalInt = Just 1 })) + + , (getTypeScriptType (Proxy :: Proxy OptionalTuple1), A.encode (OptionalTuple1 Nothing)) + , (getTypeScriptType (Proxy :: Proxy OptionalTuple1), A.encode (OptionalTuple1 (Just 1))) + + , (getTypeScriptType (Proxy :: Proxy OptionalTuple2), A.encode (OptionalTuple2 "asdf" Nothing)) + , (getTypeScriptType (Proxy :: Proxy OptionalTuple2), A.encode (OptionalTuple2 "asdf" (Just 1))) , (getTypeScriptType (Proxy :: Proxy AesonTypes), A.encode (AesonTypes { aesonValue = A.object [("foo" :: AesonKey, A.Number 42)] @@ -133,7 +143,9 @@ testDeclarations testName aesonOptions = do <> getTypeScriptDeclarations (Proxy :: Proxy Hybrid) <> getTypeScriptDeclarations (Proxy :: Proxy TwoConstructor) <> getTypeScriptDeclarations (Proxy :: Proxy (Complex T)) - <> getTypeScriptDeclarations (Proxy :: Proxy Optional) + <> getTypeScriptDeclarations (Proxy :: Proxy OptionalRecord) + <> getTypeScriptDeclarations (Proxy :: Proxy OptionalTuple1) + <> getTypeScriptDeclarations (Proxy :: Proxy OptionalTuple2) <> getTypeScriptDeclarations (Proxy :: Proxy AesonTypes) <> getTypeScriptDeclarations (Proxy :: Proxy Numbers) <> getTypeScriptDeclarations (Proxy :: Proxy FancyFunctors)