Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 19 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# EditorConfig for the generated .NET and Unity SDKs.
# `dotnet format whitespace` is the canonical formatter; this file records the
# layout that a clean generation must already match.
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.cs]
csharp_space_after_keywords_in_control_flow_statements = true
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_indent_preprocessor_directives = false
2 changes: 1 addition & 1 deletion Appwrite/Appwrite.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
<PackageId>Appwrite</PackageId>
<Version>7.0.0</Version>
<Version>8.0.0-rc.1</Version>
<Authors>Appwrite Team</Authors>
<Company>Appwrite Team</Company>
<Description>
Expand Down
106 changes: 67 additions & 39 deletions Appwrite/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,19 @@ public Client(
_http = http ?? new HttpClient();

_httpForRedirect = httpForRedirect ?? new HttpClient(
new HttpClientHandler(){
new HttpClientHandler()
{
AllowAutoRedirect = false
});

_headers = new Dictionary<string, string>()
{
{ "content-type", "application/json" },
{ "user-agent" , $"AppwriteDotNetSDK/7.0.0 ({Environment.OSVersion.Platform}; {Environment.OSVersion.VersionString})"},
{ "user-agent", $"AppwriteDotNetSDK/8.0.0-rc.1 ({Environment.OSVersion.Platform}; {Environment.OSVersion.VersionString})"},
{ "x-sdk-name", ".NET" },
{ "x-sdk-platform", "server" },
{ "x-sdk-language", "dotnet" },
{ "x-sdk-version", "7.0.0"},
{ "x-sdk-version", "8.0.0-rc.1"},
{ "X-Appwrite-Response-Format", "1.9.6" }
};

Expand Down Expand Up @@ -108,7 +109,8 @@ public Client SetSelfSigned(bool selfSigned)

public Client SetEndpoint(string endpoint)
{
if (!endpoint.StartsWith("http://") && !endpoint.StartsWith("https://")) {
if (!endpoint.StartsWith("http://") && !endpoint.StartsWith("https://"))
{
throw new AppwriteException("Invalid endpoint URL: " + endpoint);
}

Expand All @@ -117,101 +119,114 @@ public Client SetEndpoint(string endpoint)
}

/// <summary>Your project ID</summary>
public Client SetProject(string value) {
public Client SetProject(string value)
{
_config["project"] = value;

return this;
}

/// <summary>Your secret API key</summary>
public Client SetKey(string value) {
public Client SetKey(string value)
{
_config["key"] = value;
AddHeader("X-Appwrite-Key", value);

return this;
}

/// <summary>Your organization ID</summary>
public Client SetOrganization(string value) {
public Client SetOrganization(string value)
{
_config["organization"] = value;
AddHeader("X-Appwrite-Organization", value);

return this;
}

/// <summary>Your secret JSON Web Token</summary>
public Client SetJWT(string value) {
public Client SetJWT(string value)
{
_config["jWT"] = value;
AddHeader("X-Appwrite-JWT", value);

return this;
}

/// <summary>The OAuth access token to authenticate with</summary>
public Client SetBearer(string value) {
public Client SetBearer(string value)
{
_config["bearer"] = value;
AddHeader("Authorization", "Bearer " + value);

return this;
}

public Client SetLocale(string value) {
public Client SetLocale(string value)
{
_config["locale"] = value;
AddHeader("X-Appwrite-Locale", value);

return this;
}

/// <summary>The user session to authenticate with</summary>
public Client SetSession(string value) {
public Client SetSession(string value)
{
_config["session"] = value;
AddHeader("X-Appwrite-Session", value);

return this;
}

/// <summary>The user agent string of the client that made the request</summary>
public Client SetForwardedUserAgent(string value) {
public Client SetForwardedUserAgent(string value)
{
_config["forwardedUserAgent"] = value;
AddHeader("X-Forwarded-User-Agent", value);

return this;
}

/// <summary>Your secret dev API key</summary>
public Client SetDevKey(string value) {
public Client SetDevKey(string value)
{
_config["devKey"] = value;
AddHeader("X-Appwrite-Dev-Key", value);

return this;
}

/// <summary>The user cookie to authenticate with. Used by SDKs that forward an incoming Cookie header in server-side runtimes.</summary>
public Client SetCookie(string value) {
public Client SetCookie(string value)
{
_config["cookie"] = value;
AddHeader("Cookie", value);

return this;
}

/// <summary>Impersonate a user by ID</summary>
public Client SetImpersonateUserId(string value) {
public Client SetImpersonateUserId(string value)
{
_config["impersonateUserId"] = value;
AddHeader("X-Appwrite-Impersonate-User-Id", value);

return this;
}

/// <summary>Impersonate a user by email</summary>
public Client SetImpersonateUserEmail(string value) {
public Client SetImpersonateUserEmail(string value)
{
_config["impersonateUserEmail"] = value;
AddHeader("X-Appwrite-Impersonate-User-Email", value);

return this;
}

/// <summary>Impersonate a user by phone</summary>
public Client SetImpersonateUserPhone(string value) {
public Client SetImpersonateUserPhone(string value)
{
_config["impersonateUserPhone"] = value;
AddHeader("X-Appwrite-Impersonate-User-Phone", value);

Expand Down Expand Up @@ -246,7 +261,7 @@ private HttpRequestMessage PrepareRequest(
new HttpMethod(method),
_endpoint + path + queryString);

if (headers.TryGetValue("content-type", out var contentType) &&
if (headers.TryGetValue("content-type", out var contentType) &&
"multipart/form-data".Equals(contentType, StringComparison.OrdinalIgnoreCase))
{
var form = new MultipartFormDataContent();
Expand Down Expand Up @@ -293,7 +308,8 @@ private HttpRequestMessage PrepareRequest(
}
else
{
if (request.Headers.Contains(header.Key)) {
if (request.Headers.Contains(header.Key))
{
request.Headers.Remove(header.Key);
}
request.Headers.Add(header.Key, header.Value);
Expand All @@ -312,7 +328,8 @@ private HttpRequestMessage PrepareRequest(
}
else
{
if (request.Headers.Contains(header.Key)) {
if (request.Headers.Contains(header.Key))
{
request.Headers.Remove(header.Key);
}
request.Headers.Add(header.Key, header.Value);
Expand All @@ -333,7 +350,8 @@ public async Task<String> Redirect(
var response = await _httpForRedirect.SendAsync(request);
var code = (int)response.StatusCode;

if (code >= 400) {
if (code >= 400)
{
var text = await response.Content.ReadAsStringAsync();
var message = "";
var type = "";
Expand All @@ -344,8 +362,9 @@ public async Task<String> Redirect(
contentType = contentTypes.FirstOrDefault() ?? string.Empty;
}

if (contentType.Contains("application/json")) {
try
if (contentType.Contains("application/json"))
{
try
{
using var errorDoc = JsonDocument.Parse(text);
message = errorDoc.RootElement.GetProperty("message").GetString() ?? "";
Expand All @@ -358,7 +377,9 @@ public async Task<String> Redirect(
{
message = text;
}
} else {
}
else
{
message = text;
}

Expand Down Expand Up @@ -405,13 +426,15 @@ public async Task<T> Call<T>(

var isJson = contentType.Contains("application/json");

if (code >= 400) {
if (code >= 400)
{
var text = await response.Content.ReadAsStringAsync();
var message = "";
var type = "";

if (isJson) {
try
if (isJson)
{
try
{
using var errorDoc = JsonDocument.Parse(text);
message = errorDoc.RootElement.GetProperty("message").GetString() ?? "";
Expand All @@ -424,7 +447,9 @@ public async Task<T> Call<T>(
{
message = text;
}
} else {
}
else
{
message = text;
}

Expand Down Expand Up @@ -463,16 +488,16 @@ public async Task<T> ChunkedUpload<T>(
{
if (string.IsNullOrEmpty(paramName))
throw new ArgumentException("Parameter name cannot be null or empty", nameof(paramName));

if (!parameters.ContainsKey(paramName))
throw new ArgumentException($"Parameter {paramName} not found", nameof(paramName));

var input = parameters[paramName] as InputFile;
if (input == null)
throw new ArgumentException($"Parameter {paramName} must be an InputFile", nameof(paramName));

var size = 0L;
switch(input.SourceType)
switch (input.SourceType)
{
case "path":
var info = new FileInfo(input.Path);
Expand All @@ -490,15 +515,15 @@ public async Task<T> ChunkedUpload<T>(
throw new InvalidOperationException("Byte array data is null");
size = bytes.Length;
break;
};
}

var offset = 0L;
var buffer = new byte[Math.Min(size, ChunkSize)];
var result = new Dictionary<string, object?>();

if (size < ChunkSize)
{
switch(input.SourceType)
switch (input.SourceType)
{
case "path":
buffer = System.IO.File.ReadAllBytes(input.Path);
Expand Down Expand Up @@ -534,14 +559,18 @@ public async Task<T> ChunkedUpload<T>(

var uploadId = string.Empty;

if (!string.IsNullOrEmpty(idParamName))
if (idParamName is not null
&& idParamName.Length > 0
&& parameters.TryGetValue(idParamName, out var uploadIdValue)
&& uploadIdValue != null)
{
uploadId = uploadIdValue.ToString() ?? string.Empty;
try
{
// Make a request to check if a file already exists
var current = await Call<Dictionary<string, object?>>(
method: "GET",
path: $"{path}/{parameters[idParamName!]}",
path: $"{path}/{uploadId}",
new Dictionary<string, string> { { "content-type", "application/json" } },
parameters: new Dictionary<string, object?>()
);
Expand All @@ -550,7 +579,6 @@ public async Task<T> ChunkedUpload<T>(
offset = Convert.ToInt64(chunksUploadedValue) * ChunkSize;
}
result = current;
uploadId = parameters[idParamName!]?.ToString() ?? string.Empty;
}
catch
{
Expand All @@ -565,7 +593,7 @@ async Task<byte[]> ReadChunkAsync(long start, long end)
var length = (int)(end - start);
var chunk = new byte[length];

switch(input.SourceType)
switch (input.SourceType)
{
case "path":
using (var chunkStream = System.IO.File.OpenRead(input.Path))
Expand Down Expand Up @@ -744,7 +772,7 @@ bool IsUploadComplete(Dictionary<string, object?> chunkResult)
// Convert to non-nullable dictionary for converter
var nonNullableResult = result.Where(kvp => kvp.Value != null)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value!);

return converter(nonNullableResult);
}
}
Expand Down
1 change: 1 addition & 0 deletions Appwrite/Enums/BuildRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public BuildRuntime(string value)
public static BuildRuntime Bun11 => new BuildRuntime("bun-1.1");
public static BuildRuntime Bun12 => new BuildRuntime("bun-1.2");
public static BuildRuntime Bun13 => new BuildRuntime("bun-1.3");
public static BuildRuntime Bun14 => new BuildRuntime("bun-1.4");
public static BuildRuntime Go123 => new BuildRuntime("go-1.23");
public static BuildRuntime Go124 => new BuildRuntime("go-1.24");
public static BuildRuntime Go125 => new BuildRuntime("go-1.25");
Expand Down
18 changes: 18 additions & 0 deletions Appwrite/Enums/DocumentsDBIndexType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace Appwrite.Enums
{
public class DocumentsDBIndexType : IEnum
{
public string Value { get; private set; }

public DocumentsDBIndexType(string value)
{
Value = value;
}

public static DocumentsDBIndexType Key => new DocumentsDBIndexType("key");
public static DocumentsDBIndexType Fulltext => new DocumentsDBIndexType("fulltext");
public static DocumentsDBIndexType Unique => new DocumentsDBIndexType("unique");
}
}
Loading