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 swift multipart #967

Open
wants to merge 37 commits into
base: feat-multipart
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4d84584
Rename references
abnegate Aug 30, 2024
fcffcde
Add payload type
abnegate Aug 30, 2024
9c4388d
Update service
abnegate Aug 30, 2024
6a6ebae
Add payload functions
abnegate Aug 30, 2024
525a77c
Handle params
abnegate Aug 30, 2024
0a55932
Add multipart response hook
abnegate Aug 30, 2024
65d1f04
Add formdata response parsing
abnegate Aug 30, 2024
ac6c972
Handle request binary parts
abnegate Aug 30, 2024
b1f26ad
Update test
abnegate Aug 30, 2024
b3ebc22
Try + optional for payload to byte buffer
abnegate Aug 30, 2024
22ef7c0
Fix generic type
abnegate Aug 30, 2024
c6d4b7c
Handle more as upload types
abnegate Aug 30, 2024
dee0a85
Fix return type filter
abnegate Aug 30, 2024
8d32730
Update Apple tests
abnegate Aug 30, 2024
0bcc580
Update chunked upload for payloads
abnegate Aug 30, 2024
cb668ef
Merge remote-tracking branch 'origin/feat-multipart' into feat-swift-…
abnegate Sep 3, 2024
8887720
Add extensions module to avoid payload circular dependency
abnegate Sep 3, 2024
4576d87
Fix imports
abnegate Sep 3, 2024
1ca91b7
Fix chunked upload with payload
abnegate Sep 3, 2024
89831bb
Revert param name change
abnegate Sep 3, 2024
7fddaa7
Fix swift test
abnegate Sep 3, 2024
f067d5f
Fix Apple tests
abnegate Sep 3, 2024
7f1aab8
Add Swift 5.10 tests
abnegate Sep 3, 2024
574c2d5
Fix missing produces on methods
abnegate Sep 3, 2024
2f6cfb7
Check produces for adding accept header
abnegate Sep 3, 2024
985e4f4
Fix spec multipart response type
abnegate Sep 3, 2024
2e5f36f
Fix spec multipart required
abnegate Sep 3, 2024
4465360
Merge branch 'feat-multipart' into feat-swift-multipart
Meldiron Sep 18, 2024
a9d31db
Revert specs changes
Meldiron Sep 18, 2024
4206b8f
PR review changes
Meldiron Sep 18, 2024
8543733
Add more multipart tests
Meldiron Sep 18, 2024
58446b2
Formatter fix
Meldiron Sep 18, 2024
1c43152
Fix failing tests
Meldiron Sep 18, 2024
0098b76
Attempt to fix test
Meldiron Sep 25, 2024
b4c1bb6
Merge branch 'feat-multipart' of https://github.com/appwrite/sdk-gene…
loks0n Sep 30, 2024
5618994
Merge branch 'feat-multipart' of https://github.com/appwrite/sdk-gene…
loks0n Oct 1, 2024
505fce5
fix: go
loks0n Oct 1, 2024
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 .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ jobs:
Ruby30,
Ruby31,
AppleSwift56,
AppleSwift510,
Swift56,
Swift510,
WebChromium,
WebNode
]
Expand Down
36 changes: 18 additions & 18 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions mock-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM composer:2.0 as composer
FROM composer:2.0 AS composer

LABEL maintainer="[email protected]"

Expand All @@ -14,7 +14,7 @@ RUN composer install --ignore-platform-reqs --optimize-autoloader \
--no-plugins --no-scripts --prefer-dist \
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`

FROM phpswoole/swoole:5.1.2-php8.3-alpine as final
FROM phpswoole/swoole:5.1.2-php8.3-alpine AS final

RUN apk add docker

Expand Down
4 changes: 3 additions & 1 deletion mock-server/app/http.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,9 @@
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'upload')
->label('sdk.methodType', 'upload')
->label('sdk.description', 'Mock a file upload request.')
->label('sdk.request.type', 'multipart/form-data')
->label('sdk.request.type', Response::CONTENT_TYPE_MULTIPART)
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_MOCK)
Expand All @@ -319,6 +320,7 @@
->inject('request')
->inject('response')
->action(function (string $x, int $y, array $z, mixed $file, Request $request, Response $response) {

$file = $request->getFiles('file');

$contentRange = $request->getHeader('content-range');
Expand Down
27 changes: 11 additions & 16 deletions src/SDK/Language/Apple.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ public function getFiles(): array
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/{{ spec.title | caseUcfirst}}Error.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Models/{{ spec.title | caseUcfirst}}Error.swift',
'template' => '/swift/Sources/Models/Error.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/InputFile.swift',
'template' => 'swift/Sources/Models/InputFile.swift.twig',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Models/Payload.swift',
'template' => 'swift/Sources/Models/Payload.swift.twig',
],
[
'scope' => 'default',
Expand All @@ -77,29 +77,24 @@ public function getFiles(): array
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/UploadProgress.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Models/UploadProgress.swift',
'template' => 'swift/Sources/Models/UploadProgress.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/JSONCodable/Codable+JSON.swift',
'template' => 'swift/Sources/JSONCodable/Codable+JSON.swift.twig',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Extensions/Codable+JSON.swift',
'template' => 'swift/Sources/Extensions/Codable+JSON.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Extensions/Cookie+Codable.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Extensions/Cookie+Codable.swift',
'template' => 'swift/Sources/Extensions/Cookie+Codable.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Extensions/HTTPClientRequest+Cookies.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Extensions/HTTPClientRequest+Cookies.swift',
'template' => 'swift/Sources/Extensions/HTTPClientRequest+Cookies.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Extensions/String+MimeTypes.swift',
'template' => 'swift/Sources/Extensions/String+MimeTypes.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/StreamingDelegate.swift',
Expand Down Expand Up @@ -213,7 +208,7 @@ public function getFiles(): array
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/RealtimeModels.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Models/RealtimeModels.swift',
'template' => '/swift/Sources/Models/RealtimeModels.swift.twig',
],
[
Expand Down Expand Up @@ -486,11 +481,11 @@ public function getFiles(): array
];
}

protected function getReturnType(array $method, array $spec, string $namespace, string $generic = 'T'): string
protected function getReturnType(array $method, array $spec, string $generic = 'T'): string
{
if ($method['type'] === 'webAuth') {
return 'Bool';
}
return parent::getReturnType($method, $spec, $namespace, $generic);
return parent::getReturnType($method, $spec, $generic);
}
}
29 changes: 14 additions & 15 deletions src/SDK/Language/Swift.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ public function getFiles(): array
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/{{ spec.title | caseUcfirst}}Error.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Models/{{ spec.title | caseUcfirst}}Error.swift',
'template' => '/swift/Sources/Models/Error.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/InputFile.swift',
'template' => 'swift/Sources/Models/InputFile.swift.twig',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Models/Payload.swift',
'template' => 'swift/Sources/Models/Payload.swift.twig',
],
[
'scope' => 'default',
Expand All @@ -174,29 +174,24 @@ public function getFiles(): array
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Models/UploadProgress.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Models/UploadProgress.swift',
'template' => 'swift/Sources/Models/UploadProgress.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/JSONCodable/Codable+JSON.swift',
'template' => 'swift/Sources/JSONCodable/Codable+JSON.swift.twig',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Extensions/Codable+JSON.swift',
'template' => 'swift/Sources/Extensions/Codable+JSON.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Extensions/Cookie+Codable.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Extensions/Cookie+Codable.swift',
'template' => 'swift/Sources/Extensions/Cookie+Codable.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Extensions/HTTPClientRequest+Cookies.swift',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}Extensions/HTTPClientRequest+Cookies.swift',
'template' => 'swift/Sources/Extensions/HTTPClientRequest+Cookies.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/Extensions/String+MimeTypes.swift',
'template' => 'swift/Sources/Extensions/String+MimeTypes.swift.twig',
],
[
'scope' => 'default',
'destination' => '/Sources/{{ spec.title | caseUcfirst}}/StreamingDelegate.swift',
Expand Down Expand Up @@ -311,7 +306,8 @@ public function getTypeName(array $parameter, array $spec = []): string
self::TYPE_INTEGER => 'Int',
self::TYPE_NUMBER => 'Double',
self::TYPE_STRING => 'String',
self::TYPE_FILE => 'InputFile',
self::TYPE_FILE,
self::TYPE_PAYLOAD => 'Payload',
self::TYPE_BOOLEAN => 'Bool',
self::TYPE_ARRAY => (!empty(($parameter['array'] ?? [])['type']) && !\is_array($parameter['array']['type']))
? '[' . $this->getTypeName($parameter['array']) . ']'
Expand Down Expand Up @@ -397,7 +393,10 @@ public function getParamExample(array $param): string
if (empty($example) && $example !== 0 && $example !== false) {
switch ($type) {
case self::TYPE_FILE:
$output .= 'InputFile.fromPath("file.png")';
$output .= 'Payload.fromFile("/path/to/file.png")';
break;
case self::TYPE_PAYLOAD:
$output .= 'Payload.fromString("<BODY>")'; // TODO: Update to fromJson()
break;
case self::TYPE_NUMBER:
case self::TYPE_INTEGER:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ class Client @JvmOverloads constructor(
if (size < CHUNK_SIZE) {
val data = when(input.sourceType) {
"file", "path" -> File(input.path).asRequestBody()
"bytes" -> input.toBinary().toRequestBody(input.mimeType?.toMediaType())
"bytes" -> input.toBinary().toRequestBody()
else -> throw UnsupportedOperationException()
}
params[paramName] = MultipartBody.Part.createFormData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class Payload private constructor() {
lateinit var filename: String
lateinit var sourceType: String
lateinit var data: Any
var mimeType: String? = null

override fun toString(): String {
if (sourceType != "bytes") {
Expand Down Expand Up @@ -62,9 +61,6 @@ class Payload private constructor() {
fun fromFileObject(file: File, name: String = "") = Payload().apply {
path = file.canonicalPath
filename = if (name != "") name else file.name
mimeType = Files.probeContentType(Paths.get(file.canonicalPath))
?: URLConnection.guessContentTypeFromName(filename)
?: ""
sourceType = "file"
}
}
Expand Down
15 changes: 10 additions & 5 deletions templates/apple/Package.swift.twig
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,37 @@ let package = Package(
targets: [
"{{spec.title | caseUcfirst}}",
"{{spec.title | caseUcfirst}}Enums",
"{{spec.title | caseUcfirst}}Models",
"JSONCodable"
"{{spec.title | caseUcfirst}}Extensions",
"{{spec.title | caseUcfirst}}Models"
]
),
],
dependencies: [
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.19.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.58.0"),
.package(url: "https://github.com/apple/swift-crypto.git", "1.0.0" ..< "4.0.0"),
],
targets: [
.target(
name: "{{spec.title | caseUcfirst}}",
dependencies: [
.product(name: "AsyncHTTPClient", package: "async-http-client"),
.product(name: "NIOWebSocket", package: "swift-nio"),
.product(name: "Crypto", package: "swift-crypto"),
{%~ if spec.definitions is not empty %}
"{{spec.title | caseUcfirst}}Models",
{%~ endif %}
{%~ if spec.enums is not empty %}
"{{spec.title | caseUcfirst}}Enums",
{%~ endif %}
"JSONCodable"
"{{spec.title | caseUcfirst}}Extensions"
]
),
{%~ if spec.definitions is not empty %}
.target(
name: "{{spec.title | caseUcfirst}}Models",
dependencies: [
"JSONCodable"
"{{spec.title | caseUcfirst}}Extensions",
]
),
{%~ endif %}
Expand All @@ -54,7 +56,10 @@ let package = Package(
),
{%~ endif %}
.target(
name: "JSONCodable"
name: "{{spec.title | caseUcfirst}}Extensions",
dependencies: [
.product(name: "AsyncHTTPClient", package: "async-http-client"),
]
),
.testTarget(
name: "{{spec.title | caseUcfirst}}Tests",
Expand Down
Loading
Loading