Creating Currency API endpoint
This commit is contained in:
		
							parent
							
								
									9cf0b0b4fe
								
							
						
					
					
						commit
						c704a21787
					
				| @ -2,9 +2,11 @@ FSharp.Core | ||||
| DSharpPlus | ||||
| DSharpPlus.Interactivity | ||||
| DSharpPlus.SlashCommands | ||||
| FSharp.Core | ||||
| dotenv.net | ||||
| Npgsql.FSharp | ||||
| mixpanel-csharp | ||||
| Solnet.Rpc | ||||
| FsToolkit.ErrorHandling | ||||
| FSharp.Data | ||||
| Newtonsoft.Json | ||||
							
								
								
									
										118
									
								
								CurrencyAPI/Currency.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								CurrencyAPI/Currency.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | ||||
| module CurrencyAPI.App | ||||
| 
 | ||||
| open System | ||||
| open System.IO | ||||
| open Microsoft.AspNetCore.Builder | ||||
| open Microsoft.AspNetCore.Hosting | ||||
| open Microsoft.AspNetCore.Http | ||||
| open Microsoft.Extensions.Hosting | ||||
| open Microsoft.Extensions.Logging | ||||
| open Microsoft.Extensions.DependencyInjection | ||||
| open Giraffe | ||||
| open dotenv.net | ||||
| open Npgsql.FSharp | ||||
| 
 | ||||
| let prodEnv = DotEnv.Read(DotEnvOptions(envFilePaths = [ "../.prod.env"], overwriteExistingVars = false)) | ||||
| 
 | ||||
| let ( _ , connStr ) = prodEnv.TryGetValue("DATABASE_URL") | ||||
| let ( _ , apiKey ) = prodEnv.TryGetValue("API_KEY") | ||||
| 
 | ||||
| let validateApiKey (ctx : HttpContext) = | ||||
|     match ctx.TryGetRequestHeader "X-API-Key" with | ||||
|     | Some key -> apiKey.Equals key | ||||
|     | None     -> false | ||||
|      | ||||
| let accessDenied = setStatusCode 401 >=> text "Access Denied" | ||||
| let requiresApiKey = authorizeRequest validateApiKey accessDenied | ||||
| 
 | ||||
| let getCurrentBalance (discordId : string) = | ||||
|     task { | ||||
|         let! amounts = | ||||
|             connStr | ||||
|             |> Sql.connect | ||||
|             |> Sql.parameters [ "did" , Sql.string discordId ] | ||||
|             |> Sql.query """SELECT gbt FROM "user" WHERE discord_id = @did""" | ||||
|             |> Sql.executeAsync (fun r -> r.int "gbt") | ||||
|         match amounts with | ||||
|         | []   -> return Error "User not found" | ||||
|         | a::_ -> return Ok a | ||||
|     } | ||||
| 
 | ||||
| let get (discordId : string) : HttpHandler =  | ||||
|     fun (next : HttpFunc) (ctx : HttpContext) -> | ||||
|         task { | ||||
|             try | ||||
|                 match! getCurrentBalance discordId with | ||||
|                 | Ok amount -> return! json {| Amount = amount |} next ctx | ||||
|                 | Error e -> return! RequestErrors.notFound (json {| Error = e |}) next ctx | ||||
|             with ex -> | ||||
|                 return! ServerErrors.internalError (json {| Error = ex.Message |}) next ctx | ||||
|         } | ||||
|          | ||||
| let modify sign (discordId : string) : HttpHandler =  | ||||
|     fun (next : HttpFunc) (ctx : HttpContext) -> | ||||
|         task { | ||||
|             let! body = ctx.BindJsonAsync<{|Amount:int|}>() | ||||
|             match! getCurrentBalance discordId with | ||||
|             | Ok current -> | ||||
|                 let amount = body.Amount * sign | ||||
|                 if current + amount < 0 then | ||||
|                     return! RequestErrors.badRequest (json {| Error = "Insufficient funds" |}) next ctx | ||||
|                 else | ||||
|                 try | ||||
|                     let! _ = | ||||
|                         connStr | ||||
|                         |> Sql.connect | ||||
|                         |> Sql.parameters [ "did" , Sql.string discordId ; "amount" , Sql.int amount ] | ||||
|                         |> Sql.query """UPDATE "user" SET gbt = GREATEST(gbt + @amount, 0) WHERE discord_id = @did""" | ||||
|                         |> Sql.executeNonQueryAsync | ||||
|                     return! json {| NewBalance = current + amount |} next ctx | ||||
|                 with ex -> return! RequestErrors.notFound (json {| Error = ex.Message |}) next ctx | ||||
|             | Error e -> return! RequestErrors.notFound (json {| Error = e |}) next ctx | ||||
|         } | ||||
|          | ||||
| let webApp = | ||||
|     choose [ | ||||
|         GET   >=> requiresApiKey >=> routef "/user/%s/balance" get | ||||
|         PATCH >=> requiresApiKey >=> routef "/user/%s/balance/withdraw" (modify -1) | ||||
|         PATCH >=> requiresApiKey >=> routef "/user/%s/balance/deposit" (modify +1) | ||||
|         RequestErrors.NOT_FOUND "Not Found" ] | ||||
| 
 | ||||
| let errorHandler (ex : Exception) (logger : ILogger) = | ||||
|     logger.LogError(ex, "An unhandled exception has occurred while executing the request.") | ||||
|     clearResponse >=> setStatusCode 500 >=> text ex.Message | ||||
| 
 | ||||
| let configureApp (app : IApplicationBuilder) = | ||||
|     let env = app.ApplicationServices.GetService<IWebHostEnvironment>() | ||||
|     if env.IsDevelopment() then | ||||
|         app.UseDeveloperExceptionPage() | ||||
|     else | ||||
|         app.UseGiraffeErrorHandler(errorHandler) | ||||
|     |> ignore | ||||
|     app.UseGiraffe(webApp) | ||||
| 
 | ||||
| let configureServices (services : IServiceCollection) = | ||||
|     services.AddGiraffe() |> ignore | ||||
| 
 | ||||
| let configureLogging (builder : ILoggingBuilder) = | ||||
|     builder.AddConsole() | ||||
|            .AddDebug() |> ignore | ||||
| 
 | ||||
| [<EntryPoint>] | ||||
| let main args = | ||||
|     let contentRoot = Directory.GetCurrentDirectory() | ||||
|     let webRoot     = Path.Combine(contentRoot, "WebRoot") | ||||
|     Host.CreateDefaultBuilder(args) | ||||
|         .ConfigureWebHostDefaults( | ||||
|             fun webHostBuilder -> | ||||
|                 webHostBuilder | ||||
|                     .UseContentRoot(contentRoot) | ||||
|                     .UseWebRoot(webRoot) | ||||
|                     .ConfigureKestrel(fun opt -> opt.AddServerHeader <- false) | ||||
|                     .Configure(Action<IApplicationBuilder> configureApp) | ||||
|                     .ConfigureServices(configureServices) | ||||
|                     .ConfigureLogging(configureLogging) | ||||
|                     |> ignore) | ||||
|         .Build() | ||||
|         .Run() | ||||
|     0 | ||||
							
								
								
									
										19
									
								
								CurrencyAPI/CurrencyAPI.fsproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								CurrencyAPI/CurrencyAPI.fsproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net6.0</TargetFramework> | ||||
|     <AssemblyName>CurrencyAPI.App</AssemblyName> | ||||
|     <EnableDefaultContentItems>false</EnableDefaultContentItems> | ||||
|     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <Compile Include="Currency.fs" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <None Include="web.config" CopyToOutputDirectory="PreserveNewest" /> | ||||
|     <Content Include="WebRoot\**\*"> | ||||
|       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||||
|     </Content> | ||||
|   </ItemGroup> | ||||
|   <Import Project="..\.paket\Paket.Restore.targets" /> | ||||
| </Project> | ||||
							
								
								
									
										5
									
								
								CurrencyAPI/paket.references
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								CurrencyAPI/paket.references
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| FSharp.Data | ||||
| FSharp.Core | ||||
| dotenv.net | ||||
| Npgsql.FSharp | ||||
| Giraffe | ||||
							
								
								
									
										9
									
								
								CurrencyAPI/web.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								CurrencyAPI/web.config
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <configuration> | ||||
|   <system.webServer> | ||||
|     <handlers> | ||||
|       <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" /> | ||||
|     </handlers> | ||||
|     <aspNetCore processPath="dotnet" arguments="CurrencyAPI.dll" stdoutLogEnabled="false" stdoutLogFile="logs/stdout" /> | ||||
|   </system.webServer> | ||||
| </configuration> | ||||
| @ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30114.105 | ||||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||||
| Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Bot", "Bot\Bot.fsproj", "{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}" | ||||
| EndProject | ||||
| Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "CurrencyAPI", "CurrencyAPI\CurrencyAPI.fsproj", "{AFA1A9F3-625E-44CA-83DA-A50756D119B5}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|Any CPU = Debug|Any CPU | ||||
| @ -22,5 +24,9 @@ Global | ||||
| 		{44151B85-0D17-4270-AD72-490A6D8D6290}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{44151B85-0D17-4270-AD72-490A6D8D6290}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{44151B85-0D17-4270-AD72-490A6D8D6290}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 	EndGlobalSection | ||||
| EndGlobal | ||||
|  | ||||
| @ -11,7 +11,6 @@ nuget DSharpPlus.SlashCommands >= 4.3.0-nightly-01135 | ||||
| nuget FSharp.Data | ||||
| nuget FsToolkit.ErrorHandling | ||||
| 
 | ||||
| nuget MongoDB.Driver | ||||
| nuget dotenv.net 3.1.1 | ||||
| nuget Npgsql.FSharp | ||||
| nuget mixpanel-csharp 5.0.0 | ||||
| @ -19,3 +18,5 @@ nuget Solnet.Extensions | ||||
| nuget Solnet.KeyStore | ||||
| nuget Solnet.Programs | ||||
| nuget Solnet.Rpc | ||||
| 
 | ||||
| nuget Giraffe | ||||
|  | ||||
							
								
								
									
										48
									
								
								paket.lock
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								paket.lock
									
									
									
									
									
								
							| @ -4,9 +4,6 @@ NUGET | ||||
|   remote: https://api.nuget.org/v3/index.json | ||||
|     Chaos.NaCl.Standard (1.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|     ConcurrentHashSet (1.3) | ||||
|     DnsClient (1.6) | ||||
|       Microsoft.Win32.Registry (>= 5.0) | ||||
|       System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net471)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net471)) (&& (== netstandard2.1) (< netstandard2.0)) | ||||
|     dotenv.net (3.1.1) | ||||
|       System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (< netstandard2.0)) | ||||
|     DSharpPlus (4.3.0-nightly-01135) | ||||
| @ -35,6 +32,15 @@ NUGET | ||||
|       FSharp.Core (>= 4.7.2) | ||||
|     FsToolkit.ErrorHandling (2.13) | ||||
|       FSharp.Core (>= 4.7.2) | ||||
|     Giraffe (6.0) | ||||
|       FSharp.Core (>= 6.0.1) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       Giraffe.ViewEngine (>= 1.3) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       Microsoft.IO.RecyclableMemoryStream (>= 2.2) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       Newtonsoft.Json (>= 13.0.1) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       System.Text.Json (>= 6.0.2) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       Utf8Json (>= 1.3.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|     Giraffe.ViewEngine (1.4) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       FSharp.Core (>= 5.0) | ||||
|     Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) | ||||
|       System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) | ||||
|     Microsoft.Bcl.HashCode (1.1.1) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) | ||||
| @ -89,31 +95,14 @@ NUGET | ||||
|       Microsoft.Extensions.Primitives (>= 6.0) | ||||
|     Microsoft.Extensions.Primitives (6.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       System.Runtime.CompilerServices.Unsafe (>= 6.0) | ||||
|     Microsoft.IO.RecyclableMemoryStream (2.2) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|     Microsoft.NETCore.Platforms (6.0.2) | ||||
|     Microsoft.NETCore.Targets (5.0) | ||||
|     Microsoft.Win32.Primitives (4.3) | ||||
|       Microsoft.NETCore.Platforms (>= 1.1) | ||||
|       Microsoft.NETCore.Targets (>= 1.1) | ||||
|       System.Runtime (>= 4.3) | ||||
|     Microsoft.Win32.Registry (5.0) | ||||
|       System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= monoandroid) (< netstandard1.3)) (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (== netstandard2.0) (== netstandard2.1) | ||||
|       System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (>= uap10.1)) (== netstandard2.0) (== netstandard2.1) | ||||
|       System.Security.AccessControl (>= 5.0) | ||||
|       System.Security.Principal.Windows (>= 5.0) | ||||
|     mixpanel-csharp (5.0) | ||||
|     MongoDB.Bson (2.15) | ||||
|       System.Runtime.CompilerServices.Unsafe (>= 5.0) | ||||
|     MongoDB.Driver (2.15) | ||||
|       MongoDB.Bson (>= 2.15) | ||||
|       MongoDB.Driver.Core (>= 2.15) | ||||
|       MongoDB.Libmongocrypt (>= 1.3) | ||||
|     MongoDB.Driver.Core (2.15) | ||||
|       DnsClient (>= 1.6) | ||||
|       MongoDB.Bson (>= 2.15) | ||||
|       MongoDB.Libmongocrypt (>= 1.3) | ||||
|       SharpCompress (>= 0.30.1) | ||||
|       System.Buffers (>= 4.5.1) | ||||
|     MongoDB.Libmongocrypt (1.3) | ||||
|     Newtonsoft.Json (13.0.1) | ||||
|     Npgsql (6.0.3) | ||||
|       Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) | ||||
| @ -177,9 +166,6 @@ NUGET | ||||
|     runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) | ||||
|     runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) | ||||
|     runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) | ||||
|     SharpCompress (0.30.1) | ||||
|       System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) | ||||
|       System.Text.Encoding.CodePages (>= 5.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) | ||||
|     Solnet.Extensions (6.0.11) | ||||
|       Solnet.Programs (>= 6.0.11) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       Solnet.Rpc (>= 6.0.11) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
| @ -197,7 +183,7 @@ NUGET | ||||
|     Solnet.Wallet (6.0.11) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       Chaos.NaCl.Standard (>= 1.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       Portable.BouncyCastle (>= 1.9) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|     System.Buffers (4.5.1) | ||||
|     System.Buffers (4.5.1) - restriction: || (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1) (>= xamarinios)) (&& (== net6.0) (< netstandard2.1) (>= xamarinmac)) (&& (== net6.0) (< netstandard2.1) (>= xamarintvos)) (&& (== net6.0) (< netstandard2.1) (>= xamarinwatchos)) (== netstandard2.0) (== netstandard2.1) | ||||
|     System.Collections (4.3) | ||||
|       Microsoft.NETCore.Platforms (>= 1.1) | ||||
|       Microsoft.NETCore.Targets (>= 1.1) | ||||
| @ -397,6 +383,8 @@ NUGET | ||||
|       System.IO (>= 4.3) | ||||
|       System.Reflection.Primitives (>= 4.3) | ||||
|       System.Runtime (>= 4.3) | ||||
|     System.Reflection.Emit (4.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|     System.Reflection.Emit.Lightweight (4.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|     System.Reflection.Extensions (4.3) | ||||
|       Microsoft.NETCore.Platforms (>= 1.1) | ||||
|       Microsoft.NETCore.Targets (>= 1.1) | ||||
| @ -444,8 +432,6 @@ NUGET | ||||
|       System.Resources.ResourceManager (>= 4.3) | ||||
|       System.Runtime (>= 4.3) | ||||
|       System.Runtime.Extensions (>= 4.3) | ||||
|     System.Security.AccessControl (6.0) | ||||
|       System.Security.Principal.Windows (>= 5.0) - restriction: || (&& (== net6.0) (>= net461)) (== netstandard2.0) (== netstandard2.1) | ||||
|     System.Security.Claims (4.3) | ||||
|       System.Collections (>= 4.3) | ||||
|       System.Globalization (>= 4.3) | ||||
| @ -541,9 +527,6 @@ NUGET | ||||
|       Microsoft.NETCore.Platforms (>= 1.1) | ||||
|       Microsoft.NETCore.Targets (>= 1.1) | ||||
|       System.Runtime (>= 4.3) | ||||
|     System.Text.Encoding.CodePages (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) | ||||
|       System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) | ||||
|       System.Runtime.CompilerServices.Unsafe (>= 6.0) | ||||
|     System.Text.Encoding.Extensions (4.3) | ||||
|       Microsoft.NETCore.Platforms (>= 1.1) | ||||
|       Microsoft.NETCore.Targets (>= 1.1) | ||||
| @ -573,3 +556,8 @@ NUGET | ||||
|       Microsoft.NETCore.Targets (>= 1.1) | ||||
|       System.Runtime (>= 4.3) | ||||
|     System.ValueTuple (4.5) | ||||
|     Utf8Json (1.3.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) | ||||
|       System.Reflection.Emit (>= 4.3) | ||||
|       System.Reflection.Emit.Lightweight (>= 4.3) | ||||
|       System.Threading.Tasks.Extensions (>= 4.4) | ||||
|       System.ValueTuple (>= 4.4) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user