Skip to content

Commit

Permalink
Added generation GraphQLClient.fsi
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-mi committed Jun 18, 2021
1 parent 773d6c8 commit aeb9b29
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 12 deletions.
131 changes: 128 additions & 3 deletions src/CodeGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,12 @@ let generatePropsDocument
XDocument(
XElement.ofStringName("Project",
seq {
MSBuildXElement.PropertyGroup(
seq {
if copyLocalLockFileAssemblies.IsSome then
XElement.ofStringName("CopyLocalLockFileAssemblies", (copyLocalLockFileAssemblies.ToString().ToLower()))
XElement.ofStringName("GenerateDocumentationFile", true)
})
if copyLocalLockFileAssemblies.IsSome then
MSBuildXElement.PropertyGroup(copyLocalLockFileAssemblies.Value)
if not (files |> Seq.isEmpty) then
Expand All @@ -979,7 +985,7 @@ let generateProjectDocument
XElement.ofStringName("Project",
XAttribute.ofStringName("Sdk", "Microsoft.NET.Sdk"),
seq {
XElement.ofStringName("PropertyGroup",
MSBuildXElement.PropertyGroup(
seq {
XElement.ofStringName("TargetFramework", "netstandard2.0")
XElement.ofStringName("LangVersion", "latest")
Expand All @@ -989,6 +995,7 @@ let generateProjectDocument
then "true"
else "false"
)
XElement.ofStringName("GenerateDocumentationFile", true)
})
if not (Seq.isEmpty files) then
XElement.ofStringName("ItemGroup", files)
Expand Down Expand Up @@ -1167,6 +1174,7 @@ let private sampleFSharpSystemGraphqlClient projectName clientName errorType mem
open System.Net.Http
open System.Text
open System.Text.Json
open System.Text.Json.Serialization
{if useTasks then "open FSharp.Control.Tasks" else ""}
type GraphqlInput<'T> = {{ query: string; variables: Option<'T> }}
Expand All @@ -1175,7 +1183,11 @@ type GraphqlErrorResponse = {{ errors: {errorType} list }}
type {clientName}(url: string, httpClient: HttpClient, options: JsonSerializerOptions) =
new(url: string, options: JsonSerializerOptions) = {clientName}(url, new HttpClient(), options)
new(url: string) = {clientName}(url, new HttpClient(), new JsonSerializerOptions())
new(url: string, client: HttpClient) =
let options = JsonSerializerOptions()
options.Converters.Add(JsonFSharpConverter())
{clientName}(url, client, options)
new(url: string) = {clientName}(url, new HttpClient())
{members}"""

let private sampleFSharpNewtonsoftGraphqlClient projectName clientName errorType members useTasks =
Expand Down Expand Up @@ -1203,4 +1215,117 @@ type {clientName}(url: string, httpClient: HttpClient) =
let sampleFSharpGraphqlClient projectName clientName errorType members serializer =
match serializer with
| SerializerType.System -> sampleFSharpSystemGraphqlClient projectName clientName errorType members
| SerializerType.Newtonsoft -> sampleFSharpNewtonsoftGraphqlClient projectName clientName errorType members
| SerializerType.Newtonsoft -> sampleFSharpNewtonsoftGraphqlClient projectName clientName errorType members

let sampleFableGraphqlClientFsi projectName clientName =
$"""namespace {projectName}
open Fable.SimpleHttp
open Fable.SimpleJson
type {clientName} =
class
/// <summary>Creates {clientName} specifying <see href="T:HttpClient">HttpClient</see> instance</summary>
/// <remarks>
/// In order to enable all F# types serialization and deserealization <b>you must</b> add
/// <see href="T:Fable.SimpleJson.FableJsonConverter">FableJsonConverter</see>
/// from <a href="https://github.com/Zaid-Ajaj/Fable.SimpleJson">Fable.SimpleJson</a> NuGet package yourself
/// </remarks>
/// <param name="url">GraphQL endpoint URL</param>
new: url: string * headers: Header list -> SpotifyGraphqlClient
/// <summary>Creates {clientName}</summary>
/// <remarks>
/// In order to enable all F# types serialization and deserealization
/// <see href="T:Fable.SimpleJson.FableJsonConverter">FableJsonConverter</see> is added
/// from <a href="https://github.com/Zaid-Ajaj/Fable.SimpleJson">Fable.SimpleJson</a> NuGet package
/// </remarks>
new: url: string -> SpotifyGraphqlClient
end
"""

let private sampleFSharpSystemGraphqlClientFsi projectName clientName =
$"""namespace {projectName}
open System.Net.Http
open System.Text
open System.Text.Json
type {clientName} =
class
/// <summary>Creates {clientName} specifying <see href="T:HttpClient">HttpClient</see> instance</summary>
/// <remarks>
/// In order to enable all F# types serialization and deserealization <b>you must</b> add
/// <see href="T:System.Text.Json.Serialization.JsonFSharpConverter">JsonFSharpConverter</see>
/// from <a href="https://github.com/Tarmil/FSharp.SystemTextJson">FSharp.SystemTextJson</a> NuGet package yourself
/// </remarks>
/// <param name="url">GraphQL endpoint URL</param>
new: url: string * client: HttpClient * options: JsonSerializerOptions -> SpotifyGraphqlClient
/// <summary>
/// Creates {clientName} specifying <see href="T:JsonSerializerOptions">JsonSerializerOptions</see>
/// </summary>
/// <param name="url">GraphQL endpoint URL</param>
/// <remarks>
/// In order to enable all F# types serialization and deserealization <b>you must</b> add
/// <see href="T:System.Text.Json.Serialization.JsonFSharpConverter">JsonFSharpConverter</see>
/// from <a href="https://github.com/Tarmil/FSharp.SystemTextJson">FSharp.SystemTextJson</a> NuGet package yourself
/// </remarks>
new: url: string * options: JsonSerializerOptions -> SpotifyGraphqlClient
/// <summary>
/// Creates {clientName} specifying <see href="T:HttpClient">HttpClient</see> instance
/// </summary>
/// <param name="url">GraphQL endpoint URL</param>
/// <remarks>
/// In order to enable all F# types serialization and deserealization
/// <see href="T:System.Text.Json.Serialization.JsonFSharpConverter">JsonFSharpConverter</see> by default is added
/// from <a href="https://github.com/Tarmil/FSharp.SystemTextJson">FSharp.SystemTextJson</a> NuGet package
/// </remarks>
new: url: string * client: HttpClient -> SpotifyGraphqlClient
/// <summary>Creates {clientName}</summary>
/// <param name="url">GraphQL endpoint URL</param>
/// <remarks>
/// In order to enable all F# types serialization and deserealization
/// <see href="T:System.Text.Json.Serialization.JsonFSharpConverter">JsonFSharpConverter</see> by default is added
/// from <a href="https://github.com/Tarmil/FSharp.SystemTextJson">FSharp.SystemTextJson</a> NuGet package
/// </remarks>
new: url: string -> SpotifyGraphqlClient
end
"""

let private sampleFSharpNewtonsoftGraphqlClientFsi projectName clientName =
$"""namespace {projectName}
open Newtonsoft.Json
open Newtonsoft.Json.Linq
open Fable.Remoting.Json
open System.Net.Http
open System.Text
type {clientName} =
class
/// <summary>Creates {clientName} specifying <see href="T:HttpClient">HttpClient</see> instance</summary>
/// <remarks>
/// In order to enable all F# types serialization and deserealization
/// <see href="T:Fable.Remoting.Json.FableJsonConverter">FableJsonConverter</see> is added
/// from <a href="https://github.com/Zaid-Ajaj/Fable.SimpleJson">Fable.SimpleJson</a> NuGet package
/// </remarks>
/// <param name="url">GraphQL endpoint URL</param>
new: url: string * client: HttpClient -> SpotifyGraphqlClient
/// <summary>Creates {clientName}</summary>
/// <remarks>
/// In order to enable all F# types serialization and deserealization
/// <see href="T:Fable.SimpleJson.FableJsonConverter">FableJsonConverter</see> is added
/// from <a href="https://github.com/Zaid-Ajaj/Fable.SimpleJson">Fable.SimpleJson</a> NuGet package
/// </remarks>
new: string -> SpotifyGraphqlClient
end
"""

let sampleFSharpGraphqlClientFsi projectName clientName serializer =
match serializer with
| SerializerType.System -> sampleFSharpSystemGraphqlClientFsi projectName clientName
| SerializerType.Newtonsoft -> sampleFSharpNewtonsoftGraphqlClientFsi projectName clientName
4 changes: 3 additions & 1 deletion src/LinqToXmlExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
module Snowflaqe.LinqToXmlExtensions

open System
open System.Xml
open System.Xml.Linq

type XAttribute with
Expand Down Expand Up @@ -45,6 +44,9 @@ type MSBuildXElement () =
XElement.ofStringName("CopyLocalLockFileAssemblies",
(copyLocalLockFileAssemblies.ToString().ToLower())))

static member PropertyGroup ([<ParamArray>] content) =
XElement.ofStringName("PropertyGroup", content)

type XDocument with

member this.WriteTo (outputFileName: string) =
Expand Down
41 changes: 33 additions & 8 deletions src/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let [<Literal>] FableRemotingJsonVersion = "2.17.0"
let [<Literal>] FableSimpleHttpVersion = "3.0.0"
let [<Literal>] FableSimpleJsonVersion = "3.21.0"
let [<Literal>] FSharpCoreVersion = "4.7.2"
let [<Literal>] FSharpSystemTextJsonVersion = "0.17.4"
let [<Literal>] NewtonsoftJsonVersion = "12.0.2"
let [<Literal>] SystemTextJsonVersion = "4.6.0"
let [<Literal>] PlyVersion = "0.3.1"
Expand Down Expand Up @@ -456,14 +457,20 @@ let generate (configFile: string) =
match config.target with
| OutputTarget.Fable ->
let graphqlClientPath = Path.GetFullPath(Path.Combine(config.output, fileName "GraphqlClient.fs"))
let graphqlClientFsiPath = Path.GetFullPath(Path.Combine(config.output, fileName "GraphqlClient.fsi"))
colorprintfn "✏️ Generating GraphQL client $green[%s]" graphqlClientPath
generatedFiles.Add(graphqlClientPath)
generatedFiles.AddRange [|
graphqlClientFsiPath
graphqlClientPath
|]
let members =
generatedModules
|> Seq.map (fun (path, name, hasVars) -> CodeGen.sampleClientMember (File.ReadAllText(path)) name hasVars)
|> String.concat "\n"
let clientContent = CodeGen.sampleFableGraphqlClient config.project clientName config.errorType.typeName members
let fsiContent = CodeGen.sampleFableGraphqlClientFsi config.project clientName
write graphqlClientPath clientContent None
write graphqlClientFsiPath fsiContent None
colorprintfn "✏️ Generating Fable $green[%s]" projPath

let files = [
Expand Down Expand Up @@ -508,9 +515,15 @@ let generate (configFile: string) =
|> String.concat "\n"

let graphqlClientPath = Path.GetFullPath(Path.Combine(config.output, fileName "GraphqlClient.fs"))
generatedFiles.Add(graphqlClientPath)
let graphqlClientFsiPath = Path.GetFullPath(Path.Combine(config.output, fileName "GraphqlClient.fsi"))
generatedFiles.AddRange [|
graphqlClientFsiPath
graphqlClientPath
|]
let clientContent = CodeGen.sampleFSharpGraphqlClient config.project clientName config.errorType.typeName members config.serializer useTasksForAsync
let fsiContent = CodeGen.sampleFSharpGraphqlClientFsi config.project clientName config.serializer
write graphqlClientPath clientContent None
write graphqlClientFsiPath fsiContent None

let files = [
for file in generatedFiles do
Expand All @@ -521,7 +534,7 @@ let generate (configFile: string) =
yield! packageReferences
yield
match config.serializer with
| SerializerType.System -> MSBuildXElement.PackageReferenceInclude("System.Text.Json", SystemTextJsonVersion)
| SerializerType.System -> MSBuildXElement.PackageReferenceInclude("FSharp.SystemTextJson", FSharpSystemTextJsonVersion)
| SerializerType.Newtonsoft -> MSBuildXElement.PackageReferenceInclude("Fable.Remoting.Json", FableRemotingJsonVersion)

if useTasksForAsync
Expand Down Expand Up @@ -572,12 +585,15 @@ let generate (configFile: string) =
document.WriteTo(sharedDocPath)

let fsharpGraphqlClientPath = Path.GetFullPath(Path.Combine(config.output, "dotnet", fileName "GraphqlClient.fs"))
let fsharpGraphqlClientFsiPath = Path.GetFullPath(Path.Combine(config.output, "dotnet", fileName "GraphqlClient.fsi"))
let fsharpMembers =
generatedModules
|> Seq.map (fun (path, name, hasVars) -> CodeGen.sampleFSharpClientMember config.serializer (File.ReadAllText(path)) name hasVars useTasksForAsync)
|> String.concat "\n"
let dotnetClientContent = CodeGen.sampleFSharpGraphqlClient config.project clientName config.errorType.typeName fsharpMembers config.serializer useTasksForAsync
let dotnetClientFsiContent = CodeGen.sampleFSharpGraphqlClientFsi config.project clientName config.serializer
write fsharpGraphqlClientPath dotnetClientContent None
write fsharpGraphqlClientFsiPath dotnetClientFsiContent None
let sharedFSharpDocument =
if config.createProjectFile
then Path.GetFullPath(Path.Combine(config.output, "dotnet", config.project + ".Dotnet.fsproj"))
Expand All @@ -587,7 +603,7 @@ let generate (configFile: string) =
yield! packageReferences
yield
match config.serializer with
| SerializerType.System -> MSBuildXElement.PackageReferenceInclude("System.text.Json", SystemTextJsonVersion)
| SerializerType.System -> MSBuildXElement.PackageReferenceInclude("FSharp.SystemTextJson", FSharpSystemTextJsonVersion)
| SerializerType.Newtonsoft -> MSBuildXElement.PackageReferenceInclude("Fable.Remoting.Json", FableRemotingJsonVersion)
if useTasksForAsync
then yield MSBuildXElement.PackageReferenceInclude("Ply", PlyVersion)
Expand All @@ -599,10 +615,16 @@ let generate (configFile: string) =
|> Seq.singleton
let files =
if config.createProjectFile
then MSBuildXElement.Compile($".\{config.project}.GraphqlClient.fs")
else MSBuildXElement.Compile($".\{outputDirectoryName}\\dotnet\{config.project}.GraphqlClient.fs")
|> Seq.singleton

then
seq {
MSBuildXElement.Compile($".\{config.project}.GraphqlClient.fsi")
MSBuildXElement.Compile($".\{config.project}.GraphqlClient.fs")
}
else
seq {
MSBuildXElement.Compile($".\{outputDirectoryName}\\dotnet\{config.project}.GraphqlClient.fsi")
MSBuildXElement.Compile($".\{outputDirectoryName}\\dotnet\{config.project}.GraphqlClient.fs")
}
let generator =
if config.createProjectFile
then CodeGen.generateProjectDocument
Expand All @@ -624,8 +646,11 @@ let generate (configFile: string) =
|> String.concat "\n"

let fableGraphqlClientPath = Path.GetFullPath(Path.Combine(config.output, "fable", fileName "GraphqlClient.fs"))
let fableGraphqlClientFsiPath = Path.GetFullPath(Path.Combine(config.output, "fable", fileName "GraphqlClient.fsi"))
let fableClientContent = CodeGen.sampleFableGraphqlClient config.project clientName config.errorType.typeName fableMembers
let fableClientFsiContent = CodeGen.sampleFableGraphqlClientFsi config.project clientName
write fableGraphqlClientPath fableClientContent None
write fableGraphqlClientFsiPath fableClientFsiContent None
let sharedFableDocument =
if config.createProjectFile
then Path.GetFullPath(Path.Combine(config.output, "fable", config.project + ".Fable.fsproj"))
Expand Down

0 comments on commit aeb9b29

Please sign in to comment.