Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat .NET Server SDK updates #320

Merged
merged 83 commits into from
May 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
c260ae9
Add dotnet double number type
abnegate Oct 29, 2021
5a01e99
Use tuples in extensions
abnegate Oct 29, 2021
98f2362
Add model template
abnegate Oct 29, 2021
3251d8e
WIP update client with response models
abnegate Oct 29, 2021
27b7df8
WIP update service with response models
abnegate Oct 29, 2021
a4525a2
Update target frameworks
abnegate Oct 29, 2021
657b509
Handle empty responses and non-returning methods
abnegate Nov 1, 2021
4a85735
Fix model conversions
abnegate Nov 1, 2021
4710e7b
WIP update test to C# + NUnit
abnegate Nov 1, 2021
230a6d5
Test fixes
abnegate Nov 3, 2021
852a024
Replace default params with null filtering
abnegate Nov 3, 2021
4b1037e
Warnings fixes
abnegate Nov 3, 2021
d6e9f2e
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Nov 4, 2021
262e625
Fix output directory
abnegate Nov 4, 2021
77683cb
Support .NET Framework 4.8, .NET Core App 3.1, 5.0, .NET Standard 1.3…
abnegate Nov 4, 2021
0679c55
Fix rule nullability warnings
abnegate Nov 4, 2021
24faaf6
Run tests targeting current SDK
abnegate Nov 4, 2021
23ed00f
Disable metadata property handling so `$` prefixed vars are deserialised
abnegate Nov 8, 2021
1813ad0
Add Int32 converter to stop exceptions from default deserialiser Int6…
abnegate Nov 8, 2021
abdd5bb
Fix config reference
abnegate Nov 8, 2021
8711826
Support .NET Framework 4.7,4.7.1,4.7.2
abnegate Nov 8, 2021
8eebfe9
Remove redundant dependency
abnegate Nov 8, 2021
3bf3262
Fix overlapping rule models
abnegate Nov 12, 2021
c3f30f2
Escape attributes matching type names
abnegate Nov 12, 2021
cd49959
Merge remote-tracking branch 'origin/feat-lang-name-overrides' into f…
abnegate Nov 16, 2021
ad1a15e
Merge branch 'feat-lang-name-overrides' into feat-dotnet-response-models
abnegate Nov 16, 2021
a9ddb24
Use identifier overrides for dotnet response models
abnegate Nov 23, 2021
963ad79
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Nov 23, 2021
7677c90
Fix parsing empty data map
abnegate Nov 23, 2021
6879e96
Add missing using
abnegate Nov 23, 2021
e5e9bb9
Add missing identifier overrides
abnegate Nov 23, 2021
5feb6f2
Parse non schema list type as JArray
abnegate Nov 23, 2021
869866a
Remove obsolete target frameworks
abnegate Nov 23, 2021
2eaa134
Fix sub-schema deserialization
abnegate Nov 24, 2021
40097b8
Update dotnet doc template
abnegate Nov 29, 2021
6958e87
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Dec 1, 2021
8ebed28
Fix un-templated output paths
abnegate Dec 1, 2021
98c9042
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Mar 23, 2022
547a01b
Update tests for new structure
abnegate Mar 23, 2022
b54b680
Fix model nullables in fromMap
abnegate Mar 23, 2022
6251d56
Fix model param defaults
abnegate Mar 23, 2022
c0bf48a
Use long instead of int
abnegate Mar 23, 2022
cdde5a1
WIP add chunked upload
abnegate Mar 31, 2022
475f59c
Chunked upload updates
abnegate Apr 13, 2022
a1fff24
Fix .NET 6 test
abnegate Apr 13, 2022
5bab0f0
Properly fix tests
abnegate Apr 13, 2022
838d90f
Update travis
abnegate Apr 13, 2022
d63494d
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Apr 13, 2022
edc4a46
Fix models
abnegate Apr 14, 2022
0665d54
Fix .NET 3.1 target typed creation
abnegate Apr 28, 2022
1debc76
Fix other target typed creation ref
abnegate Apr 28, 2022
98109a1
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Jun 29, 2022
1953cee
Update for 0.15
abnegate Jun 29, 2022
0acc434
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Jun 30, 2022
832d1e9
Merge branch 'master' into feat-dotnet-response-models
abnegate Aug 4, 2022
44b75f6
refactor .NET templates
everly-gif Aug 5, 2022
1a6d96b
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Aug 19, 2022
c99dfeb
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Sep 29, 2022
58068ee
Update for Appwrite 1.0
abnegate Sep 29, 2022
0b2a846
Update tests
abnegate Sep 29, 2022
890ac0c
Merge remote-tracking branch 'origin/feat-dotnet-refactor' into feat-…
abnegate Oct 13, 2022
993a13b
Add headers test
abnegate Oct 13, 2022
b0b5afb
Merge fixes
abnegate Oct 13, 2022
d168697
Fix list query params
abnegate Oct 13, 2022
4461647
Fix list query values
abnegate Oct 13, 2022
9660524
Fix bool query values
abnegate Oct 13, 2022
bf1e0f7
Fix endpoint
abnegate Oct 13, 2022
2b81ad1
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Oct 13, 2022
a8fb765
Fix compilation for .NET < 6
abnegate Oct 21, 2022
17fed89
Disable flutter beta test
abnegate Oct 21, 2022
066a48d
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Oct 24, 2022
6935c14
Lint
abnegate Oct 24, 2022
cc46c3d
Remove irrelevant change
abnegate Nov 4, 2022
dec2518
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Nov 4, 2022
5006102
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Nov 16, 2022
e685290
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate Feb 10, 2023
64b19b0
Merge branch 'master' into feat-dotnet-response-models
abnegate Feb 16, 2023
31c7827
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate May 3, 2023
9e7a321
Add new 1.3 queries
abnegate May 3, 2023
a9a28c0
Add new 1.3 query tests
abnegate May 3, 2023
715c47b
Update tests to .NET 6 + 7 with alpine images
abnegate May 3, 2023
75b45e8
Update target frameworks to netstandard2.0 + net461
abnegate May 3, 2023
0cec05e
Merge remote-tracking branch 'origin/master' into feat-dotnet-respons…
abnegate May 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ env:
- SDK=DartStable
- SDK=Deno1193
- SDK=Deno1303
- SDK=DotNet60
- SDK=DotNet70
- SDK=FlutterStable
- SDK=FlutterBeta
- SDK=Go112
Expand Down
91 changes: 65 additions & 26 deletions src/SDK/Language/DotNet.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,23 +139,26 @@ public function getKeywords(): array
public function getIdentifierOverrides(): array
{
return [
'Jwt' => 'JWT'
'Jwt' => 'JWT',
'Domain' => 'XDomain',
];
}

/**
* @param $type
* @param array $parameter
* @return string
*/
public function getTypeName(array $parameter): string
{
switch ($parameter['type']) {
case self::TYPE_INTEGER:
return 'int';
return 'long';
case self::TYPE_NUMBER:
return 'double';
case self::TYPE_STRING:
return 'string';
case self::TYPE_FILE:
return 'FileInfo';
return 'InputFile';
case self::TYPE_BOOLEAN:
return 'bool';
case self::TYPE_ARRAY:
Expand Down Expand Up @@ -249,7 +252,13 @@ public function getParamExample(array $param): string
$output .= '[object]';
break;
case self::TYPE_ARRAY:
$output .= '[List<object>]';
if (\str_starts_with($example, '[')) {
$example = \substr($example, 1);
}
if (\str_ends_with($example, ']')) {
$example = \substr($example, 0, -1);
}
$output .= 'new List<' . $this->getTypeName($param['array']) . '> {' . $example . '}';
break;
}
} else {
Expand Down Expand Up @@ -283,23 +292,28 @@ public function getFiles(): array
return [
[
'scope' => 'default',
'destination' => 'README.md',
'template' => 'dotnet/README.md.twig',
'destination' => '.travis.yml',
'template' => 'dotnet/.travis.yml.twig',
],
[
'scope' => 'default',
'destination' => 'CHANGELOG.md',
'template' => 'dotnet/CHANGELOG.md.twig',
],
[
'scope' => 'copy',
'destination' => '/icon.png',
'template' => 'dotnet/icon.png',
],
[
'scope' => 'default',
'destination' => 'LICENSE',
'template' => 'dotnet/LICENSE.twig',
],
[
'scope' => 'default',
'destination' => '.travis.yml',
'template' => 'dotnet/.travis.yml.twig',
'destination' => 'README.md',
'template' => 'dotnet/README.md.twig',
],
[
'scope' => 'method',
Expand All @@ -308,53 +322,78 @@ public function getFiles(): array
],
[
'scope' => 'default',
'destination' => '/src/Appwrite.sln',
'destination' => '/src/{{ spec.title | caseUcfirst }}.sln',
'template' => 'dotnet/src/Appwrite.sln',
],
[
'scope' => 'copy',
'destination' => '/icon.png',
'template' => 'dotnet/icon.png',
],
[
'scope' => 'default',
'destination' => '/src/Appwrite/Appwrite.csproj',
'destination' => '/src/{{ spec.title | caseUcfirst }}/{{ spec.title | caseUcfirst }}.csproj',
'template' => 'dotnet/src/Appwrite/Appwrite.csproj.twig',
],
[
'scope' => 'default',
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Client.cs',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Client.cs',
'template' => 'dotnet/src/Appwrite/Client.cs.twig',
],
[
'scope' => 'default',
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Helpers/ExtensionMethods.cs',
'template' => 'dotnet/src/Appwrite/Helpers/ExtensionMethods.cs',
'destination' => '/src/{{ spec.title | caseUcfirst }}/{{ spec.title | caseUcfirst }}Exception.cs',
'template' => 'dotnet/src/Appwrite/Exception.cs.twig',
],
[
'scope' => 'default',
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Models/OrderType.cs',
'destination' => '/src/{{ spec.title | caseUcfirst }}/ID.cs',
'template' => 'dotnet/src/Appwrite/ID.cs.twig',
],
[
'scope' => 'default',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Permission.cs',
'template' => 'dotnet/src/Appwrite/Permission.cs.twig',
],
[
'scope' => 'default',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Query.cs',
'template' => 'dotnet/src/Appwrite/Query.cs.twig',
],
[
'scope' => 'default',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Role.cs',
'template' => 'dotnet/src/Appwrite/Role.cs.twig',
],
[
'scope' => 'default',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Extensions/Extensions.cs',
'template' => 'dotnet/src/Appwrite/Extensions/Extensions.cs.twig',
],
[
'scope' => 'default',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/OrderType.cs',
'template' => 'dotnet/src/Appwrite/Models/OrderType.cs.twig',
],
[
'scope' => 'default',
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Models/Rule.cs',
'template' => 'dotnet/src/Appwrite/Models/Rule.cs.twig',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/UploadProgress.cs',
'template' => 'dotnet/src/Appwrite/Models/UploadProgress.cs.twig',
],
[
'scope' => 'default',
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Models/Exception.cs',
'template' => 'dotnet/src/Appwrite/Models/Exception.cs.twig',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/InputFile.cs',
'template' => 'dotnet/src/Appwrite/Models/InputFile.cs.twig',
],
[
'scope' => 'default',
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Services/Service.cs',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Services/Service.cs',
'template' => 'dotnet/src/Appwrite/Services/Service.cs.twig',
],
[
'scope' => 'service',
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Services/{{service.name | caseUcfirst}}.cs',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Services/{{service.name | caseUcfirst}}.cs',
'template' => 'dotnet/src/Appwrite/Services/ServiceTemplate.cs.twig',
],
[
'scope' => 'definition',
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/{{ definition.name | caseUcfirst | overrideIdentifier }}.cs',
'template' => 'dotnet/src/Appwrite/Models/Model.cs.twig',
]
];
}
Expand Down
21 changes: 21 additions & 0 deletions templates/dotnet/base/params.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{% import 'dotnet/base/utils.twig' as utils %}
{%~ for parameter in method.parameters.path %}
.Replace("{{ '{' ~ parameter.name | caseCamel ~ '}' }}", {{ parameter.name | caseCamel | escapeKeyword }}){% if loop.last %};{% endif %}

{%~ endfor %}

var parameters = new Dictionary<string, object?>()
{
{%~ for parameter in method.parameters.query | merge(method.parameters.body) %}
{ "{{ parameter.name }}", {{ utils.map_parameter(parameter) }} }{% if not loop.last %},{% endif %}

{%~ endfor %}
};

var headers = new Dictionary<string, string>()
{
{%~ for key, header in method.headers %}
{ "{{ key }}", "{{ header }}" }{% if not loop.last %},{% endif %}

{%~ endfor %}
};
11 changes: 11 additions & 0 deletions templates/dotnet/base/requests/api.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% import 'dotnet/base/utils.twig' as utils %}
return _client.Call{% if method.type != 'webAuth' %}<{{ utils.resultType(spec.title, method) }}>{% endif %}(
method: "{{ method.method | caseUpper }}",
path: path,
headers: headers,
{%~ if not method.responseModel %}
parameters: parameters.Where(it => it.Value != null).ToDictionary(it => it.Key, it => it.Value)!);
{%~ else %}
parameters: parameters.Where(it => it.Value != null).ToDictionary(it => it.Key, it => it.Value)!,
convert: Convert);
{%~ endif %}
18 changes: 18 additions & 0 deletions templates/dotnet/base/requests/file.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
string? idParamName = {% if method.parameters.all | filter(p => p.isUploadID) | length > 0 %}{% for parameter in method.parameters.all | filter(parameter => parameter.isUploadID) %}"{{ parameter.name }}"{% endfor %}{% else %}null{% endif %};

{%~ for parameter in method.parameters.all %}
{%~ if parameter.type == 'file' %}
var paramName = "{{ parameter.name }}";
{%~ endif %}
{%~ endfor %}

return _client.ChunkedUpload(
path,
headers,
parameters,
{%~ if method.responseModel %}
Convert,
{%~ endif %}
paramName,
idParamName,
onProgress);
5 changes: 5 additions & 0 deletions templates/dotnet/base/requests/location.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
return _client.Call<byte[]>(
method: "{{ method.method | caseUpper }}",
path: path,
headers: headers,
parameters: parameters.Where(it => it.Value != null).ToDictionary(it => it.Key, it => it.Value)!);
16 changes: 16 additions & 0 deletions templates/dotnet/base/utils.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% macro parameter(parameter) %}
{% if parameter.name == 'orderType' %}{{ 'OrderType orderType = OrderType.ASC' }}{% else %}
{{ parameter | typeName }}{% if not parameter.required %}?{% endif %} {{ parameter.name | caseCamel | escapeKeyword }}{% if not parameter.required %} = null{% endif %}{% endif %}
{% endmacro %}
{% macro method_parameters(parameters, consumes) %}
{% if parameters.all|length > 0 %}{% for parameter in parameters.all | filter((param) => not param.isGlobal) %}{{ _self.parameter(parameter) }}{% if not loop.last %}{{ ', ' }}{% endif %}{% endfor %}{% if 'multipart/form-data' in consumes %},{% endif %}{% endif %}{% if 'multipart/form-data' in consumes %} Action<UploadProgress>? onProgress = null{% endif %}
{% endmacro %}
{% macro map_parameter(parameter) %}
{% if parameter.name == 'orderType' %}{{ parameter.name | caseCamel ~ '.ToString()'}}{% elseif parameter.isGlobal %}{{ parameter.name | caseUcfirst | escapeKeyword }}{% else %}{{ parameter.name | caseCamel | escapeKeyword }}{% endif %}
{% endmacro %}
{% macro methodNeedsSecurityParameters(method) %}
{% if (method.type == "webAuth" or method.type == "location") and method.auth|length > 0 %}{{ true }}{% else %}{{false}}{% endif %}
{% endmacro %}
{% macro resultType(namespace, method) %}
{% if method.type == "webAuth" %}bool{% elseif method.type == "location" %}byte[]{% elseif not method.responseModel or method.responseModel == 'any' %}object{% else %}Models.{{method.responseModel | caseUcfirst | overrideIdentifier }}{% endif %}
{% endmacro %}
20 changes: 10 additions & 10 deletions templates/dotnet/docs/example.md.twig
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
using {{ spec.title | caseUcfirst }};
using {{ spec.title | caseUcfirst }}.Models;

Client client = new Client();

Client client = new Client()
{% if method.auth|length > 0 %}
client
.SetEndPoint("https://cloud.appwrite.io/v1") // Your API Endpoint
.SetEndPoint("https://cloud.appwrite.io/v1") // Your API Endpoint
{% for node in method.auth %}
{% for key,header in node|keys %}
.Set{{header | caseUcfirst}}("{{node[header]["x-appwrite"]["demo"]}}") // {{node[header].description}}
{% endfor %}
{% endfor %};
.Set{{header | caseUcfirst}}("{{node[header]['x-appwrite']['demo']}}"){% if loop.last %};{% endif %} // {{node[header].description}}
{% endfor %}{% endfor %}{% endif %}

{{ service.name | caseUcfirst }} {{ service.name | caseCamel }} = new {{ service.name | caseUcfirst }}(client);

{% endif %}
{{ service.name | caseUcfirst }} {{ service.name | caseCamel }} = new {{ service.name | caseUcfirst }}(client{% if service.globalParams | length %}{% for parameter in service.globalParams %}, {{ parameter | paramExample }}{% endfor %}{% endif %});
{% if method.type == 'location' %}byte[]{% else %}{{ method.responseModel | caseUcfirst | overrideIdentifier }}{% endif %} result = await {{ service.name | caseCamel }}.{{ method.name | caseUcfirst }}({% if method.parameters.all | length == 0 %});{% endif %}
{% for parameter in method.parameters.all %}{% if parameter.required %}{% if not loop.first %},{% endif %}

{% if method.type == 'location' %}string{% else %}HttpResponseMessage{% endif %} result = await {{ service.name | caseCamel }}.{{ method.name | caseUcfirst }}({% for parameter in method.parameters.all %}{% if parameter.required %}{% if not loop.first %}, {% endif %}{{ parameter | paramExample }}{% endif %}{% endfor %});
{{ parameter.name }}: {{ parameter | paramExample }}{% endif %}{% endfor %}{% if method.parameters.all | length > 0 %});{% endif %}
7 changes: 4 additions & 3 deletions templates/dotnet/src/Appwrite/Appwrite.csproj.twig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net461;netstandard2.0;</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<PackageId>{{spec.title}}</PackageId>
<Version>{{sdk.version}}</Version>
<Authors>{{spec.contactName}}</Authors>
Expand All @@ -14,11 +14,12 @@
<RepositoryType>git</RepositoryType>
<RepositoryUrl>{{sdk.gitURL}}</RepositoryUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<None Include="..\..\icon.png" Pack="true" PackagePath="$(PackageIcon)"/>
</ItemGroup>
Expand Down
Loading