Skip to content

Commit

Permalink
- Enable nullability in project (ref: supabase-community/supabase-csh…
Browse files Browse the repository at this point in the history
…arp#34)

- Restructure to support DI (implements #1)
  • Loading branch information
acupofjose committed Nov 4, 2022
1 parent 503049f commit 563f37b
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 96 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.1.0 - 2022-11-04

- `Client` is no longer a Singleton class, it should be initialized using a default constructor.
- [#1](https://github.com/supabase-community/functions-csharp/issues/1) Restructures library to support DI.

## 1.0.1 - 2022-04-15

- Default `token` to be `null` in `Invoke` calls to allow `Authorization` to be passed solely via Headers.
Expand Down
11 changes: 6 additions & 5 deletions Functions/Client.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using Supabase.Functions.Interfaces;
using Supabase.Functions.Responses;
using System;
using System.Collections.Generic;
Expand All @@ -9,7 +10,7 @@

namespace Supabase.Functions
{
public class Client
public class Client : IFunctionsClient
{
private static readonly HttpClient client = new HttpClient();

Expand All @@ -20,7 +21,7 @@ public class Client
/// <param name="token">Anon Key.</param>
/// <param name="options">Options</param>
/// <returns></returns>
public static async Task<HttpContent> RawInvoke(string url, string token = null, InvokeFunctionOptions options = null) => (await HandleRequest(url, token, options)).Content;
public async Task<HttpContent> RawInvoke(string url, string? token = null, InvokeFunctionOptions? options = null) => (await HandleRequest(url, token, options)).Content;

/// <summary>
/// Invokes a function and returns the Text content of the response.
Expand All @@ -29,7 +30,7 @@ public class Client
/// <param name="token">Anon Key.</param>
/// <param name="options">Options</param>
/// <returns></returns>
public static async Task<string> Invoke(string url, string token = null, InvokeFunctionOptions options = null)
public async Task<string> Invoke(string url, string? token = null, InvokeFunctionOptions? options = null)
{
var response = await HandleRequest(url, token, options);

Expand All @@ -44,7 +45,7 @@ public static async Task<string> Invoke(string url, string token = null, InvokeF
/// <param name="token">Anon Key.</param>
/// <param name="options">Options</param>
/// <returns></returns>
public static async Task<T> Invoke<T>(string url, string token = null, InvokeFunctionOptions options = null)
public async Task<T?> Invoke<T>(string url, string? token = null, InvokeFunctionOptions? options = null) where T : class
{
var response = await HandleRequest(url, token, options);

Expand All @@ -61,7 +62,7 @@ public static async Task<T> Invoke<T>(string url, string token = null, InvokeFun
/// <param name="options"></param>
/// <returns></returns>
/// <exception cref="RequestException"></exception>
private static async Task<HttpResponseMessage> HandleRequest(string url, string token = null, InvokeFunctionOptions options = null)
private async Task<HttpResponseMessage> HandleRequest(string url, string? token = null, InvokeFunctionOptions? options = null)
{
if (options == null)
{
Expand Down
63 changes: 34 additions & 29 deletions Functions/Functions.csproj
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackOnBuild>true</PackOnBuild>
<PackageId>functions-csharp</PackageId>
<Authors>Joseph Schultz &lt;[email protected]&gt;</Authors>
<Copyright>MIT</Copyright>
<NeutralLanguage>en</NeutralLanguage>
<Owners>Joseph Schultz &lt;[email protected]&gt;</Owners>
<Summary>A C# client for Supabase functions</Summary>
<Title>Function</Title>
<Description>A C# client for Supabase functions</Description>
<RootNamespace>Supabase.Functions</RootNamespace>
<PackageIconUrl>https://avatars.githubusercontent.com/u/54469796?s=200&amp;v=4</PackageIconUrl>
<PackageLicenseUrl>https://github.com/supabase-community/functions-csharp/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/supabase-community/functions-csharp</PackageProjectUrl>
<PackageTags>supabase, functions</PackageTags>
<PackageVersion>1.0.1</PackageVersion>
<ReleaseVersion>1.0.1</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Version)' == '' ">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackOnBuild>true</PackOnBuild>
<PackageId>functions-csharp</PackageId>
<Authors>Joseph Schultz &lt;[email protected]&gt;</Authors>
<Copyright>MIT</Copyright>
<NeutralLanguage>en</NeutralLanguage>
<Owners>Joseph Schultz &lt;[email protected]&gt;</Owners>
<Summary>A C# client for Supabase functions</Summary>
<Title>Function</Title>
<Description>A C# client for Supabase functions</Description>
<RootNamespace>Supabase.Functions</RootNamespace>
<PackageIconUrl>https://avatars.githubusercontent.com/u/54469796?s=200&amp;v=4</PackageIconUrl>
<PackageLicenseUrl>https://github.com/supabase-community/functions-csharp/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/supabase-community/functions-csharp</PackageProjectUrl>
<PackageTags>supabase, functions</PackageTags>
<PackageVersion>1.1.0</PackageVersion>
<ReleaseVersion>1.1.0</ReleaseVersion>
</PropertyGroup>
<PropertyGroup>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Version)' == '' ">
<VersionPrefix Condition=" '$(VersionPrefix)' == '' ">1.0.1</VersionPrefix>
<VersionSuffix Condition=" '$(VersionSuffix)' == '' ">
</VersionSuffix>
<Version Condition=" '$(VersionSuffix)' != '' ">$(VersionPrefix)-$(VersionSuffix)</Version>
<Version Condition=" '$(Version)' == '' ">$(VersionPrefix)</Version>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>
12 changes: 12 additions & 0 deletions Functions/Interfaces/IFunctionsClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Net.Http;
using System.Threading.Tasks;

namespace Supabase.Functions.Interfaces
{
public interface IFunctionsClient
{
Task<string> Invoke(string url, string? token = null, Client.InvokeFunctionOptions? options = null);
Task<T?> Invoke<T>(string url, string? token = null, Client.InvokeFunctionOptions? options = null) where T : class;
Task<HttpContent> RawInvoke(string url, string? token = null, Client.InvokeFunctionOptions? options = null);
}
}
4 changes: 2 additions & 2 deletions Functions/Responses/BaseResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ namespace Supabase.Functions.Responses
public class BaseResponse
{
[JsonIgnore]
public HttpResponseMessage ResponseMessage { get; set; }
public HttpResponseMessage? ResponseMessage { get; set; }

[JsonIgnore]
public string Content { get; set; }
public string? Content { get; set; }
}
}
2 changes: 1 addition & 1 deletion Functions/Responses/ErrorResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ namespace Supabase.Functions.Responses
/// </summary>
public class ErrorResponse : BaseResponse
{
public string Message { get; set; }
public string? Message { get; set; }
}
}
116 changes: 57 additions & 59 deletions FunctionsTests/Client.cs → FunctionsTests/ClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,59 +1,57 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static Supabase.Functions.Client;

namespace FunctionsTests
{
[TestClass]
public class Client
{
[TestMethod("Invokes a function.")]
public async Task Invokes()
{
var token = Environment.GetEnvironmentVariable("TOKEN");
var endpoint = Environment.GetEnvironmentVariable("FUNCTION_ENDPOINT");

var result = await Invoke(endpoint, token, new InvokeFunctionOptions
{
Body = new Dictionary<string, object>
{
{"name", "supabase" }
}
});

Assert.IsTrue(result.Contains("supabase"));


var result2 = await Invoke<Dictionary<string, string>>(endpoint, token, new InvokeFunctionOptions
{
Body = new Dictionary<string, object>
{
{ "name", "functions" }
}
});

Assert.IsInstanceOfType(result2, typeof(Dictionary<string, string>));
Assert.IsTrue(result2.ContainsKey("message"));
Assert.IsTrue(result2["message"].Contains("functions"));


var result3 = await RawInvoke(endpoint, token, new InvokeFunctionOptions
{
Body = new Dictionary<string, object>
{
{ "name", "functions" }
}
});

var bytes = await result3.ReadAsByteArrayAsync();

Assert.IsInstanceOfType(bytes, typeof(byte[]));
}
}
}
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Supabase.Functions;
using static Supabase.Functions.Client;

namespace FunctionsTests
{
[TestClass]
public class ClientTests
{
[TestMethod("Invokes a function.")]
public async Task Invokes()
{
var token = Environment.GetEnvironmentVariable("TOKEN");
var endpoint = Environment.GetEnvironmentVariable("FUNCTION_ENDPOINT");
var client = new Client();

var result = await client.Invoke(endpoint, token, new InvokeFunctionOptions
{
Body = new Dictionary<string, object>
{
{"name", "supabase" }
}
});

Assert.IsTrue(result.Contains("supabase"));


var result2 = await client.Invoke<Dictionary<string, string>>(endpoint, token, new InvokeFunctionOptions
{
Body = new Dictionary<string, object>
{
{ "name", "functions" }
}
});

Assert.IsInstanceOfType(result2, typeof(Dictionary<string, string>));
Assert.IsTrue(result2.ContainsKey("message"));
Assert.IsTrue(result2["message"].Contains("functions"));


var result3 = await client.RawInvoke(endpoint, token, new InvokeFunctionOptions
{
Body = new Dictionary<string, object>
{
{ "name", "functions" }
}
});

var bytes = await result3.ReadAsByteArrayAsync();

Assert.IsInstanceOfType(bytes, typeof(byte[]));
}
}
}

0 comments on commit 563f37b

Please sign in to comment.