diff --git a/CHANGELOG.md b/CHANGELOG.md index f3aa24a8..435676ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log +## 28.0.0 + +* Breaking: removed `Account.listLogs` and the `Log`, `LogList` models +* Breaking: removed `Client.setDevKey` +* Breaking: SDK now targets Appwrite 2.3 (`x-appwrite-response-format: 2.3.0`) +* Added: `Account.createIdTokenSession` for native Apple and Google sign-in with `IdTokenProvider` enum +* Added: `Account.createRecoveryOTP` and `Account.updateRecoveryOTP` for code-based password recovery +* Added: `Account.createEmailVerificationOTP` and `Account.updateEmailVerificationOTP` +* Added: `KAKAO` and `TIKTOK` values to `OAuthProvider` +* Added: `passwordPwned` field on `User` and `providerIdToken` field on `Identity` +* Fixed: empty-string required path parameters are rejected instead of sent to the API + ## 27.2.0 * Added: `DocumentsDB` and `VectorsDB` services for document and vector database access diff --git a/README.md b/README.md index e8e30481..c8fb25f0 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ ![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-2.0.0-blue.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-2.3.0-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 targets Appwrite server version 2.0.x as shipped on Appwrite Cloud.** Self-hosted releases can lag behind Cloud — if you run an older self-hosted build, use a matching older SDK from [previous releases](https://github.com/appwrite/sdk-for-android/releases) when APIs differ. +**This SDK targets Appwrite server version 2.3.x as shipped on Appwrite Cloud.** Self-hosted releases can lag behind Cloud — if you run an older self-hosted build, use a matching older SDK from [previous releases](https://github.com/appwrite/sdk-for-android/releases) when APIs differ. 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) @@ -38,7 +38,7 @@ repositories { Next, add the dependency to your project's `build.gradle(.kts)` file: ```groovy -implementation("io.appwrite:sdk-for-android:27.2.0") +implementation("io.appwrite:sdk-for-android:28.0.0") ``` ### Maven @@ -49,7 +49,7 @@ Add this to your project's `pom.xml` file: io.appwrite sdk-for-android - 27.2.0 + 28.0.0 ``` diff --git a/docs/examples/java/account/list-logs.md b/docs/examples/java/account/create-email-verification-otp.md similarity index 86% rename from docs/examples/java/account/list-logs.md rename to docs/examples/java/account/create-email-verification-otp.md index e8de501d..951b4bd8 100644 --- a/docs/examples/java/account/list-logs.md +++ b/docs/examples/java/account/create-email-verification-otp.md @@ -11,9 +11,8 @@ Client client = new Client(context) Account account = new Account(client); -account.listLogs( - List.of(), // queries (optional) - false, // total (optional) +account.createEmailVerificationOTP( + false, // phrase (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/java/account/create-id-token-session.md b/docs/examples/java/account/create-id-token-session.md new file mode 100644 index 00000000..457b9fee --- /dev/null +++ b/docs/examples/java/account/create-id-token-session.md @@ -0,0 +1,32 @@ +```java +import android.util.Log; + +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; +import io.appwrite.enums.IdTokenProvider; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Account account = new Account(client); + +account.createIdTokenSession( + IdTokenProvider.APPLE, // provider + "", // idToken + "", // nonce (optional) + "", // accessToken (optional) + 0, // accessTokenExpiry (optional) + "", // name (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + +``` diff --git a/docs/examples/java/account/create-recovery-otp.md b/docs/examples/java/account/create-recovery-otp.md new file mode 100644 index 00000000..66c165b8 --- /dev/null +++ b/docs/examples/java/account/create-recovery-otp.md @@ -0,0 +1,27 @@ +```java +import android.util.Log; + +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Account account = new Account(client); + +account.createRecoveryOTP( + "email@example.com", // email + false, // phrase (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + +``` diff --git a/docs/examples/java/account/update-email-verification-otp.md b/docs/examples/java/account/update-email-verification-otp.md new file mode 100644 index 00000000..d66521c8 --- /dev/null +++ b/docs/examples/java/account/update-email-verification-otp.md @@ -0,0 +1,27 @@ +```java +import android.util.Log; + +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Account account = new Account(client); + +account.updateEmailVerificationOTP( + "", // userId + "", // secret + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + +``` diff --git a/docs/examples/java/account/update-recovery-otp.md b/docs/examples/java/account/update-recovery-otp.md new file mode 100644 index 00000000..c16df289 --- /dev/null +++ b/docs/examples/java/account/update-recovery-otp.md @@ -0,0 +1,28 @@ +```java +import android.util.Log; + +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Account account = new Account(client); + +account.updateRecoveryOTP( + "", // userId + "", // secret + "password", // password + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + +``` diff --git a/docs/examples/kotlin/account/list-logs.md b/docs/examples/kotlin/account/create-email-verification-otp.md similarity index 76% rename from docs/examples/kotlin/account/list-logs.md rename to docs/examples/kotlin/account/create-email-verification-otp.md index 0bccbf25..6acba146 100644 --- a/docs/examples/kotlin/account/list-logs.md +++ b/docs/examples/kotlin/account/create-email-verification-otp.md @@ -9,8 +9,7 @@ val client = Client(context) val account = Account(client) -val result = account.listLogs( - queries = listOf(), // (optional) - total = false, // (optional) +val result = account.createEmailVerificationOTP( + phrase = false, // (optional) ) ``` diff --git a/docs/examples/kotlin/account/create-id-token-session.md b/docs/examples/kotlin/account/create-id-token-session.md new file mode 100644 index 00000000..5eb6d0da --- /dev/null +++ b/docs/examples/kotlin/account/create-id-token-session.md @@ -0,0 +1,21 @@ +```kotlin +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account +import io.appwrite.enums.IdTokenProvider + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val account = Account(client) + +val result = account.createIdTokenSession( + provider = IdTokenProvider.APPLE, + idToken = "", + nonce = "", // (optional) + accessToken = "", // (optional) + accessTokenExpiry = 0, // (optional) + name = "", // (optional) +) +``` diff --git a/docs/examples/kotlin/account/create-recovery-otp.md b/docs/examples/kotlin/account/create-recovery-otp.md new file mode 100644 index 00000000..754baa87 --- /dev/null +++ b/docs/examples/kotlin/account/create-recovery-otp.md @@ -0,0 +1,16 @@ +```kotlin +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val account = Account(client) + +val result = account.createRecoveryOTP( + email = "email@example.com", + phrase = false, // (optional) +) +``` diff --git a/docs/examples/kotlin/account/update-email-verification-otp.md b/docs/examples/kotlin/account/update-email-verification-otp.md new file mode 100644 index 00000000..639605bc --- /dev/null +++ b/docs/examples/kotlin/account/update-email-verification-otp.md @@ -0,0 +1,16 @@ +```kotlin +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val account = Account(client) + +val result = account.updateEmailVerificationOTP( + userId = "", + secret = "", +) +``` diff --git a/docs/examples/kotlin/account/update-recovery-otp.md b/docs/examples/kotlin/account/update-recovery-otp.md new file mode 100644 index 00000000..00b2ff0a --- /dev/null +++ b/docs/examples/kotlin/account/update-recovery-otp.md @@ -0,0 +1,17 @@ +```kotlin +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val account = Account(client) + +val result = account.updateRecoveryOTP( + userId = "", + secret = "", + password = "password", +) +``` diff --git a/example/build.gradle.kts b/example/build.gradle.kts index 8f1ca9b8..2b339ac0 100644 --- a/example/build.gradle.kts +++ b/example/build.gradle.kts @@ -41,9 +41,9 @@ dependencies { implementation("androidx.appcompat:appcompat:1.8.0") implementation("com.google.android.material:material:1.14.0") implementation("androidx.constraintlayout:constraintlayout:2.2.2") - implementation("androidx.navigation:navigation-fragment-ktx:2.10.0") + implementation("androidx.navigation:navigation-fragment-ktx:2.10.1") implementation("androidx.fragment:fragment-ktx:1.9.0") - implementation("androidx.navigation:navigation-ui-ktx:2.10.0") + implementation("androidx.navigation:navigation-ui-ktx:2.10.1") implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.11.0") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.11.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0") diff --git a/library/build.gradle.kts b/library/build.gradle.kts index a526d1f2..45641217 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -94,7 +94,7 @@ dependencies { testImplementation("junit:junit:4.13.2") testImplementation("androidx.test.ext:junit-ktx:1.3.0") testImplementation("androidx.test:core-ktx:1.7.0") - testImplementation("org.robolectric:robolectric:4.16.1") + testImplementation("org.robolectric:robolectric:4.17") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.11.0") } diff --git a/library/src/main/java/io/appwrite/Client.kt b/library/src/main/java/io/appwrite/Client.kt index 8b5455ea..40431217 100644 --- a/library/src/main/java/io/appwrite/Client.kt +++ b/library/src/main/java/io/appwrite/Client.kt @@ -96,8 +96,8 @@ class Client @JvmOverloads constructor( "x-sdk-name" to "Android", "x-sdk-platform" to "client", "x-sdk-language" to "android", - "x-sdk-version" to "27.2.0", - "x-appwrite-response-format" to "2.0.0" + "x-sdk-version" to "28.0.0", + "x-appwrite-response-format" to "2.3.0" ) config = mutableMapOf() @@ -176,21 +176,6 @@ class Client @JvmOverloads constructor( return this } - /** - * Set DevKey - * - * Your secret dev API key - * - * @param {string} devkey - * - * @return this - */ - fun setDevKey(value: String): Client { - config["devKey"] = value - addHeader("x-appwrite-dev-key", value) - return this - } - /** * Set Cookie * diff --git a/library/src/main/java/io/appwrite/enums/IdTokenProvider.kt b/library/src/main/java/io/appwrite/enums/IdTokenProvider.kt new file mode 100644 index 00000000..fb5d6f12 --- /dev/null +++ b/library/src/main/java/io/appwrite/enums/IdTokenProvider.kt @@ -0,0 +1,12 @@ +package io.appwrite.enums + +import com.google.gson.annotations.SerializedName + +enum class IdTokenProvider(val value: String) { + @SerializedName("apple") + APPLE("apple"), + @SerializedName("google") + GOOGLE("google"); + + override fun toString() = value +} diff --git a/library/src/main/java/io/appwrite/enums/OAuthProvider.kt b/library/src/main/java/io/appwrite/enums/OAuthProvider.kt index e71acdf2..4eb5cbfd 100644 --- a/library/src/main/java/io/appwrite/enums/OAuthProvider.kt +++ b/library/src/main/java/io/appwrite/enums/OAuthProvider.kt @@ -47,6 +47,8 @@ enum class OAuthProvider(val value: String) { GOOGLE("google"), @SerializedName("huggingface") HUGGINGFACE("huggingface"), + @SerializedName("kakao") + KAKAO("kakao"), @SerializedName("keycloak") KEYCLOAK("keycloak"), @SerializedName("kick") @@ -77,6 +79,8 @@ enum class OAuthProvider(val value: String) { SPOTIFY("spotify"), @SerializedName("stripe") STRIPE("stripe"), + @SerializedName("tiktok") + TIKTOK("tiktok"), @SerializedName("tradeshift") TRADESHIFT("tradeshift"), @SerializedName("tradeshiftBox") diff --git a/library/src/main/java/io/appwrite/models/Execution.kt b/library/src/main/java/io/appwrite/models/Execution.kt index 662c48ea..c698d9c6 100644 --- a/library/src/main/java/io/appwrite/models/Execution.kt +++ b/library/src/main/java/io/appwrite/models/Execution.kt @@ -113,7 +113,7 @@ data class Execution( val errors: String, /** - * Resource(function/site) execution duration in seconds. + * Total time the resource(function/site) took to respond, in seconds. */ @SerializedName("duration") val duration: Double, diff --git a/library/src/main/java/io/appwrite/models/Identity.kt b/library/src/main/java/io/appwrite/models/Identity.kt index ab70557a..011c32e4 100644 --- a/library/src/main/java/io/appwrite/models/Identity.kt +++ b/library/src/main/java/io/appwrite/models/Identity.kt @@ -67,6 +67,12 @@ data class Identity( @SerializedName("providerRefreshToken") val providerRefreshToken: String, + /** + * Identity Provider ID token (JWT) from the most recent native sign-in. Empty for identities created through the browser OAuth2 flow. + */ + @SerializedName("providerIdToken") + val providerIdToken: String, + ) { fun toMap(): Map = mapOf( "\$id" to id as Any, @@ -79,6 +85,7 @@ data class Identity( "providerAccessToken" to providerAccessToken as Any, "providerAccessTokenExpiry" to providerAccessTokenExpiry as Any, "providerRefreshToken" to providerRefreshToken as Any, + "providerIdToken" to providerIdToken as Any, ) companion object { @@ -96,6 +103,7 @@ data class Identity( providerAccessToken = map["providerAccessToken"] as String, providerAccessTokenExpiry = map["providerAccessTokenExpiry"] as String, providerRefreshToken = map["providerRefreshToken"] as String, + providerIdToken = map["providerIdToken"] as String, ) } } diff --git a/library/src/main/java/io/appwrite/models/Log.kt b/library/src/main/java/io/appwrite/models/Log.kt deleted file mode 100644 index 586841c0..00000000 --- a/library/src/main/java/io/appwrite/models/Log.kt +++ /dev/null @@ -1,197 +0,0 @@ -package io.appwrite.models - -import com.google.gson.annotations.SerializedName -import io.appwrite.extensions.jsonCast - -/** - * Log - */ -data class Log( - /** - * Event name. - */ - @SerializedName("event") - val event: String, - - /** - * User ID of the actor recorded for this log. During impersonation, this is the original impersonator, not the impersonated target user. - */ - @SerializedName("userId") - val userId: String, - - /** - * User email of the actor recorded for this log. During impersonation, this is the original impersonator. - */ - @SerializedName("userEmail") - val userEmail: String, - - /** - * User name of the actor recorded for this log. During impersonation, this is the original impersonator. - */ - @SerializedName("userName") - val userName: String, - - /** - * API mode when event triggered. - */ - @SerializedName("mode") - val mode: String, - - /** - * User type who triggered the audit log. Possible values: user, admin, guest, hidden, keyProject, keyAccount, keyOrganization. - */ - @SerializedName("userType") - val userType: String, - - /** - * IP session in use when the session was created. - */ - @SerializedName("ip") - val ip: String, - - /** - * Log creation date in ISO 8601 format. - */ - @SerializedName("time") - val time: String, - - /** - * Operating system code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). - */ - @SerializedName("osCode") - val osCode: String, - - /** - * Operating system name. - */ - @SerializedName("osName") - val osName: String, - - /** - * Operating system version. - */ - @SerializedName("osVersion") - val osVersion: String, - - /** - * Client type. - */ - @SerializedName("clientType") - val clientType: String, - - /** - * Client code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). - */ - @SerializedName("clientCode") - val clientCode: String, - - /** - * Client name. - */ - @SerializedName("clientName") - val clientName: String, - - /** - * Client version. - */ - @SerializedName("clientVersion") - val clientVersion: String, - - /** - * Client engine name. - */ - @SerializedName("clientEngine") - val clientEngine: String, - - /** - * Client engine name. - */ - @SerializedName("clientEngineVersion") - val clientEngineVersion: String, - - /** - * Device name. - */ - @SerializedName("deviceName") - val deviceName: String, - - /** - * Device brand name. - */ - @SerializedName("deviceBrand") - val deviceBrand: String, - - /** - * Device model name. - */ - @SerializedName("deviceModel") - val deviceModel: String, - - /** - * Country two-character ISO 3166-1 alpha code. - */ - @SerializedName("countryCode") - val countryCode: String, - - /** - * Country name. - */ - @SerializedName("countryName") - val countryName: String, - -) { - fun toMap(): Map = mapOf( - "event" to event as Any, - "userId" to userId as Any, - "userEmail" to userEmail as Any, - "userName" to userName as Any, - "mode" to mode as Any, - "userType" to userType as Any, - "ip" to ip as Any, - "time" to time as Any, - "osCode" to osCode as Any, - "osName" to osName as Any, - "osVersion" to osVersion as Any, - "clientType" to clientType as Any, - "clientCode" to clientCode as Any, - "clientName" to clientName as Any, - "clientVersion" to clientVersion as Any, - "clientEngine" to clientEngine as Any, - "clientEngineVersion" to clientEngineVersion as Any, - "deviceName" to deviceName as Any, - "deviceBrand" to deviceBrand as Any, - "deviceModel" to deviceModel as Any, - "countryCode" to countryCode as Any, - "countryName" to countryName as Any, - ) - - companion object { - @Suppress("UNCHECKED_CAST") - fun from( - map: Map, - ) = Log( - event = map["event"] as String, - userId = map["userId"] as String, - userEmail = map["userEmail"] as String, - userName = map["userName"] as String, - mode = map["mode"] as String, - userType = map["userType"] as String, - ip = map["ip"] as String, - time = map["time"] as String, - osCode = map["osCode"] as String, - osName = map["osName"] as String, - osVersion = map["osVersion"] as String, - clientType = map["clientType"] as String, - clientCode = map["clientCode"] as String, - clientName = map["clientName"] as String, - clientVersion = map["clientVersion"] as String, - clientEngine = map["clientEngine"] as String, - clientEngineVersion = map["clientEngineVersion"] as String, - deviceName = map["deviceName"] as String, - deviceBrand = map["deviceBrand"] as String, - deviceModel = map["deviceModel"] as String, - countryCode = map["countryCode"] as String, - countryName = map["countryName"] as String, - ) - } -} diff --git a/library/src/main/java/io/appwrite/models/LogList.kt b/library/src/main/java/io/appwrite/models/LogList.kt deleted file mode 100644 index ef51d7a7..00000000 --- a/library/src/main/java/io/appwrite/models/LogList.kt +++ /dev/null @@ -1,37 +0,0 @@ -package io.appwrite.models - -import com.google.gson.annotations.SerializedName -import io.appwrite.extensions.jsonCast - -/** - * Logs List - */ -data class LogList( - /** - * Total number of logs that matched your query. - */ - @SerializedName("total") - val total: Long, - - /** - * List of logs. - */ - @SerializedName("logs") - val logs: List, - -) { - fun toMap(): Map = mapOf( - "total" to total as Any, - "logs" to logs.map { it.toMap() } as Any, - ) - - companion object { - @Suppress("UNCHECKED_CAST") - fun from( - map: Map, - ) = LogList( - total = (map["total"] as Number).toLong(), - logs = (map["logs"] as List>).map { Log.from(map = it) }, - ) - } -} diff --git a/library/src/main/java/io/appwrite/models/User.kt b/library/src/main/java/io/appwrite/models/User.kt index 473cb7fd..0eea3b00 100644 --- a/library/src/main/java/io/appwrite/models/User.kt +++ b/library/src/main/java/io/appwrite/models/User.kt @@ -121,6 +121,12 @@ data class User( @SerializedName("emailIsCanonical") var emailIsCanonical: Boolean?, + /** + * Whether the password was found in a known data breach the last time it was checked. Null when the password has never been checked. + */ + @SerializedName("passwordPwned") + var passwordPwned: Boolean?, + /** * Phone verification status. */ @@ -184,6 +190,7 @@ data class User( "emailIsDisposable" to emailIsDisposable as Any?, "emailIsCorporate" to emailIsCorporate as Any?, "emailIsCanonical" to emailIsCanonical as Any?, + "passwordPwned" to passwordPwned as Any?, "phoneVerification" to phoneVerification as Any, "mfa" to mfa as Any, "prefs" to prefs.toMap() as Any, @@ -214,6 +221,7 @@ data class User( emailIsDisposable: Boolean?, emailIsCorporate: Boolean?, emailIsCanonical: Boolean?, + passwordPwned: Boolean?, phoneVerification: Boolean, mfa: Boolean, prefs: Preferences>, @@ -241,6 +249,7 @@ data class User( emailIsDisposable, emailIsCorporate, emailIsCanonical, + passwordPwned, phoneVerification, mfa, prefs, @@ -274,6 +283,7 @@ data class User( emailIsDisposable = map["emailIsDisposable"] as? Boolean, emailIsCorporate = map["emailIsCorporate"] as? Boolean, emailIsCanonical = map["emailIsCanonical"] as? Boolean, + passwordPwned = map["passwordPwned"] as? Boolean, phoneVerification = map["phoneVerification"] as Boolean, mfa = map["mfa"] as Boolean, prefs = Preferences.from(map = map["prefs"] as Map, nestedType), diff --git a/library/src/main/java/io/appwrite/services/Account.kt b/library/src/main/java/io/appwrite/services/Account.kt index fd2a009e..17cdf820 100644 --- a/library/src/main/java/io/appwrite/services/Account.kt +++ b/library/src/main/java/io/appwrite/services/Account.kt @@ -165,6 +165,9 @@ class Account(client: Client) : Service(client) { suspend fun getConsent( consentId: String, ): io.appwrite.models.Oauth2Consent { + if (consentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"consentId\"") + } val apiPath = ("/account/consents/{consentId}" .replace("{consentId}", consentId) ) @@ -196,6 +199,9 @@ class Account(client: Client) : Service(client) { suspend fun deleteConsent( consentId: String, ): Any { + if (consentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"consentId\"") + } val apiPath = ("/account/consents/{consentId}" .replace("{consentId}", consentId) ) @@ -228,6 +234,9 @@ class Account(client: Client) : Service(client) { queries: List? = null, total: Boolean? = null, ): io.appwrite.models.Oauth2ConsentTokenList { + if (consentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"consentId\"") + } val apiPath = ("/account/consents/{consentId}/tokens" .replace("{consentId}", consentId) ) @@ -264,6 +273,12 @@ class Account(client: Client) : Service(client) { consentId: String, tokenId: String, ): io.appwrite.models.Oauth2ConsentToken { + if (consentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"consentId\"") + } + if (tokenId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tokenId\"") + } val apiPath = ("/account/consents/{consentId}/tokens/{tokenId}" .replace("{consentId}", consentId) .replace("{tokenId}", tokenId) @@ -298,6 +313,12 @@ class Account(client: Client) : Service(client) { consentId: String, tokenId: String, ): Any { + if (consentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"consentId\"") + } + if (tokenId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tokenId\"") + } val apiPath = ("/account/consents/{consentId}/tokens/{tokenId}" .replace("{consentId}", consentId) .replace("{tokenId}", tokenId) @@ -418,6 +439,9 @@ class Account(client: Client) : Service(client) { suspend fun deleteIdentity( identityId: String, ): Any { + if (identityId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"identityId\"") + } val apiPath = ("/account/identities/{identityId}" .replace("{identityId}", identityId) ) @@ -425,6 +449,7 @@ class Account(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -468,41 +493,6 @@ class Account(client: Client) : Service(client) { ) } - /** - * Get the list of latest security activity logs for the currently logged in user. Each log returns user IP address, location and date and time of log. - * - * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset - * @param total When set to false, the total count returned will be 0 and will not be calculated. - * @return [io.appwrite.models.LogList] - */ - @JvmOverloads - suspend fun listLogs( - queries: List? = null, - total: Boolean? = null, - ): io.appwrite.models.LogList { - val apiPath = "/account/logs" - val apiParams = mutableMapOf( - "queries" to queries, - "total" to total, - ) - val apiHeaders = mutableMapOf( - "X-Appwrite-Project" to client.config["project"].orEmpty(), - "accept" to "application/json", - ) - val converter: (Any) -> io.appwrite.models.LogList = { - @Suppress("UNCHECKED_CAST") - io.appwrite.models.LogList.from(map = it as Map) - } - return client.call( - "GET", - apiPath, - apiHeaders, - apiParams, - responseType = io.appwrite.models.LogList::class.java, - converter, - ) - } - /** * Enable or disable MFA on an account. * @@ -754,6 +744,7 @@ class Account(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -780,6 +771,7 @@ class Account(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -1475,6 +1467,84 @@ class Account(client: Client) : Service(client) { ) } + /** + * Use this endpoint to send a 6-digit password recovery code to the user's email address. Unlike [createRecovery](https://appwrite.io/docs/references/cloud/client-web/account#createRecovery), this method requires no redirect URL, which makes it suitable for mobile and desktop apps that cannot host a recovery page. Learn more about how to [complete the recovery process](https://appwrite.io/docs/references/cloud/client-web/account#updateRecoveryOTP). The code sent to the user's email address is valid for 15 minutes. + * + * Enable the **phrase** parameter to include a randomly generated security phrase in both the email and the response. Showing that phrase in your app lets the user confirm the email genuinely came from your request, which helps protect against phishing. + * + * + * @param email User email. + * @param phrase Toggle for security phrase. If enabled, email will be sent with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow. + * @return [io.appwrite.models.Token] + */ + @JvmOverloads + suspend fun createRecoveryOTP( + email: String, + phrase: Boolean? = null, + ): io.appwrite.models.Token { + val apiPath = "/account/recovery/otp" + val apiParams = mutableMapOf( + "email" to email, + "phrase" to phrase, + ) + val apiHeaders = mutableMapOf( + "X-Appwrite-Project" to client.config["project"].orEmpty(), + "content-type" to "application/json", + "accept" to "application/json", + ) + val converter: (Any) -> io.appwrite.models.Token = { + @Suppress("UNCHECKED_CAST") + io.appwrite.models.Token.from(map = it as Map) + } + return client.call( + "POST", + apiPath, + apiHeaders, + apiParams, + responseType = io.appwrite.models.Token::class.java, + converter, + ) + } + + /** + * Use this endpoint to complete the user password recovery process using the 6-digit code that was emailed by [createRecoveryOTP](https://appwrite.io/docs/references/cloud/client-web/account#createRecoveryOTP). Pass the **userId** of the user along with the **secret** code from the email and the new **password** to set. If confirmed, this route will return a 200 status code, the code is consumed and the user's password is updated. + * + * + * @param userId User ID. + * @param secret Valid recovery OTP code. + * @param password New user password. Must be between 8 and 256 chars. + * @return [io.appwrite.models.Token] + */ + suspend fun updateRecoveryOTP( + userId: String, + secret: String, + password: String, + ): io.appwrite.models.Token { + val apiPath = "/account/recovery/otp" + val apiParams = mutableMapOf( + "userId" to userId, + "secret" to secret, + "password" to password, + ) + val apiHeaders = mutableMapOf( + "X-Appwrite-Project" to client.config["project"].orEmpty(), + "content-type" to "application/json", + "accept" to "application/json", + ) + val converter: (Any) -> io.appwrite.models.Token = { + @Suppress("UNCHECKED_CAST") + io.appwrite.models.Token.from(map = it as Map) + } + return client.call( + "PUT", + apiPath, + apiHeaders, + apiParams, + responseType = io.appwrite.models.Token::class.java, + converter, + ) + } + /** * Get the list of active sessions across different devices for the currently logged in user. * @@ -1512,6 +1582,7 @@ class Account(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -1586,6 +1657,65 @@ class Account(client: Client) : Service(client) { ) } + /** + * Allow the user to login to their account using an OpenID Connect ID token obtained natively from the OAuth2 provider, for example via Google Credential Manager on Android or Sign in with Apple on iOS. No browser or redirect is involved: the ID token is verified against the provider's published signing keys and a session is created in a single request. + * + * Native sign-in is switched on per provider with its nativeEnabled setting. It is independent of the browser-based flow's enabled setting, which has no effect on this endpoint. The token's audience must match the provider's configured client ID or one of its native client IDs; tokens issued for any other client ID are rejected. For Sign in with Apple, register your app's bundle ID as a native client ID. For Google, the web client ID used by Credential Manager is usually the configured client ID; add your Android and iOS client IDs as native client IDs if your app requests tokens for them. + * + * Pass the raw nonce used when requesting the ID token so it can be validated against the token's nonce claim. When signing in with Apple, the nonce is required: hash it with SHA-256 before passing it to the Apple SDK, and send the raw value here - Apple tokens requested without a nonce are rejected. For Google the nonce is optional: it is validated whenever the token carries one, and ignored when the provider issued the token without one. Apple only returns the user's name on the first authorization, and never inside the ID token - capture it on the client and pass it via the name parameter. + * + * If there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the verified email received from the provider and attach the new session to the existing user. If no matching user is found - the server will create a new user. + * + * This flow does not return provider refresh tokens. You may pass an access token the provider handed your client, along with its lifetime, to store it on the session - but Appwrite cannot renew it once it expires. If your app needs long-lived access to provider APIs, use the browser-based OAuth2 flow instead. + * + * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). + * + * + * @param provider OAuth2 provider that issued the ID token. Currently, supported providers are: apple, google. + * @param idToken OpenID Connect ID token (JWT) obtained natively from the provider, for example via Google Credential Manager or Sign in with Apple. + * @param nonce Raw nonce used when requesting the ID token. Required for Apple, and whenever the token carries a nonce claim, which must match it. Ignored when the provider issued the token without a nonce. + * @param accessToken Provider access token to store alongside the session for calling provider APIs. Never used for authentication. + * @param accessTokenExpiry Seconds until the provider access token expires, as reported by the provider. Stored so clients can tell when the stored token goes stale. + * @param name User name. Only used when creating a new user and the ID token has no name claim, such as on the first Sign in with Apple authorization. + * @return [io.appwrite.models.Session] + */ + @JvmOverloads + suspend fun createIdTokenSession( + provider: io.appwrite.enums.IdTokenProvider, + idToken: String, + nonce: String? = null, + accessToken: String? = null, + accessTokenExpiry: Long? = null, + name: String? = null, + ): io.appwrite.models.Session { + val apiPath = "/account/sessions/id-token" + val apiParams = mutableMapOf( + "provider" to provider, + "idToken" to idToken, + "nonce" to nonce, + "accessToken" to accessToken, + "accessTokenExpiry" to accessTokenExpiry, + "name" to name, + ) + val apiHeaders = mutableMapOf( + "X-Appwrite-Project" to client.config["project"].orEmpty(), + "content-type" to "application/json", + "accept" to "application/json", + ) + val converter: (Any) -> io.appwrite.models.Session = { + @Suppress("UNCHECKED_CAST") + io.appwrite.models.Session.from(map = it as Map) + } + return client.call( + "POST", + apiPath, + apiHeaders, + apiParams, + responseType = io.appwrite.models.Session::class.java, + converter, + ) + } + /** * Use this endpoint to create a session from token. Provide the **userId** and **secret** parameters from the successful response of authentication flows initiated by token creation. For example, magic URL and phone login. * @@ -1633,7 +1763,7 @@ class Account(client: Client) : Service(client) { * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * * - * @param provider OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. + * @param provider OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. * @param success URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param failure URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param scopes A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of 100 scopes are allowed, each 4096 characters long. @@ -1784,6 +1914,9 @@ class Account(client: Client) : Service(client) { suspend fun getSession( sessionId: String, ): io.appwrite.models.Session { + if (sessionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"sessionId\"") + } val apiPath = ("/account/sessions/{sessionId}" .replace("{sessionId}", sessionId) ) @@ -1815,6 +1948,9 @@ class Account(client: Client) : Service(client) { suspend fun updateSession( sessionId: String, ): io.appwrite.models.Session { + if (sessionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"sessionId\"") + } val apiPath = ("/account/sessions/{sessionId}" .replace("{sessionId}", sessionId) ) @@ -1847,6 +1983,9 @@ class Account(client: Client) : Service(client) { suspend fun deleteSession( sessionId: String, ): Any { + if (sessionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"sessionId\"") + } val apiPath = ("/account/sessions/{sessionId}" .replace("{sessionId}", sessionId) ) @@ -1854,6 +1993,7 @@ class Account(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -1904,7 +2044,7 @@ class Account(client: Client) : Service(client) { ) /** - * Use this endpoint to register a device for push notifications. Provide a target ID (custom or generated using ID.unique()), a device identifier (usually a device token), and optionally specify which provider should send notifications to this target. The target is automatically linked to the current session and includes device information like brand and model. + * Use this endpoint to register a device for push notifications. Provide a target ID (custom or generated using ID.unique()), a device identifier (usually a device token), and optionally specify which provider should send notifications to this target. The target is automatically linked to the current session and includes device information like brand and model. A session holds one push target per provider, so if one already exists this endpoint updates and returns that target instead of creating a second one, and a device that rotates its token is never notified twice. * * @param targetId Target ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. * @param identifier The target identifier (token, email, phone etc.) @@ -1953,6 +2093,9 @@ class Account(client: Client) : Service(client) { targetId: String, identifier: String, ): io.appwrite.models.Target { + if (targetId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"targetId\"") + } val apiPath = ("/account/targets/{targetId}/push" .replace("{targetId}", targetId) ) @@ -1987,6 +2130,9 @@ class Account(client: Client) : Service(client) { suspend fun deletePushTarget( targetId: String, ): Any { + if (targetId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"targetId\"") + } val apiPath = ("/account/targets/{targetId}/push" .replace("{targetId}", targetId) ) @@ -1994,6 +2140,7 @@ class Account(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -2096,9 +2243,11 @@ class Account(client: Client) : Service(client) { * * If authentication succeeds, `userId` and `secret` of a token will be appended to the success URL as query parameters. These can be used to create a new session using the [Create session](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint. * + * If there is already an active session, the OAuth2 identity is attached to the logged-in account and that session stays active until the token is exchanged for a new one. + * * A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits). * - * @param provider OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. + * @param provider OAuth2 Provider. Currently, supported providers are: amazon, apple, appwrite, auth0, authentik, autodesk, bitbucket, bitly, box, cloudflare, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, fusionauth, github, gitlab, google, huggingface, kakao, keycloak, kick, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, resend, salesforce, slack, spotify, stripe, tiktok, tradeshift, tradeshiftBox, twitch, wordpress, x, yahoo, yammer, yandex, zoho, zoom. * @param success URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param failure URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project's platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API. * @param scopes A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of 100 scopes are allowed, each 4096 characters long. @@ -2351,6 +2500,78 @@ class Account(client: Client) : Service(client) { ) } + /** + * Use this endpoint to send a 6-digit verification code to the currently logged in user's email address. Unlike [createEmailVerification](https://appwrite.io/docs/references/cloud/client-web/account#createEmailVerification), this method requires no redirect URL, which makes it suitable for mobile and desktop apps that cannot host a verification page. Learn more about how to [complete the verification process](https://appwrite.io/docs/references/cloud/client-web/account#updateEmailVerificationOTP). The code sent to the user's email address is valid for 15 minutes. + * + * Enable the **phrase** parameter to include a randomly generated security phrase in both the email and the response. Showing that phrase in your app lets the user confirm the email genuinely came from your request, which helps protect against phishing. + * + * + * @param phrase Toggle for security phrase. If enabled, email will be sent with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow. + * @return [io.appwrite.models.Token] + */ + @JvmOverloads + suspend fun createEmailVerificationOTP( + phrase: Boolean? = null, + ): io.appwrite.models.Token { + val apiPath = "/account/verifications/email/otp" + val apiParams = mutableMapOf( + "phrase" to phrase, + ) + val apiHeaders = mutableMapOf( + "X-Appwrite-Project" to client.config["project"].orEmpty(), + "content-type" to "application/json", + "accept" to "application/json", + ) + val converter: (Any) -> io.appwrite.models.Token = { + @Suppress("UNCHECKED_CAST") + io.appwrite.models.Token.from(map = it as Map) + } + return client.call( + "POST", + apiPath, + apiHeaders, + apiParams, + responseType = io.appwrite.models.Token::class.java, + converter, + ) + } + + /** + * Use this endpoint to complete the user email verification process using the 6-digit code that was emailed by [createEmailVerificationOTP](https://appwrite.io/docs/references/cloud/client-web/account#createEmailVerificationOTP). Pass the **userId** of the user being verified along with the **secret** code from the email. If confirmed, this route will return a 200 status code and the code is consumed. + * + * + * @param userId User ID. + * @param secret Valid verification OTP code. + * @return [io.appwrite.models.Token] + */ + suspend fun updateEmailVerificationOTP( + userId: String, + secret: String, + ): io.appwrite.models.Token { + val apiPath = "/account/verifications/email/otp" + val apiParams = mutableMapOf( + "userId" to userId, + "secret" to secret, + ) + val apiHeaders = mutableMapOf( + "X-Appwrite-Project" to client.config["project"].orEmpty(), + "content-type" to "application/json", + "accept" to "application/json", + ) + val converter: (Any) -> io.appwrite.models.Token = { + @Suppress("UNCHECKED_CAST") + io.appwrite.models.Token.from(map = it as Map) + } + return client.call( + "PUT", + apiPath, + apiHeaders, + apiParams, + responseType = io.appwrite.models.Token::class.java, + converter, + ) + } + /** * Use this endpoint to send a verification SMS to the currently logged in user. This endpoint is meant for use after updating a user's phone number using the [accountUpdatePhone](https://appwrite.io/docs/references/cloud/client-web/account#updatePhone) endpoint. Learn more about how to [complete the verification process](https://appwrite.io/docs/references/cloud/client-web/account#updatePhoneVerification). The verification code sent to the user's phone number is valid for 15 minutes. * diff --git a/library/src/main/java/io/appwrite/services/Databases.kt b/library/src/main/java/io/appwrite/services/Databases.kt index a1dda292..fcc85678 100644 --- a/library/src/main/java/io/appwrite/services/Databases.kt +++ b/library/src/main/java/io/appwrite/services/Databases.kt @@ -98,6 +98,9 @@ class Databases(client: Client) : Service(client) { suspend fun getTransaction( transactionId: String, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/databases/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -138,6 +141,9 @@ class Databases(client: Client) : Service(client) { commit: Boolean? = null, rollback: Boolean? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/databases/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -177,6 +183,9 @@ class Databases(client: Client) : Service(client) { suspend fun deleteTransaction( transactionId: String, ): Any { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/databases/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -184,6 +193,7 @@ class Databases(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -210,6 +220,9 @@ class Databases(client: Client) : Service(client) { transactionId: String, operations: List>? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/databases/transactions/{transactionId}/operations" .replace("{transactionId}", transactionId) ) @@ -260,6 +273,12 @@ class Databases(client: Client) : Service(client) { ttl: Long? = null, nestedType: Class, ): io.appwrite.models.DocumentList { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -347,6 +366,12 @@ class Databases(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -433,6 +458,15 @@ class Databases(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -516,6 +550,15 @@ class Databases(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -604,6 +647,15 @@ class Databases(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -687,6 +739,15 @@ class Databases(client: Client) : Service(client) { documentId: String, transactionId: String? = null, ): Any { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -698,6 +759,7 @@ class Databases(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -735,6 +797,18 @@ class Databases(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } + if (attribute.isEmpty()) { + throw AppwriteException("Missing required parameter: \"attribute\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/decrement" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -829,6 +903,18 @@ class Databases(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } + if (attribute.isEmpty()) { + throw AppwriteException("Missing required parameter: \"attribute\"") + } val apiPath = ("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/increment" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) diff --git a/library/src/main/java/io/appwrite/services/DocumentsDB.kt b/library/src/main/java/io/appwrite/services/DocumentsDB.kt index 28646d98..fb7cd720 100644 --- a/library/src/main/java/io/appwrite/services/DocumentsDB.kt +++ b/library/src/main/java/io/appwrite/services/DocumentsDB.kt @@ -86,6 +86,9 @@ class DocumentsDB(client: Client) : Service(client) { suspend fun getTransaction( transactionId: String, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/documentsdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -122,6 +125,9 @@ class DocumentsDB(client: Client) : Service(client) { commit: Boolean? = null, rollback: Boolean? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/documentsdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -157,6 +163,9 @@ class DocumentsDB(client: Client) : Service(client) { suspend fun deleteTransaction( transactionId: String, ): Any { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/documentsdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -164,6 +173,7 @@ class DocumentsDB(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -186,6 +196,9 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String, operations: List>? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/documentsdb/transactions/{transactionId}/operations" .replace("{transactionId}", transactionId) ) @@ -232,6 +245,12 @@ class DocumentsDB(client: Client) : Service(client) { ttl: Long? = null, nestedType: Class, ): io.appwrite.models.DocumentList { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -311,6 +330,12 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -387,6 +412,12 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.DocumentList { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -457,6 +488,15 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -532,6 +572,15 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -612,6 +661,15 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -687,6 +745,15 @@ class DocumentsDB(client: Client) : Service(client) { documentId: String, transactionId: String? = null, ): Any { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -698,6 +765,7 @@ class DocumentsDB(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -731,6 +799,18 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } + if (attribute.isEmpty()) { + throw AppwriteException("Missing required parameter: \"attribute\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/decrement" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -817,6 +897,18 @@ class DocumentsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } + if (attribute.isEmpty()) { + throw AppwriteException("Missing required parameter: \"attribute\"") + } val apiPath = ("/documentsdb/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/increment" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) diff --git a/library/src/main/java/io/appwrite/services/Functions.kt b/library/src/main/java/io/appwrite/services/Functions.kt index b6da2d17..57821693 100644 --- a/library/src/main/java/io/appwrite/services/Functions.kt +++ b/library/src/main/java/io/appwrite/services/Functions.kt @@ -26,6 +26,9 @@ class Functions(client: Client) : Service(client) { queries: List? = null, total: Boolean? = null, ): io.appwrite.models.ExecutionList { + if (functionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"functionId\"") + } val apiPath = ("/functions/{functionId}/executions" .replace("{functionId}", functionId) ) @@ -73,6 +76,9 @@ class Functions(client: Client) : Service(client) { headers: Map? = null, scheduledAt: String? = null, ): io.appwrite.models.Execution { + if (functionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"functionId\"") + } val apiPath = ("/functions/{functionId}/executions" .replace("{functionId}", functionId) ) @@ -114,6 +120,12 @@ class Functions(client: Client) : Service(client) { functionId: String, executionId: String, ): io.appwrite.models.Execution { + if (functionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"functionId\"") + } + if (executionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"executionId\"") + } val apiPath = ("/functions/{functionId}/executions/{executionId}" .replace("{functionId}", functionId) .replace("{executionId}", executionId) diff --git a/library/src/main/java/io/appwrite/services/Messaging.kt b/library/src/main/java/io/appwrite/services/Messaging.kt index 85b03fb2..0e816f78 100644 --- a/library/src/main/java/io/appwrite/services/Messaging.kt +++ b/library/src/main/java/io/appwrite/services/Messaging.kt @@ -25,6 +25,9 @@ class Messaging(client: Client) : Service(client) { subscriberId: String, targetId: String, ): io.appwrite.models.Subscriber { + if (topicId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"topicId\"") + } val apiPath = ("/messaging/topics/{topicId}/subscribers" .replace("{topicId}", topicId) ) @@ -62,6 +65,12 @@ class Messaging(client: Client) : Service(client) { topicId: String, subscriberId: String, ): Any { + if (topicId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"topicId\"") + } + if (subscriberId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"subscriberId\"") + } val apiPath = ("/messaging/topics/{topicId}/subscribers/{subscriberId}" .replace("{topicId}", topicId) .replace("{subscriberId}", subscriberId) @@ -70,6 +79,7 @@ class Messaging(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", diff --git a/library/src/main/java/io/appwrite/services/Organization.kt b/library/src/main/java/io/appwrite/services/Organization.kt index 64b343c2..264a356e 100644 --- a/library/src/main/java/io/appwrite/services/Organization.kt +++ b/library/src/main/java/io/appwrite/services/Organization.kt @@ -92,6 +92,9 @@ class Organization(client: Client) : Service(client) { suspend fun getInstallation( installationId: String, ): io.appwrite.models.AppInstallation { + if (installationId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"installationId\"") + } val apiPath = ("/organization/installations/{installationId}" .replace("{installationId}", installationId) ) @@ -126,6 +129,9 @@ class Organization(client: Client) : Service(client) { installationId: String, authorizationDetails: String? = null, ): io.appwrite.models.AppInstallation { + if (installationId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"installationId\"") + } val apiPath = ("/organization/installations/{installationId}" .replace("{installationId}", installationId) ) @@ -160,6 +166,9 @@ class Organization(client: Client) : Service(client) { suspend fun deleteInstallation( installationId: String, ): Any { + if (installationId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"installationId\"") + } val apiPath = ("/organization/installations/{installationId}" .replace("{installationId}", installationId) ) diff --git a/library/src/main/java/io/appwrite/services/Presences.kt b/library/src/main/java/io/appwrite/services/Presences.kt index 1d22d96d..a28448e4 100644 --- a/library/src/main/java/io/appwrite/services/Presences.kt +++ b/library/src/main/java/io/appwrite/services/Presences.kt @@ -61,6 +61,9 @@ class Presences(client: Client) : Service(client) { suspend fun get( presenceId: String, ): io.appwrite.models.Presence { + if (presenceId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"presenceId\"") + } val apiPath = ("/presences/{presenceId}" .replace("{presenceId}", presenceId) ) @@ -102,6 +105,9 @@ class Presences(client: Client) : Service(client) { expiresAt: String? = null, metadata: Map? = null, ): io.appwrite.models.Presence { + if (presenceId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"presenceId\"") + } val apiPath = ("/presences/{presenceId}" .replace("{presenceId}", presenceId) ) @@ -151,6 +157,9 @@ class Presences(client: Client) : Service(client) { permissions: List? = null, purge: Boolean? = null, ): io.appwrite.models.Presence { + if (presenceId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"presenceId\"") + } val apiPath = ("/presences/{presenceId}" .replace("{presenceId}", presenceId) ) @@ -190,6 +199,9 @@ class Presences(client: Client) : Service(client) { suspend fun delete( presenceId: String, ): Any { + if (presenceId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"presenceId\"") + } val apiPath = ("/presences/{presenceId}" .replace("{presenceId}", presenceId) ) @@ -197,6 +209,7 @@ class Presences(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", diff --git a/library/src/main/java/io/appwrite/services/Storage.kt b/library/src/main/java/io/appwrite/services/Storage.kt index 7c38e0fa..cc4f8608 100644 --- a/library/src/main/java/io/appwrite/services/Storage.kt +++ b/library/src/main/java/io/appwrite/services/Storage.kt @@ -30,6 +30,9 @@ class Storage(client: Client) : Service(client) { search: String? = null, total: Boolean? = null, ): io.appwrite.models.FileList { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files" .replace("{bucketId}", bucketId) ) @@ -82,6 +85,9 @@ class Storage(client: Client) : Service(client) { folder: String? = null, onProgress: ((UploadProgress) -> Unit)? = null ): io.appwrite.models.File { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files" .replace("{bucketId}", bucketId) ) @@ -125,6 +131,12 @@ class Storage(client: Client) : Service(client) { bucketId: String, fileId: String, ): io.appwrite.models.File { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } + if (fileId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"fileId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files/{fileId}" .replace("{bucketId}", bucketId) .replace("{fileId}", fileId) @@ -164,6 +176,12 @@ class Storage(client: Client) : Service(client) { name: String? = null, permissions: List? = null, ): io.appwrite.models.File { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } + if (fileId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"fileId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files/{fileId}" .replace("{bucketId}", bucketId) .replace("{fileId}", fileId) @@ -202,6 +220,12 @@ class Storage(client: Client) : Service(client) { bucketId: String, fileId: String, ): Any { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } + if (fileId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"fileId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files/{fileId}" .replace("{bucketId}", bucketId) .replace("{fileId}", fileId) @@ -210,6 +234,7 @@ class Storage(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -234,6 +259,12 @@ class Storage(client: Client) : Service(client) { fileId: String, token: String? = null, ): ByteArray { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } + if (fileId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"fileId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files/{fileId}/download" .replace("{bucketId}", bucketId) .replace("{fileId}", fileId) @@ -290,6 +321,12 @@ class Storage(client: Client) : Service(client) { output: io.appwrite.enums.ImageFormat? = null, token: String? = null, ): ByteArray { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } + if (fileId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"fileId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files/{fileId}/preview" .replace("{bucketId}", bucketId) .replace("{fileId}", fileId) @@ -335,6 +372,12 @@ class Storage(client: Client) : Service(client) { fileId: String, token: String? = null, ): ByteArray { + if (bucketId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"bucketId\"") + } + if (fileId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"fileId\"") + } val apiPath = ("/storage/buckets/{bucketId}/files/{fileId}/view" .replace("{bucketId}", bucketId) .replace("{fileId}", fileId) diff --git a/library/src/main/java/io/appwrite/services/TablesDB.kt b/library/src/main/java/io/appwrite/services/TablesDB.kt index 0c7554ad..7a8881df 100644 --- a/library/src/main/java/io/appwrite/services/TablesDB.kt +++ b/library/src/main/java/io/appwrite/services/TablesDB.kt @@ -86,6 +86,9 @@ class TablesDB(client: Client) : Service(client) { suspend fun getTransaction( transactionId: String, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/tablesdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -122,6 +125,9 @@ class TablesDB(client: Client) : Service(client) { commit: Boolean? = null, rollback: Boolean? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/tablesdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -157,6 +163,9 @@ class TablesDB(client: Client) : Service(client) { suspend fun deleteTransaction( transactionId: String, ): Any { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/tablesdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -164,6 +173,7 @@ class TablesDB(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -186,6 +196,9 @@ class TablesDB(client: Client) : Service(client) { transactionId: String, operations: List>? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/tablesdb/transactions/{transactionId}/operations" .replace("{transactionId}", transactionId) ) @@ -232,6 +245,12 @@ class TablesDB(client: Client) : Service(client) { ttl: Long? = null, nestedType: Class, ): io.appwrite.models.RowList { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) @@ -311,6 +330,12 @@ class TablesDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Row { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) @@ -389,6 +414,15 @@ class TablesDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Row { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } + if (rowId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"rowId\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) @@ -464,6 +498,15 @@ class TablesDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Row { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } + if (rowId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"rowId\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) @@ -544,6 +587,15 @@ class TablesDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Row { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } + if (rowId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"rowId\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) @@ -619,6 +671,15 @@ class TablesDB(client: Client) : Service(client) { rowId: String, transactionId: String? = null, ): Any { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } + if (rowId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"rowId\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) @@ -630,6 +691,7 @@ class TablesDB(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -663,6 +725,18 @@ class TablesDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Row { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } + if (rowId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"rowId\"") + } + if (column.isEmpty()) { + throw AppwriteException("Missing required parameter: \"column\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}/{column}/decrement" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) @@ -749,6 +823,18 @@ class TablesDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Row { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (tableId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"tableId\"") + } + if (rowId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"rowId\"") + } + if (column.isEmpty()) { + throw AppwriteException("Missing required parameter: \"column\"") + } val apiPath = ("/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}/{column}/increment" .replace("{databaseId}", databaseId) .replace("{tableId}", tableId) diff --git a/library/src/main/java/io/appwrite/services/Teams.kt b/library/src/main/java/io/appwrite/services/Teams.kt index 9cf474da..7708fcca 100644 --- a/library/src/main/java/io/appwrite/services/Teams.kt +++ b/library/src/main/java/io/appwrite/services/Teams.kt @@ -143,6 +143,9 @@ class Teams(client: Client) : Service(client) { teamId: String, nestedType: Class, ): io.appwrite.models.Team { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}" .replace("{teamId}", teamId) ) @@ -191,6 +194,9 @@ class Teams(client: Client) : Service(client) { name: String, nestedType: Class, ): io.appwrite.models.Team { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}" .replace("{teamId}", teamId) ) @@ -242,6 +248,9 @@ class Teams(client: Client) : Service(client) { suspend fun delete( teamId: String, ): Any { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}" .replace("{teamId}", teamId) ) @@ -249,6 +258,7 @@ class Teams(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -273,6 +283,9 @@ class Teams(client: Client) : Service(client) { queries: List? = null, total: Boolean? = null, ): io.appwrite.models.AppInstallationList { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}/installations" .replace("{teamId}", teamId) ) @@ -312,6 +325,9 @@ class Teams(client: Client) : Service(client) { appId: String, authorizationDetails: String? = null, ): io.appwrite.models.AppInstallation { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}/installations" .replace("{teamId}", teamId) ) @@ -349,6 +365,12 @@ class Teams(client: Client) : Service(client) { teamId: String, installationId: String, ): io.appwrite.models.AppInstallation { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } + if (installationId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"installationId\"") + } val apiPath = ("/teams/{teamId}/installations/{installationId}" .replace("{teamId}", teamId) .replace("{installationId}", installationId) @@ -386,6 +408,12 @@ class Teams(client: Client) : Service(client) { installationId: String, authorizationDetails: String? = null, ): io.appwrite.models.AppInstallation { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } + if (installationId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"installationId\"") + } val apiPath = ("/teams/{teamId}/installations/{installationId}" .replace("{teamId}", teamId) .replace("{installationId}", installationId) @@ -423,6 +451,12 @@ class Teams(client: Client) : Service(client) { teamId: String, installationId: String, ): Any { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } + if (installationId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"installationId\"") + } val apiPath = ("/teams/{teamId}/installations/{installationId}" .replace("{teamId}", teamId) .replace("{installationId}", installationId) @@ -458,6 +492,9 @@ class Teams(client: Client) : Service(client) { search: String? = null, total: Boolean? = null, ): io.appwrite.models.MembershipList { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}/memberships" .replace("{teamId}", teamId) ) @@ -513,6 +550,9 @@ class Teams(client: Client) : Service(client) { url: String? = null, name: String? = null, ): io.appwrite.models.Membership { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}/memberships" .replace("{teamId}", teamId) ) @@ -554,6 +594,12 @@ class Teams(client: Client) : Service(client) { teamId: String, membershipId: String, ): io.appwrite.models.Membership { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } + if (membershipId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"membershipId\"") + } val apiPath = ("/teams/{teamId}/memberships/{membershipId}" .replace("{teamId}", teamId) .replace("{membershipId}", membershipId) @@ -591,6 +637,12 @@ class Teams(client: Client) : Service(client) { membershipId: String, roles: List, ): io.appwrite.models.Membership { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } + if (membershipId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"membershipId\"") + } val apiPath = ("/teams/{teamId}/memberships/{membershipId}" .replace("{teamId}", teamId) .replace("{membershipId}", membershipId) @@ -628,6 +680,12 @@ class Teams(client: Client) : Service(client) { teamId: String, membershipId: String, ): Any { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } + if (membershipId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"membershipId\"") + } val apiPath = ("/teams/{teamId}/memberships/{membershipId}" .replace("{teamId}", teamId) .replace("{membershipId}", membershipId) @@ -636,6 +694,7 @@ class Teams(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -664,6 +723,12 @@ class Teams(client: Client) : Service(client) { userId: String, secret: String, ): io.appwrite.models.Membership { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } + if (membershipId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"membershipId\"") + } val apiPath = ("/teams/{teamId}/memberships/{membershipId}/status" .replace("{teamId}", teamId) .replace("{membershipId}", membershipId) @@ -701,6 +766,9 @@ class Teams(client: Client) : Service(client) { teamId: String, nestedType: Class, ): io.appwrite.models.Preferences { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}/prefs" .replace("{teamId}", teamId) ) @@ -749,6 +817,9 @@ class Teams(client: Client) : Service(client) { prefs: Map, nestedType: Class, ): io.appwrite.models.Preferences { + if (teamId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"teamId\"") + } val apiPath = ("/teams/{teamId}/prefs" .replace("{teamId}", teamId) ) diff --git a/library/src/main/java/io/appwrite/services/VectorsDB.kt b/library/src/main/java/io/appwrite/services/VectorsDB.kt index 47c4d435..9fa2f291 100644 --- a/library/src/main/java/io/appwrite/services/VectorsDB.kt +++ b/library/src/main/java/io/appwrite/services/VectorsDB.kt @@ -86,6 +86,9 @@ class VectorsDB(client: Client) : Service(client) { suspend fun getTransaction( transactionId: String, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/vectorsdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -122,6 +125,9 @@ class VectorsDB(client: Client) : Service(client) { commit: Boolean? = null, rollback: Boolean? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/vectorsdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -157,6 +163,9 @@ class VectorsDB(client: Client) : Service(client) { suspend fun deleteTransaction( transactionId: String, ): Any { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/vectorsdb/transactions/{transactionId}" .replace("{transactionId}", transactionId) ) @@ -164,6 +173,7 @@ class VectorsDB(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE", @@ -186,6 +196,9 @@ class VectorsDB(client: Client) : Service(client) { transactionId: String, operations: List>? = null, ): io.appwrite.models.Transaction { + if (transactionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"transactionId\"") + } val apiPath = ("/vectorsdb/transactions/{transactionId}/operations" .replace("{transactionId}", transactionId) ) @@ -232,6 +245,12 @@ class VectorsDB(client: Client) : Service(client) { ttl: Long? = null, nestedType: Class, ): io.appwrite.models.DocumentList { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/vectorsdb/{databaseId}/collections/{collectionId}/documents" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -311,6 +330,12 @@ class VectorsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/vectorsdb/{databaseId}/collections/{collectionId}/documents" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -392,6 +417,12 @@ class VectorsDB(client: Client) : Service(client) { ttl: Long? = null, nestedType: Class, ): io.appwrite.models.DocumentList { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } val apiPath = ("/vectorsdb/{databaseId}/collections/{collectionId}/documents/query" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -471,6 +502,15 @@ class VectorsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/vectorsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -546,6 +586,15 @@ class VectorsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/vectorsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -626,6 +675,15 @@ class VectorsDB(client: Client) : Service(client) { transactionId: String? = null, nestedType: Class, ): io.appwrite.models.Document { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/vectorsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -701,6 +759,15 @@ class VectorsDB(client: Client) : Service(client) { documentId: String, transactionId: String? = null, ): Any { + if (databaseId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"databaseId\"") + } + if (collectionId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"collectionId\"") + } + if (documentId.isEmpty()) { + throw AppwriteException("Missing required parameter: \"documentId\"") + } val apiPath = ("/vectorsdb/{databaseId}/collections/{collectionId}/documents/{documentId}" .replace("{databaseId}", databaseId) .replace("{collectionId}", collectionId) @@ -712,6 +779,7 @@ class VectorsDB(client: Client) : Service(client) { val apiHeaders = mutableMapOf( "X-Appwrite-Project" to client.config["project"].orEmpty(), "content-type" to "application/json", + "accept" to "application/json", ) return client.call( "DELETE",