module Cardano.Wasm.Api.InfoToTypeScript where
import Cardano.Wasm.Api.Info (tsTypeAsString)
import Cardano.Wasm.Api.Info qualified as Info
import Cardano.Wasm.Api.TypeScriptDefs qualified as TypeScript
import Data.List (nub)
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Maybe (fromMaybe)
apiInfoToTypeScriptFile :: Info.ApiInfo -> [TypeScript.TypeScriptFile]
apiInfoToTypeScriptFile :: ApiInfo -> [TypeScriptFile]
apiInfoToTypeScriptFile ApiInfo
apiInfo =
( TypeScript.TypeScriptFile
{ typeScriptFileName :: [Char]
TypeScript.typeScriptFileName = VirtualObjectInfo -> [Char]
Info.dashCaseName (ApiInfo -> VirtualObjectInfo
Info.mainObject ApiInfo
apiInfo) [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
".d.ts"
, typeScriptFileContent :: [Declaration]
TypeScript.typeScriptFileContent =
[Char]
-> Bool
-> Map [Char] VirtualObjectInfo
-> VirtualObjectInfo
-> [Declaration]
virtualObjectInfoToInterfaceDecs
[Char]
mainObjectName
Bool
False
Map [Char] VirtualObjectInfo
voMap
(ApiInfo -> VirtualObjectInfo
Info.mainObject ApiInfo
apiInfo)
[Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [ [[Char]] -> DeclarationType -> Declaration
TypeScript.Declaration
[ ApiInfo -> [Char]
Info.initialiseFunctionDoc ApiInfo
apiInfo
, [Char]
"@returns " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> ApiInfo -> [Char]
Info.initialiseFunctionReturnDoc ApiInfo
apiInfo
]
( FunctionHeader -> DeclarationType
TypeScript.FunctionDec (FunctionHeader -> DeclarationType)
-> FunctionHeader -> DeclarationType
forall a b. (a -> b) -> a -> b
$
TypeScript.FunctionHeader
{ functionName :: [Char]
TypeScript.functionName = [Char]
"initialise"
, functionParams :: [FunctionParam]
TypeScript.functionParams = []
, functionReturnType :: [Char]
TypeScript.functionReturnType =
[Char]
"Promise<" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> VirtualObjectInfo -> [Char]
Info.virtualObjectName (ApiInfo -> VirtualObjectInfo
Info.mainObject ApiInfo
apiInfo) [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
">"
}
)
, [[Char]] -> DeclarationType -> Declaration
TypeScript.Declaration [] (Bool -> [Char] -> DeclarationType
TypeScript.ExportDec Bool
True [Char]
"initialise")
]
}
)
TypeScriptFile -> [TypeScriptFile] -> [TypeScriptFile]
forall a. a -> [a] -> [a]
: [TypeScriptFile]
virtualObjectInterfaces
where
virtualObjectInterfaces :: [TypeScriptFile]
virtualObjectInterfaces =
(VirtualObjectInfo -> TypeScriptFile)
-> [VirtualObjectInfo] -> [TypeScriptFile]
forall a b. (a -> b) -> [a] -> [b]
map ([Char]
-> Map [Char] VirtualObjectInfo
-> VirtualObjectInfo
-> TypeScriptFile
virtualObjectInfoToTypeScriptFile [Char]
mainObjectName Map [Char] VirtualObjectInfo
voMap) (ApiInfo -> [VirtualObjectInfo]
Info.virtualObjects ApiInfo
apiInfo)
voMap :: Map [Char] VirtualObjectInfo
voMap = [([Char], VirtualObjectInfo)] -> Map [Char] VirtualObjectInfo
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo, VirtualObjectInfo
vo) | VirtualObjectInfo
vo <- ApiInfo -> [VirtualObjectInfo]
Info.virtualObjects ApiInfo
apiInfo]
mainObjectName :: [Char]
mainObjectName = VirtualObjectInfo -> [Char]
Info.virtualObjectName (VirtualObjectInfo -> [Char]) -> VirtualObjectInfo -> [Char]
forall a b. (a -> b) -> a -> b
$ ApiInfo -> VirtualObjectInfo
Info.mainObject ApiInfo
apiInfo
importDeclaration :: Info.VirtualObjectInfo -> TypeScript.Declaration
importDeclaration :: VirtualObjectInfo -> Declaration
importDeclaration VirtualObjectInfo
vo =
TypeScript.Declaration
{ declarationComment :: [[Char]]
TypeScript.declarationComment = []
, declarationContent :: DeclarationType
TypeScript.declarationContent =
[Char] -> [Char] -> DeclarationType
TypeScript.ImportDec (VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo) ([Char] -> DeclarationType) -> [Char] -> DeclarationType
forall a b. (a -> b) -> a -> b
$ VirtualObjectInfo -> [Char]
Info.dashCaseName VirtualObjectInfo
vo
}
importDeclarations
:: Map String Info.VirtualObjectInfo -> Info.VirtualObjectInfo -> [TypeScript.Declaration]
importDeclarations :: Map [Char] VirtualObjectInfo -> VirtualObjectInfo -> [Declaration]
importDeclarations Map [Char] VirtualObjectInfo
voMap (Info.VirtualObjectInfo{virtualObjectMethods :: VirtualObjectInfo -> [MethodHierarchy]
Info.virtualObjectMethods = [MethodHierarchy]
methods}) =
(VirtualObjectInfo -> Declaration)
-> [VirtualObjectInfo] -> [Declaration]
forall a b. (a -> b) -> [a] -> [b]
map
VirtualObjectInfo -> Declaration
importDeclaration
([VirtualObjectInfo] -> [Declaration])
-> [VirtualObjectInfo] -> [Declaration]
forall a b. (a -> b) -> a -> b
$ [VirtualObjectInfo] -> [VirtualObjectInfo]
forall a. Eq a => [a] -> [a]
nub
[ VirtualObjectInfo
vo
| Info.MethodInfo{methodReturnType :: MethodInfo -> MethodReturnTypeInfo
Info.methodReturnType = Info.NewObject [Char]
returnType} <- [MethodHierarchy] -> [MethodInfo]
flattenMethods [MethodHierarchy]
methods
, Just VirtualObjectInfo
vo <- [[Char] -> Map [Char] VirtualObjectInfo -> Maybe VirtualObjectInfo
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup [Char]
returnType Map [Char] VirtualObjectInfo
voMap]
]
flattenMethods :: [Info.MethodHierarchy] -> [Info.MethodInfo]
flattenMethods :: [MethodHierarchy] -> [MethodInfo]
flattenMethods = (MethodHierarchy -> [MethodInfo])
-> [MethodHierarchy] -> [MethodInfo]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap MethodHierarchy -> [MethodInfo]
flattenMethods'
where
flattenMethods' :: Info.MethodHierarchy -> [Info.MethodInfo]
flattenMethods' :: MethodHierarchy -> [MethodInfo]
flattenMethods' (Info.MethodInfoEntry MethodInfo
mi) = [MethodInfo
mi]
flattenMethods' (Info.MethodGroupEntry (Info.MethodGroup{groupMethods :: MethodGroup -> [MethodHierarchy]
Info.groupMethods = [MethodHierarchy]
methods})) = [MethodHierarchy] -> [MethodInfo]
flattenMethods [MethodHierarchy]
methods
virtualObjectInfoToTypeScriptFile
:: String -> Map String Info.VirtualObjectInfo -> Info.VirtualObjectInfo -> TypeScript.TypeScriptFile
virtualObjectInfoToTypeScriptFile :: [Char]
-> Map [Char] VirtualObjectInfo
-> VirtualObjectInfo
-> TypeScriptFile
virtualObjectInfoToTypeScriptFile [Char]
mainObjectName Map [Char] VirtualObjectInfo
voMap VirtualObjectInfo
vo =
TypeScript.TypeScriptFile
{ typeScriptFileName :: [Char]
TypeScript.typeScriptFileName = VirtualObjectInfo -> [Char]
Info.dashCaseName VirtualObjectInfo
vo [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
".d.ts"
, typeScriptFileContent :: [Declaration]
TypeScript.typeScriptFileContent = [Char]
-> Bool
-> Map [Char] VirtualObjectInfo
-> VirtualObjectInfo
-> [Declaration]
virtualObjectInfoToInterfaceDecs [Char]
mainObjectName Bool
True Map [Char] VirtualObjectInfo
voMap VirtualObjectInfo
vo
}
oxfordCommaSeparatedList :: [String] -> String
oxfordCommaSeparatedList :: [[Char]] -> [Char]
oxfordCommaSeparatedList [] = [Char]
""
oxfordCommaSeparatedList [[Char]
l] = [Char]
l
oxfordCommaSeparatedList [[Char]
p, [Char]
l] = [Char]
p [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
" and " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
l
oxfordCommaSeparatedList [[Char]
a, [Char]
p, [Char]
l] = [Char]
a [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
", " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
p [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
", and " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
l
oxfordCommaSeparatedList ([Char]
h : [[Char]]
t) = [Char]
h [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
", " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [[Char]] -> [Char]
oxfordCommaSeparatedList [[Char]]
t
virtualObjectInfoToInterfaceDecs
:: String
-> Bool
-> Map String Info.VirtualObjectInfo
-> Info.VirtualObjectInfo
-> [TypeScript.Declaration]
virtualObjectInfoToInterfaceDecs :: [Char]
-> Bool
-> Map [Char] VirtualObjectInfo
-> VirtualObjectInfo
-> [Declaration]
virtualObjectInfoToInterfaceDecs [Char]
mainObjectName Bool
isDefaultExport Map [Char] VirtualObjectInfo
voMap VirtualObjectInfo
vo =
Map [Char] VirtualObjectInfo -> VirtualObjectInfo -> [Declaration]
importDeclarations Map [Char] VirtualObjectInfo
voMap VirtualObjectInfo
vo
[Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [ [[Char]] -> DeclarationType -> Declaration
TypeScript.Declaration
[VirtualObjectInfo -> [Char]
Info.virtualObjectDoc VirtualObjectInfo
vo]
( [Char] -> [GroupedInterfaceContent] -> DeclarationType
TypeScript.InterfaceDec
(VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo)
( [ InterfaceContent -> GroupedInterfaceContent
TypeScript.SingleInterfaceContent (InterfaceContent -> GroupedInterfaceContent)
-> InterfaceContent -> GroupedInterfaceContent
forall a b. (a -> b) -> a -> b
$
[[Char]] -> InterfaceContentType -> InterfaceContent
TypeScript.InterfaceContent
[ [Char]
"The type of the object, used for identification (the \""
[Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo
[Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\" string)."
, [Char]
"Other types of objects would be:"
, [[Char]] -> [Char]
oxfordCommaSeparatedList
( ( if [Char]
mainObjectName [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo
then [[Char]] -> [[Char]]
forall a. a -> a
id
else ([Char] -> [Char]
forall a. Show a => a -> [Char]
show [Char]
mainObjectName [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
:)
)
[ [Char] -> [Char]
forall a. Show a => a -> [Char]
show ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
v
| VirtualObjectInfo
v <- Map [Char] VirtualObjectInfo -> [VirtualObjectInfo]
forall k a. Map k a -> [a]
Map.elems Map [Char] VirtualObjectInfo
voMap
, VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
v [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/= VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo
]
)
]
([Char] -> [Char] -> InterfaceContentType
TypeScript.InterfaceProperty [Char]
"objectType" [Char]
"string")
]
[GroupedInterfaceContent]
-> [GroupedInterfaceContent] -> [GroupedInterfaceContent]
forall a. Semigroup a => a -> a -> a
<> (MethodHierarchy -> GroupedInterfaceContent)
-> [MethodHierarchy] -> [GroupedInterfaceContent]
forall a b. (a -> b) -> [a] -> [b]
map
([Char] -> MethodHierarchy -> GroupedInterfaceContent
methodHierarchyToGroupedInterfaceContents (VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo))
(VirtualObjectInfo -> [MethodHierarchy]
Info.virtualObjectMethods VirtualObjectInfo
vo)
)
)
]
[Declaration] -> [Declaration] -> [Declaration]
forall a. [a] -> [a] -> [a]
++ [ [[Char]] -> DeclarationType -> Declaration
TypeScript.Declaration [] (Bool -> [Char] -> DeclarationType
TypeScript.ExportDec Bool
True ([Char] -> DeclarationType) -> [Char] -> DeclarationType
forall a b. (a -> b) -> a -> b
$ VirtualObjectInfo -> [Char]
Info.virtualObjectName VirtualObjectInfo
vo) | Bool
isDefaultExport
]
methodHierarchyToGroupedInterfaceContents
:: String -> Info.MethodHierarchy -> TypeScript.GroupedInterfaceContent
methodHierarchyToGroupedInterfaceContents :: [Char] -> MethodHierarchy -> GroupedInterfaceContent
methodHierarchyToGroupedInterfaceContents [Char]
selfTypeName (Info.MethodInfoEntry MethodInfo
method) =
InterfaceContent -> GroupedInterfaceContent
TypeScript.SingleInterfaceContent (InterfaceContent -> GroupedInterfaceContent)
-> InterfaceContent -> GroupedInterfaceContent
forall a b. (a -> b) -> a -> b
$ [Char] -> MethodInfo -> InterfaceContent
methodInfoToInterfaceContent [Char]
selfTypeName MethodInfo
method
methodHierarchyToGroupedInterfaceContents [Char]
selfTypeName (Info.MethodGroupEntry MethodGroup
group) =
InterfaceContentGroup -> GroupedInterfaceContent
TypeScript.GroupedInterfaceContent (InterfaceContentGroup -> GroupedInterfaceContent)
-> InterfaceContentGroup -> GroupedInterfaceContent
forall a b. (a -> b) -> a -> b
$
[[Char]]
-> [Char] -> [GroupedInterfaceContent] -> InterfaceContentGroup
TypeScript.InterfaceContentGroup
(MethodGroup -> [[Char]]
Info.groupDoc MethodGroup
group)
(MethodGroup -> [Char]
Info.groupName MethodGroup
group)
( (MethodHierarchy -> GroupedInterfaceContent)
-> [MethodHierarchy] -> [GroupedInterfaceContent]
forall a b. (a -> b) -> [a] -> [b]
map
([Char] -> MethodHierarchy -> GroupedInterfaceContent
methodHierarchyToGroupedInterfaceContents [Char]
selfTypeName)
(MethodGroup -> [MethodHierarchy]
Info.groupMethods MethodGroup
group)
)
methodInfoToInterfaceContent :: String -> Info.MethodInfo -> TypeScript.InterfaceContent
methodInfoToInterfaceContent :: [Char] -> MethodInfo -> InterfaceContent
methodInfoToInterfaceContent [Char]
selfTypeName MethodInfo
method =
[[Char]] -> InterfaceContentType -> InterfaceContent
TypeScript.InterfaceContent
( [MethodInfo -> [Char]
Info.methodDoc MethodInfo
method]
[[Char]] -> [[Char]] -> [[Char]]
forall a. Semigroup a => a -> a -> a
<> (ParamInfo -> [Char]) -> [ParamInfo] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (\ParamInfo
p -> [Char]
"@param " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> ParamInfo -> [Char]
Info.paramName ParamInfo
p [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
" " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> ParamInfo -> [Char]
Info.paramDoc ParamInfo
p) (MethodInfo -> [ParamInfo]
Info.methodParams MethodInfo
method)
[[Char]] -> [[Char]] -> [[Char]]
forall a. Semigroup a => a -> a -> a
<> [[Char]
"@returns " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> MethodInfo -> [Char]
Info.methodReturnDoc MethodInfo
method]
)
( [Char] -> [FunctionParam] -> [Char] -> InterfaceContentType
TypeScript.InterfaceMethod
([Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe (MethodInfo -> [Char]
Info.methodName MethodInfo
method) (MethodInfo -> Maybe [Char]
Info.methodSimpleName MethodInfo
method))
((ParamInfo -> FunctionParam) -> [ParamInfo] -> [FunctionParam]
forall a b. (a -> b) -> [a] -> [b]
map ParamInfo -> FunctionParam
paramInfoToFunctionParam ([ParamInfo] -> [FunctionParam]) -> [ParamInfo] -> [FunctionParam]
forall a b. (a -> b) -> a -> b
$ MethodInfo -> [ParamInfo]
Info.methodParams MethodInfo
method)
([Char] -> MethodReturnTypeInfo -> [Char]
methodReturnTypeToString [Char]
selfTypeName (MethodReturnTypeInfo -> [Char]) -> MethodReturnTypeInfo -> [Char]
forall a b. (a -> b) -> a -> b
$ MethodInfo -> MethodReturnTypeInfo
Info.methodReturnType MethodInfo
method)
)
paramInfoToFunctionParam :: Info.ParamInfo -> TypeScript.FunctionParam
paramInfoToFunctionParam :: ParamInfo -> FunctionParam
paramInfoToFunctionParam ParamInfo
p =
TypeScript.FunctionParam
{ paramName :: [Char]
TypeScript.paramName = ParamInfo -> [Char]
Info.paramName ParamInfo
p
, paramType :: [Char]
TypeScript.paramType = TSType -> [Char]
tsTypeAsString (TSType -> [Char]) -> TSType -> [Char]
forall a b. (a -> b) -> a -> b
$ ParamInfo -> TSType
Info.paramType ParamInfo
p
}
methodReturnTypeToString :: String -> Info.MethodReturnTypeInfo -> String
methodReturnTypeToString :: [Char] -> MethodReturnTypeInfo -> [Char]
methodReturnTypeToString [Char]
selfTypeName MethodReturnTypeInfo
Info.Fluent = [Char]
selfTypeName
methodReturnTypeToString [Char]
_ (Info.NewObject [Char]
objTypeName) = [Char]
"Promise<" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
objTypeName [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
">"
methodReturnTypeToString [Char]
_ (Info.OtherType TSType
typeName) = [Char]
"Promise<" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> TSType -> [Char]
tsTypeAsString TSType
typeName [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
">"