Skip to content

Commit 713a790

Browse files
Merge pull request #66 from appwrite/dev
chore: regenerate sdk
2 parents 7dc4b81 + a160896 commit 713a790

File tree

113 files changed

+1198
-1044
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+1198
-1044
lines changed

Appwrite/Appwrite.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
3+
<TargetFrameworks>netstandard2.0;net462</TargetFrameworks>
44
<PackageId>Appwrite</PackageId>
5-
<Version>0.13.0</Version>
5+
<Version>0.14.0</Version>
66
<Authors>Appwrite Team</Authors>
77
<Company>Appwrite Team</Company>
88
<Description>
@@ -20,7 +20,7 @@
2020
</PropertyGroup>
2121

2222
<ItemGroup>
23-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
23+
<PackageReference Include="System.Text.Json" Version="9.0.5" />
2424
<PackageReference Include="System.Net.Http" Version="4.3.4" />
2525
<None Include="..\icon.png" Pack="true" PackagePath="$(PackageIcon)"/>
2626
<None Include="..\README.md" Pack="true" PackagePath="$(PackageReadmeFile)"/>

Appwrite/Client.cs

Lines changed: 102 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
using Newtonsoft.Json;
2-
using Newtonsoft.Json.Converters;
3-
using Newtonsoft.Json.Linq;
4-
using Newtonsoft.Json.Serialization;
51
using System;
62
using System.Collections.Generic;
73
using System.IO;
84
using System.Linq;
95
using System.Net.Http;
106
using System.Net.Http.Headers;
117
using System.Text;
8+
using System.Text.Json;
9+
using System.Text.Json.Serialization;
1210
using System.Threading.Tasks;
1311
using Appwrite.Converters;
1412
using Appwrite.Extensions;
@@ -29,26 +27,28 @@ public class Client
2927

3028
private static readonly int ChunkSize = 5 * 1024 * 1024;
3129

32-
public static JsonSerializerSettings DeserializerSettings { get; set; } = new JsonSerializerSettings
30+
public static JsonSerializerOptions DeserializerOptions { get; set; } = new JsonSerializerOptions
3331
{
34-
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
35-
NullValueHandling = NullValueHandling.Ignore,
36-
ContractResolver = new CamelCasePropertyNamesContractResolver(),
37-
Converters = new List<JsonConverter>
32+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
33+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
34+
PropertyNameCaseInsensitive = true,
35+
Converters =
3836
{
39-
new StringEnumConverter(new CamelCaseNamingStrategy()),
40-
new ValueClassConverter()
37+
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
38+
new ValueClassConverter(),
39+
new ObjectToInferredTypesConverter()
4140
}
4241
};
4342

44-
public static JsonSerializerSettings SerializerSettings { get; set; } = new JsonSerializerSettings
43+
public static JsonSerializerOptions SerializerOptions { get; set; } = new JsonSerializerOptions
4544
{
46-
NullValueHandling = NullValueHandling.Ignore,
47-
ContractResolver = new CamelCasePropertyNamesContractResolver(),
48-
Converters = new List<JsonConverter>
45+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
46+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
47+
Converters =
4948
{
50-
new StringEnumConverter(new CamelCaseNamingStrategy()),
51-
new ValueClassConverter()
49+
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
50+
new ValueClassConverter(),
51+
new ObjectToInferredTypesConverter()
5252
}
5353
};
5454

@@ -69,11 +69,12 @@ public Client(
6969
_headers = new Dictionary<string, string>()
7070
{
7171
{ "content-type", "application/json" },
72-
{ "user-agent" , "AppwriteDotNetSDK/0.13.0 (${Environment.OSVersion.Platform}; ${Environment.OSVersion.VersionString})"},
72+
{ "user-agent" , $"AppwriteDotNetSDK/0.14.0 ({Environment.OSVersion.Platform}; {Environment.OSVersion.VersionString})"},
7373
{ "x-sdk-name", ".NET" },
7474
{ "x-sdk-platform", "server" },
7575
{ "x-sdk-language", "dotnet" },
76-
{ "x-sdk-version", "0.13.0"}, { "X-Appwrite-Response-Format", "1.7.0" }
76+
{ "x-sdk-version", "0.14.0"},
77+
{ "X-Appwrite-Response-Format", "1.7.0" }
7778
};
7879

7980
_config = new Dictionary<string, string>();
@@ -82,8 +83,6 @@ public Client(
8283
{
8384
SetSelfSigned(true);
8485
}
85-
86-
JsonConvert.DefaultSettings = () => DeserializerSettings;
8786
}
8887

8988
public Client SetSelfSigned(bool selfSigned)
@@ -189,19 +188,23 @@ private HttpRequestMessage PrepareRequest(
189188
{
190189
if (parameter.Key == "file")
191190
{
192-
form.Add(((MultipartFormDataContent)parameters["file"]).First()!);
191+
var fileContent = parameters["file"] as MultipartFormDataContent;
192+
if (fileContent != null)
193+
{
194+
form.Add(fileContent.First()!);
195+
}
193196
}
194197
else if (parameter.Value is IEnumerable<object> enumerable)
195198
{
196199
var list = new List<object>(enumerable);
197200
for (int index = 0; index < list.Count; index++)
198201
{
199-
form.Add(new StringContent(list[index].ToString()!), $"{parameter.Key}[{index}]");
202+
form.Add(new StringContent(list[index]?.ToString() ?? string.Empty), $"{parameter.Key}[{index}]");
200203
}
201204
}
202205
else
203206
{
204-
form.Add(new StringContent(parameter.Value.ToString()!), parameter.Key);
207+
form.Add(new StringContent(parameter.Value?.ToString() ?? string.Empty), parameter.Key);
205208
}
206209
}
207210
request.Content = form;
@@ -274,16 +277,27 @@ public async Task<String> Redirect(
274277
}
275278

276279
if (contentType.Contains("application/json")) {
277-
message = JObject.Parse(text)["message"]!.ToString();
278-
type = JObject.Parse(text)["type"]?.ToString() ?? string.Empty;
280+
try
281+
{
282+
using var errorDoc = JsonDocument.Parse(text);
283+
message = errorDoc.RootElement.GetProperty("message").GetString() ?? "";
284+
if (errorDoc.RootElement.TryGetProperty("type", out var typeElement))
285+
{
286+
type = typeElement.GetString() ?? "";
287+
}
288+
}
289+
catch
290+
{
291+
message = text;
292+
}
279293
} else {
280294
message = text;
281295
}
282296

283297
throw new AppwriteException(message, code, type, text);
284298
}
285299

286-
return response.Headers.Location.OriginalString;
300+
return response.Headers.Location?.OriginalString ?? string.Empty;
287301
}
288302

289303
public Task<Dictionary<string, object?>> Call(
@@ -329,8 +343,19 @@ public async Task<T> Call<T>(
329343
var type = "";
330344

331345
if (isJson) {
332-
message = JObject.Parse(text)["message"]!.ToString();
333-
type = JObject.Parse(text)["type"]?.ToString() ?? string.Empty;
346+
try
347+
{
348+
using var errorDoc = JsonDocument.Parse(text);
349+
message = errorDoc.RootElement.GetProperty("message").GetString() ?? "";
350+
if (errorDoc.RootElement.TryGetProperty("type", out var typeElement))
351+
{
352+
type = typeElement.GetString() ?? "";
353+
}
354+
}
355+
catch
356+
{
357+
message = text;
358+
}
334359
} else {
335360
message = text;
336361
}
@@ -342,13 +367,13 @@ public async Task<T> Call<T>(
342367
{
343368
var responseString = await response.Content.ReadAsStringAsync();
344369

345-
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(
370+
var dict = JsonSerializer.Deserialize<Dictionary<string, object>>(
346371
responseString,
347-
DeserializerSettings);
372+
DeserializerOptions);
348373

349-
if (convert != null)
374+
if (convert != null && dict != null)
350375
{
351-
return convert(dict!);
376+
return convert(dict);
352377
}
353378

354379
return (dict as T)!;
@@ -368,7 +393,16 @@ public async Task<T> ChunkedUpload<T>(
368393
string? idParamName = null,
369394
Action<UploadProgress>? onProgress = null) where T : class
370395
{
396+
if (string.IsNullOrEmpty(paramName))
397+
throw new ArgumentException("Parameter name cannot be null or empty", nameof(paramName));
398+
399+
if (!parameters.ContainsKey(paramName))
400+
throw new ArgumentException($"Parameter {paramName} not found", nameof(paramName));
401+
371402
var input = parameters[paramName] as InputFile;
403+
if (input == null)
404+
throw new ArgumentException($"Parameter {paramName} must be an InputFile", nameof(paramName));
405+
372406
var size = 0L;
373407
switch(input.SourceType)
374408
{
@@ -378,10 +412,16 @@ public async Task<T> ChunkedUpload<T>(
378412
size = info.Length;
379413
break;
380414
case "stream":
381-
size = (input.Data as Stream).Length;
415+
var stream = input.Data as Stream;
416+
if (stream == null)
417+
throw new InvalidOperationException("Stream data is null");
418+
size = stream.Length;
382419
break;
383420
case "bytes":
384-
size = ((byte[])input.Data).Length;
421+
var bytes = input.Data as byte[];
422+
if (bytes == null)
423+
throw new InvalidOperationException("Byte array data is null");
424+
size = bytes.Length;
385425
break;
386426
};
387427

@@ -395,10 +435,16 @@ public async Task<T> ChunkedUpload<T>(
395435
{
396436
case "path":
397437
case "stream":
398-
await (input.Data as Stream).ReadAsync(buffer, 0, (int)size);
438+
var dataStream = input.Data as Stream;
439+
if (dataStream == null)
440+
throw new InvalidOperationException("Stream data is null");
441+
await dataStream.ReadAsync(buffer, 0, (int)size);
399442
break;
400443
case "bytes":
401-
buffer = (byte[])input.Data;
444+
var dataBytes = input.Data as byte[];
445+
if (dataBytes == null)
446+
throw new InvalidOperationException("Byte array data is null");
447+
buffer = dataBytes;
402448
break;
403449
}
404450

@@ -424,14 +470,16 @@ public async Task<T> ChunkedUpload<T>(
424470
// Make a request to check if a file already exists
425471
var current = await Call<Dictionary<string, object?>>(
426472
method: "GET",
427-
path: $"{path}/{parameters[idParamName]}",
473+
path: $"{path}/{parameters[idParamName!]}",
428474
new Dictionary<string, string> { { "content-type", "application/json" } },
429475
parameters: new Dictionary<string, object?>()
430476
);
431-
var chunksUploaded = (long)current["chunksUploaded"];
432-
offset = chunksUploaded * ChunkSize;
477+
if (current.TryGetValue("chunksUploaded", out var chunksUploadedValue) && chunksUploadedValue != null)
478+
{
479+
offset = Convert.ToInt64(chunksUploadedValue) * ChunkSize;
480+
}
433481
}
434-
catch (Exception ex)
482+
catch
435483
{
436484
// ignored as it mostly means file not found
437485
}
@@ -444,6 +492,8 @@ public async Task<T> ChunkedUpload<T>(
444492
case "path":
445493
case "stream":
446494
var stream = input.Data as Stream;
495+
if (stream == null)
496+
throw new InvalidOperationException("Stream data is null");
447497
stream.Seek(offset, SeekOrigin.Begin);
448498
await stream.ReadAsync(buffer, 0, ChunkSize);
449499
break;
@@ -476,12 +526,12 @@ public async Task<T> ChunkedUpload<T>(
476526
var id = result.ContainsKey("$id")
477527
? result["$id"]?.ToString() ?? string.Empty
478528
: string.Empty;
479-
var chunksTotal = result.ContainsKey("chunksTotal")
480-
? (long)result["chunksTotal"]
481-
: 0;
482-
var chunksUploaded = result.ContainsKey("chunksUploaded")
483-
? (long)result["chunksUploaded"]
484-
: 0;
529+
var chunksTotal = result.TryGetValue("chunksTotal", out var chunksTotalValue) && chunksTotalValue != null
530+
? Convert.ToInt64(chunksTotalValue)
531+
: 0L;
532+
var chunksUploaded = result.TryGetValue("chunksUploaded", out var chunksUploadedValue) && chunksUploadedValue != null
533+
? Convert.ToInt64(chunksUploadedValue)
534+
: 0L;
485535

486536
headers["x-appwrite-id"] = id;
487537

@@ -494,7 +544,11 @@ public async Task<T> ChunkedUpload<T>(
494544
chunksUploaded: chunksUploaded));
495545
}
496546

497-
return converter(result);
547+
// Convert to non-nullable dictionary for converter
548+
var nonNullableResult = result.Where(kvp => kvp.Value != null)
549+
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value!);
550+
551+
return converter(nonNullableResult);
498552
}
499553
}
500554
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text.Json;
4+
using System.Text.Json.Serialization;
5+
6+
namespace Appwrite.Converters
7+
{
8+
public class ObjectToInferredTypesConverter : JsonConverter<object>
9+
{
10+
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
11+
{
12+
switch (reader.TokenType)
13+
{
14+
case JsonTokenType.True:
15+
return true;
16+
case JsonTokenType.False:
17+
return false;
18+
case JsonTokenType.Number:
19+
if (reader.TryGetInt64(out long l))
20+
{
21+
return l;
22+
}
23+
return reader.GetDouble();
24+
case JsonTokenType.String:
25+
if (reader.TryGetDateTime(out DateTime datetime))
26+
{
27+
return datetime;
28+
}
29+
return reader.GetString()!;
30+
case JsonTokenType.StartObject:
31+
return JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options)!;
32+
case JsonTokenType.StartArray:
33+
return JsonSerializer.Deserialize<object[]>(ref reader, options)!;
34+
default:
35+
return JsonDocument.ParseValue(ref reader).RootElement.Clone();
36+
}
37+
}
38+
39+
public override void Write(Utf8JsonWriter writer, object objectToWrite, JsonSerializerOptions options)
40+
{
41+
JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options);
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)