Skip to content

Commit 6d747e4

Browse files
Merge pull request #320 from appwrite/feat-dotnet-response-models
2 parents 3dd97aa + 0cec05e commit 6d747e4

29 files changed

+1757
-336
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ env:
2929
- SDK=DartStable
3030
- SDK=Deno1193
3131
- SDK=Deno1303
32+
- SDK=DotNet60
33+
- SDK=DotNet70
3234
- SDK=FlutterStable
3335
- SDK=FlutterBeta
3436
- SDK=Go112

src/SDK/Language/DotNet.php

Lines changed: 65 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -139,23 +139,26 @@ public function getKeywords(): array
139139
public function getIdentifierOverrides(): array
140140
{
141141
return [
142-
'Jwt' => 'JWT'
142+
'Jwt' => 'JWT',
143+
'Domain' => 'XDomain',
143144
];
144145
}
145146

146147
/**
147-
* @param $type
148+
* @param array $parameter
148149
* @return string
149150
*/
150151
public function getTypeName(array $parameter): string
151152
{
152153
switch ($parameter['type']) {
153154
case self::TYPE_INTEGER:
154-
return 'int';
155+
return 'long';
156+
case self::TYPE_NUMBER:
157+
return 'double';
155158
case self::TYPE_STRING:
156159
return 'string';
157160
case self::TYPE_FILE:
158-
return 'FileInfo';
161+
return 'InputFile';
159162
case self::TYPE_BOOLEAN:
160163
return 'bool';
161164
case self::TYPE_ARRAY:
@@ -249,7 +252,13 @@ public function getParamExample(array $param): string
249252
$output .= '[object]';
250253
break;
251254
case self::TYPE_ARRAY:
252-
$output .= '[List<object>]';
255+
if (\str_starts_with($example, '[')) {
256+
$example = \substr($example, 1);
257+
}
258+
if (\str_ends_with($example, ']')) {
259+
$example = \substr($example, 0, -1);
260+
}
261+
$output .= 'new List<' . $this->getTypeName($param['array']) . '> {' . $example . '}';
253262
break;
254263
}
255264
} else {
@@ -283,23 +292,28 @@ public function getFiles(): array
283292
return [
284293
[
285294
'scope' => 'default',
286-
'destination' => 'README.md',
287-
'template' => 'dotnet/README.md.twig',
295+
'destination' => '.travis.yml',
296+
'template' => 'dotnet/.travis.yml.twig',
288297
],
289298
[
290299
'scope' => 'default',
291300
'destination' => 'CHANGELOG.md',
292301
'template' => 'dotnet/CHANGELOG.md.twig',
293302
],
303+
[
304+
'scope' => 'copy',
305+
'destination' => '/icon.png',
306+
'template' => 'dotnet/icon.png',
307+
],
294308
[
295309
'scope' => 'default',
296310
'destination' => 'LICENSE',
297311
'template' => 'dotnet/LICENSE.twig',
298312
],
299313
[
300314
'scope' => 'default',
301-
'destination' => '.travis.yml',
302-
'template' => 'dotnet/.travis.yml.twig',
315+
'destination' => 'README.md',
316+
'template' => 'dotnet/README.md.twig',
303317
],
304318
[
305319
'scope' => 'method',
@@ -308,53 +322,78 @@ public function getFiles(): array
308322
],
309323
[
310324
'scope' => 'default',
311-
'destination' => '/src/Appwrite.sln',
325+
'destination' => '/src/{{ spec.title | caseUcfirst }}.sln',
312326
'template' => 'dotnet/src/Appwrite.sln',
313327
],
314-
[
315-
'scope' => 'copy',
316-
'destination' => '/icon.png',
317-
'template' => 'dotnet/icon.png',
318-
],
319328
[
320329
'scope' => 'default',
321-
'destination' => '/src/Appwrite/Appwrite.csproj',
330+
'destination' => '/src/{{ spec.title | caseUcfirst }}/{{ spec.title | caseUcfirst }}.csproj',
322331
'template' => 'dotnet/src/Appwrite/Appwrite.csproj.twig',
323332
],
324333
[
325334
'scope' => 'default',
326-
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Client.cs',
335+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Client.cs',
327336
'template' => 'dotnet/src/Appwrite/Client.cs.twig',
328337
],
329338
[
330339
'scope' => 'default',
331-
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Helpers/ExtensionMethods.cs',
332-
'template' => 'dotnet/src/Appwrite/Helpers/ExtensionMethods.cs',
340+
'destination' => '/src/{{ spec.title | caseUcfirst }}/{{ spec.title | caseUcfirst }}Exception.cs',
341+
'template' => 'dotnet/src/Appwrite/Exception.cs.twig',
333342
],
334343
[
335344
'scope' => 'default',
336-
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Models/OrderType.cs',
345+
'destination' => '/src/{{ spec.title | caseUcfirst }}/ID.cs',
346+
'template' => 'dotnet/src/Appwrite/ID.cs.twig',
347+
],
348+
[
349+
'scope' => 'default',
350+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Permission.cs',
351+
'template' => 'dotnet/src/Appwrite/Permission.cs.twig',
352+
],
353+
[
354+
'scope' => 'default',
355+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Query.cs',
356+
'template' => 'dotnet/src/Appwrite/Query.cs.twig',
357+
],
358+
[
359+
'scope' => 'default',
360+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Role.cs',
361+
'template' => 'dotnet/src/Appwrite/Role.cs.twig',
362+
],
363+
[
364+
'scope' => 'default',
365+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Extensions/Extensions.cs',
366+
'template' => 'dotnet/src/Appwrite/Extensions/Extensions.cs.twig',
367+
],
368+
[
369+
'scope' => 'default',
370+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/OrderType.cs',
337371
'template' => 'dotnet/src/Appwrite/Models/OrderType.cs.twig',
338372
],
339373
[
340374
'scope' => 'default',
341-
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Models/Rule.cs',
342-
'template' => 'dotnet/src/Appwrite/Models/Rule.cs.twig',
375+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/UploadProgress.cs',
376+
'template' => 'dotnet/src/Appwrite/Models/UploadProgress.cs.twig',
343377
],
344378
[
345379
'scope' => 'default',
346-
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Models/Exception.cs',
347-
'template' => 'dotnet/src/Appwrite/Models/Exception.cs.twig',
380+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/InputFile.cs',
381+
'template' => 'dotnet/src/Appwrite/Models/InputFile.cs.twig',
348382
],
349383
[
350384
'scope' => 'default',
351-
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Services/Service.cs',
385+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Services/Service.cs',
352386
'template' => 'dotnet/src/Appwrite/Services/Service.cs.twig',
353387
],
354388
[
355389
'scope' => 'service',
356-
'destination' => '/{{ sdk.namespace | caseSlash }}/src/Appwrite/Services/{{service.name | caseUcfirst}}.cs',
390+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Services/{{service.name | caseUcfirst}}.cs',
357391
'template' => 'dotnet/src/Appwrite/Services/ServiceTemplate.cs.twig',
392+
],
393+
[
394+
'scope' => 'definition',
395+
'destination' => '/src/{{ spec.title | caseUcfirst }}/Models/{{ definition.name | caseUcfirst | overrideIdentifier }}.cs',
396+
'template' => 'dotnet/src/Appwrite/Models/Model.cs.twig',
358397
]
359398
];
360399
}

templates/dotnet/base/params.twig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% import 'dotnet/base/utils.twig' as utils %}
2+
{%~ for parameter in method.parameters.path %}
3+
.Replace("{{ '{' ~ parameter.name | caseCamel ~ '}' }}", {{ parameter.name | caseCamel | escapeKeyword }}){% if loop.last %};{% endif %}
4+
5+
{%~ endfor %}
6+
7+
var parameters = new Dictionary<string, object?>()
8+
{
9+
{%~ for parameter in method.parameters.query | merge(method.parameters.body) %}
10+
{ "{{ parameter.name }}", {{ utils.map_parameter(parameter) }} }{% if not loop.last %},{% endif %}
11+
12+
{%~ endfor %}
13+
};
14+
15+
var headers = new Dictionary<string, string>()
16+
{
17+
{%~ for key, header in method.headers %}
18+
{ "{{ key }}", "{{ header }}" }{% if not loop.last %},{% endif %}
19+
20+
{%~ endfor %}
21+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% import 'dotnet/base/utils.twig' as utils %}
2+
return _client.Call{% if method.type != 'webAuth' %}<{{ utils.resultType(spec.title, method) }}>{% endif %}(
3+
method: "{{ method.method | caseUpper }}",
4+
path: path,
5+
headers: headers,
6+
{%~ if not method.responseModel %}
7+
parameters: parameters.Where(it => it.Value != null).ToDictionary(it => it.Key, it => it.Value)!);
8+
{%~ else %}
9+
parameters: parameters.Where(it => it.Value != null).ToDictionary(it => it.Key, it => it.Value)!,
10+
convert: Convert);
11+
{%~ endif %}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
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 %};
2+
3+
{%~ for parameter in method.parameters.all %}
4+
{%~ if parameter.type == 'file' %}
5+
var paramName = "{{ parameter.name }}";
6+
{%~ endif %}
7+
{%~ endfor %}
8+
9+
return _client.ChunkedUpload(
10+
path,
11+
headers,
12+
parameters,
13+
{%~ if method.responseModel %}
14+
Convert,
15+
{%~ endif %}
16+
paramName,
17+
idParamName,
18+
onProgress);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return _client.Call<byte[]>(
2+
method: "{{ method.method | caseUpper }}",
3+
path: path,
4+
headers: headers,
5+
parameters: parameters.Where(it => it.Value != null).ToDictionary(it => it.Key, it => it.Value)!);

templates/dotnet/base/utils.twig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{% macro parameter(parameter) %}
2+
{% if parameter.name == 'orderType' %}{{ 'OrderType orderType = OrderType.ASC' }}{% else %}
3+
{{ parameter | typeName }}{% if not parameter.required %}?{% endif %} {{ parameter.name | caseCamel | escapeKeyword }}{% if not parameter.required %} = null{% endif %}{% endif %}
4+
{% endmacro %}
5+
{% macro method_parameters(parameters, consumes) %}
6+
{% 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 %}
7+
{% endmacro %}
8+
{% macro map_parameter(parameter) %}
9+
{% if parameter.name == 'orderType' %}{{ parameter.name | caseCamel ~ '.ToString()'}}{% elseif parameter.isGlobal %}{{ parameter.name | caseUcfirst | escapeKeyword }}{% else %}{{ parameter.name | caseCamel | escapeKeyword }}{% endif %}
10+
{% endmacro %}
11+
{% macro methodNeedsSecurityParameters(method) %}
12+
{% if (method.type == "webAuth" or method.type == "location") and method.auth|length > 0 %}{{ true }}{% else %}{{false}}{% endif %}
13+
{% endmacro %}
14+
{% macro resultType(namespace, method) %}
15+
{% 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 %}
16+
{% endmacro %}

templates/dotnet/docs/example.md.twig

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
using {{ spec.title | caseUcfirst }};
2+
using {{ spec.title | caseUcfirst }}.Models;
23

3-
Client client = new Client();
4-
4+
Client client = new Client()
55
{% if method.auth|length > 0 %}
6-
client
7-
.SetEndPoint("https://cloud.appwrite.io/v1") // Your API Endpoint
6+
.SetEndPoint("https://cloud.appwrite.io/v1") // Your API Endpoint
87
{% for node in method.auth %}
98
{% for key,header in node|keys %}
10-
.Set{{header | caseUcfirst}}("{{node[header]["x-appwrite"]["demo"]}}") // {{node[header].description}}
11-
{% endfor %}
12-
{% endfor %};
9+
.Set{{header | caseUcfirst}}("{{node[header]['x-appwrite']['demo']}}"){% if loop.last %};{% endif %} // {{node[header].description}}
10+
{% endfor %}{% endfor %}{% endif %}
11+
12+
{{ service.name | caseUcfirst }} {{ service.name | caseCamel }} = new {{ service.name | caseUcfirst }}(client);
1313

14-
{% endif %}
15-
{{ service.name | caseUcfirst }} {{ service.name | caseCamel }} = new {{ service.name | caseUcfirst }}(client{% if service.globalParams | length %}{% for parameter in service.globalParams %}, {{ parameter | paramExample }}{% endfor %}{% endif %});
14+
{% 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 %}
15+
{% for parameter in method.parameters.all %}{% if parameter.required %}{% if not loop.first %},{% endif %}
1616

17-
{% 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 %});
17+
{{ parameter.name }}: {{ parameter | paramExample }}{% endif %}{% endfor %}{% if method.parameters.all | length > 0 %});{% endif %}

templates/dotnet/src/Appwrite/Appwrite.csproj.twig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>netcoreapp3.1;net461;netstandard2.0;</TargetFrameworks>
3+
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
44
<PackageId>{{spec.title}}</PackageId>
55
<Version>{{sdk.version}}</Version>
66
<Authors>{{spec.contactName}}</Authors>
@@ -14,11 +14,12 @@
1414
<RepositoryType>git</RepositoryType>
1515
<RepositoryUrl>{{sdk.gitURL}}</RepositoryUrl>
1616
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
17+
<LangVersion>latest</LangVersion>
18+
<Nullable>enable</Nullable>
1719
</PropertyGroup>
1820

1921
<ItemGroup>
20-
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
21-
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
22+
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
2223
<PackageReference Include="System.Net.Http" Version="4.3.4" />
2324
<None Include="..\..\icon.png" Pack="true" PackagePath="$(PackageIcon)"/>
2425
</ItemGroup>

0 commit comments

Comments
 (0)