Add array-based enum parameters

This commit is contained in:
root
2026-02-02 12:03:57 +00:00
parent 906ecd35d0
commit 96fc421bd5
36 changed files with 520 additions and 70 deletions
+4
View File
@@ -1,5 +1,9 @@
# Change Log
## 12.0.0
* Add array-based enum parameters (e.g., `permissions: List<BrowserPermission>`).
## 11.4.0
* Add `getScreenshot` method to `Avatars` service
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2025 Appwrite (https://appwrite.io) and individual contributors.
Copyright (c) 2026 Appwrite (https://appwrite.io) and individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+4 -4
View File
@@ -2,14 +2,14 @@
![Maven Central](https://img.shields.io/maven-central/v/io.appwrite/sdk-for-android.svg?color=green&style=flat-square)
![License](https://img.shields.io/github/license/appwrite/sdk-for-android.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.8.0-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.8.1-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
**This SDK is compatible with Appwrite server version 1.8.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-android/releases).**
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Android SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Android SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
![Appwrite](https://github.com/appwrite/appwrite/raw/main/public/images/github.png)
@@ -38,7 +38,7 @@ repositories {
Next, add the dependency to your project's `build.gradle(.kts)` file:
```groovy
implementation("io.appwrite:sdk-for-android:11.4.0")
implementation("io.appwrite:sdk-for-android:12.0.0")
```
### Maven
@@ -49,7 +49,7 @@ Add this to your project's `pom.xml` file:
<dependency>
<groupId>io.appwrite</groupId>
<artifactId>sdk-for-android</artifactId>
<version>11.4.0</version>
<version>12.0.0</version>
</dependency>
</dependencies>
```
-1
View File
@@ -29,6 +29,5 @@ task clean(type: Delete) {
delete rootProject.buildDir
}
apply from: "${rootDir}/scripts/publish-config.gradle"
+11 -7
View File
@@ -8,11 +8,15 @@ Client client = new Client(context)
Account account = new Account(client);
account.createJWT(new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
}
account.createJWT(
0, // duration (optional)
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
}
Log.d("Appwrite", result.toString());
})
);
Log.d("Appwrite", result.toString());
}));
+4 -3
View File
@@ -3,7 +3,8 @@ import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Avatars;
import io.appwrite.enums.Theme;
import io.appwrite.enums.Timezone;
import io.appwrite.enums.Output;
import io.appwrite.enums.BrowserPermission;
import io.appwrite.enums.ImageFormat;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
@@ -29,12 +30,12 @@ avatars.getScreenshot(
-122.4194, // longitude (optional)
100, // accuracy (optional)
true, // touch (optional)
List.of("geolocation", "notifications"), // permissions (optional)
BrowserPermission.GEOLOCATION, // permissions (optional)
3, // sleep (optional)
800, // width (optional)
600, // height (optional)
85, // quality (optional)
Output.JPG, // output (optional)
ImageFormat.JPG, // output (optional)
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
@@ -14,7 +14,13 @@ databases.updateDocument(
"<DATABASE_ID>", // databaseId
"<COLLECTION_ID>", // collectionId
"<DOCUMENT_ID>", // documentId
Map.of("a", "b"), // data (optional)
Map.of(
"username", "walter.obrien",
"email", "walter.obrien@example.com",
"fullName", "Walter O'Brien",
"age", 33,
"isAdmin", false
), // data (optional)
List.of(Permission.read(Role.any())), // permissions (optional)
"<TRANSACTION_ID>", // transactionId (optional)
new CoroutineCallback<>((result, error) -> {
@@ -14,7 +14,13 @@ databases.upsertDocument(
"<DATABASE_ID>", // databaseId
"<COLLECTION_ID>", // collectionId
"<DOCUMENT_ID>", // documentId
Map.of("a", "b"), // data
Map.of(
"username", "walter.obrien",
"email", "walter.obrien@example.com",
"fullName", "Walter O'Brien",
"age", 30,
"isAdmin", false
), // data (optional)
List.of(Permission.read(Role.any())), // permissions (optional)
"<TRANSACTION_ID>", // transactionId (optional)
new CoroutineCallback<>((result, error) -> {
+7 -1
View File
@@ -14,7 +14,13 @@ tablesDB.updateRow(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
Map.of("a", "b"), // data (optional)
Map.of(
"username", "walter.obrien",
"email", "walter.obrien@example.com",
"fullName", "Walter O'Brien",
"age", 33,
"isAdmin", false
), // data (optional)
List.of(Permission.read(Role.any())), // permissions (optional)
"<TRANSACTION_ID>", // transactionId (optional)
new CoroutineCallback<>((result, error) -> {
+7 -1
View File
@@ -14,7 +14,13 @@ tablesDB.upsertRow(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
Map.of("a", "b"), // data (optional)
Map.of(
"username", "walter.obrien",
"email", "walter.obrien@example.com",
"fullName", "Walter O'Brien",
"age", 33,
"isAdmin", false
), // data (optional)
List.of(Permission.read(Role.any())), // permissions (optional)
"<TRANSACTION_ID>", // transactionId (optional)
new CoroutineCallback<>((result, error) -> {
@@ -1,6 +1,7 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Teams;
import io.appwrite.enums.Roles;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
@@ -10,7 +11,7 @@ Teams teams = new Teams(client);
teams.createMembership(
"<TEAM_ID>", // teamId
List.of(), // roles
Roles.ADMIN, // roles
"email@example.com", // email (optional)
"<USER_ID>", // userId (optional)
"+12065550100", // phone (optional)
@@ -1,6 +1,7 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Teams;
import io.appwrite.enums.Roles;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
@@ -11,7 +12,7 @@ Teams teams = new Teams(client);
teams.updateMembership(
"<TEAM_ID>", // teamId
"<MEMBERSHIP_ID>", // membershipId
List.of(), // roles
Roles.ADMIN, // roles
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
+3 -1
View File
@@ -8,4 +8,6 @@ val client = Client(context)
val account = Account(client)
val result = account.createJWT()
val result = account.createJWT(
duration = 0, // (optional)
)
@@ -3,7 +3,8 @@ import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Avatars
import io.appwrite.enums.Theme
import io.appwrite.enums.Timezone
import io.appwrite.enums.Output
import io.appwrite.enums.BrowserPermission
import io.appwrite.enums.ImageFormat
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
@@ -29,10 +30,10 @@ val result = avatars.getScreenshot(
longitude = -122.4194, // (optional)
accuracy = 100, // (optional)
touch = true, // (optional)
permissions = listOf("geolocation", "notifications"), // (optional)
permissions = BrowserPermission.GEOLOCATION, // (optional)
sleep = 3, // (optional)
width = 800, // (optional)
height = 600, // (optional)
quality = 85, // (optional)
output = output.JPG, // (optional)
output = ImageFormat.JPG, // (optional)
)
@@ -14,7 +14,13 @@ val result = databases.updateDocument(
databaseId = "<DATABASE_ID>",
collectionId = "<COLLECTION_ID>",
documentId = "<DOCUMENT_ID>",
data = mapOf( "a" to "b" ), // (optional)
data = mapOf(
"username" to "walter.obrien",
"email" to "walter.obrien@example.com",
"fullName" to "Walter O'Brien",
"age" to 33,
"isAdmin" to false
), // (optional)
permissions = listOf(Permission.read(Role.any())), // (optional)
transactionId = "<TRANSACTION_ID>", // (optional)
)
@@ -14,7 +14,13 @@ val result = databases.upsertDocument(
databaseId = "<DATABASE_ID>",
collectionId = "<COLLECTION_ID>",
documentId = "<DOCUMENT_ID>",
data = mapOf( "a" to "b" ),
data = mapOf(
"username" to "walter.obrien",
"email" to "walter.obrien@example.com",
"fullName" to "Walter O'Brien",
"age" to 30,
"isAdmin" to false
), // (optional)
permissions = listOf(Permission.read(Role.any())), // (optional)
transactionId = "<TRANSACTION_ID>", // (optional)
)
+7 -1
View File
@@ -14,7 +14,13 @@ val result = tablesDB.updateRow(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
rowId = "<ROW_ID>",
data = mapOf( "a" to "b" ), // (optional)
data = mapOf(
"username" to "walter.obrien",
"email" to "walter.obrien@example.com",
"fullName" to "Walter O'Brien",
"age" to 33,
"isAdmin" to false
), // (optional)
permissions = listOf(Permission.read(Role.any())), // (optional)
transactionId = "<TRANSACTION_ID>", // (optional)
)
+7 -1
View File
@@ -14,7 +14,13 @@ val result = tablesDB.upsertRow(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
rowId = "<ROW_ID>",
data = mapOf( "a" to "b" ), // (optional)
data = mapOf(
"username" to "walter.obrien",
"email" to "walter.obrien@example.com",
"fullName" to "Walter O'Brien",
"age" to 33,
"isAdmin" to false
), // (optional)
permissions = listOf(Permission.read(Role.any())), // (optional)
transactionId = "<TRANSACTION_ID>", // (optional)
)
@@ -1,6 +1,7 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Teams
import io.appwrite.enums.Roles
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
@@ -10,7 +11,7 @@ val teams = Teams(client)
val result = teams.createMembership(
teamId = "<TEAM_ID>",
roles = listOf(),
roles = roles.ADMIN,
email = "email@example.com", // (optional)
userId = "<USER_ID>", // (optional)
phone = "+12065550100", // (optional)
@@ -1,6 +1,7 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Teams
import io.appwrite.enums.Roles
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
@@ -11,5 +12,5 @@ val teams = Teams(client)
val result = teams.updateMembership(
teamId = "<TEAM_ID>",
membershipId = "<MEMBERSHIP_ID>",
roles = listOf(),
roles = roles.ADMIN,
)
@@ -13,7 +13,6 @@ import androidx.fragment.app.viewModels
import io.appwrite.android.R
import io.appwrite.android.databinding.FragmentAccountBinding
class AccountsFragment : Fragment() {
private lateinit var binding: FragmentAccountBinding
+1 -1
View File
@@ -10,7 +10,7 @@ ext {
POM_URL = 'https://github.com/appwrite/sdk-for-android'
POM_SCM_URL = 'https://github.com/appwrite/sdk-for-android'
POM_ISSUE_URL = 'https://github.com/appwrite/sdk-for-android/issues'
POM_DESCRIPTION = 'Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Android SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)'
POM_DESCRIPTION = 'Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Android SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)'
POM_LICENSE_URL = 'https://opensource.org/licenses/GPL-3.0'
POM_LICENSE_NAME = "GPL-3.0"
POM_DEVELOPER_ID = 'appwrite'
@@ -0,0 +1,262 @@
package io.appwrite
// Marker interfaces for type safety
public interface _Root
public interface _Database
public interface _Collection
public interface _Document
public interface _TablesDB
public interface _Table
public interface _Row
public interface _Bucket
public interface _File
public interface _Func
public interface _Execution
public interface _Team
public interface _Membership
public interface _Resolved
// Union type for actionable channels
typealias Actionable = _Document
/**
* Helper for normalizing IDs
*/
private fun normalize(id: String): String {
val trimmed = id.trim()
return if (trimmed.isEmpty()) "*" else trimmed
}
/**
* Channel class with generic type parameter for type-safe method chaining
*/
class Channel<out T> private constructor(
private val segments: List<String>
) {
/**
* Internal helper to transition to next state with segment and ID
* Public for extension function access
*/
fun <N> next(segment: String, id: String = "*"): Channel<N> {
return Channel(segments + listOf(segment, normalize(id)))
}
/**
* Internal helper for terminal actions (no ID segment)
* Public for extension function access
*/
fun resolve(action: String): Channel<_Resolved> {
return Channel(segments + listOf(action))
}
/**
* Convert channel to string representation
*/
override fun toString(): String = segments.joinToString(".")
companion object {
fun database(id: String = "*"): Channel<_Database> =
Channel(listOf("databases", normalize(id)))
fun tablesdb(id: String = "*"): Channel<_TablesDB> =
Channel(listOf("tablesdb", normalize(id)))
fun bucket(id: String = "*"): Channel<_Bucket> =
Channel(listOf("buckets", normalize(id)))
fun function(id: String = "*"): Channel<_Func> =
Channel(listOf("functions", normalize(id)))
fun team(id: String = "*"): Channel<_Team> =
Channel(listOf("teams", normalize(id)))
fun membership(id: String = "*"): Channel<_Membership> =
Channel(listOf("memberships", normalize(id)))
fun account(userId: String = ""): String {
val id = normalize(userId)
return if (id == "*") "account" else "account.$id"
}
// Global events
fun documents(): String = "documents"
fun rows(): String = "rows"
fun files(): String = "files"
fun executions(): String = "executions"
fun teams(): String = "teams"
}
}
// --- DATABASE ROUTE ---
// Extension functions restricted by receiver type
/**
* Only available on Channel<_Database>
*/
fun Channel<_Database>.collection(id: String = "*"): Channel<_Collection> =
this.next("collections", id)
/**
* Only available on Channel<_Collection>
*/
fun Channel<_Collection>.document(id: String = "*"): Channel<_Document> =
this.next("documents", id)
// --- TABLESDB ROUTE ---
/**
* Only available on Channel<_TablesDB>
*/
fun Channel<_TablesDB>.table(id: String = "*"): Channel<_Table> =
this.next("tables", id)
/**
* Only available on Channel<_Table>
*/
fun Channel<_Table>.row(id: String = "*"): Channel<_Row> =
this.next("rows", id)
// --- BUCKET ROUTE ---
/**
* Only available on Channel<_Bucket>
*/
fun Channel<_Bucket>.file(id: String = "*"): Channel<_File> =
this.next("files", id)
// --- FUNCTION ROUTE ---
/**
* Only available on Channel<_Func>
*/
fun Channel<_Func>.execution(id: String = "*"): Channel<_Execution> =
this.next("executions", id)
// --- TERMINAL ACTIONS ---
// Restricted to Actionable types (_Document, _Row, _File, _Execution, _Team, _Membership)
/**
* Only available on Channel<_Document>
*/
@JvmName("createDocument")
fun Channel<_Document>.create(): Channel<_Resolved> =
this.resolve("create")
/**
* Only available on Channel<_Document>
*/
@JvmName("updateDocument")
fun Channel<_Document>.update(): Channel<_Resolved> =
this.resolve("update")
/**
* Only available on Channel<_Document>
*/
@JvmName("deleteDocument")
fun Channel<_Document>.delete(): Channel<_Resolved> =
this.resolve("delete")
/**
* Only available on Channel<_Row>
*/
@JvmName("createRow")
fun Channel<_Row>.create(): Channel<_Resolved> =
this.resolve("create")
/**
* Only available on Channel<_Row>
*/
@JvmName("updateRow")
fun Channel<_Row>.update(): Channel<_Resolved> =
this.resolve("update")
/**
* Only available on Channel<_Row>
*/
@JvmName("deleteRow")
fun Channel<_Row>.delete(): Channel<_Resolved> =
this.resolve("delete")
/**
* Only available on Channel<_File>
*/
@JvmName("createFile")
fun Channel<_File>.create(): Channel<_Resolved> =
this.resolve("create")
/**
* Only available on Channel<_File>
*/
@JvmName("updateFile")
fun Channel<_File>.update(): Channel<_Resolved> =
this.resolve("update")
/**
* Only available on Channel<_File>
*/
@JvmName("deleteFile")
fun Channel<_File>.delete(): Channel<_Resolved> =
this.resolve("delete")
/**
* Only available on Channel<_Execution>
*/
@JvmName("createExecution")
fun Channel<_Execution>.create(): Channel<_Resolved> =
this.resolve("create")
/**
* Only available on Channel<_Execution>
*/
@JvmName("updateExecution")
fun Channel<_Execution>.update(): Channel<_Resolved> =
this.resolve("update")
/**
* Only available on Channel<_Execution>
*/
@JvmName("deleteExecution")
fun Channel<_Execution>.delete(): Channel<_Resolved> =
this.resolve("delete")
/**
* Only available on Channel<_Team>
*/
@JvmName("createTeam")
fun Channel<_Team>.create(): Channel<_Resolved> =
this.resolve("create")
/**
* Only available on Channel<_Team>
*/
@JvmName("updateTeam")
fun Channel<_Team>.update(): Channel<_Resolved> =
this.resolve("update")
/**
* Only available on Channel<_Team>
*/
@JvmName("deleteTeam")
fun Channel<_Team>.delete(): Channel<_Resolved> =
this.resolve("delete")
/**
* Only available on Channel<_Membership>
*/
@JvmName("createMembership")
fun Channel<_Membership>.create(): Channel<_Resolved> =
this.resolve("create")
/**
* Only available on Channel<_Membership>
*/
@JvmName("updateMembership")
fun Channel<_Membership>.update(): Channel<_Resolved> =
this.resolve("update")
/**
* Only available on Channel<_Membership>
*/
@JvmName("deleteMembership")
fun Channel<_Membership>.delete(): Channel<_Resolved> =
this.resolve("delete")
+1 -1
View File
@@ -87,7 +87,7 @@ class Client @JvmOverloads constructor(
"x-sdk-name" to "Android",
"x-sdk-platform" to "client",
"x-sdk-language" to "android",
"x-sdk-version" to "11.4.0",
"x-sdk-version" to "12.0.0",
"x-appwrite-response-format" to "1.8.0"
)
config = mutableMapOf()
@@ -38,6 +38,15 @@ class Query(
*/
fun notEqual(attribute: String, value: Any) = Query("notEqual", attribute, parseValue(value)).toJson()
/**
* Filter resources where attribute matches a regular expression pattern.
*
* @param attribute The attribute to filter on.
* @param pattern The regular expression pattern to match.
* @returns The query string.
*/
fun regex(attribute: String, pattern: String) = Query("regex", attribute, parseValue(pattern)).toJson()
/**
* Filter resources where attribute is less than value.
*
@@ -99,6 +108,22 @@ class Query(
*/
fun isNotNull(attribute: String) = Query("isNotNull", attribute).toJson()
/**
* Filter resources where the specified attributes exist.
*
* @param attributes The list of attributes that must exist.
* @returns The query string.
*/
fun exists(attributes: List<String>) = Query("exists", null, attributes).toJson()
/**
* Filter resources where the specified attributes do not exist.
*
* @param attributes The list of attributes that must not exist.
* @returns The query string.
*/
fun notExists(attributes: List<String>) = Query("notExists", null, attributes).toJson()
/**
* Filter resources where attribute is between start and end (inclusive).
*
@@ -311,6 +336,15 @@ class Query(
*/
fun and(queries: List<String>) = Query("and", null, queries.map { it.fromJson<Query>() }).toJson()
/**
* Filter array elements where at least one element matches all the specified queries.
*
* @param attribute The attribute containing the array to filter on.
* @param queries The list of query strings to match against array elements.
* @returns The query string.
*/
fun elemMatch(attribute: String, queries: List<String>) = Query("elemMatch", attribute, queries.map { it.fromJson<Query>() }).toJson()
/**
* Filter resources where attribute is at a specific distance from the given coordinates.
*
@@ -0,0 +1,48 @@
package io.appwrite.enums
import com.google.gson.annotations.SerializedName
enum class BrowserPermission(val value: String) {
@SerializedName("geolocation")
GEOLOCATION("geolocation"),
@SerializedName("camera")
CAMERA("camera"),
@SerializedName("microphone")
MICROPHONE("microphone"),
@SerializedName("notifications")
NOTIFICATIONS("notifications"),
@SerializedName("midi")
MIDI("midi"),
@SerializedName("push")
PUSH("push"),
@SerializedName("clipboard-read")
CLIPBOARD_READ("clipboard-read"),
@SerializedName("clipboard-write")
CLIPBOARD_WRITE("clipboard-write"),
@SerializedName("payment-handler")
PAYMENT_HANDLER("payment-handler"),
@SerializedName("usb")
USB("usb"),
@SerializedName("bluetooth")
BLUETOOTH("bluetooth"),
@SerializedName("accelerometer")
ACCELEROMETER("accelerometer"),
@SerializedName("gyroscope")
GYROSCOPE("gyroscope"),
@SerializedName("magnetometer")
MAGNETOMETER("magnetometer"),
@SerializedName("ambient-light-sensor")
AMBIENT_LIGHT_SENSOR("ambient-light-sensor"),
@SerializedName("background-sync")
BACKGROUND_SYNC("background-sync"),
@SerializedName("persistent-storage")
PERSISTENT_STORAGE("persistent-storage"),
@SerializedName("screen-wake-lock")
SCREEN_WAKE_LOCK("screen-wake-lock"),
@SerializedName("web-share")
WEB_SHARE("web-share"),
@SerializedName("xr-spatial-tracking")
XR_SPATIAL_TRACKING("xr-spatial-tracking");
override fun toString() = value
}
@@ -80,9 +80,7 @@ enum class OAuthProvider(val value: String) {
@SerializedName("zoho")
ZOHO("zoho"),
@SerializedName("zoom")
ZOOM("zoom"),
@SerializedName("mock")
MOCK("mock");
ZOOM("zoom");
override fun toString() = value
}
@@ -1,22 +0,0 @@
package io.appwrite.enums
import com.google.gson.annotations.SerializedName
enum class Output(val value: String) {
@SerializedName("jpg")
JPG("jpg"),
@SerializedName("jpeg")
JPEG("jpeg"),
@SerializedName("png")
PNG("png"),
@SerializedName("webp")
WEBP("webp"),
@SerializedName("heic")
HEIC("heic"),
@SerializedName("avif")
AVIF("avif"),
@SerializedName("gif")
GIF("gif");
override fun toString() = value
}
@@ -0,0 +1,14 @@
package io.appwrite.enums
import com.google.gson.annotations.SerializedName
enum class Roles(val value: String) {
@SerializedName("admin")
ADMIN("admin"),
@SerializedName("developer")
DEVELOPER("developer"),
@SerializedName("owner")
OWNER("owner");
override fun toString() = value
}
@@ -73,6 +73,18 @@ data class File(
@SerializedName("chunksUploaded")
val chunksUploaded: Long,
/**
* Whether file contents are encrypted at rest.
*/
@SerializedName("encryption")
val encryption: Boolean,
/**
* Compression algorithm used for the file. Will be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd).
*/
@SerializedName("compression")
val compression: String,
) {
fun toMap(): Map<String, Any> = mapOf(
"\$id" to id as Any,
@@ -86,6 +98,8 @@ data class File(
"sizeOriginal" to sizeOriginal as Any,
"chunksTotal" to chunksTotal as Any,
"chunksUploaded" to chunksUploaded as Any,
"encryption" to encryption as Any,
"compression" to compression as Any,
)
companion object {
@@ -105,6 +119,8 @@ data class File(
sizeOriginal = (map["sizeOriginal"] as Number).toLong(),
chunksTotal = (map["chunksTotal"] as Number).toLong(),
chunksUploaded = (map["chunksUploaded"] as Number).toLong(),
encryption = map["encryption"] as Boolean,
compression = map["compression"] as String,
)
}
}
@@ -244,13 +244,17 @@ class Account(client: Client) : Service(client) {
/**
* Use this endpoint to create a JSON Web Token. You can use the resulting JWT to authenticate on behalf of the current user when working with the Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes from its creation and will be invalid if the user will logout in that time frame.
*
* @param duration Time in seconds before JWT expires. Default duration is 900 seconds, and maximum is 3600 seconds.
* @return [io.appwrite.models.Jwt]
*/
@JvmOverloads
suspend fun createJWT(
duration: Long? = null,
): io.appwrite.models.Jwt {
val apiPath = "/account/jwts"
val apiParams = mutableMapOf<String, Any?>(
"duration" to duration,
)
val apiHeaders = mutableMapOf<String, String>(
"content-type" to "application/json",
@@ -306,12 +306,12 @@ class Avatars(client: Client) : Service(client) {
longitude: Double? = null,
accuracy: Double? = null,
touch: Boolean? = null,
permissions: List<String>? = null,
permissions: List<io.appwrite.enums.BrowserPermission>? = null,
sleep: Long? = null,
width: Long? = null,
height: Long? = null,
quality: Long? = null,
output: io.appwrite.enums.Output? = null,
output: io.appwrite.enums.ImageFormat? = null,
): ByteArray {
val apiPath = "/avatars/screenshots"
@@ -476,7 +476,7 @@ class Databases(client: Client) : Service(client) {
databaseId: String,
collectionId: String,
documentId: String,
data: Any,
data: Any? = null,
permissions: List<String>? = null,
transactionId: String? = null,
nestedType: Class<T>,
@@ -529,7 +529,7 @@ class Databases(client: Client) : Service(client) {
databaseId: String,
collectionId: String,
documentId: String,
data: Any,
data: Any? = null,
permissions: List<String>? = null,
transactionId: String? = null,
): io.appwrite.models.Document<Map<String, Any>> = upsertDocument(
@@ -2,6 +2,7 @@ package io.appwrite.services
import io.appwrite.Service
import io.appwrite.Client
import io.appwrite.Channel
import io.appwrite.exceptions.AppwriteException
import io.appwrite.extensions.forEachAsync
import io.appwrite.extensions.fromJson
@@ -109,6 +110,27 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
else -> 60000L
}
/**
* Convert channel value to string
* All Channel instances have toString() method
*/
private fun channelToString(channel: Any): String {
return when {
channel is String -> channel
channel is Channel<*> -> channel.toString()
else -> channel.toString()
}
}
fun subscribe(
vararg channels: Channel<*>,
callback: (RealtimeResponseEvent<Any>) -> Unit,
) = subscribe(
channels = channels.map { channelToString(it) }.toTypedArray(),
Any::class.java,
callback
)
fun subscribe(
vararg channels: String,
callback: (RealtimeResponseEvent<Any>) -> Unit,
@@ -118,6 +140,18 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
callback
)
fun <T> subscribe(
vararg channels: Channel<*>,
payloadType: Class<T>,
callback: (RealtimeResponseEvent<T>) -> Unit,
): RealtimeSubscription {
return subscribe(
channels = channels.map { channelToString(it) }.toTypedArray(),
payloadType = payloadType,
callback = callback
)
}
fun <T> subscribe(
vararg channels: String,
payloadType: Class<T>,
@@ -148,10 +148,10 @@ class Storage(client: Client) : Service(client) {
/**
* Update a file by its unique ID. Only users with write permissions have access to update this resource.
*
* @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
* @param fileId File unique ID.
* @param name Name of the file
* @param permissions An array of permission string. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).
* @param bucketId Bucket unique ID.
* @param fileId File ID.
* @param name File name.
* @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).
* @return [io.appwrite.models.File]
*/
@JvmOverloads
@@ -320,7 +320,7 @@ class Teams(client: Client) : Service(client) {
@JvmOverloads
suspend fun createMembership(
teamId: String,
roles: List<String>,
roles: List<io.appwrite.enums.Roles>,
email: String? = null,
userId: String? = null,
phone: String? = null,
@@ -402,7 +402,7 @@ class Teams(client: Client) : Service(client) {
suspend fun updateMembership(
teamId: String,
membershipId: String,
roles: List<String>,
roles: List<io.appwrite.enums.Roles>,
): io.appwrite.models.Membership {
val apiPath = "/teams/{teamId}/memberships/{membershipId}"
.replace("{teamId}", teamId)