diff --git a/.github/workflows/sdk-build-validation.yml b/.github/workflows/sdk-build-validation.yml index 3bea2ee67b..2460e312b5 100644 --- a/.github/workflows/sdk-build-validation.yml +++ b/.github/workflows/sdk-build-validation.yml @@ -66,10 +66,13 @@ jobs: - sdk: rust platform: server + - sdk: cpp + platform: server + # Console SDKs - sdk: cli platform: console - + - sdk: web platform: console @@ -161,6 +164,15 @@ jobs: if: matrix.sdk == 'rust' uses: dtolnay/rust-toolchain@1.83.0 + - name: Setup C++ + if: matrix.sdk == 'cpp' + run: | + sudo apt-get update + sudo apt-get install -y build-essential cmake libcurl4-openssl-dev nlohmann-json3-dev libgtest-dev + git clone --depth 1 --branch 1.10.5 https://github.com/libcpr/cpr.git /tmp/cpr + cmake -S /tmp/cpr -B /tmp/cpr/build -DCPR_BUILD_TESTS=OFF -DCPR_USE_SYSTEM_CURL=ON -DCMAKE_INSTALL_PREFIX=/usr/local + sudo cmake --build /tmp/cpr/build --target install -j$(nproc) + - name: Build SDK working-directory: examples/${{ matrix.sdk }} run: | @@ -237,6 +249,11 @@ jobs: cargo build --release cargo test --lib ;; + cpp) + cmake -S . -B build -DAPPWRITE_BUILD_TESTS=ON -DCMAKE_PREFIX_PATH=/usr/local + cmake --build build -j$(nproc) + ctest --test-dir build --output-on-failure + ;; *) echo "Unknown SDK: ${{ matrix.sdk }}" exit 1 diff --git a/.gitignore b/.gitignore index bf42aae9f0..8b7fa494df 100755 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ tests/tmp # exception to the rule !examples/.gitkeep +!examples/cpp/ **/.DS_Store templates/swift/example/.build @@ -28,3 +29,11 @@ go.sum # exclude raw lock files in templates (use .twig versions instead) templates/cli/package-lock.json templates/cli/bun.lock + +# exclude demo folder +demo/ +integration_output.log +temp_master_workflow.yml +examples/*/build/ +scratch/ +rebase_todo.txt diff --git a/example.php b/example.php index accb310429..2e8c0cead6 100644 --- a/example.php +++ b/example.php @@ -26,6 +26,7 @@ use Appwrite\SDK\Language\AgentSkills; use Appwrite\SDK\Language\CursorPlugin; use Appwrite\SDK\Language\Rust; +use Appwrite\SDK\Language\Cpp; try { @@ -345,6 +346,41 @@ function configureSDK($sdk, $overrides = []) { configureSDK($sdk); $sdk->generate(__DIR__ . '/examples/rust'); } + + // C++ + if (!$requestedSdk || $requestedSdk === 'cpp') { + $sdk = new SDK(new Cpp(), new Swagger2($spec)); + configureSDK($sdk, [ + 'name' => 'cpp', + 'version' => '0.0.1', + 'platform' => $platform, + 'namespace' => 'appwrite', + 'exclude' => [ + 'services' => [ + ['name' => 'avatars'], + ['name' => 'health'], + ['name' => 'locale'], + ['name' => 'messaging'], + ['name' => 'migrations'], + ['name' => 'graphql'], + ['name' => 'vcs'], + ['name' => 'assistant'], + ['name' => 'activities'], + ['name' => 'backups'], + ['name' => 'console'], + ['name' => 'domains'], + ['name' => 'organizations'], + ['name' => 'project'], + ['name' => 'projects'], + ['name' => 'proxy'], + ['name' => 'sites'], + ['name' => 'tables_db'], + ['name' => 'tokens'], + ] + ] + ]); + $sdk->generate(__DIR__ . '/examples/cpp'); + } } catch (Exception $exception) { echo 'Error: ' . $exception->getMessage() . ' on ' . $exception->getFile() . ':' . $exception->getLine() . "\n"; diff --git a/examples/cpp/.github/workflows/autoclose.yml b/examples/cpp/.github/workflows/autoclose.yml new file mode 100755 index 0000000000..d9629e1667 --- /dev/null +++ b/examples/cpp/.github/workflows/autoclose.yml @@ -0,0 +1,12 @@ +name: Auto-close External Pull Requests + +on: + pull_request_target: + types: [opened, reopened] + +jobs: + auto_close: + if: github.head_ref != 'dev' + uses: appwrite/.github/.github/workflows/autoclose.yml@main + secrets: + GH_AUTO_CLOSE_PR_TOKEN: ${{ secrets.GH_AUTO_CLOSE_PR_TOKEN }} diff --git a/examples/cpp/.github/workflows/publish.yml b/examples/cpp/.github/workflows/publish.yml new file mode 100755 index 0000000000..b84ae2fff0 --- /dev/null +++ b/examples/cpp/.github/workflows/publish.yml @@ -0,0 +1,35 @@ +name: Publish Release + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + publish: + name: Tag and publish release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup C++ build environment + run: | + sudo apt-get update + sudo apt-get install -y build-essential cmake libcurl4-openssl-dev + + - name: Build and validate SDK + run: | + cmake -S . -B build -DAPPWRITE_BUILD_TESTS=ON + cmake --build build + ctest --test-dir build --output-on-failure + + - name: Create GitHub Release archive + run: | + git archive --format=tar.gz --prefix=reponame/ HEAD \ + > reponame-${{ github.ref_name }}.tar.gz + + - name: Upload release artifact + uses: softprops/action-gh-release@v2 + with: + files: reponame-${{ github.ref_name }}.tar.gz diff --git a/examples/cpp/.github/workflows/stale.yml b/examples/cpp/.github/workflows/stale.yml new file mode 100755 index 0000000000..5888b6156f --- /dev/null +++ b/examples/cpp/.github/workflows/stale.yml @@ -0,0 +1,9 @@ +name: Mark stale issues + +on: + schedule: + - cron: "0 0 * * *" # Midnight Runtime + +jobs: + stale: + uses: appwrite/.github/.github/workflows/stale.yml@main diff --git a/examples/cpp/CHANGELOG.md b/examples/cpp/CHANGELOG.md new file mode 100755 index 0000000000..bcac28d5be --- /dev/null +++ b/examples/cpp/CHANGELOG.md @@ -0,0 +1,568 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.0.1] - TBD + +### Added +- Initial release of Appwrite C++ SDK +- Full support for Appwrite API 1.9.1 +- Header-only library for easy integration +- Modern C++20 API with coroutine/async support via C++20 coroutines +- Built-in `Result` error handling (no exceptions required in calling code) +- File upload support with automatic chunking for large files +- Query builder (`Query::equal`, `Query::between`, geo queries, etc.) +- Permission and role management utilities +- ID generation utilities +- Comprehensive model structs with JSON serialization/deserialization +- Enum types for all API parameters +- Realtime event subscription support +- Self-signed certificate support +- Custom header support +- CMake FetchContent integration for zero-install setup + +### Services +#### Account +The Account service allows you to authenticate and manage a user account. +- `get()` - Get the currently logged in user. +- `create()` - Use this endpoint to allow a new user to register a new account in your project. After the user registration completes successfully, you can use the [/account/verfication](https://appwrite.io/docs/references/cloud/client-web/account#createVerification) route to start verifying the user email address. To allow the new user to login to their new account, you need to create a new [account session](https://appwrite.io/docs/references/cloud/client-web/account#createEmailSession). +- `updateEmail()` - Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request. +This endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password. + +- `listIdentities()` - Get the list of identities for the currently logged in user. +- `deleteIdentity()` - Delete an identity by its unique ID. +- `createJWT()` - Use this endpoint to create a JSON Web Token. You can use the resulting JWT to authenticate on behalf of the current user when working with the Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes from its creation and will be invalid if the user will logout in that time frame. +- `listLogs()` - 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. +- `updateMFA()` - Enable or disable MFA on an account. +- `createMfaAuthenticator()` - Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) method. +- `createMFAAuthenticator()` - Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) method. +- `updateMfaAuthenticator()` - Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method. +- `updateMFAAuthenticator()` - Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method. +- `deleteMfaAuthenticator()` - Delete an authenticator for a user by ID. +- `deleteMFAAuthenticator()` - Delete an authenticator for a user by ID. +- `createMfaChallenge()` - Begin the process of MFA verification after sign-in. Finish the flow with [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) method. +- `createMFAChallenge()` - Begin the process of MFA verification after sign-in. Finish the flow with [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) method. +- `updateMfaChallenge()` - Complete the MFA challenge by providing the one-time password. Finish the process of MFA verification by providing the one-time password. To begin the flow, use [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `updateMFAChallenge()` - Complete the MFA challenge by providing the one-time password. Finish the process of MFA verification by providing the one-time password. To begin the flow, use [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `listMfaFactors()` - List the factors available on the account to be used as a MFA challange. +- `listMFAFactors()` - List the factors available on the account to be used as a MFA challange. +- `getMfaRecoveryCodes()` - Get recovery codes that can be used as backup for MFA flow. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to read recovery codes. +- `getMFARecoveryCodes()` - Get recovery codes that can be used as backup for MFA flow. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to read recovery codes. +- `createMfaRecoveryCodes()` - Generate recovery codes as backup for MFA flow. It's recommended to generate and show then immediately after user successfully adds their authehticator. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `createMFARecoveryCodes()` - Generate recovery codes as backup for MFA flow. It's recommended to generate and show then immediately after user successfully adds their authehticator. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method. +- `updateMfaRecoveryCodes()` - Regenerate recovery codes that can be used as backup for MFA flow. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to regenreate recovery codes. +- `updateMFARecoveryCodes()` - Regenerate recovery codes that can be used as backup for MFA flow. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. An OTP challenge is required to regenreate recovery codes. +- `updateName()` - Update currently logged in user account name. +- `updatePassword()` - Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth, Team Invites and Magic URL, oldPassword is optional. +- `updatePhone()` - Update the currently logged in user's phone number. After updating the phone number, the phone verification status will be reset. A confirmation SMS is not sent automatically, however you can use the [POST /account/verification/phone](https://appwrite.io/docs/references/cloud/client-web/account#createPhoneVerification) endpoint to send a confirmation SMS. +- `getPrefs()` - Get the preferences as a key-value object for the currently logged in user. +- `updatePrefs()` - Update currently logged in user account preferences. The object you pass is stored as is, and replaces any previous value. The maximum allowed prefs size is 64kB and throws error if exceeded. +- `createRecovery()` - Sends the user an email with a temporary secret key for password reset. When the user clicks the confirmation link he is redirected back to your app password reset URL with the secret key and email address values attached to the URL query string. Use the query string params to submit a request to the [PUT /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#updateRecovery) endpoint to complete the process. The verification link sent to the user's email address is valid for 1 hour. +- `updateRecovery()` - Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#createRecovery) endpoint. + +Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface. +- `listSessions()` - Get the list of active sessions across different devices for the currently logged in user. +- `deleteSessions()` - Delete all sessions from the user account and remove any sessions cookies from the end client. +- `createAnonymousSession()` - Use this endpoint to allow a new user to register an anonymous account in your project. This route will also create a new session for the user. To allow the new user to convert an anonymous account to a normal account, you need to update its [email and password](https://appwrite.io/docs/references/cloud/client-web/account#updateEmail) or create an [OAuth2 session](https://appwrite.io/docs/references/cloud/client-web/account#CreateOAuth2Session). +- `createEmailPasswordSession()` - Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user. + +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). +- `updateMagicURLSession()` - 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. +- `updatePhoneSession()` - 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. +- `createSession()` - 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. +- `getSession()` - Use this endpoint to get a logged in user's session using a Session ID. Inputting 'current' will return the current session being used. +- `updateSession()` - Use this endpoint to extend a session's length. Extending a session is useful when session expiry is short. If the session was created using an OAuth provider, this endpoint refreshes the access token from the provider. +- `deleteSession()` - Logout the user. Use 'current' as the session ID to logout on this device, use a session ID to logout on another device. If you're looking to logout the user on all devices, use [Delete Sessions](https://appwrite.io/docs/references/cloud/client-web/account#deleteSessions) instead. +- `updateStatus()` - Block the currently logged in user account. Behind the scene, the user record is not deleted but permanently blocked from any access. To completely delete a user, use the Users API instead. +- `createEmailToken()` - Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes. + +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). + +- `createMagicURLToken()` - Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. + +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). + +- `createOAuth2Token()` - Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. + +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. + +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). +- `createPhoneToken()` - Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes. + +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). +- `createEmailVerification()` - Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). The verification link sent to the user's email address is valid for 7 days. + +Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface. + +- `createVerification()` - Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). The verification link sent to the user's email address is valid for 7 days. + +Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface. + +- `updateEmailVerification()` - Use this endpoint to complete the user email verification process. Use both the **userId** and **secret** parameters that were attached to your app URL to verify the user email ownership. If confirmed this route will return a 200 status code. +- `updateVerification()` - Use this endpoint to complete the user email verification process. Use both the **userId** and **secret** parameters that were attached to your app URL to verify the user email ownership. If confirmed this route will return a 200 status code. +- `createPhoneVerification()` - 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. +- `updatePhoneVerification()` - Use this endpoint to complete the user phone verification process. Use the **userId** and **secret** that were sent to your user's phone number to verify the user email ownership. If confirmed this route will return a 200 status code. + +#### Databases +The Databases service allows you to create structured collections of documents, query and filter lists of documents +- `list()` - Get a list of all databases from the current Appwrite project. You can use the search parameter to filter your results. +- `create()` - Create a new Database. + +- `listTransactions()` - List transactions across all databases. +- `createTransaction()` - Create a new transaction. +- `getTransaction()` - Get a transaction by its unique ID. +- `updateTransaction()` - Update a transaction, to either commit or roll back its operations. +- `deleteTransaction()` - Delete a transaction by its unique ID. +- `createOperations()` - Create multiple operations in a single transaction. +- `get()` - Get a database by its unique ID. This endpoint response returns a JSON object with the database metadata. +- `update()` - Update a database by its unique ID. +- `delete()` - Delete a database by its unique ID. Only API keys with with databases.write scope can delete a database. +- `listCollections()` - Get a list of all collections that belong to the provided databaseId. You can use the search parameter to filter your results. +- `createCollection()` - Create a new Collection. Before using this route, you should create a new database resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `getCollection()` - Get a collection by its unique ID. This endpoint response returns a JSON object with the collection metadata. +- `updateCollection()` - Update a collection by its unique ID. +- `deleteCollection()` - Delete a collection by its unique ID. Only users with write permissions have access to delete this resource. +- `listAttributes()` - List attributes in the collection. +- `createBooleanAttribute()` - Create a boolean attribute. + +- `updateBooleanAttribute()` - Update a boolean attribute. Changing the `default` value will not update already existing documents. +- `createDatetimeAttribute()` - Create a date time attribute according to the ISO 8601 standard. +- `updateDatetimeAttribute()` - Update a date time attribute. Changing the `default` value will not update already existing documents. +- `createEmailAttribute()` - Create an email attribute. + +- `updateEmailAttribute()` - Update an email attribute. Changing the `default` value will not update already existing documents. + +- `createEnumAttribute()` - Create an enum attribute. The `elements` param acts as a white-list of accepted values for this attribute. + +- `updateEnumAttribute()` - Update an enum attribute. Changing the `default` value will not update already existing documents. + +- `createFloatAttribute()` - Create a float attribute. Optionally, minimum and maximum values can be provided. + +- `updateFloatAttribute()` - Update a float attribute. Changing the `default` value will not update already existing documents. + +- `createIntegerAttribute()` - Create an integer attribute. Optionally, minimum and maximum values can be provided. + +- `updateIntegerAttribute()` - Update an integer attribute. Changing the `default` value will not update already existing documents. + +- `createIpAttribute()` - Create IP address attribute. + +- `updateIpAttribute()` - Update an ip attribute. Changing the `default` value will not update already existing documents. + +- `createLineAttribute()` - Create a geometric line attribute. +- `updateLineAttribute()` - Update a line attribute. Changing the `default` value will not update already existing documents. +- `createLongtextAttribute()` - Create a longtext attribute. + +- `updateLongtextAttribute()` - Update a longtext attribute. Changing the `default` value will not update already existing documents. + +- `createMediumtextAttribute()` - Create a mediumtext attribute. + +- `updateMediumtextAttribute()` - Update a mediumtext attribute. Changing the `default` value will not update already existing documents. + +- `createPointAttribute()` - Create a geometric point attribute. +- `updatePointAttribute()` - Update a point attribute. Changing the `default` value will not update already existing documents. +- `createPolygonAttribute()` - Create a geometric polygon attribute. +- `updatePolygonAttribute()` - Update a polygon attribute. Changing the `default` value will not update already existing documents. +- `createRelationshipAttribute()` - Create relationship attribute. [Learn more about relationship attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + +- `updateRelationshipAttribute()` - Update relationship attribute. [Learn more about relationship attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + +- `createStringAttribute()` - Create a string attribute. + +- `updateStringAttribute()` - Update a string attribute. Changing the `default` value will not update already existing documents. + +- `createTextAttribute()` - Create a text attribute. + +- `updateTextAttribute()` - Update a text attribute. Changing the `default` value will not update already existing documents. + +- `createUrlAttribute()` - Create a URL attribute. + +- `updateUrlAttribute()` - Update an url attribute. Changing the `default` value will not update already existing documents. + +- `createVarcharAttribute()` - Create a varchar attribute. + +- `updateVarcharAttribute()` - Update a varchar attribute. Changing the `default` value will not update already existing documents. + +- `getAttribute()` - Get attribute by ID. +- `deleteAttribute()` - Deletes an attribute. +- `listDocuments()` - Get a list of all the user's documents in a given collection. You can use the query params to filter your results. +- `createDocument()` - Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `createDocuments()` - Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `upsertDocuments()` - Create or update Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. + +- `updateDocuments()` - Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated. +- `deleteDocuments()` - Bulk delete documents using queries, if no queries are passed then all documents are deleted. +- `getDocument()` - Get a document by its unique ID. This endpoint response returns a JSON object with the document data. +- `upsertDocument()` - Create or update a Document. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. +- `updateDocument()` - Update a document by its unique ID. Using the patch method you can pass only specific fields that will get updated. +- `deleteDocument()` - Delete a document by its unique ID. +- `decrementDocumentAttribute()` - Decrement a specific attribute of a document by a given value. +- `incrementDocumentAttribute()` - Increment a specific attribute of a document by a given value. +- `listIndexes()` - List indexes in the collection. +- `createIndex()` - Creates an index on the attributes listed. Your index should include all the attributes you will query in a single request. +Attributes can be `key`, `fulltext`, and `unique`. +- `getIndex()` - Get an index by its unique ID. +- `deleteIndex()` - Delete an index. + +#### Functions +The Functions Service allows you view, create and manage your Cloud Functions. +- `list()` - Get a list of all the project's functions. You can use the query params to filter your results. +- `create()` - Create a new function. You can pass a list of [permissions](https://appwrite.io/docs/permissions) to allow different project users or team with access to execute the function using the client API. +- `listRuntimes()` - Get a list of all runtimes that are currently active on your instance. +- `listSpecifications()` - List allowed function specifications for this instance. +- `get()` - Get a function by its unique ID. +- `update()` - Update function by its unique ID. +- `delete()` - Delete a function by its unique ID. +- `updateFunctionDeployment()` - Update the function active deployment. Use this endpoint to switch the code deployment that should be used when visitor opens your function. +- `listDeployments()` - Get a list of all the function's code deployments. You can use the query params to filter your results. +- `createDeployment()` - Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID. + +This endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](https://appwrite.io/docs/functions). + +Use the "command" param to set the entrypoint used to execute your code. +- `createDuplicateDeployment()` - Create a new build for an existing function deployment. This endpoint allows you to rebuild a deployment with the updated function configuration, including its entrypoint and build commands if they have been modified. The build process will be queued and executed asynchronously. The original deployment's code will be preserved and used for the new build. +- `createTemplateDeployment()` - Create a deployment based on a template. + +Use this endpoint with combination of [listTemplates](https://appwrite.io/docs/products/functions/templates) to find the template details. +- `createVcsDeployment()` - Create a deployment when a function is connected to VCS. + +This endpoint lets you create deployment from a branch, commit, or a tag. +- `getDeployment()` - Get a function deployment by its unique ID. +- `deleteDeployment()` - Delete a code deployment by its unique ID. +- `getDeploymentDownload()` - Get a function deployment content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory. +- `updateDeploymentStatus()` - Cancel an ongoing function deployment build. If the build is already in progress, it will be stopped and marked as canceled. If the build hasn't started yet, it will be marked as canceled without executing. You cannot cancel builds that have already completed (status 'ready') or failed. The response includes the final build status and details. +- `listExecutions()` - Get a list of all the current user function execution logs. You can use the query params to filter your results. +- `createExecution()` - Trigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously. +- `getExecution()` - Get a function execution log by its unique ID. +- `deleteExecution()` - Delete a function execution by its unique ID. +- `listVariables()` - Get a list of all variables of a specific function. +- `createVariable()` - Create a new function environment variable. These variables can be accessed in the function at runtime as environment variables. +- `getVariable()` - Get a variable by its unique ID. +- `updateVariable()` - Update variable by its unique ID. +- `deleteVariable()` - Delete a variable by its unique ID. + +#### Storage +The Storage service allows you to manage your project files. +- `listBuckets()` - Get a list of all the storage buckets. You can use the query params to filter your results. +- `createBucket()` - Create a new storage bucket. +- `getBucket()` - Get a storage bucket by its unique ID. This endpoint response returns a JSON object with the storage bucket metadata. +- `updateBucket()` - Update a storage bucket by its unique ID. +- `deleteBucket()` - Delete a storage bucket by its unique ID. +- `listFiles()` - Get a list of all the user files. You can use the query params to filter your results. +- `createFile()` - Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https://appwrite.io/docs/server/storage#storageCreateBucket) API or directly from your Appwrite console. + +Larger files should be uploaded using multiple requests with the [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes. + +When the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in `x-appwrite-id` header to allow the server to know that the partial upload is for the existing file and not for a new one. + +If you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally. + +- `getFile()` - Get a file by its unique ID. This endpoint response returns a JSON object with the file metadata. +- `updateFile()` - Update a file by its unique ID. Only users with write permissions have access to update this resource. +- `deleteFile()` - Delete a file by its unique ID. Only users with write permissions have access to delete this resource. +- `getFileDownload()` - Get a file content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory. +- `getFilePreview()` - Get a file preview image. Currently, this method supports preview for image files (jpg, png, and gif), other supported formats, like pdf, docs, slides, and spreadsheets, will return the file icon image. You can also pass query string arguments for cutting and resizing your preview image. Preview is supported only for image files smaller than 10MB. +- `getFileView()` - Get a file content by its unique ID. This endpoint is similar to the download method but returns with no 'Content-Disposition: attachment' header. + +#### TablesDB + +- `list()` - Get a list of all databases from the current Appwrite project. You can use the search parameter to filter your results. +- `create()` - Create a new Database. + +- `listTransactions()` - List transactions across all databases. +- `createTransaction()` - Create a new transaction. +- `getTransaction()` - Get a transaction by its unique ID. +- `updateTransaction()` - Update a transaction, to either commit or roll back its operations. +- `deleteTransaction()` - Delete a transaction by its unique ID. +- `createOperations()` - Create multiple operations in a single transaction. +- `get()` - Get a database by its unique ID. This endpoint response returns a JSON object with the database metadata. +- `update()` - Update a database by its unique ID. +- `delete()` - Delete a database by its unique ID. Only API keys with with databases.write scope can delete a database. +- `listTables()` - Get a list of all tables that belong to the provided databaseId. You can use the search parameter to filter your results. +- `createTable()` - Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `getTable()` - Get a table by its unique ID. This endpoint response returns a JSON object with the table metadata. +- `updateTable()` - Update a table by its unique ID. +- `deleteTable()` - Delete a table by its unique ID. Only users with write permissions have access to delete this resource. +- `listColumns()` - List columns in the table. +- `createBooleanColumn()` - Create a boolean column. + +- `updateBooleanColumn()` - Update a boolean column. Changing the `default` value will not update already existing rows. +- `createDatetimeColumn()` - Create a date time column according to the ISO 8601 standard. +- `updateDatetimeColumn()` - Update a date time column. Changing the `default` value will not update already existing rows. +- `createEmailColumn()` - Create an email column. + +- `updateEmailColumn()` - Update an email column. Changing the `default` value will not update already existing rows. + +- `createEnumColumn()` - Create an enumeration column. The `elements` param acts as a white-list of accepted values for this column. +- `updateEnumColumn()` - Update an enum column. Changing the `default` value will not update already existing rows. + +- `createFloatColumn()` - Create a float column. Optionally, minimum and maximum values can be provided. + +- `updateFloatColumn()` - Update a float column. Changing the `default` value will not update already existing rows. + +- `createIntegerColumn()` - Create an integer column. Optionally, minimum and maximum values can be provided. + +- `updateIntegerColumn()` - Update an integer column. Changing the `default` value will not update already existing rows. + +- `createIpColumn()` - Create IP address column. + +- `updateIpColumn()` - Update an ip column. Changing the `default` value will not update already existing rows. + +- `createLineColumn()` - Create a geometric line column. +- `updateLineColumn()` - Update a line column. Changing the `default` value will not update already existing rows. +- `createLongtextColumn()` - Create a longtext column. + +- `updateLongtextColumn()` - Update a longtext column. Changing the `default` value will not update already existing rows. + +- `createMediumtextColumn()` - Create a mediumtext column. + +- `updateMediumtextColumn()` - Update a mediumtext column. Changing the `default` value will not update already existing rows. + +- `createPointColumn()` - Create a geometric point column. +- `updatePointColumn()` - Update a point column. Changing the `default` value will not update already existing rows. +- `createPolygonColumn()` - Create a geometric polygon column. +- `updatePolygonColumn()` - Update a polygon column. Changing the `default` value will not update already existing rows. +- `createRelationshipColumn()` - Create relationship column. [Learn more about relationship columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + +- `createStringColumn()` - Create a string column. + +- `updateStringColumn()` - Update a string column. Changing the `default` value will not update already existing rows. + +- `createTextColumn()` - Create a text column. + +- `updateTextColumn()` - Update a text column. Changing the `default` value will not update already existing rows. + +- `createUrlColumn()` - Create a URL column. + +- `updateUrlColumn()` - Update an url column. Changing the `default` value will not update already existing rows. + +- `createVarcharColumn()` - Create a varchar column. + +- `updateVarcharColumn()` - Update a varchar column. Changing the `default` value will not update already existing rows. + +- `getColumn()` - Get column by ID. +- `deleteColumn()` - Deletes a column. +- `updateRelationshipColumn()` - Update relationship column. [Learn more about relationship columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + +- `listIndexes()` - List indexes on the table. +- `createIndex()` - Creates an index on the columns listed. Your index should include all the columns you will query in a single request. +Type can be `key`, `fulltext`, or `unique`. +- `getIndex()` - Get index by ID. +- `deleteIndex()` - Delete an index. +- `listRows()` - Get a list of all the user's rows in a given table. You can use the query params to filter your results. +- `createRow()` - Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `createRows()` - Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `upsertRows()` - Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. + +- `updateRows()` - Update all rows that match your queries, if no queries are submitted then all rows are updated. You can pass only specific fields to be updated. +- `deleteRows()` - Bulk delete rows using queries, if no queries are passed then all rows are deleted. +- `getRow()` - Get a row by its unique ID. This endpoint response returns a JSON object with the row data. +- `upsertRow()` - Create or update a Row. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) API or directly from your database console. +- `updateRow()` - Update a row by its unique ID. Using the patch method you can pass only specific fields that will get updated. +- `deleteRow()` - Delete a row by its unique ID. +- `decrementRowColumn()` - Decrement a specific column of a row by a given value. +- `incrementRowColumn()` - Increment a specific column of a row by a given value. + +#### Teams +The Teams service allows you to group users of your project and to enable them to share read and write access to your project resources +- `list()` - Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results. +- `create()` - Create a new team. The user who creates the team will automatically be assigned as the owner of the team. Only the users with the owner role can invite new members, add new owners and delete or update the team. +- `get()` - Get a team by its ID. All team members have read access for this resource. +- `updateName()` - Update the team's name by its unique ID. +- `delete()` - Delete a team using its ID. Only team members with the owner role can delete the team. +- `listMemberships()` - Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console. +- `createMembership()` - Invite a new member to join your team. Provide an ID for existing users, or invite unregistered users using an email or phone number. If initiated from a Client SDK, Appwrite will send an email or sms with a link to join the team to the invited user, and an account will be created for them if one doesn't exist. If initiated from a Server SDK, the new member will be added automatically to the team. + +You only need to provide one of a user ID, email, or phone number. Appwrite will prioritize accepting the user ID > email > phone number if you provide more than one of these parameters. + +Use the `url` parameter to redirect the user from the invitation email to your app. After the user is redirected, use the [Update Team Membership Status](https://appwrite.io/docs/references/cloud/client-web/teams#updateMembershipStatus) endpoint to allow the user to accept the invitation to the team. + +Please note that to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) Appwrite will accept the only redirect URLs under the domains you have added as a platform on the Appwrite Console. + +- `getMembership()` - Get a team member by the membership unique id. All team members have read access for this resource. Hide sensitive attributes from the response by toggling membership privacy in the Console. +- `updateMembership()` - Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). + +- `deleteMembership()` - This endpoint allows a user to leave a team or for a team owner to delete the membership of any other team member. You can also use this endpoint to delete a user membership even if it is not accepted. +- `updateMembershipStatus()` - Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user. + +If the request is successful, a session for the user is automatically created. + +- `getPrefs()` - Get the team's shared preferences by its unique ID. If a preference doesn't need to be shared by all team members, prefer storing them in [user preferences](https://appwrite.io/docs/references/cloud/client-web/account#getPrefs). +- `updatePrefs()` - Update the team's preferences by its unique ID. The object you pass is stored as is and replaces any previous value. The maximum allowed prefs size is 64kB and throws an error if exceeded. + +#### Users +The Users service allows you to manage your project users. +- `list()` - Get a list of all the project's users. You can use the query params to filter your results. +- `create()` - Create a new user. +- `createArgon2User()` - Create a new user. Password provided must be hashed with the [Argon2](https://en.wikipedia.org/wiki/Argon2) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `createBcryptUser()` - Create a new user. Password provided must be hashed with the [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `listIdentities()` - Get identities for all users. +- `deleteIdentity()` - Delete an identity by its unique ID. +- `createMD5User()` - Create a new user. Password provided must be hashed with the [MD5](https://en.wikipedia.org/wiki/MD5) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `createPHPassUser()` - Create a new user. Password provided must be hashed with the [PHPass](https://www.openwall.com/phpass/) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `createScryptUser()` - Create a new user. Password provided must be hashed with the [Scrypt](https://github.com/Tarsnap/scrypt) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `createScryptModifiedUser()` - Create a new user. Password provided must be hashed with the [Scrypt Modified](https://gist.github.com/Meldiron/eecf84a0225eccb5a378d45bb27462cc) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `createSHAUser()` - Create a new user. Password provided must be hashed with the [SHA](https://en.wikipedia.org/wiki/Secure_Hash_Algorithm) algorithm. Use the [POST /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to create users with a plain text password. +- `get()` - Get a user by its unique ID. +- `delete()` - Delete a user by its unique ID, thereby releasing it's ID. Since ID is released and can be reused, all user-related resources like documents or storage files should be deleted before user deletion. If you want to keep ID reserved, use the [updateStatus](https://appwrite.io/docs/server/users#usersUpdateStatus) endpoint instead. +- `updateEmail()` - Update the user email by its unique ID. +- `updateImpersonator()` - Enable or disable whether a user can impersonate other users. When impersonation headers are used, the request runs as the target user for API behavior, while internal audit logs still attribute the action to the original impersonator and store the impersonated target details only in internal audit payload data. + +- `createJWT()` - Use this endpoint to create a JSON Web Token for user by its unique ID. You can use the resulting JWT to authenticate on behalf of the user. The JWT secret will become invalid if the session it uses gets deleted. +- `updateLabels()` - Update the user labels by its unique ID. + +Labels can be used to grant access to resources. While teams are a way for user's to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https://appwrite.io/docs/permissions) for more info. +- `listLogs()` - Get the user activity logs list by its unique ID. +- `listMemberships()` - Get the user membership list by its unique ID. +- `updateMfa()` - Enable or disable MFA on a user account. +- `updateMFA()` - Enable or disable MFA on a user account. +- `deleteMfaAuthenticator()` - Delete an authenticator app. +- `deleteMFAAuthenticator()` - Delete an authenticator app. +- `listMfaFactors()` - List the factors available on the account to be used as a MFA challange. +- `listMFAFactors()` - List the factors available on the account to be used as a MFA challange. +- `getMfaRecoveryCodes()` - Get recovery codes that can be used as backup for MFA flow by User ID. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `getMFARecoveryCodes()` - Get recovery codes that can be used as backup for MFA flow by User ID. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `updateMfaRecoveryCodes()` - Regenerate recovery codes that can be used as backup for MFA flow by User ID. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `updateMFARecoveryCodes()` - Regenerate recovery codes that can be used as backup for MFA flow by User ID. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method. +- `createMfaRecoveryCodes()` - Generate recovery codes used as backup for MFA flow for User ID. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method by client SDK. +- `createMFARecoveryCodes()` - Generate recovery codes used as backup for MFA flow for User ID. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method by client SDK. +- `updateName()` - Update the user name by its unique ID. +- `updatePassword()` - Update the user password by its unique ID. +- `updatePhone()` - Update the user phone by its unique ID. +- `getPrefs()` - Get the user preferences by its unique ID. +- `updatePrefs()` - Update the user preferences by its unique ID. The object you pass is stored as is, and replaces any previous value. The maximum allowed prefs size is 64kB and throws error if exceeded. +- `listSessions()` - Get the user sessions list by its unique ID. +- `createSession()` - Creates a session for a user. Returns an immediately usable session object. + +If you want to generate a token for a custom authentication flow, use the [POST /users/{userId}/tokens](https://appwrite.io/docs/server/users#createToken) endpoint. +- `deleteSessions()` - Delete all user's sessions by using the user's unique ID. +- `deleteSession()` - Delete a user sessions by its unique ID. +- `updateStatus()` - Update the user status by its unique ID. Use this endpoint as an alternative to deleting a user if you want to keep user's ID reserved. +- `listTargets()` - List the messaging targets that are associated with a user. +- `createTarget()` - Create a messaging target. +- `getTarget()` - Get a user's push notification target by ID. +- `updateTarget()` - Update a messaging target. +- `deleteTarget()` - Delete a messaging target. +- `createToken()` - Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT /account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. + +- `updateEmailVerification()` - Update the user email verification status by its unique ID. +- `updatePhoneVerification()` - Update the user phone verification status by its unique ID. + +#### Webhooks + +- `list()` - Get a list of all webhooks belonging to the project. You can use the query params to filter your results. +- `create()` - Create a new webhook. Use this endpoint to configure a URL that will receive events from Appwrite when specific events occur. +- `get()` - Get a webhook by its unique ID. This endpoint returns details about a specific webhook configured for a project. +- `update()` - Update a webhook by its unique ID. Use this endpoint to update the URL, events, or status of an existing webhook. +- `delete()` - Delete a webhook by its unique ID. Once deleted, the webhook will no longer receive project events. +- `updateSecret()` - Update the webhook signing key. This endpoint can be used to regenerate the signing key used to sign and validate payload deliveries for a specific webhook. + + +### Models +- `RowList` - Rows List +- `DocumentList` - Documents List +- `TableList` - Tables List +- `CollectionList` - Collections List +- `DatabaseList` - Databases List +- `IndexList` - Indexes List +- `ColumnIndexList` - Column Indexes List +- `UserList` - Users List +- `SessionList` - Sessions List +- `IdentityList` - Identities List +- `LogList` - Logs List +- `FileList` - Files List +- `BucketList` - Buckets List +- `TeamList` - Teams List +- `MembershipList` - Memberships List +- `FunctionList` - Functions List +- `RuntimeList` - Runtimes List +- `DeploymentList` - Deployments List +- `ExecutionList` - Executions List +- `WebhookList` - Webhooks List +- `VariableList` - Variables List +- `TargetList` - Target list +- `TransactionList` - Transaction List +- `SpecificationList` - Specifications List +- `Database` - Database +- `Collection` - Collection +- `AttributeList` - Attributes List +- `AttributeString` - AttributeString +- `AttributeInteger` - AttributeInteger +- `AttributeFloat` - AttributeFloat +- `AttributeBoolean` - AttributeBoolean +- `AttributeEmail` - AttributeEmail +- `AttributeEnum` - AttributeEnum +- `AttributeIp` - AttributeIP +- `AttributeUrl` - AttributeURL +- `AttributeDatetime` - AttributeDatetime +- `AttributeRelationship` - AttributeRelationship +- `AttributePoint` - AttributePoint +- `AttributeLine` - AttributeLine +- `AttributePolygon` - AttributePolygon +- `AttributeVarchar` - AttributeVarchar +- `AttributeText` - AttributeText +- `AttributeMediumtext` - AttributeMediumtext +- `AttributeLongtext` - AttributeLongtext +- `Table` - Table +- `ColumnList` - Columns List +- `ColumnString` - ColumnString +- `ColumnInteger` - ColumnInteger +- `ColumnFloat` - ColumnFloat +- `ColumnBoolean` - ColumnBoolean +- `ColumnEmail` - ColumnEmail +- `ColumnEnum` - ColumnEnum +- `ColumnIp` - ColumnIP +- `ColumnUrl` - ColumnURL +- `ColumnDatetime` - ColumnDatetime +- `ColumnRelationship` - ColumnRelationship +- `ColumnPoint` - ColumnPoint +- `ColumnLine` - ColumnLine +- `ColumnPolygon` - ColumnPolygon +- `ColumnVarchar` - ColumnVarchar +- `ColumnText` - ColumnText +- `ColumnMediumtext` - ColumnMediumtext +- `ColumnLongtext` - ColumnLongtext +- `Index` - Index +- `ColumnIndex` - Index +- `Row` - Row +- `Document` - Document +- `Log` - Log +- `User` - User +- `AlgoMd5` - AlgoMD5 +- `AlgoSha` - AlgoSHA +- `AlgoPhpass` - AlgoPHPass +- `AlgoBcrypt` - AlgoBcrypt +- `AlgoScrypt` - AlgoScrypt +- `AlgoScryptModified` - AlgoScryptModified +- `AlgoArgon2` - AlgoArgon2 +- `Preferences` - Preferences +- `Session` - Session +- `Identity` - Identity +- `Token` - Token +- `Jwt` - JWT +- `File` - File +- `Bucket` - Bucket +- `Team` - Team +- `Membership` - Membership +- `Function` - Function +- `Runtime` - Runtime +- `Deployment` - Deployment +- `Execution` - Execution +- `Webhook` - Webhook +- `Variable` - Variable +- `Headers` - Headers +- `Specification` - Specification +- `MfaChallenge` - MFA Challenge +- `MfaRecoveryCodes` - MFA Recovery Codes +- `MfaType` - MFAType +- `MfaFactors` - MFAFactors +- `Transaction` - Transaction +- `Target` - Target + +### Dependencies +- [cpr](https://github.com/libcpr/cpr) 1.10.5+ for HTTP client +- [nlohmann/json](https://github.com/nlohmann/json) 3.11.3+ for JSON serialization + +[0.0.1]: https://github.com/repoowner/sdk-for-cpp/releases/tag/0.0.1 diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt new file mode 100755 index 0000000000..3bdafa38c9 --- /dev/null +++ b/examples/cpp/CMakeLists.txt @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.14) + +project(cpp VERSION 0.0.1) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(FetchContent) + +find_package(cpr QUIET) +if(NOT cpr_FOUND) + set(CPR_USE_SYSTEM_CURL ON CACHE BOOL "" FORCE) + FetchContent_Declare(cpr + GIT_REPOSITORY https://github.com/libcpr/cpr.git + GIT_TAG 3b15fa82ea74739b574d705fea44959b58142eb8) # sync with CI Dockerfile + FetchContent_MakeAvailable(cpr) +endif() + +find_package(nlohmann_json QUIET) +if(NOT nlohmann_json_FOUND) + FetchContent_Declare(nlohmann_json + GIT_REPOSITORY https://github.com/nlohmann/json.git + GIT_TAG 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03) # sync with CI Dockerfile + FetchContent_MakeAvailable(nlohmann_json) +endif() + +# Compiler warnings +if(MSVC) + add_compile_options(/W4) +else() + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# Header-only library +add_library(${PROJECT_NAME} INTERFACE) +target_include_directories(${PROJECT_NAME} INTERFACE + $ + $ +) +target_link_libraries(${PROJECT_NAME} INTERFACE + cpr::cpr + nlohmann_json::nlohmann_json +) + +# Automated Tests +option(APPWRITE_BUILD_TESTS "Build automated tests" OFF) +option(APPWRITE_RUN_INTEGRATION "Run integration tests" OFF) +if(APPWRITE_BUILD_TESTS) + enable_testing() + find_package(GTest QUIET) + if(NOT GTest_FOUND) + FetchContent_Declare(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571) # sync with CI Dockerfile + FetchContent_MakeAvailable(googletest) + endif() + + add_executable(test_appwrite + tests/tests.cpp + tests/model_tests.cpp + ) + target_link_libraries(test_appwrite PRIVATE ${PROJECT_NAME} GTest::gtest) + + add_executable(integration_test + tests/integration.cpp + tests/integration_logic.cpp + ) + if(APPWRITE_RUN_INTEGRATION) + target_compile_definitions(integration_test PRIVATE APPWRITE_RUN_INTEGRATION) + endif() + target_link_libraries(integration_test PRIVATE ${PROJECT_NAME} nlohmann_json::nlohmann_json) + + add_test(NAME sdk_tests COMMAND test_appwrite) + add_test(NAME integration_tests COMMAND integration_test) +endif() + +# Installation +include(GNUInstallDirs) +install(DIRECTORY include/appwrite DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + diff --git a/examples/cpp/LICENSE b/examples/cpp/LICENSE new file mode 100755 index 0000000000..d49aab150c --- /dev/null +++ b/examples/cpp/LICENSE @@ -0,0 +1 @@ +test test test diff --git a/examples/cpp/README.md b/examples/cpp/README.md new file mode 100755 index 0000000000..fe4cf8f77b --- /dev/null +++ b/examples/cpp/README.md @@ -0,0 +1,148 @@ +# cpp + +**The official C++ SDK for Appwrite.** + +A production-ready, modern C++20 SDK for Appwrite, designed for game engines, IoT, and high-concurrency backend environments. + +## ✨ Features + +- **Header-Only**: Drop in via CMake FetchContent — no precompilation required. +- **Thread-Safe by Design**: Mutex-guarded configuration, per-request HTTP sessions — no state leakage. +- **Concurrent API**: Thread-pool dispatch with C++20 coroutine syntax (`co_await`). Each call runs on a background thread; `.get()` blocks until complete. True non-blocking I/O requires an async runtime (Asio/libuv), which is out of scope. +- **Result Error Model**: Errors are surfaced as values. Chainable and composable. +- **Resumable Uploads**: Automatic chunked upload with progress callbacks. +- **Realtime Support**: Pluggable `SocketBackend` for WebSocket event subscriptions. +- **Rich Query Builder**: `Query::equal`, `Query::between`, geo queries, `or_`, `and_`, `elemMatch`, and more. + +## 🚀 Installation + +### CMake (FetchContent) + +Add the following to your `CMakeLists.txt`: + +```cmake +include(FetchContent) +FetchContent_Declare( + cpp + GIT_REPOSITORY https://github.com/repoowner/sdk-for-cpp.git + GIT_TAG v0.0.1 +) +FetchContent_MakeAvailable(cpp) + +target_link_libraries(my_app PRIVATE cpp) +``` + +## 🛠 Usage + +### Initialization + +```cpp +#include + +appwrite::Client client; +client + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("5df5dec0e45d4") + .setKey("your-api-key"); +``` + +### Calling a Service + +```cpp +appwrite::services::Users users(client); + +auto result = users.list({}); +if (result) { + std::cout << "Total users: " << result->toJson()["total"] << std::endl; +} else { + std::cerr << "Error " << result.error().code() + << ": " << result.error().message() << std::endl; +} +``` + +### Async / Coroutines (C++20) + +```cpp +appwrite::Task> run(appwrite::Client& client) { + appwrite::services::Users users(client); + // Note: Task dispatches to a background thread pool. + auto result = co_await users.listAsync({}); + co_return result; +} +``` + +### Using Query Builder + +```cpp +#include + +auto queries = { + appwrite::Query::equal("status", "active"), + appwrite::Query::between("age", 18, 65), + appwrite::Query::orderDesc("$createdAt"), + appwrite::Query::limit(25), +}; +``` + +### Permissions + +```cpp +#include + +std::vector permissions = { + appwrite::Permission::read(appwrite::Role::any()), + appwrite::Permission::write(appwrite::Role::user("userId")), +}; +``` + +### Realtime Subscriptions + +```cpp +#include + +appwrite::services::Realtime realtime(client); + +auto sub = realtime.subscribe({"collections.movies.documents"}, [](auto const& event) { + std::cout << "Event: " << event.event << std::endl; + std::cout << "Data: " << event.data.dump() << std::endl; +}); + +// Clean up: +sub.unsubscribe(); +``` + +### File Uploads + +```cpp +#include + +appwrite::services::Storage storage(client); + +auto result = storage.createFile( + "bucket-id", + appwrite::Id::unique(), + appwrite::InputFile::fromPath("/path/to/file.png"), + {}, // permissions + [](appwrite::InputFile::Progress p) { + std::cout << "Progress: " << p.progress << "%" << std::endl; + } +); +``` + +## 🧪 Building & Testing + +```bash +# Build with tests enabled +cmake -S . -B build -DAPPWRITE_BUILD_TESTS=ON +cmake --build build + +# Run unit tests (GoogleTest) +ctest --test-dir build --output-on-failure + +# Run integration test against mock server +./build/integration_test +``` + +## 📄 License + +This SDK is released under the [](LICENSE). diff --git a/examples/cpp/examples/basic_usage.cpp b/examples/cpp/examples/basic_usage.cpp new file mode 100755 index 0000000000..46961fa2a4 --- /dev/null +++ b/examples/cpp/examples/basic_usage.cpp @@ -0,0 +1,96 @@ +/** + * Basic usage example for Appwrite C++ SDK + * + * Build with: + * cmake -S . -B build && cmake --build build + * ./build/basic_usage + */ +#include +#include + +int main() { + // Initialize the client + appwrite::Client client; + client + .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint + .setProject("5df5acd0d48c2") // Your project ID + .setKey("919c2d18fb5d4...a2ae413da83346ad2"); // Your secret API key + + std::cout << "🚀 Appwrite C++ SDK Example\n"; + std::cout << "Connected to: " << client.getEndpoint() << "\n"; + + // Initialize services + appwrite::services::Users users(client); + + // Create a new user + std::cout << "\n📝 Creating a new user...\n"; + auto result = users.create( + appwrite::Id::unique(), + "walter.obrien@example.com", + "+1234567890", + "password123", + "Walter O'Brien" + ); + + if (result) { + std::cout << "✅ User created successfully!\n"; + std::cout << "User: " << result->toJson().dump(2) << "\n"; + } else { + std::cout << "❌ Error " << result.error().code() + << ": " << result.error().message() << "\n"; + } + + // List users with queries + std::cout << "\n📋 Listing users...\n"; + auto listResult = users.list( + { appwrite::Query::limit(10) } + ); + + if (listResult) { + std::cout << "✅ Found " << listResult->toJson()["total"] << " users\n"; + } else { + std::cout << "❌ Error " << listResult.error().code() + << ": " << listResult.error().message() << "\n"; + } + + // Databases + std::cout << "\n🗄️ Working with databases...\n"; + appwrite::services::Databases databases(client); + auto docsResult = databases.listDocuments( + "your-database-id", + "your-collection-id", + { + appwrite::Query::limit(10), + appwrite::Query::orderDesc("$createdAt") + } + ); + if (docsResult) { + std::cout << "✅ Found " << docsResult->toJson()["total"] << " documents\n"; + } else { + std::cout << "❌ " << docsResult.error().message() << "\n"; + } + + // Storage — upload a file + std::cout << "\n📁 Uploading a file...\n"; + appwrite::services::Storage storage(client); + auto fileResult = storage.createFile( + "your-bucket-id", + appwrite::Id::unique(), + appwrite::InputFile::fromPath("path/to/your/file.png") + ); + if (fileResult) { + std::cout << "✅ File uploaded: " << fileResult->toJson()["name"] << "\n"; + } else { + std::cout << "❌ " << fileResult.error().message() << "\n"; + } + + // Query builder examples + std::cout << "\n🔍 Query builder examples:\n"; + std::cout << " equal: " << appwrite::Query::equal("status", "active") << "\n"; + std::cout << " between: " << appwrite::Query::between("age", 18, 65) << "\n"; + std::cout << " select: " << appwrite::Query::select({"name", "email"}) << "\n"; + std::cout << " limit: " << appwrite::Query::limit(25) << "\n"; + + std::cout << "\n🎉 Example complete!\n"; + return 0; +} diff --git a/examples/cpp/include/appwrite/appwrite.hpp b/examples/cpp/include/appwrite/appwrite.hpp new file mode 100644 index 0000000000..bcc673ddf5 --- /dev/null +++ b/examples/cpp/include/appwrite/appwrite.hpp @@ -0,0 +1,14 @@ +#pragma once + +/** + * Appwrite C++ SDK — single-header entry point. + * Include this file to use the full SDK. + * + * #include + * using namespace appwrite; + */ +#include "base.hpp" +#include "core.hpp" +#include "models.hpp" +#include "services.hpp" +#include "enums/enums.hpp" diff --git a/examples/cpp/include/appwrite/base.hpp b/examples/cpp/include/appwrite/base.hpp new file mode 100755 index 0000000000..5cc6d071e3 --- /dev/null +++ b/examples/cpp/include/appwrite/base.hpp @@ -0,0 +1,289 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nlohmann { + template + struct adl_serializer> { + static void to_json(json& j, const std::optional& opt) { + if (opt == std::nullopt) j = nullptr; + else j = *opt; + } + + static void from_json(const json& j, std::optional& opt) { + if (j.is_null()) opt = std::nullopt; + else opt = j.template get(); + } + }; +} + +namespace appwrite { + +/** + * @brief Base exception for all Appwrite SDK errors. + */ +class AppwriteException : public std::exception { +public: + explicit AppwriteException(std::string message, int code = 0, + std::string response = "") + : message_(std::move(message)), code_(code), response_(std::move(response)) {} + + virtual ~AppwriteException() = default; + + [[nodiscard]] virtual std::shared_ptr clone() const { + return std::make_shared(*this); + } + + [[nodiscard]] const char* what() const noexcept override { return message_.c_str(); } + [[nodiscard]] int code() const noexcept { return code_; } + [[nodiscard]] const std::string& message() const noexcept { return message_; } + [[nodiscard]] const std::string& response() const noexcept { return response_; } + +protected: + std::string message_; + int code_; + std::string response_; +}; + +class NetworkException final : public AppwriteException { +public: + explicit NetworkException(std::string message) + : AppwriteException(std::move(message), 0) {} + + [[nodiscard]] std::shared_ptr clone() const override { + return std::make_shared(*this); + } +}; + +class ServerException final : public AppwriteException { +public: + ServerException(std::string message, int code, + std::string type = "", std::string response = "") + : AppwriteException(std::move(message), code, std::move(response)) + , type_(std::move(type)) {} + + [[nodiscard]] std::shared_ptr clone() const override { + return std::make_shared(*this); + } + + [[nodiscard]] const std::string& type() const noexcept { return type_; } + +private: + std::string type_; +}; + +class DeserializationException final : public AppwriteException { +public: + explicit DeserializationException(std::string message, + std::string raw_response = "") + : AppwriteException(std::move(message), -1, std::move(raw_response)) {} + + [[nodiscard]] std::shared_ptr clone() const override { + return std::make_shared(*this); + } +}; + +using Exception = AppwriteException; + +/** + * @brief Result class to represent either a success value or an Exception. + */ +template +class Result { +public: + static Result Ok(T value) { return Result(std::move(value)); } + static Result Err(std::exception_ptr eptr) { return Result(std::move(eptr)); } + static Result Err(const AppwriteException& error) { + try { throw error; } + catch (...) { return Result(std::current_exception()); } + } + + [[nodiscard]] bool isOk() const { return std::holds_alternative(data_); } + [[nodiscard]] bool has_value() const { return isOk(); } + [[nodiscard]] bool isErr() const { return !isOk(); } + explicit operator bool() const { return isOk(); } + + const T* operator->() const { return &value(); } + T* operator->() { return &value(); } + const T& operator*() const { return value(); } + T& operator*() { return value(); } + + const T& value() const { + if (isErr()) std::rethrow_exception(std::get(data_)); + return std::get(data_); + } + + T& value() { + if (isErr()) std::rethrow_exception(std::get(data_)); + return std::get(data_); + } + + T value_or(T defaultValue) const { + if (isErr()) return defaultValue; + return std::get(data_); + } + + std::shared_ptr error() const { + if (isOk()) throw AppwriteException("Result is Ok, no error available"); + try { std::rethrow_exception(std::get(data_)); } + catch (const AppwriteException& e) { return e.clone(); } + throw AppwriteException("Unknown error"); + } + +private: + explicit Result(T value) : data_(std::move(value)) {} + explicit Result(std::exception_ptr eptr) : data_(std::move(eptr)) {} + std::variant data_; +}; + +/** + * @brief Result specialization for void return types. + * @note To inspect error details, call value() inside a try-catch block. + */ +template <> +class Result { +public: + static Result Ok() { return Result(); } + static Result Err(std::exception_ptr eptr) { return Result(std::move(eptr)); } + static Result Err(const AppwriteException& error) { + try { throw error; } + catch (...) { return Result(std::current_exception()); } + } + + [[nodiscard]] bool isOk() const { return !eptr_.has_value(); } + [[nodiscard]] bool isErr() const { return eptr_.has_value(); } + void value() const { if (isErr()) std::rethrow_exception(*eptr_); } + + explicit operator bool() const { return isOk(); } + void operator*() const { value(); } + +private: + Result() : eptr_(std::nullopt) {} + explicit Result(std::exception_ptr eptr) : eptr_(std::move(eptr)) {} + std::optional eptr_; +}; + +/** + * @brief Lightweight move-only coroutine task. + */ +template +struct Task { + struct promise_type { + Task get_return_object() { return Task{std::coroutine_handle::from_promise(*this)}; } + std::suspend_always initial_suspend() noexcept { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void unhandled_exception() { result = std::current_exception(); } + template + void return_value(V&& value) { result = std::variant(std::forward(value)); } + std::optional> result; + }; + + explicit Task(std::coroutine_handle h) : handle(h) {} + ~Task() { if (handle) handle.destroy(); } + Task(Task&& other) noexcept : handle(std::exchange(other.handle, nullptr)) {} + T get() { + if (handle && !handle.done()) handle.resume(); + if (!handle.promise().result) throw AppwriteException("Coroutine did not return a value"); + if (handle.promise().result->index() == 1) std::rethrow_exception(std::get<1>(*handle.promise().result)); + return std::move(std::get<0>(*handle.promise().result)); + } + + auto operator co_await() noexcept { + struct Awaiter { + Task task_; + bool await_ready() const noexcept { return task_.handle.done(); } + void await_suspend(std::coroutine_handle<> h) noexcept { + task_.handle.resume(); + h.resume(); + } + T await_resume() { + auto& res = *task_.handle.promise().result; + if (res.index() == 1) std::rethrow_exception(std::get<1>(res)); + return std::move(std::get<0>(res)); + } + }; + // Note: Task is move-only. After co_await, the original Task handle is null. + return Awaiter{std::move(*this)}; + } + + std::coroutine_handle handle; +}; + +template<> +struct Task { + struct promise_type { + Task get_return_object() { return Task{std::coroutine_handle::from_promise(*this)}; } + std::suspend_always initial_suspend() noexcept { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void unhandled_exception() { exception = std::current_exception(); } + void return_void() noexcept {} + std::exception_ptr exception; + }; + explicit Task(std::coroutine_handle h) : handle(h) {} + ~Task() { if (handle) handle.destroy(); } + Task(Task&& other) noexcept : handle(std::exchange(other.handle, nullptr)) {} + void get() { + if (handle && !handle.done()) handle.resume(); + if (handle.promise().exception) std::rethrow_exception(handle.promise().exception); + } + + auto operator co_await() noexcept { + struct Awaiter { + Task task_; + bool await_ready() const noexcept { return task_.handle.done(); } + void await_suspend(std::coroutine_handle<> h) noexcept { + task_.handle.resume(); + h.resume(); + } + void await_resume() { + if (task_.handle.promise().exception) std::rethrow_exception(task_.handle.promise().exception); + } + }; + // Note: Task is move-only. After co_await, the original Task handle is null. + return Awaiter{std::move(*this)}; + } + + std::coroutine_handle handle; +}; + +/** + * @brief Represents a binary response from the API. + */ +class BinaryResponse { +public: + BinaryResponse() = default; + explicit BinaryResponse(std::vector data) : data_(std::move(data)) {} + [[nodiscard]] std::span span() const { return {data_.data(), data_.size()}; } + [[nodiscard]] const std::vector& data() const { return data_; } + [[nodiscard]] size_t size() const { return data_.size(); } + [[nodiscard]] bool empty() const { return data_.empty(); } +private: + std::vector data_; +}; + + + +/** + * @brief Interface for a Realtime Socket Backend. + */ +class SocketBackend { +public: + virtual ~SocketBackend() = default; + virtual void connect(const std::string& endpoint, const std::string& project) = 0; + virtual void close() = 0; + virtual void subscribe(const std::vector& channels) = 0; + virtual void onMessage(std::function callback) = 0; + virtual void onError(std::function callback) = 0; +}; + +} // namespace appwrite diff --git a/examples/cpp/include/appwrite/client.hpp b/examples/cpp/include/appwrite/client.hpp new file mode 100755 index 0000000000..6b4f3ba276 --- /dev/null +++ b/examples/cpp/include/appwrite/client.hpp @@ -0,0 +1,581 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "base.hpp" +#include "core.hpp" + +namespace appwrite { + +/** + * @brief ThreadPoolAwaiter for yielding coroutines. + */ +struct ThreadPoolAwaiter { + std::function)> enq; + bool await_ready() const noexcept { return false; } + void await_suspend(std::coroutine_handle<> h) { enq([h] { h.resume(); }); } + void await_resume() const noexcept {} +}; + +/** + * @brief ThreadPool for asynchronous Appwrite SDK operations. + */ +class ThreadPool { +public: + explicit ThreadPool(size_t threads = 0) { + if (threads == 0) { + threads = std::max(8, std::thread::hardware_concurrency() * 2); + } + for (size_t i = 0; i < threads; ++i) { + workers_.emplace_back([this] { + while (true) { + std::function t; + { + std::unique_lock lock(mutex_); + cv_tasks_.wait(lock, [this] { return stop.load(std::memory_order_acquire) || !tasks_.empty(); }); + if (stop.load(std::memory_order_acquire) && tasks_.empty()) return; + t = std::move(tasks_.front()); + tasks_.pop(); + } + cv_space_.notify_one(); + try { t(); } catch (...) {} + } + }); + } + } + + ~ThreadPool() { + stop.store(true, std::memory_order_release); + cv_tasks_.notify_all(); + cv_space_.notify_all(); + for (auto& w : workers_) w.join(); + } + + void enqueue(std::function t) { + { + std::unique_lock lock(mutex_); + cv_space_.wait(lock, [this] { return stop.load(std::memory_order_acquire) || tasks_.size() < 1024; }); + if (stop.load(std::memory_order_acquire)) return; + tasks_.push(std::move(t)); + } + cv_tasks_.notify_one(); + } + + auto operator co_await() noexcept { + return ThreadPoolAwaiter{[this](auto f) { enqueue(std::move(f)); }}; + } + +private: + std::vector workers_; + std::queue> tasks_; + std::mutex mutex_; + std::condition_variable cv_tasks_, cv_space_; + std::atomic stop{false}; +}; + +/** + * @brief The primary entry point for all Appwrite API operations. + */ +class Client { +public: + using ProgressCallback = std::function; + + struct RetryPolicy { + int maxRetries = 3; + std::chrono::milliseconds retryDelay{500}; + }; + + struct Config { + std::string endpoint = "https://cloud.appwrite.io/v1"; + std::unordered_map headers = { + {"X-Appwrite-Response-Format", "1.9.1"}, + {"x-sdk-name", "cpp"}, + {"x-sdk-platform", "server"}, + {"x-sdk-language", "cpp"}, + {"x-sdk-version", "0.0.1"}, + }; + bool selfSigned = false; + size_t chunkSize = 5 * 1024 * 1024; + std::chrono::milliseconds timeout{10000}; + RetryPolicy retryOptions; + }; + + using ConfigPtr = std::shared_ptr; + + Client() : pool(std::make_shared()) {} + + Client(const Client&) = delete; + Client& operator=(const Client&) = delete; + + Client& setEndpoint(std::string endpoint) { + if (endpoint.find("http://") != 0 && endpoint.find("https://") != 0) { + throw AppwriteException("Invalid endpoint URL: " + endpoint); + } + auto next = *get_cfg(); + next.endpoint = std::move(endpoint); + set_cfg(std::move(next)); + return *this; + } + + [[nodiscard]] std::string getEndpoint() const { return get_cfg()->endpoint; } + [[nodiscard]] const std::unordered_map& getHeaders() const { return get_cfg()->headers; } + + Client& setProject(std::string projectId) { return addHeader("x-appwrite-project", std::move(projectId)); } + Client& setKey(std::string key) { return addHeader("x-appwrite-key", std::move(key)); } + Client& setJWT(std::string jwt) { return addHeader("x-appwrite-jwt", std::move(jwt)); } + Client& setSelfSigned(bool status) { + auto next = *get_cfg(); + next.selfSigned = status; + set_cfg(std::move(next)); + return *this; + } + + Client& addHeader(std::string k, std::string v) { + auto next = *get_cfg(); + next.headers[std::move(k)] = std::move(v); + set_cfg(std::move(next)); + return *this; + } + + Client& setTimeout(std::chrono::milliseconds timeout) { + auto next = *get_cfg(); + next.timeout = timeout; + set_cfg(std::move(next)); + return *this; + } + + // Realtime support + using SocketFactory = std::function()>; + Client& setSocketFactory(SocketFactory factory) { + socketFactory_ = std::move(factory); + return *this; + } + + [[nodiscard]] std::shared_ptr createSocket() const { + if (!socketFactory_) throw AppwriteException("Socket factory not set. Use client.setSocketFactory()."); + return socketFactory_(); + } + + [[nodiscard]] std::string getRealtimeEndpoint() const { + auto endpoint = get_cfg()->endpoint; + if (endpoint.find("https://") == 0) endpoint.replace(0, 8, "wss://"); + else if (endpoint.find("http://") == 0) endpoint.replace(0, 7, "ws://"); + return endpoint + "/realtime"; + } + + [[nodiscard]] std::string getProject() const { + auto const c = get_cfg(); + if (c->headers.contains("x-appwrite-project")) return c->headers.at("x-appwrite-project"); + return ""; + } + + // Async Requests — dispatch synchronous calls onto the thread pool. + // The returned Task is a fire-and-forget future; call .get() to block + // until the result is ready, or co_await it from another coroutine. + + Task> callVoidAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return callVoid(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + template + Task> callAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return call(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + Task> callLocationAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return callLocation(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + Task> callBytesAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return callBytes(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + template + Task> fileUploadAsync(std::string m, std::string p, std::string fk, + InputFile file, std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + ProgressCallback cb = nullptr, + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), fk=std::move(fk), + file=std::move(file), h=std::move(h), pms=std::move(pms), + cb=std::move(cb), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return fileUpload(std::move(m), std::move(p), std::move(fk), std::move(file), + std::move(h), std::move(pms), std::move(cb), token); + }); + } + + // Main send logic with retries and hardened session management + template + Result call(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, false); + verify(r); + auto j = r.text.empty() ? nlohmann::json::object() : nlohmann::json::parse(r.text); + if constexpr (std::is_same_v) { + return Result::Ok(j); + } else { + return Result::Ok(T::fromJson(j)); + } + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(DeserializationException(e.what()))); + } + } + + Result callVoid(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, false); + verify(r); + return Result::Ok(); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(DeserializationException(e.what()))); + } + } + + Result callLocation(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, true); // true = no redirect + if (r.status_code == 0) throw NetworkException(r.error.message); + if (r.status_code >= 400) { + std::string msg = "Server Error"; + std::string type = ""; + try { + auto j = nlohmann::json::parse(r.text); + if (j.contains("message")) msg = j["message"]; + if (j.contains("type")) type = j["type"]; + } catch (...) {} + throw ServerException(msg, r.status_code, std::move(type), r.text); + } + if (r.status_code >= 300 && r.status_code < 400 && r.header.contains("Location")) { + return Result::Ok(r.header["Location"]); + } + return Result::Ok(r.text); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + + Result callBytes(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, false); + verify(r); + std::vector data; + if (!r.text.empty()) { + data.assign(r.text.begin(), r.text.end()); + } + return Result::Ok(BinaryResponse(std::move(data))); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + + template + Result fileUpload(std::string m, std::string p, std::string fk, + InputFile file, std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + ProgressCallback cb = nullptr, + std::stop_token token = {}) const { + try { + auto const c = get_cfg(); + if (file.size() <= c->chunkSize) { + std::string data = file.readChunk(0, file.size()); + cpr::Session s; + init(s, *c, m, p, h, pms, false, true); + + cpr::Multipart multipart = prepareMultipart(pms); + multipart.parts.emplace_back(std::move(fk), cpr::Buffer{data.begin(), data.end(), file.filename()}); + + s.SetMultipart(multipart); + auto resp = runSession(s, m); + verify(resp); + + if (cb) { + cb(InputFile::Progress{ + .id = 0, + .progress = 100.0, + .sizeUploaded = file.size(), + .chunksTotal = 1, + .chunksUploaded = 1 + }); + } + + auto j = nlohmann::json::parse(resp.text); + if constexpr (std::is_same_v) return Result::Ok(j); + else return Result::Ok(T::fromJson(j)); + } + return upload_chunks(c, std::move(m), std::move(p), std::move(h), std::move(pms), std::move(fk), std::move(file), std::move(cb), token); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + +private: + mutable std::shared_ptr cfg_{std::make_shared()}; + mutable std::mutex cfg_mutex_; + + ConfigPtr get_cfg() const { + std::lock_guard lock(cfg_mutex_); + return cfg_; + } + void set_cfg(Config next) { + std::lock_guard lock(cfg_mutex_); + cfg_ = std::make_shared(std::move(next)); + } + + static cpr::Response send(const Config& c, std::string_view m, std::string_view p, const auto& h, const auto& pms, bool no_redir = false) { + int attempt = 0; + while (true) { + cpr::Session s; + init(s, c, m, p, h, pms, no_redir); + cpr::Response r = runSession(s, m); + if (r.status_code == 0) { + if (attempt < c.retryOptions.maxRetries) { + attempt++; + std::this_thread::sleep_for(c.retryOptions.retryDelay); + continue; + } + } + return r; + } + } + + static void init(cpr::Session& s, const Config& c, std::string_view m, std::string_view p, const auto& h, const auto& pms, bool no_redir, bool is_multipart = false) { + s.SetUrl(cpr::Url{c.endpoint + (p[0] == '/' ? "" : "/") + std::string(p)}); + s.SetVerifySsl(!c.selfSigned); + s.SetTimeout(c.timeout); + if (no_redir) s.SetRedirect(cpr::Redirect{0, false, false, cpr::PostRedirectFlags::POST_ALL}); + + cpr::Header heads; + for (auto const& [k, v] : c.headers) heads[k] = v; + for (auto const& [k, v] : h) heads[k] = v; + if (m != "GET" && !pms.empty() && !is_multipart) heads["content-type"] = "application/json"; + s.SetHeader(heads); + + if (m == "GET") { + cpr::Parameters params; + for (auto const& [k, v] : pms.items()) { + if (v.is_array()) { + for (auto const& item : v) { + if (item.is_string()) { + params.Add(cpr::Parameter(k + "[]", item.template get())); + } else { + params.Add(cpr::Parameter(k + "[]", item.dump())); + } + } + } else if (v.is_string()) { + params.Add(cpr::Parameter(k, v.template get())); + } else { + params.Add(cpr::Parameter(k, v.dump())); + } + } + s.SetParameters(params); + } else if (!pms.empty() && !is_multipart) { + s.SetBody(cpr::Body{pms.dump()}); + } + } + + static cpr::Response runSession(cpr::Session& s, std::string_view m) { + if (m == "GET") return s.Get(); + if (m == "POST") return s.Post(); + if (m == "PUT") return s.Put(); + if (m == "PATCH") return s.Patch(); + if (m == "DELETE") return s.Delete(); + throw AppwriteException("Bad method: " + std::string(m)); + } + + static cpr::Multipart prepareMultipart(const nlohmann::json& pms) { + cpr::Multipart multipart{}; + for (auto const& [key, val] : pms.items()) { + if (val.is_string()) { + multipart.parts.emplace_back(key, val.template get()); + } else if (val.is_array()) { + for (auto const& item : val) { + if (item.is_string()) { + multipart.parts.emplace_back(key + "[]", item.template get()); + } else { + multipart.parts.emplace_back(key + "[]", item.dump()); + } + } + } else { + multipart.parts.emplace_back(key, val.dump()); + } + } + return multipart; + } + + static void verify(const cpr::Response& r) { + if (r.status_code == 0) throw NetworkException(r.error.message); + if (r.status_code >= 400) { + std::string msg = r.text; // fallback: raw body (e.g. text/plain responses) + std::string type = ""; + try { + auto j = nlohmann::json::parse(r.text); + if (j.contains("message")) msg = j["message"]; + if (j.contains("type")) type = j["type"]; + } catch (...) {} + throw ServerException(msg, r.status_code, std::move(type), r.text); + } + } + + template + Result upload_chunks(ConfigPtr c, std::string m, std::string p, + const std::unordered_map& h, + const nlohmann::json& pms, const std::string& fk, + const InputFile& file, const ProgressCallback& cb, + std::stop_token token = {}) const { + try { + size_t size = file.size(), chunk_size = c->chunkSize, off = 0; + nlohmann::json last; + size_t chunksTotal = (size + chunk_size - 1) / chunk_size; + size_t chunksUploaded = 0; + std::string fileId; + + while (off < size) { + if (token.stop_requested()) throw AppwriteException("Cancelled"); + size_t end = std::min(off + chunk_size, size); + std::string chunk = file.readChunk(off, end - off); + + auto cur_h = h; + if (!fileId.empty()) cur_h["x-appwrite-id"] = fileId; + cur_h["Content-Range"] = "bytes " + std::to_string(off) + "-" + std::to_string(end - 1) + "/" + std::to_string(size); + + cpr::Session s; + init(s, *c, m, p, cur_h, pms, false, true); + + cpr::Multipart multipart = prepareMultipart(pms); + multipart.parts.emplace_back(fk, cpr::Buffer{chunk.begin(), chunk.end(), file.filename()}); + + s.SetMultipart(multipart); + auto resp = runSession(s, m); + verify(resp); + + last = nlohmann::json::parse(resp.text); + if (fileId.empty() && last.contains("$id")) fileId = last["$id"].get(); + off = end; + chunksUploaded++; + + if (cb) { + cb(InputFile::Progress{ + .id = 0, + .progress = (double)off / (double)size * 100.0, + .sizeUploaded = off, + .chunksTotal = chunksTotal, + .chunksUploaded = chunksUploaded + }); + } + } + + if constexpr (std::is_same_v) return Result::Ok(last); + else return Result::Ok(T::fromJson(last)); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + + std::shared_ptr pool; + SocketFactory socketFactory_; + + // Dispatches a synchronous callable onto the thread pool and returns a + // Task. The Task uses std::future internally, so calling .get() or + // co_await blocks the calling thread until the HTTP response arrives. + // True non-blocking I/O would require an event-loop runtime (Asio, libuv) + // which is out of scope for this SDK. The thread-pool model still provides + // concurrency — multiple async calls proceed in parallel on separate threads. + template + Task dispatchAsync(F func) const { + auto promise = std::make_shared>(); + auto future = promise->get_future(); + pool->enqueue([promise = std::move(promise), func = std::move(func)]() mutable { + try { promise->set_value(func()); } + catch (...) { promise->set_exception(std::current_exception()); } + }); + return makeResolvedTask(std::move(future)); + } + + // Builds a Task that wraps a std::future. Task::get() blocks until the + // future is ready, keeping the interface identical to a coroutine Task. + // Note: T must be a Result specialization for T::Err to be valid. + template + static Task makeResolvedTask(std::future fut) { + // Use a shared_ptr so the future survives until Task::get() is called. + auto shared = std::make_shared>(std::move(fut)); + return [](std::shared_ptr> f) -> Task { + try { + co_return f->get(); + } catch (const AppwriteException&) { + co_return T::Err(std::current_exception()); + } catch (const std::exception& e) { + co_return T::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + }(std::move(shared)); + } +}; + +} // namespace appwrite diff --git a/examples/cpp/include/appwrite/core.hpp b/examples/cpp/include/appwrite/core.hpp new file mode 100755 index 0000000000..59d20136c7 --- /dev/null +++ b/examples/cpp/include/appwrite/core.hpp @@ -0,0 +1,404 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace appwrite { + +namespace internal { + +static std::string quote(std::string_view s) { + std::string out = "\""; + for (char c : s) { + if (c == '"') out += "\\\""; + else if (c == '\\') out += "\\\\"; + else if (c == '\n') out += "\\n"; + else out += c; + } + return out + "\""; +} + +static std::string int_str(int64_t v) { return std::to_string(v); } + +static std::string dbl_str(double v) { + char buf[32]; + auto [ptr, ec] = std::to_chars(buf, buf + sizeof(buf), v); + return ec == std::errc{} ? std::string(buf, ptr) : "0"; +} + +static std::string point(double lat, double lon) { + return "[" + dbl_str(lat) + "," + dbl_str(lon) + "]"; +} + +static std::string join(const std::vector& parts) { + std::string out; + for (size_t i = 0; i < parts.size(); ++i) { + if (i) out += ','; + out += parts[i]; + } + return out; +} + +static std::vector quote_all(const std::vector& v) { + std::vector out; + out.reserve(v.size()); + for (auto const& s : v) out.push_back(quote(s)); + return out; +} + +static std::string build(std::string_view method, std::string_view attribute, const std::vector& values, bool force_values = false) { + std::string s = "{\"method\":\"" + std::string(method) + "\""; + if (!attribute.empty()) s += ",\"attribute\":" + quote(attribute); + if (!values.empty() || force_values) { + s += ",\"values\":[" + join(values) + "]"; + } + return s + "}"; +} + +} // namespace internal + +/** + * @brief Strong ID type for Appwrite resources. + */ +class Id { +public: + Id() = default; + Id(std::string value) : value_(std::move(value)) {} + Id(std::string_view value) : value_(value) {} + Id(const char* value) : value_(value) {} + + static Id custom(std::string id) { return Id(std::move(id)); } + static Id unique() { + static constexpr std::string_view hex = "0123456789abcdef"; + static std::mt19937 rng{std::random_device{}()}; + static std::uniform_int_distribution dist{0, 15}; + static std::mutex m; + std::string id(20, '0'); + std::lock_guard lock(m); + for (char& c : id) c = hex[dist(rng)]; + return Id(id); + } + + [[nodiscard]] const std::string& str() const { return value_; } + operator const std::string&() const { return value_; } + [[nodiscard]] bool operator==(const Id& other) const { return value_ == other.value_; } + [[nodiscard]] bool operator!=(const Id& other) const { return value_ != other.value_; } + +private: + std::string value_; +}; + +using ID = Id; + +class Role { +public: + static std::string any() { return "any"; } + static std::string guests() { return "guests"; } + static std::string users(const std::string& status = "") { return status.empty() ? "users" : "users/" + status; } + static std::string user(const std::string& id, const std::string& status = "") { return status.empty() ? "user:" + id : "user:" + id + "/" + status; } + static std::string team(const std::string& id, const std::string& role = "") { return role.empty() ? "team:" + id : "team:" + id + "/" + role; } + static std::string member(const std::string& id) { return "member:" + id; } + static std::string label(const std::string& name) { return "label:" + name; } +}; + +class Permission { +public: + static std::string read(const std::string& role) { return "read(\"" + role + "\")"; } + static std::string write(const std::string& role) { return "write(\"" + role + "\")"; } + static std::string create(const std::string& role) { return "create(\"" + role + "\")"; } + static std::string update(const std::string& role) { return "update(\"" + role + "\")"; } + static std::string delete_(const std::string& role) { return "delete(\"" + role + "\")"; } +}; + +/** + * @brief Fluent builder for Appwrite query filters. + */ +class Query { +public: + [[nodiscard]] static std::string equal(std::string_view attribute, std::string_view value) { return internal::build("equal", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, const char* value) { return internal::build("equal", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, int64_t value) { return internal::build("equal", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, int value) { return equal(attribute, (int64_t)value); } + [[nodiscard]] static std::string equal(std::string_view attribute, double value) { return internal::build("equal", attribute, {internal::dbl_str(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, bool value) { return internal::build("equal", attribute, {value ? "true" : "false"}); } + [[nodiscard]] static std::string equal(std::string_view attribute, const std::vector& values) { return internal::build("equal", attribute, internal::quote_all(values)); } + + [[nodiscard]] static std::string notEqual(std::string_view attribute, std::string_view value) { return internal::build("notEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, const char* value) { return internal::build("notEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, int64_t value) { return internal::build("notEqual", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, int value) { return notEqual(attribute, (int64_t)value); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, double value) { return internal::build("notEqual", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string lessThan(std::string_view attribute, std::string_view value) { return internal::build("lessThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, const char* value) { return internal::build("lessThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, int64_t value) { return internal::build("lessThan", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, int value) { return lessThan(attribute, (int64_t)value); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, double value) { return internal::build("lessThan", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, std::string_view value) { return internal::build("lessThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, const char* value) { return internal::build("lessThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, int64_t value) { return internal::build("lessThanEqual", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, int value) { return lessThanEqual(attribute, (int64_t)value); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, double value) { return internal::build("lessThanEqual", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string greaterThan(std::string_view attribute, std::string_view value) { return internal::build("greaterThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, const char* value) { return internal::build("greaterThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, int64_t value) { return internal::build("greaterThan", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, int value) { return greaterThan(attribute, (int64_t)value); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, double value) { return internal::build("greaterThan", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, std::string_view value) { return internal::build("greaterThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, const char* value) { return internal::build("greaterThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, int64_t value) { return internal::build("greaterThanEqual", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, int value) { return greaterThanEqual(attribute, (int64_t)value); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, double value) { return internal::build("greaterThanEqual", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string search(std::string_view attribute, std::string_view value) { return internal::build("search", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string search(std::string_view attribute, const char* value) { return internal::build("search", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notSearch(std::string_view attribute, std::string_view value) { return internal::build("notSearch", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notSearch(std::string_view attribute, const char* value) { return internal::build("notSearch", attribute, {internal::quote(value)}); } + + static std::string contains(std::string_view attribute, std::string_view value) { return internal::build("contains", attribute, {internal::quote(value)}); } + static std::string contains(std::string_view attribute, const char* value) { return internal::build("contains", attribute, {internal::quote(value)}); } + static std::string contains(std::string_view attribute, const std::vector& values) { return internal::build("contains", attribute, internal::quote_all(values)); } + static std::string containsAny(std::string_view attribute, const std::vector& values) { return internal::build("containsAny", attribute, internal::quote_all(values)); } + static std::string containsAll(std::string_view attribute, const std::vector& values) { return internal::build("containsAll", attribute, internal::quote_all(values)); } + static std::string notContains(std::string_view attribute, std::string_view value) { return internal::build("notContains", attribute, {internal::quote(value)}); } + static std::string notContains(std::string_view attribute, const char* value) { return internal::build("notContains", attribute, {internal::quote(value)}); } + static std::string notContains(std::string_view attribute, const std::vector& values) { return internal::build("notContains", attribute, internal::quote_all(values)); } + + static std::string between(std::string_view attribute, int64_t start, int64_t end) { return internal::build("between", attribute, {internal::int_str(start), internal::int_str(end)}); } + static std::string between(std::string_view attribute, int start, int end) { return between(attribute, (int64_t)start, (int64_t)end); } + static std::string between(std::string_view attribute, double start, double end) { return internal::build("between", attribute, {internal::dbl_str(start), internal::dbl_str(end)}); } + static std::string between(std::string_view attribute, std::string_view start, std::string_view end) { return internal::build("between", attribute, {internal::quote(start), internal::quote(end)}); } + static std::string between(std::string_view attribute, const char* start, const char* end) { return internal::build("between", attribute, {internal::quote(start), internal::quote(end)}); } + + static std::string notBetween(std::string_view attribute, int64_t start, int64_t end) { return internal::build("notBetween", attribute, {internal::int_str(start), internal::int_str(end)}); } + static std::string notBetween(std::string_view attribute, int start, int end) { return notBetween(attribute, (int64_t)start, (int64_t)end); } + static std::string notBetween(std::string_view attribute, double start, double end) { return internal::build("notBetween", attribute, {internal::dbl_str(start), internal::dbl_str(end)}); } + static std::string notBetween(std::string_view attribute, std::string_view start, std::string_view end) { return internal::build("notBetween", attribute, {internal::quote(start), internal::quote(end)}); } + static std::string notBetween(std::string_view attribute, const char* start, const char* end) { return internal::build("notBetween", attribute, {internal::quote(start), internal::quote(end)}); } + + static std::string startsWith(std::string_view attribute, std::string_view value) { return internal::build("startsWith", attribute, {internal::quote(value)}); } + static std::string startsWith(std::string_view attribute, const char* value) { return internal::build("startsWith", attribute, {internal::quote(value)}); } + static std::string notStartsWith(std::string_view attribute, std::string_view value) { return internal::build("notStartsWith", attribute, {internal::quote(value)}); } + static std::string notStartsWith(std::string_view attribute, const char* value) { return internal::build("notStartsWith", attribute, {internal::quote(value)}); } + + static std::string endsWith(std::string_view attribute, std::string_view value) { return internal::build("endsWith", attribute, {internal::quote(value)}); } + static std::string endsWith(std::string_view attribute, const char* value) { return internal::build("endsWith", attribute, {internal::quote(value)}); } + static std::string notEndsWith(std::string_view attribute, std::string_view value) { return internal::build("notEndsWith", attribute, {internal::quote(value)}); } + static std::string notEndsWith(std::string_view attribute, const char* value) { return internal::build("notEndsWith", attribute, {internal::quote(value)}); } + + static std::string regex(std::string_view attribute, std::string_view value) { return internal::build("regex", attribute, {internal::quote(value)}); } + static std::string regex(std::string_view attribute, const char* value) { return internal::build("regex", attribute, {internal::quote(value)}); } + + static std::string elemMatch(std::string_view attribute, const std::vector& queries) { + return internal::build("elemMatch", attribute, queries); + } + + [[nodiscard]] static std::string isNull(std::string_view attribute) { + return "{\"method\":\"isNull\",\"attribute\":" + internal::quote(attribute) + "}"; + } + [[nodiscard]] static std::string isNotNull(std::string_view attribute) { + return "{\"method\":\"isNotNull\",\"attribute\":" + internal::quote(attribute) + "}"; + } + + static std::string exists(const std::vector& attrs) { + return internal::build("exists", "", internal::quote_all(attrs)); + } + + static std::string notExists(const std::vector& attrs) { + return internal::build("notExists", "", internal::quote_all(attrs)); + } + + [[nodiscard]] static std::string limit(int64_t limit) { + return "{\"method\":\"limit\",\"values\":[" + std::to_string(limit) + "]}"; + } + [[nodiscard]] static std::string limit(int n) { return limit((int64_t)n); } + + [[nodiscard]] static std::string offset(int64_t offset) { + return "{\"method\":\"offset\",\"values\":[" + std::to_string(offset) + "]}"; + } + [[nodiscard]] static std::string offset(int n) { return offset((int64_t)n); } + + [[nodiscard]] static std::string cursorAfter(std::string_view documentId) { return internal::build("cursorAfter", "", {internal::quote(documentId)}); } + [[nodiscard]] static std::string cursorAfter(const char* documentId) { return internal::build("cursorAfter", "", {internal::quote(documentId)}); } + [[nodiscard]] static std::string cursorBefore(std::string_view documentId) { return internal::build("cursorBefore", "", {internal::quote(documentId)}); } + [[nodiscard]] static std::string cursorBefore(const char* documentId) { return internal::build("cursorBefore", "", {internal::quote(documentId)}); } + + [[nodiscard]] static std::string select(const std::vector& attributes) { + return internal::build("select", "", internal::quote_all(attributes)); + } + + [[nodiscard]] static std::string orderAsc(std::string_view attribute) { + return "{\"method\":\"orderAsc\",\"attribute\":" + internal::quote(attribute) + "}"; + } + [[nodiscard]] static std::string orderDesc(std::string_view attribute) { + return "{\"method\":\"orderDesc\",\"attribute\":" + internal::quote(attribute) + "}"; + } + static std::string orderRandom() { return "{\"method\":\"orderRandom\"}"; } + + // Geospatial queries - EXACT structures to match Base.php + static std::string distanceEqual(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceEqual", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string distanceEqual(std::string_view attribute, double lat1, double lon1, double lat2, double lon2, double distance) { + // values:[[[[p1],[p2]],distance,true]] — points nested inside an extra array + return internal::build("distanceEqual", attribute, { + "[[" + internal::point(lat1, lon1) + "," + internal::point(lat2, lon2) + "]," + + internal::dbl_str(distance) + ",true]" + }); + } + static std::string distanceNotEqual(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceNotEqual", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string distanceLessThan(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceLessThan", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string distanceGreaterThan(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceGreaterThan", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string intersects(std::string_view attribute, double lat, double lon) { + return internal::build("intersects", attribute, {internal::point(lat, lon)}); + } + static std::string notIntersects(std::string_view attribute, double lat, double lon) { + return internal::build("notIntersects", attribute, {internal::point(lat, lon)}); + } + static std::string crosses(std::string_view attribute, double lat, double lon) { + return internal::build("crosses", attribute, {internal::point(lat, lon)}); + } + static std::string notCrosses(std::string_view attribute, double lat, double lon) { + return internal::build("notCrosses", attribute, {internal::point(lat, lon)}); + } + static std::string overlaps(std::string_view attribute, double lat, double lon) { + return internal::build("overlaps", attribute, {internal::point(lat, lon)}); + } + static std::string notOverlaps(std::string_view attribute, double lat, double lon) { + return internal::build("notOverlaps", attribute, {internal::point(lat, lon)}); + } + static std::string touches(std::string_view attribute, double lat, double lon) { + return internal::build("touches", attribute, {internal::point(lat, lon)}); + } + static std::string notTouches(std::string_view attribute, double lat, double lon) { + return internal::build("notTouches", attribute, {internal::point(lat, lon)}); + } + + [[nodiscard]] static std::string or_(const std::vector& queries) { + return internal::build("or", "", queries); + } + [[nodiscard]] static std::string and_(const std::vector& queries) { + return internal::build("and", "", queries); + } +}; + +/** + * @brief Database field update operators. + */ +class Operator { +public: + static std::string increment(double value = 1.0) { return internal::build("increment", "", {internal::dbl_str(value)}); } + static std::string increment(double value, double max) { return internal::build("increment", "", {internal::dbl_str(value), internal::dbl_str(max)}); } + static std::string decrement(double value = 1.0) { return internal::build("decrement", "", {internal::dbl_str(value)}); } + static std::string decrement(double value, double min) { return internal::build("decrement", "", {internal::dbl_str(value), internal::dbl_str(min)}); } + static std::string multiply(double value) { return internal::build("multiply", "", {internal::dbl_str(value)}); } + static std::string multiply(double value, double max) { return internal::build("multiply", "", {internal::dbl_str(value), internal::dbl_str(max)}); } + static std::string divide(double value) { return internal::build("divide", "", {internal::dbl_str(value)}); } + static std::string divide(double value, double min) { return internal::build("divide", "", {internal::dbl_str(value), internal::dbl_str(min)}); } + static std::string modulo(double value) { return internal::build("modulo", "", {internal::dbl_str(value)}); } + static std::string power(double value) { return internal::build("power", "", {internal::dbl_str(value)}); } + static std::string power(double value, double max) { return internal::build("power", "", {internal::dbl_str(value), internal::dbl_str(max)}); } + + static std::string arrayAppend(const std::string& value) { return internal::build("arrayAppend", "", {internal::quote(value)}); } + static std::string arrayAppend(const std::vector& values) { return internal::build("arrayAppend", "", internal::quote_all(values)); } + static std::string arrayPrepend(const std::string& value) { return internal::build("arrayPrepend", "", {internal::quote(value)}); } + static std::string arrayPrepend(const std::vector& values) { return internal::build("arrayPrepend", "", internal::quote_all(values)); } + static std::string arrayInsert(int index, const std::string& value) { + return internal::build("arrayInsert", "", {std::to_string(index), internal::quote(value)}); + } + static std::string arrayRemove(const std::string& value) { return internal::build("arrayRemove", "", {internal::quote(value)}); } + static std::string arrayUnique() { return internal::build("arrayUnique", "", {}, true); } + static std::string arrayIntersect(const std::vector& values) { return internal::build("arrayIntersect", "", internal::quote_all(values)); } + static std::string arrayDiff(const std::vector& values) { return internal::build("arrayDiff", "", internal::quote_all(values)); } + static std::string arrayFilter(const std::string& method, const std::string& param) { return internal::build("arrayFilter", "", {internal::quote(method), internal::quote(param)}); } + + static std::string stringConcat(const std::string& value) { return internal::build("stringConcat", "", {internal::quote(value)}); } + static std::string stringReplace(const std::string& search, const std::string& replace) { + return internal::build("stringReplace", "", {internal::quote(search), internal::quote(replace)}); + } + + static std::string toggle() { return internal::build("toggle", "", {}, true); } + + static std::string dateAddDays(int days) { return internal::build("dateAddDays", "", {std::to_string(days)}); } + static std::string dateSubDays(int days) { return internal::build("dateSubDays", "", {std::to_string(days)}); } + static std::string dateSetNow() { return internal::build("dateSetNow", "", {}, true); } +}; + +/** + * @brief Wrapper for files to be uploaded to the Appwrite API. + */ +class InputFile { +public: + struct Progress { + size_t id; + double progress; + size_t sizeUploaded; + size_t chunksTotal; + size_t chunksUploaded; + }; + + [[nodiscard]] static InputFile fromPath(std::string path) { + std::ifstream file(path, std::ios::binary | std::ios::ate); + if (!file) throw std::runtime_error("Could not open file: " + path); + size_t size = file.tellg(); + std::string filename = std::filesystem::path(path).filename().string(); + return InputFile(std::move(path), std::move(filename), size); + } + + [[nodiscard]] const std::string& path() const { return path_; } + [[nodiscard]] const std::string& filename() const { return filename_; } + [[nodiscard]] size_t size() const { return size_; } + + [[nodiscard]] std::string readChunk(size_t offset, size_t size) const { + std::ifstream file(path_, std::ios::binary); + if (!file) throw std::runtime_error("Could not open file: " + path_); + + file.seekg(offset); + std::string buffer; + buffer.resize(size); + file.read(buffer.data(), size); + buffer.resize(file.gcount()); + return buffer; + } + + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + j["$inputFile"]["path"] = path_; + j["$inputFile"]["filename"] = filename_; + j["$inputFile"]["size"] = size_; + return j; + } + +private: + InputFile(std::string path, std::string filename, size_t size) + : path_(std::move(path)), filename_(std::move(filename)), size_(size) {} + std::string path_; + std::string filename_; + size_t size_; +}; + +} // namespace appwrite diff --git a/examples/cpp/include/appwrite/enums/enums.hpp b/examples/cpp/include/appwrite/enums/enums.hpp new file mode 100755 index 0000000000..0fd0083680 --- /dev/null +++ b/examples/cpp/include/appwrite/enums/enums.hpp @@ -0,0 +1,1480 @@ +// Enums umbrella header for the Appwrite C++ SDK +// Auto-generated — do not edit manually +#pragma once + +#include +#include +#include + +namespace appwrite { +namespace enums { + +enum class AuthenticatorType { + TOTP +}; + +inline std::string toString(AuthenticatorType value) { + switch (value) { + case AuthenticatorType :: TOTP: return "totp"; + default: throw std::invalid_argument("Unknown AuthenticatorType enum value"); + } +} + +inline AuthenticatorType authenticatorTypeFromString(const std::string& s) { + if (s == "totp") return AuthenticatorType::TOTP; + throw std::invalid_argument("Unknown AuthenticatorType value: " + s); +} + +inline void from_json(const nlohmann::json& j, AuthenticatorType& v) { + v = authenticatorTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const AuthenticatorType& v) { + j = toString(v); +} + +enum class AuthenticationFactor { + EMAIL, + PHONE, + TOTP, + RECOVERYCODE +}; + +inline std::string toString(AuthenticationFactor value) { + switch (value) { + case AuthenticationFactor :: EMAIL: return "email"; + case AuthenticationFactor :: PHONE: return "phone"; + case AuthenticationFactor :: TOTP: return "totp"; + case AuthenticationFactor :: RECOVERYCODE: return "recoverycode"; + default: throw std::invalid_argument("Unknown AuthenticationFactor enum value"); + } +} + +inline AuthenticationFactor authenticationFactorFromString(const std::string& s) { + if (s == "email") return AuthenticationFactor::EMAIL; + if (s == "phone") return AuthenticationFactor::PHONE; + if (s == "totp") return AuthenticationFactor::TOTP; + if (s == "recoverycode") return AuthenticationFactor::RECOVERYCODE; + throw std::invalid_argument("Unknown AuthenticationFactor value: " + s); +} + +inline void from_json(const nlohmann::json& j, AuthenticationFactor& v) { + v = authenticationFactorFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const AuthenticationFactor& v) { + j = toString(v); +} + +enum class OAuthProvider { + AMAZON, + APPLE, + AUTH0, + AUTHENTIK, + AUTODESK, + BITBUCKET, + BITLY, + BOX, + DAILYMOTION, + DISCORD, + DISQUS, + DROPBOX, + ETSY, + FACEBOOK, + FIGMA, + GITHUB, + GITLAB, + GOOGLE, + LINKEDIN, + MICROSOFT, + NOTION, + OIDC, + OKTA, + PAYPAL, + PAYPALSANDBOX, + PODIO, + SALESFORCE, + SLACK, + SPOTIFY, + STRIPE, + TRADESHIFT, + TRADESHIFTBOX, + TWITCH, + WORDPRESS, + X, + YAHOO, + YAMMER, + YANDEX, + ZOHO, + ZOOM +}; + +inline std::string toString(OAuthProvider value) { + switch (value) { + case OAuthProvider :: AMAZON: return "amazon"; + case OAuthProvider :: APPLE: return "apple"; + case OAuthProvider :: AUTH0: return "auth0"; + case OAuthProvider :: AUTHENTIK: return "authentik"; + case OAuthProvider :: AUTODESK: return "autodesk"; + case OAuthProvider :: BITBUCKET: return "bitbucket"; + case OAuthProvider :: BITLY: return "bitly"; + case OAuthProvider :: BOX: return "box"; + case OAuthProvider :: DAILYMOTION: return "dailymotion"; + case OAuthProvider :: DISCORD: return "discord"; + case OAuthProvider :: DISQUS: return "disqus"; + case OAuthProvider :: DROPBOX: return "dropbox"; + case OAuthProvider :: ETSY: return "etsy"; + case OAuthProvider :: FACEBOOK: return "facebook"; + case OAuthProvider :: FIGMA: return "figma"; + case OAuthProvider :: GITHUB: return "github"; + case OAuthProvider :: GITLAB: return "gitlab"; + case OAuthProvider :: GOOGLE: return "google"; + case OAuthProvider :: LINKEDIN: return "linkedin"; + case OAuthProvider :: MICROSOFT: return "microsoft"; + case OAuthProvider :: NOTION: return "notion"; + case OAuthProvider :: OIDC: return "oidc"; + case OAuthProvider :: OKTA: return "okta"; + case OAuthProvider :: PAYPAL: return "paypal"; + case OAuthProvider :: PAYPALSANDBOX: return "paypalSandbox"; + case OAuthProvider :: PODIO: return "podio"; + case OAuthProvider :: SALESFORCE: return "salesforce"; + case OAuthProvider :: SLACK: return "slack"; + case OAuthProvider :: SPOTIFY: return "spotify"; + case OAuthProvider :: STRIPE: return "stripe"; + case OAuthProvider :: TRADESHIFT: return "tradeshift"; + case OAuthProvider :: TRADESHIFTBOX: return "tradeshiftBox"; + case OAuthProvider :: TWITCH: return "twitch"; + case OAuthProvider :: WORDPRESS: return "wordpress"; + case OAuthProvider :: X: return "x"; + case OAuthProvider :: YAHOO: return "yahoo"; + case OAuthProvider :: YAMMER: return "yammer"; + case OAuthProvider :: YANDEX: return "yandex"; + case OAuthProvider :: ZOHO: return "zoho"; + case OAuthProvider :: ZOOM: return "zoom"; + default: throw std::invalid_argument("Unknown OAuthProvider enum value"); + } +} + +inline OAuthProvider oAuthProviderFromString(const std::string& s) { + if (s == "amazon") return OAuthProvider::AMAZON; + if (s == "apple") return OAuthProvider::APPLE; + if (s == "auth0") return OAuthProvider::AUTH0; + if (s == "authentik") return OAuthProvider::AUTHENTIK; + if (s == "autodesk") return OAuthProvider::AUTODESK; + if (s == "bitbucket") return OAuthProvider::BITBUCKET; + if (s == "bitly") return OAuthProvider::BITLY; + if (s == "box") return OAuthProvider::BOX; + if (s == "dailymotion") return OAuthProvider::DAILYMOTION; + if (s == "discord") return OAuthProvider::DISCORD; + if (s == "disqus") return OAuthProvider::DISQUS; + if (s == "dropbox") return OAuthProvider::DROPBOX; + if (s == "etsy") return OAuthProvider::ETSY; + if (s == "facebook") return OAuthProvider::FACEBOOK; + if (s == "figma") return OAuthProvider::FIGMA; + if (s == "github") return OAuthProvider::GITHUB; + if (s == "gitlab") return OAuthProvider::GITLAB; + if (s == "google") return OAuthProvider::GOOGLE; + if (s == "linkedin") return OAuthProvider::LINKEDIN; + if (s == "microsoft") return OAuthProvider::MICROSOFT; + if (s == "notion") return OAuthProvider::NOTION; + if (s == "oidc") return OAuthProvider::OIDC; + if (s == "okta") return OAuthProvider::OKTA; + if (s == "paypal") return OAuthProvider::PAYPAL; + if (s == "paypalSandbox") return OAuthProvider::PAYPALSANDBOX; + if (s == "podio") return OAuthProvider::PODIO; + if (s == "salesforce") return OAuthProvider::SALESFORCE; + if (s == "slack") return OAuthProvider::SLACK; + if (s == "spotify") return OAuthProvider::SPOTIFY; + if (s == "stripe") return OAuthProvider::STRIPE; + if (s == "tradeshift") return OAuthProvider::TRADESHIFT; + if (s == "tradeshiftBox") return OAuthProvider::TRADESHIFTBOX; + if (s == "twitch") return OAuthProvider::TWITCH; + if (s == "wordpress") return OAuthProvider::WORDPRESS; + if (s == "x") return OAuthProvider::X; + if (s == "yahoo") return OAuthProvider::YAHOO; + if (s == "yammer") return OAuthProvider::YAMMER; + if (s == "yandex") return OAuthProvider::YANDEX; + if (s == "zoho") return OAuthProvider::ZOHO; + if (s == "zoom") return OAuthProvider::ZOOM; + throw std::invalid_argument("Unknown OAuthProvider value: " + s); +} + +inline void from_json(const nlohmann::json& j, OAuthProvider& v) { + v = oAuthProviderFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const OAuthProvider& v) { + j = toString(v); +} + +enum class RelationshipType { + ONETOONE, + MANYTOONE, + MANYTOMANY, + ONETOMANY +}; + +inline std::string toString(RelationshipType value) { + switch (value) { + case RelationshipType :: ONETOONE: return "oneToOne"; + case RelationshipType :: MANYTOONE: return "manyToOne"; + case RelationshipType :: MANYTOMANY: return "manyToMany"; + case RelationshipType :: ONETOMANY: return "oneToMany"; + default: throw std::invalid_argument("Unknown RelationshipType enum value"); + } +} + +inline RelationshipType relationshipTypeFromString(const std::string& s) { + if (s == "oneToOne") return RelationshipType::ONETOONE; + if (s == "manyToOne") return RelationshipType::MANYTOONE; + if (s == "manyToMany") return RelationshipType::MANYTOMANY; + if (s == "oneToMany") return RelationshipType::ONETOMANY; + throw std::invalid_argument("Unknown RelationshipType value: " + s); +} + +inline void from_json(const nlohmann::json& j, RelationshipType& v) { + v = relationshipTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const RelationshipType& v) { + j = toString(v); +} + +enum class RelationMutate { + CASCADE, + RESTRICT, + SETNULL +}; + +inline std::string toString(RelationMutate value) { + switch (value) { + case RelationMutate :: CASCADE: return "cascade"; + case RelationMutate :: RESTRICT: return "restrict"; + case RelationMutate :: SETNULL: return "setNull"; + default: throw std::invalid_argument("Unknown RelationMutate enum value"); + } +} + +inline RelationMutate relationMutateFromString(const std::string& s) { + if (s == "cascade") return RelationMutate::CASCADE; + if (s == "restrict") return RelationMutate::RESTRICT; + if (s == "setNull") return RelationMutate::SETNULL; + throw std::invalid_argument("Unknown RelationMutate value: " + s); +} + +inline void from_json(const nlohmann::json& j, RelationMutate& v) { + v = relationMutateFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const RelationMutate& v) { + j = toString(v); +} + +enum class DatabasesIndexType { + KEY, + FULLTEXT, + UNIQUE, + SPATIAL +}; + +inline std::string toString(DatabasesIndexType value) { + switch (value) { + case DatabasesIndexType :: KEY: return "key"; + case DatabasesIndexType :: FULLTEXT: return "fulltext"; + case DatabasesIndexType :: UNIQUE: return "unique"; + case DatabasesIndexType :: SPATIAL: return "spatial"; + default: throw std::invalid_argument("Unknown DatabasesIndexType enum value"); + } +} + +inline DatabasesIndexType databasesIndexTypeFromString(const std::string& s) { + if (s == "key") return DatabasesIndexType::KEY; + if (s == "fulltext") return DatabasesIndexType::FULLTEXT; + if (s == "unique") return DatabasesIndexType::UNIQUE; + if (s == "spatial") return DatabasesIndexType::SPATIAL; + throw std::invalid_argument("Unknown DatabasesIndexType value: " + s); +} + +inline void from_json(const nlohmann::json& j, DatabasesIndexType& v) { + v = databasesIndexTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const DatabasesIndexType& v) { + j = toString(v); +} + +enum class OrderBy { + ASC, + DESC +}; + +inline std::string toString(OrderBy value) { + switch (value) { + case OrderBy :: ASC: return "asc"; + case OrderBy :: DESC: return "desc"; + default: throw std::invalid_argument("Unknown OrderBy enum value"); + } +} + +inline OrderBy orderByFromString(const std::string& s) { + if (s == "asc") return OrderBy::ASC; + if (s == "desc") return OrderBy::DESC; + throw std::invalid_argument("Unknown OrderBy value: " + s); +} + +inline void from_json(const nlohmann::json& j, OrderBy& v) { + v = orderByFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const OrderBy& v) { + j = toString(v); +} + +enum class Runtime { + NODE_14_5, + NODE_16_0, + NODE_18_0, + NODE_19_0, + NODE_20_0, + NODE_21_0, + NODE_22, + NODE_23, + NODE_24, + NODE_25, + PHP_8_0, + PHP_8_1, + PHP_8_2, + PHP_8_3, + PHP_8_4, + RUBY_3_0, + RUBY_3_1, + RUBY_3_2, + RUBY_3_3, + RUBY_3_4, + RUBY_4_0, + PYTHON_3_8, + PYTHON_3_9, + PYTHON_3_10, + PYTHON_3_11, + PYTHON_3_12, + PYTHON_3_13, + PYTHON_3_14, + PYTHON_ML_3_11, + PYTHON_ML_3_12, + PYTHON_ML_3_13, + DENO_1_21, + DENO_1_24, + DENO_1_35, + DENO_1_40, + DENO_1_46, + DENO_2_0, + DENO_2_5, + DENO_2_6, + DART_2_15, + DART_2_16, + DART_2_17, + DART_2_18, + DART_2_19, + DART_3_0, + DART_3_1, + DART_3_3, + DART_3_5, + DART_3_8, + DART_3_9, + DART_3_10, + DART_3_11, + DOTNET_6_0, + DOTNET_7_0, + DOTNET_8_0, + DOTNET_10, + JAVA_8_0, + JAVA_11_0, + JAVA_17_0, + JAVA_18_0, + JAVA_21_0, + JAVA_22, + JAVA_25, + SWIFT_5_5, + SWIFT_5_8, + SWIFT_5_9, + SWIFT_5_10, + SWIFT_6_2, + KOTLIN_1_6, + KOTLIN_1_8, + KOTLIN_1_9, + KOTLIN_2_0, + KOTLIN_2_3, + CPP_17, + CPP_20, + BUN_1_0, + BUN_1_1, + BUN_1_2, + BUN_1_3, + GO_1_23, + GO_1_24, + GO_1_25, + GO_1_26, + STATIC_1, + FLUTTER_3_24, + FLUTTER_3_27, + FLUTTER_3_29, + FLUTTER_3_32, + FLUTTER_3_35, + FLUTTER_3_38, + FLUTTER_3_41 +}; + +inline std::string toString(Runtime value) { + switch (value) { + case Runtime :: NODE_14_5: return "node-14.5"; + case Runtime :: NODE_16_0: return "node-16.0"; + case Runtime :: NODE_18_0: return "node-18.0"; + case Runtime :: NODE_19_0: return "node-19.0"; + case Runtime :: NODE_20_0: return "node-20.0"; + case Runtime :: NODE_21_0: return "node-21.0"; + case Runtime :: NODE_22: return "node-22"; + case Runtime :: NODE_23: return "node-23"; + case Runtime :: NODE_24: return "node-24"; + case Runtime :: NODE_25: return "node-25"; + case Runtime :: PHP_8_0: return "php-8.0"; + case Runtime :: PHP_8_1: return "php-8.1"; + case Runtime :: PHP_8_2: return "php-8.2"; + case Runtime :: PHP_8_3: return "php-8.3"; + case Runtime :: PHP_8_4: return "php-8.4"; + case Runtime :: RUBY_3_0: return "ruby-3.0"; + case Runtime :: RUBY_3_1: return "ruby-3.1"; + case Runtime :: RUBY_3_2: return "ruby-3.2"; + case Runtime :: RUBY_3_3: return "ruby-3.3"; + case Runtime :: RUBY_3_4: return "ruby-3.4"; + case Runtime :: RUBY_4_0: return "ruby-4.0"; + case Runtime :: PYTHON_3_8: return "python-3.8"; + case Runtime :: PYTHON_3_9: return "python-3.9"; + case Runtime :: PYTHON_3_10: return "python-3.10"; + case Runtime :: PYTHON_3_11: return "python-3.11"; + case Runtime :: PYTHON_3_12: return "python-3.12"; + case Runtime :: PYTHON_3_13: return "python-3.13"; + case Runtime :: PYTHON_3_14: return "python-3.14"; + case Runtime :: PYTHON_ML_3_11: return "python-ml-3.11"; + case Runtime :: PYTHON_ML_3_12: return "python-ml-3.12"; + case Runtime :: PYTHON_ML_3_13: return "python-ml-3.13"; + case Runtime :: DENO_1_21: return "deno-1.21"; + case Runtime :: DENO_1_24: return "deno-1.24"; + case Runtime :: DENO_1_35: return "deno-1.35"; + case Runtime :: DENO_1_40: return "deno-1.40"; + case Runtime :: DENO_1_46: return "deno-1.46"; + case Runtime :: DENO_2_0: return "deno-2.0"; + case Runtime :: DENO_2_5: return "deno-2.5"; + case Runtime :: DENO_2_6: return "deno-2.6"; + case Runtime :: DART_2_15: return "dart-2.15"; + case Runtime :: DART_2_16: return "dart-2.16"; + case Runtime :: DART_2_17: return "dart-2.17"; + case Runtime :: DART_2_18: return "dart-2.18"; + case Runtime :: DART_2_19: return "dart-2.19"; + case Runtime :: DART_3_0: return "dart-3.0"; + case Runtime :: DART_3_1: return "dart-3.1"; + case Runtime :: DART_3_3: return "dart-3.3"; + case Runtime :: DART_3_5: return "dart-3.5"; + case Runtime :: DART_3_8: return "dart-3.8"; + case Runtime :: DART_3_9: return "dart-3.9"; + case Runtime :: DART_3_10: return "dart-3.10"; + case Runtime :: DART_3_11: return "dart-3.11"; + case Runtime :: DOTNET_6_0: return "dotnet-6.0"; + case Runtime :: DOTNET_7_0: return "dotnet-7.0"; + case Runtime :: DOTNET_8_0: return "dotnet-8.0"; + case Runtime :: DOTNET_10: return "dotnet-10"; + case Runtime :: JAVA_8_0: return "java-8.0"; + case Runtime :: JAVA_11_0: return "java-11.0"; + case Runtime :: JAVA_17_0: return "java-17.0"; + case Runtime :: JAVA_18_0: return "java-18.0"; + case Runtime :: JAVA_21_0: return "java-21.0"; + case Runtime :: JAVA_22: return "java-22"; + case Runtime :: JAVA_25: return "java-25"; + case Runtime :: SWIFT_5_5: return "swift-5.5"; + case Runtime :: SWIFT_5_8: return "swift-5.8"; + case Runtime :: SWIFT_5_9: return "swift-5.9"; + case Runtime :: SWIFT_5_10: return "swift-5.10"; + case Runtime :: SWIFT_6_2: return "swift-6.2"; + case Runtime :: KOTLIN_1_6: return "kotlin-1.6"; + case Runtime :: KOTLIN_1_8: return "kotlin-1.8"; + case Runtime :: KOTLIN_1_9: return "kotlin-1.9"; + case Runtime :: KOTLIN_2_0: return "kotlin-2.0"; + case Runtime :: KOTLIN_2_3: return "kotlin-2.3"; + case Runtime :: CPP_17: return "cpp-17"; + case Runtime :: CPP_20: return "cpp-20"; + case Runtime :: BUN_1_0: return "bun-1.0"; + case Runtime :: BUN_1_1: return "bun-1.1"; + case Runtime :: BUN_1_2: return "bun-1.2"; + case Runtime :: BUN_1_3: return "bun-1.3"; + case Runtime :: GO_1_23: return "go-1.23"; + case Runtime :: GO_1_24: return "go-1.24"; + case Runtime :: GO_1_25: return "go-1.25"; + case Runtime :: GO_1_26: return "go-1.26"; + case Runtime :: STATIC_1: return "static-1"; + case Runtime :: FLUTTER_3_24: return "flutter-3.24"; + case Runtime :: FLUTTER_3_27: return "flutter-3.27"; + case Runtime :: FLUTTER_3_29: return "flutter-3.29"; + case Runtime :: FLUTTER_3_32: return "flutter-3.32"; + case Runtime :: FLUTTER_3_35: return "flutter-3.35"; + case Runtime :: FLUTTER_3_38: return "flutter-3.38"; + case Runtime :: FLUTTER_3_41: return "flutter-3.41"; + default: throw std::invalid_argument("Unknown Runtime enum value"); + } +} + +inline Runtime runtimeFromString(const std::string& s) { + if (s == "node-14.5") return Runtime::NODE_14_5; + if (s == "node-16.0") return Runtime::NODE_16_0; + if (s == "node-18.0") return Runtime::NODE_18_0; + if (s == "node-19.0") return Runtime::NODE_19_0; + if (s == "node-20.0") return Runtime::NODE_20_0; + if (s == "node-21.0") return Runtime::NODE_21_0; + if (s == "node-22") return Runtime::NODE_22; + if (s == "node-23") return Runtime::NODE_23; + if (s == "node-24") return Runtime::NODE_24; + if (s == "node-25") return Runtime::NODE_25; + if (s == "php-8.0") return Runtime::PHP_8_0; + if (s == "php-8.1") return Runtime::PHP_8_1; + if (s == "php-8.2") return Runtime::PHP_8_2; + if (s == "php-8.3") return Runtime::PHP_8_3; + if (s == "php-8.4") return Runtime::PHP_8_4; + if (s == "ruby-3.0") return Runtime::RUBY_3_0; + if (s == "ruby-3.1") return Runtime::RUBY_3_1; + if (s == "ruby-3.2") return Runtime::RUBY_3_2; + if (s == "ruby-3.3") return Runtime::RUBY_3_3; + if (s == "ruby-3.4") return Runtime::RUBY_3_4; + if (s == "ruby-4.0") return Runtime::RUBY_4_0; + if (s == "python-3.8") return Runtime::PYTHON_3_8; + if (s == "python-3.9") return Runtime::PYTHON_3_9; + if (s == "python-3.10") return Runtime::PYTHON_3_10; + if (s == "python-3.11") return Runtime::PYTHON_3_11; + if (s == "python-3.12") return Runtime::PYTHON_3_12; + if (s == "python-3.13") return Runtime::PYTHON_3_13; + if (s == "python-3.14") return Runtime::PYTHON_3_14; + if (s == "python-ml-3.11") return Runtime::PYTHON_ML_3_11; + if (s == "python-ml-3.12") return Runtime::PYTHON_ML_3_12; + if (s == "python-ml-3.13") return Runtime::PYTHON_ML_3_13; + if (s == "deno-1.21") return Runtime::DENO_1_21; + if (s == "deno-1.24") return Runtime::DENO_1_24; + if (s == "deno-1.35") return Runtime::DENO_1_35; + if (s == "deno-1.40") return Runtime::DENO_1_40; + if (s == "deno-1.46") return Runtime::DENO_1_46; + if (s == "deno-2.0") return Runtime::DENO_2_0; + if (s == "deno-2.5") return Runtime::DENO_2_5; + if (s == "deno-2.6") return Runtime::DENO_2_6; + if (s == "dart-2.15") return Runtime::DART_2_15; + if (s == "dart-2.16") return Runtime::DART_2_16; + if (s == "dart-2.17") return Runtime::DART_2_17; + if (s == "dart-2.18") return Runtime::DART_2_18; + if (s == "dart-2.19") return Runtime::DART_2_19; + if (s == "dart-3.0") return Runtime::DART_3_0; + if (s == "dart-3.1") return Runtime::DART_3_1; + if (s == "dart-3.3") return Runtime::DART_3_3; + if (s == "dart-3.5") return Runtime::DART_3_5; + if (s == "dart-3.8") return Runtime::DART_3_8; + if (s == "dart-3.9") return Runtime::DART_3_9; + if (s == "dart-3.10") return Runtime::DART_3_10; + if (s == "dart-3.11") return Runtime::DART_3_11; + if (s == "dotnet-6.0") return Runtime::DOTNET_6_0; + if (s == "dotnet-7.0") return Runtime::DOTNET_7_0; + if (s == "dotnet-8.0") return Runtime::DOTNET_8_0; + if (s == "dotnet-10") return Runtime::DOTNET_10; + if (s == "java-8.0") return Runtime::JAVA_8_0; + if (s == "java-11.0") return Runtime::JAVA_11_0; + if (s == "java-17.0") return Runtime::JAVA_17_0; + if (s == "java-18.0") return Runtime::JAVA_18_0; + if (s == "java-21.0") return Runtime::JAVA_21_0; + if (s == "java-22") return Runtime::JAVA_22; + if (s == "java-25") return Runtime::JAVA_25; + if (s == "swift-5.5") return Runtime::SWIFT_5_5; + if (s == "swift-5.8") return Runtime::SWIFT_5_8; + if (s == "swift-5.9") return Runtime::SWIFT_5_9; + if (s == "swift-5.10") return Runtime::SWIFT_5_10; + if (s == "swift-6.2") return Runtime::SWIFT_6_2; + if (s == "kotlin-1.6") return Runtime::KOTLIN_1_6; + if (s == "kotlin-1.8") return Runtime::KOTLIN_1_8; + if (s == "kotlin-1.9") return Runtime::KOTLIN_1_9; + if (s == "kotlin-2.0") return Runtime::KOTLIN_2_0; + if (s == "kotlin-2.3") return Runtime::KOTLIN_2_3; + if (s == "cpp-17") return Runtime::CPP_17; + if (s == "cpp-20") return Runtime::CPP_20; + if (s == "bun-1.0") return Runtime::BUN_1_0; + if (s == "bun-1.1") return Runtime::BUN_1_1; + if (s == "bun-1.2") return Runtime::BUN_1_2; + if (s == "bun-1.3") return Runtime::BUN_1_3; + if (s == "go-1.23") return Runtime::GO_1_23; + if (s == "go-1.24") return Runtime::GO_1_24; + if (s == "go-1.25") return Runtime::GO_1_25; + if (s == "go-1.26") return Runtime::GO_1_26; + if (s == "static-1") return Runtime::STATIC_1; + if (s == "flutter-3.24") return Runtime::FLUTTER_3_24; + if (s == "flutter-3.27") return Runtime::FLUTTER_3_27; + if (s == "flutter-3.29") return Runtime::FLUTTER_3_29; + if (s == "flutter-3.32") return Runtime::FLUTTER_3_32; + if (s == "flutter-3.35") return Runtime::FLUTTER_3_35; + if (s == "flutter-3.38") return Runtime::FLUTTER_3_38; + if (s == "flutter-3.41") return Runtime::FLUTTER_3_41; + throw std::invalid_argument("Unknown Runtime value: " + s); +} + +inline void from_json(const nlohmann::json& j, Runtime& v) { + v = runtimeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const Runtime& v) { + j = toString(v); +} + +enum class Scopes { + SESSIONS_WRITE, + USERS_READ, + USERS_WRITE, + TEAMS_READ, + TEAMS_WRITE, + DATABASES_READ, + DATABASES_WRITE, + COLLECTIONS_READ, + COLLECTIONS_WRITE, + TABLES_READ, + TABLES_WRITE, + ATTRIBUTES_READ, + ATTRIBUTES_WRITE, + COLUMNS_READ, + COLUMNS_WRITE, + INDEXES_READ, + INDEXES_WRITE, + DOCUMENTS_READ, + DOCUMENTS_WRITE, + ROWS_READ, + ROWS_WRITE, + FILES_READ, + FILES_WRITE, + BUCKETS_READ, + BUCKETS_WRITE, + FUNCTIONS_READ, + FUNCTIONS_WRITE, + SITES_READ, + SITES_WRITE, + LOG_READ, + LOG_WRITE, + EXECUTION_READ, + EXECUTION_WRITE, + LOCALE_READ, + AVATARS_READ, + HEALTH_READ, + PROVIDERS_READ, + PROVIDERS_WRITE, + MESSAGES_READ, + MESSAGES_WRITE, + TOPICS_READ, + TOPICS_WRITE, + SUBSCRIBERS_READ, + SUBSCRIBERS_WRITE, + TARGETS_READ, + TARGETS_WRITE, + RULES_READ, + RULES_WRITE, + SCHEDULES_READ, + SCHEDULES_WRITE, + MIGRATIONS_READ, + MIGRATIONS_WRITE, + VCS_READ, + VCS_WRITE, + ASSISTANT_READ, + TOKENS_READ, + TOKENS_WRITE, + WEBHOOKS_READ, + WEBHOOKS_WRITE, + PROJECT_READ, + PROJECT_WRITE, + KEYS_READ, + KEYS_WRITE, + PLATFORMS_READ, + PLATFORMS_WRITE, + POLICIES_WRITE, + POLICIES_READ, + ARCHIVES_READ, + ARCHIVES_WRITE, + RESTORATIONS_READ, + RESTORATIONS_WRITE, + DOMAINS_READ, + DOMAINS_WRITE, + EVENTS_READ +}; + +inline std::string toString(Scopes value) { + switch (value) { + case Scopes :: SESSIONS_WRITE: return "sessions.write"; + case Scopes :: USERS_READ: return "users.read"; + case Scopes :: USERS_WRITE: return "users.write"; + case Scopes :: TEAMS_READ: return "teams.read"; + case Scopes :: TEAMS_WRITE: return "teams.write"; + case Scopes :: DATABASES_READ: return "databases.read"; + case Scopes :: DATABASES_WRITE: return "databases.write"; + case Scopes :: COLLECTIONS_READ: return "collections.read"; + case Scopes :: COLLECTIONS_WRITE: return "collections.write"; + case Scopes :: TABLES_READ: return "tables.read"; + case Scopes :: TABLES_WRITE: return "tables.write"; + case Scopes :: ATTRIBUTES_READ: return "attributes.read"; + case Scopes :: ATTRIBUTES_WRITE: return "attributes.write"; + case Scopes :: COLUMNS_READ: return "columns.read"; + case Scopes :: COLUMNS_WRITE: return "columns.write"; + case Scopes :: INDEXES_READ: return "indexes.read"; + case Scopes :: INDEXES_WRITE: return "indexes.write"; + case Scopes :: DOCUMENTS_READ: return "documents.read"; + case Scopes :: DOCUMENTS_WRITE: return "documents.write"; + case Scopes :: ROWS_READ: return "rows.read"; + case Scopes :: ROWS_WRITE: return "rows.write"; + case Scopes :: FILES_READ: return "files.read"; + case Scopes :: FILES_WRITE: return "files.write"; + case Scopes :: BUCKETS_READ: return "buckets.read"; + case Scopes :: BUCKETS_WRITE: return "buckets.write"; + case Scopes :: FUNCTIONS_READ: return "functions.read"; + case Scopes :: FUNCTIONS_WRITE: return "functions.write"; + case Scopes :: SITES_READ: return "sites.read"; + case Scopes :: SITES_WRITE: return "sites.write"; + case Scopes :: LOG_READ: return "log.read"; + case Scopes :: LOG_WRITE: return "log.write"; + case Scopes :: EXECUTION_READ: return "execution.read"; + case Scopes :: EXECUTION_WRITE: return "execution.write"; + case Scopes :: LOCALE_READ: return "locale.read"; + case Scopes :: AVATARS_READ: return "avatars.read"; + case Scopes :: HEALTH_READ: return "health.read"; + case Scopes :: PROVIDERS_READ: return "providers.read"; + case Scopes :: PROVIDERS_WRITE: return "providers.write"; + case Scopes :: MESSAGES_READ: return "messages.read"; + case Scopes :: MESSAGES_WRITE: return "messages.write"; + case Scopes :: TOPICS_READ: return "topics.read"; + case Scopes :: TOPICS_WRITE: return "topics.write"; + case Scopes :: SUBSCRIBERS_READ: return "subscribers.read"; + case Scopes :: SUBSCRIBERS_WRITE: return "subscribers.write"; + case Scopes :: TARGETS_READ: return "targets.read"; + case Scopes :: TARGETS_WRITE: return "targets.write"; + case Scopes :: RULES_READ: return "rules.read"; + case Scopes :: RULES_WRITE: return "rules.write"; + case Scopes :: SCHEDULES_READ: return "schedules.read"; + case Scopes :: SCHEDULES_WRITE: return "schedules.write"; + case Scopes :: MIGRATIONS_READ: return "migrations.read"; + case Scopes :: MIGRATIONS_WRITE: return "migrations.write"; + case Scopes :: VCS_READ: return "vcs.read"; + case Scopes :: VCS_WRITE: return "vcs.write"; + case Scopes :: ASSISTANT_READ: return "assistant.read"; + case Scopes :: TOKENS_READ: return "tokens.read"; + case Scopes :: TOKENS_WRITE: return "tokens.write"; + case Scopes :: WEBHOOKS_READ: return "webhooks.read"; + case Scopes :: WEBHOOKS_WRITE: return "webhooks.write"; + case Scopes :: PROJECT_READ: return "project.read"; + case Scopes :: PROJECT_WRITE: return "project.write"; + case Scopes :: KEYS_READ: return "keys.read"; + case Scopes :: KEYS_WRITE: return "keys.write"; + case Scopes :: PLATFORMS_READ: return "platforms.read"; + case Scopes :: PLATFORMS_WRITE: return "platforms.write"; + case Scopes :: POLICIES_WRITE: return "policies.write"; + case Scopes :: POLICIES_READ: return "policies.read"; + case Scopes :: ARCHIVES_READ: return "archives.read"; + case Scopes :: ARCHIVES_WRITE: return "archives.write"; + case Scopes :: RESTORATIONS_READ: return "restorations.read"; + case Scopes :: RESTORATIONS_WRITE: return "restorations.write"; + case Scopes :: DOMAINS_READ: return "domains.read"; + case Scopes :: DOMAINS_WRITE: return "domains.write"; + case Scopes :: EVENTS_READ: return "events.read"; + default: throw std::invalid_argument("Unknown Scopes enum value"); + } +} + +inline Scopes scopesFromString(const std::string& s) { + if (s == "sessions.write") return Scopes::SESSIONS_WRITE; + if (s == "users.read") return Scopes::USERS_READ; + if (s == "users.write") return Scopes::USERS_WRITE; + if (s == "teams.read") return Scopes::TEAMS_READ; + if (s == "teams.write") return Scopes::TEAMS_WRITE; + if (s == "databases.read") return Scopes::DATABASES_READ; + if (s == "databases.write") return Scopes::DATABASES_WRITE; + if (s == "collections.read") return Scopes::COLLECTIONS_READ; + if (s == "collections.write") return Scopes::COLLECTIONS_WRITE; + if (s == "tables.read") return Scopes::TABLES_READ; + if (s == "tables.write") return Scopes::TABLES_WRITE; + if (s == "attributes.read") return Scopes::ATTRIBUTES_READ; + if (s == "attributes.write") return Scopes::ATTRIBUTES_WRITE; + if (s == "columns.read") return Scopes::COLUMNS_READ; + if (s == "columns.write") return Scopes::COLUMNS_WRITE; + if (s == "indexes.read") return Scopes::INDEXES_READ; + if (s == "indexes.write") return Scopes::INDEXES_WRITE; + if (s == "documents.read") return Scopes::DOCUMENTS_READ; + if (s == "documents.write") return Scopes::DOCUMENTS_WRITE; + if (s == "rows.read") return Scopes::ROWS_READ; + if (s == "rows.write") return Scopes::ROWS_WRITE; + if (s == "files.read") return Scopes::FILES_READ; + if (s == "files.write") return Scopes::FILES_WRITE; + if (s == "buckets.read") return Scopes::BUCKETS_READ; + if (s == "buckets.write") return Scopes::BUCKETS_WRITE; + if (s == "functions.read") return Scopes::FUNCTIONS_READ; + if (s == "functions.write") return Scopes::FUNCTIONS_WRITE; + if (s == "sites.read") return Scopes::SITES_READ; + if (s == "sites.write") return Scopes::SITES_WRITE; + if (s == "log.read") return Scopes::LOG_READ; + if (s == "log.write") return Scopes::LOG_WRITE; + if (s == "execution.read") return Scopes::EXECUTION_READ; + if (s == "execution.write") return Scopes::EXECUTION_WRITE; + if (s == "locale.read") return Scopes::LOCALE_READ; + if (s == "avatars.read") return Scopes::AVATARS_READ; + if (s == "health.read") return Scopes::HEALTH_READ; + if (s == "providers.read") return Scopes::PROVIDERS_READ; + if (s == "providers.write") return Scopes::PROVIDERS_WRITE; + if (s == "messages.read") return Scopes::MESSAGES_READ; + if (s == "messages.write") return Scopes::MESSAGES_WRITE; + if (s == "topics.read") return Scopes::TOPICS_READ; + if (s == "topics.write") return Scopes::TOPICS_WRITE; + if (s == "subscribers.read") return Scopes::SUBSCRIBERS_READ; + if (s == "subscribers.write") return Scopes::SUBSCRIBERS_WRITE; + if (s == "targets.read") return Scopes::TARGETS_READ; + if (s == "targets.write") return Scopes::TARGETS_WRITE; + if (s == "rules.read") return Scopes::RULES_READ; + if (s == "rules.write") return Scopes::RULES_WRITE; + if (s == "schedules.read") return Scopes::SCHEDULES_READ; + if (s == "schedules.write") return Scopes::SCHEDULES_WRITE; + if (s == "migrations.read") return Scopes::MIGRATIONS_READ; + if (s == "migrations.write") return Scopes::MIGRATIONS_WRITE; + if (s == "vcs.read") return Scopes::VCS_READ; + if (s == "vcs.write") return Scopes::VCS_WRITE; + if (s == "assistant.read") return Scopes::ASSISTANT_READ; + if (s == "tokens.read") return Scopes::TOKENS_READ; + if (s == "tokens.write") return Scopes::TOKENS_WRITE; + if (s == "webhooks.read") return Scopes::WEBHOOKS_READ; + if (s == "webhooks.write") return Scopes::WEBHOOKS_WRITE; + if (s == "project.read") return Scopes::PROJECT_READ; + if (s == "project.write") return Scopes::PROJECT_WRITE; + if (s == "keys.read") return Scopes::KEYS_READ; + if (s == "keys.write") return Scopes::KEYS_WRITE; + if (s == "platforms.read") return Scopes::PLATFORMS_READ; + if (s == "platforms.write") return Scopes::PLATFORMS_WRITE; + if (s == "policies.write") return Scopes::POLICIES_WRITE; + if (s == "policies.read") return Scopes::POLICIES_READ; + if (s == "archives.read") return Scopes::ARCHIVES_READ; + if (s == "archives.write") return Scopes::ARCHIVES_WRITE; + if (s == "restorations.read") return Scopes::RESTORATIONS_READ; + if (s == "restorations.write") return Scopes::RESTORATIONS_WRITE; + if (s == "domains.read") return Scopes::DOMAINS_READ; + if (s == "domains.write") return Scopes::DOMAINS_WRITE; + if (s == "events.read") return Scopes::EVENTS_READ; + throw std::invalid_argument("Unknown Scopes value: " + s); +} + +inline void from_json(const nlohmann::json& j, Scopes& v) { + v = scopesFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const Scopes& v) { + j = toString(v); +} + +enum class TemplateReferenceType { + COMMIT, + BRANCH, + TAG +}; + +inline std::string toString(TemplateReferenceType value) { + switch (value) { + case TemplateReferenceType :: COMMIT: return "commit"; + case TemplateReferenceType :: BRANCH: return "branch"; + case TemplateReferenceType :: TAG: return "tag"; + default: throw std::invalid_argument("Unknown TemplateReferenceType enum value"); + } +} + +inline TemplateReferenceType templateReferenceTypeFromString(const std::string& s) { + if (s == "commit") return TemplateReferenceType::COMMIT; + if (s == "branch") return TemplateReferenceType::BRANCH; + if (s == "tag") return TemplateReferenceType::TAG; + throw std::invalid_argument("Unknown TemplateReferenceType value: " + s); +} + +inline void from_json(const nlohmann::json& j, TemplateReferenceType& v) { + v = templateReferenceTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const TemplateReferenceType& v) { + j = toString(v); +} + +enum class VCSReferenceType { + BRANCH, + COMMIT +}; + +inline std::string toString(VCSReferenceType value) { + switch (value) { + case VCSReferenceType :: BRANCH: return "branch"; + case VCSReferenceType :: COMMIT: return "commit"; + default: throw std::invalid_argument("Unknown VCSReferenceType enum value"); + } +} + +inline VCSReferenceType vCSReferenceTypeFromString(const std::string& s) { + if (s == "branch") return VCSReferenceType::BRANCH; + if (s == "commit") return VCSReferenceType::COMMIT; + throw std::invalid_argument("Unknown VCSReferenceType value: " + s); +} + +inline void from_json(const nlohmann::json& j, VCSReferenceType& v) { + v = vCSReferenceTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const VCSReferenceType& v) { + j = toString(v); +} + +enum class DeploymentDownloadType { + SOURCE, + OUTPUT +}; + +inline std::string toString(DeploymentDownloadType value) { + switch (value) { + case DeploymentDownloadType :: SOURCE: return "source"; + case DeploymentDownloadType :: OUTPUT: return "output"; + default: throw std::invalid_argument("Unknown DeploymentDownloadType enum value"); + } +} + +inline DeploymentDownloadType deploymentDownloadTypeFromString(const std::string& s) { + if (s == "source") return DeploymentDownloadType::SOURCE; + if (s == "output") return DeploymentDownloadType::OUTPUT; + throw std::invalid_argument("Unknown DeploymentDownloadType value: " + s); +} + +inline void from_json(const nlohmann::json& j, DeploymentDownloadType& v) { + v = deploymentDownloadTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const DeploymentDownloadType& v) { + j = toString(v); +} + +enum class ExecutionMethod { + GET, + POST, + PUT, + PATCH, + DELETE, + OPTIONS, + HEAD +}; + +inline std::string toString(ExecutionMethod value) { + switch (value) { + case ExecutionMethod :: GET: return "GET"; + case ExecutionMethod :: POST: return "POST"; + case ExecutionMethod :: PUT: return "PUT"; + case ExecutionMethod :: PATCH: return "PATCH"; + case ExecutionMethod :: DELETE: return "DELETE"; + case ExecutionMethod :: OPTIONS: return "OPTIONS"; + case ExecutionMethod :: HEAD: return "HEAD"; + default: throw std::invalid_argument("Unknown ExecutionMethod enum value"); + } +} + +inline ExecutionMethod executionMethodFromString(const std::string& s) { + if (s == "GET") return ExecutionMethod::GET; + if (s == "POST") return ExecutionMethod::POST; + if (s == "PUT") return ExecutionMethod::PUT; + if (s == "PATCH") return ExecutionMethod::PATCH; + if (s == "DELETE") return ExecutionMethod::DELETE; + if (s == "OPTIONS") return ExecutionMethod::OPTIONS; + if (s == "HEAD") return ExecutionMethod::HEAD; + throw std::invalid_argument("Unknown ExecutionMethod value: " + s); +} + +inline void from_json(const nlohmann::json& j, ExecutionMethod& v) { + v = executionMethodFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const ExecutionMethod& v) { + j = toString(v); +} + +enum class Compression { + NONE, + GZIP, + ZSTD +}; + +inline std::string toString(Compression value) { + switch (value) { + case Compression :: NONE: return "none"; + case Compression :: GZIP: return "gzip"; + case Compression :: ZSTD: return "zstd"; + default: throw std::invalid_argument("Unknown Compression enum value"); + } +} + +inline Compression compressionFromString(const std::string& s) { + if (s == "none") return Compression::NONE; + if (s == "gzip") return Compression::GZIP; + if (s == "zstd") return Compression::ZSTD; + throw std::invalid_argument("Unknown Compression value: " + s); +} + +inline void from_json(const nlohmann::json& j, Compression& v) { + v = compressionFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const Compression& v) { + j = toString(v); +} + +enum class ImageGravity { + CENTER, + TOP_LEFT, + TOP, + TOP_RIGHT, + LEFT, + RIGHT, + BOTTOM_LEFT, + BOTTOM, + BOTTOM_RIGHT +}; + +inline std::string toString(ImageGravity value) { + switch (value) { + case ImageGravity :: CENTER: return "center"; + case ImageGravity :: TOP_LEFT: return "top-left"; + case ImageGravity :: TOP: return "top"; + case ImageGravity :: TOP_RIGHT: return "top-right"; + case ImageGravity :: LEFT: return "left"; + case ImageGravity :: RIGHT: return "right"; + case ImageGravity :: BOTTOM_LEFT: return "bottom-left"; + case ImageGravity :: BOTTOM: return "bottom"; + case ImageGravity :: BOTTOM_RIGHT: return "bottom-right"; + default: throw std::invalid_argument("Unknown ImageGravity enum value"); + } +} + +inline ImageGravity imageGravityFromString(const std::string& s) { + if (s == "center") return ImageGravity::CENTER; + if (s == "top-left") return ImageGravity::TOP_LEFT; + if (s == "top") return ImageGravity::TOP; + if (s == "top-right") return ImageGravity::TOP_RIGHT; + if (s == "left") return ImageGravity::LEFT; + if (s == "right") return ImageGravity::RIGHT; + if (s == "bottom-left") return ImageGravity::BOTTOM_LEFT; + if (s == "bottom") return ImageGravity::BOTTOM; + if (s == "bottom-right") return ImageGravity::BOTTOM_RIGHT; + throw std::invalid_argument("Unknown ImageGravity value: " + s); +} + +inline void from_json(const nlohmann::json& j, ImageGravity& v) { + v = imageGravityFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const ImageGravity& v) { + j = toString(v); +} + +enum class ImageFormat { + JPG, + JPEG, + PNG, + WEBP, + HEIC, + AVIF, + GIF +}; + +inline std::string toString(ImageFormat value) { + switch (value) { + case ImageFormat :: JPG: return "jpg"; + case ImageFormat :: JPEG: return "jpeg"; + case ImageFormat :: PNG: return "png"; + case ImageFormat :: WEBP: return "webp"; + case ImageFormat :: HEIC: return "heic"; + case ImageFormat :: AVIF: return "avif"; + case ImageFormat :: GIF: return "gif"; + default: throw std::invalid_argument("Unknown ImageFormat enum value"); + } +} + +inline ImageFormat imageFormatFromString(const std::string& s) { + if (s == "jpg") return ImageFormat::JPG; + if (s == "jpeg") return ImageFormat::JPEG; + if (s == "png") return ImageFormat::PNG; + if (s == "webp") return ImageFormat::WEBP; + if (s == "heic") return ImageFormat::HEIC; + if (s == "avif") return ImageFormat::AVIF; + if (s == "gif") return ImageFormat::GIF; + throw std::invalid_argument("Unknown ImageFormat value: " + s); +} + +inline void from_json(const nlohmann::json& j, ImageFormat& v) { + v = imageFormatFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const ImageFormat& v) { + j = toString(v); +} + +enum class TablesDBIndexType { + KEY, + FULLTEXT, + UNIQUE, + SPATIAL +}; + +inline std::string toString(TablesDBIndexType value) { + switch (value) { + case TablesDBIndexType :: KEY: return "key"; + case TablesDBIndexType :: FULLTEXT: return "fulltext"; + case TablesDBIndexType :: UNIQUE: return "unique"; + case TablesDBIndexType :: SPATIAL: return "spatial"; + default: throw std::invalid_argument("Unknown TablesDBIndexType enum value"); + } +} + +inline TablesDBIndexType tablesDBIndexTypeFromString(const std::string& s) { + if (s == "key") return TablesDBIndexType::KEY; + if (s == "fulltext") return TablesDBIndexType::FULLTEXT; + if (s == "unique") return TablesDBIndexType::UNIQUE; + if (s == "spatial") return TablesDBIndexType::SPATIAL; + throw std::invalid_argument("Unknown TablesDBIndexType value: " + s); +} + +inline void from_json(const nlohmann::json& j, TablesDBIndexType& v) { + v = tablesDBIndexTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const TablesDBIndexType& v) { + j = toString(v); +} + +enum class PasswordHash { + SHA1, + SHA224, + SHA256, + SHA384, + SHA512_224, + SHA512_256, + SHA512, + SHA3_224, + SHA3_256, + SHA3_384, + SHA3_512 +}; + +inline std::string toString(PasswordHash value) { + switch (value) { + case PasswordHash :: SHA1: return "sha1"; + case PasswordHash :: SHA224: return "sha224"; + case PasswordHash :: SHA256: return "sha256"; + case PasswordHash :: SHA384: return "sha384"; + case PasswordHash :: SHA512_224: return "sha512/224"; + case PasswordHash :: SHA512_256: return "sha512/256"; + case PasswordHash :: SHA512: return "sha512"; + case PasswordHash :: SHA3_224: return "sha3-224"; + case PasswordHash :: SHA3_256: return "sha3-256"; + case PasswordHash :: SHA3_384: return "sha3-384"; + case PasswordHash :: SHA3_512: return "sha3-512"; + default: throw std::invalid_argument("Unknown PasswordHash enum value"); + } +} + +inline PasswordHash passwordHashFromString(const std::string& s) { + if (s == "sha1") return PasswordHash::SHA1; + if (s == "sha224") return PasswordHash::SHA224; + if (s == "sha256") return PasswordHash::SHA256; + if (s == "sha384") return PasswordHash::SHA384; + if (s == "sha512/224") return PasswordHash::SHA512_224; + if (s == "sha512/256") return PasswordHash::SHA512_256; + if (s == "sha512") return PasswordHash::SHA512; + if (s == "sha3-224") return PasswordHash::SHA3_224; + if (s == "sha3-256") return PasswordHash::SHA3_256; + if (s == "sha3-384") return PasswordHash::SHA3_384; + if (s == "sha3-512") return PasswordHash::SHA3_512; + throw std::invalid_argument("Unknown PasswordHash value: " + s); +} + +inline void from_json(const nlohmann::json& j, PasswordHash& v) { + v = passwordHashFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const PasswordHash& v) { + j = toString(v); +} + +enum class MessagingProviderType { + EMAIL, + SMS, + PUSH +}; + +inline std::string toString(MessagingProviderType value) { + switch (value) { + case MessagingProviderType :: EMAIL: return "email"; + case MessagingProviderType :: SMS: return "sms"; + case MessagingProviderType :: PUSH: return "push"; + default: throw std::invalid_argument("Unknown MessagingProviderType enum value"); + } +} + +inline MessagingProviderType messagingProviderTypeFromString(const std::string& s) { + if (s == "email") return MessagingProviderType::EMAIL; + if (s == "sms") return MessagingProviderType::SMS; + if (s == "push") return MessagingProviderType::PUSH; + throw std::invalid_argument("Unknown MessagingProviderType value: " + s); +} + +inline void from_json(const nlohmann::json& j, MessagingProviderType& v) { + v = messagingProviderTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const MessagingProviderType& v) { + j = toString(v); +} + +enum class DatabaseType { + LEGACY, + TABLESDB, + DOCUMENTSDB, + VECTORSDB +}; + +inline std::string toString(DatabaseType value) { + switch (value) { + case DatabaseType :: LEGACY: return "legacy"; + case DatabaseType :: TABLESDB: return "tablesdb"; + case DatabaseType :: DOCUMENTSDB: return "documentsdb"; + case DatabaseType :: VECTORSDB: return "vectorsdb"; + default: throw std::invalid_argument("Unknown DatabaseType enum value"); + } +} + +inline DatabaseType databaseTypeFromString(const std::string& s) { + if (s == "legacy") return DatabaseType::LEGACY; + if (s == "tablesdb") return DatabaseType::TABLESDB; + if (s == "documentsdb") return DatabaseType::DOCUMENTSDB; + if (s == "vectorsdb") return DatabaseType::VECTORSDB; + throw std::invalid_argument("Unknown DatabaseType value: " + s); +} + +inline void from_json(const nlohmann::json& j, DatabaseType& v) { + v = databaseTypeFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const DatabaseType& v) { + j = toString(v); +} + +enum class AttributeStatus { + AVAILABLE, + PROCESSING, + DELETING, + STUCK, + FAILED +}; + +inline std::string toString(AttributeStatus value) { + switch (value) { + case AttributeStatus :: AVAILABLE: return "available"; + case AttributeStatus :: PROCESSING: return "processing"; + case AttributeStatus :: DELETING: return "deleting"; + case AttributeStatus :: STUCK: return "stuck"; + case AttributeStatus :: FAILED: return "failed"; + default: throw std::invalid_argument("Unknown AttributeStatus enum value"); + } +} + +inline AttributeStatus attributeStatusFromString(const std::string& s) { + if (s == "available") return AttributeStatus::AVAILABLE; + if (s == "processing") return AttributeStatus::PROCESSING; + if (s == "deleting") return AttributeStatus::DELETING; + if (s == "stuck") return AttributeStatus::STUCK; + if (s == "failed") return AttributeStatus::FAILED; + throw std::invalid_argument("Unknown AttributeStatus value: " + s); +} + +inline void from_json(const nlohmann::json& j, AttributeStatus& v) { + v = attributeStatusFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const AttributeStatus& v) { + j = toString(v); +} + +enum class ColumnStatus { + AVAILABLE, + PROCESSING, + DELETING, + STUCK, + FAILED +}; + +inline std::string toString(ColumnStatus value) { + switch (value) { + case ColumnStatus :: AVAILABLE: return "available"; + case ColumnStatus :: PROCESSING: return "processing"; + case ColumnStatus :: DELETING: return "deleting"; + case ColumnStatus :: STUCK: return "stuck"; + case ColumnStatus :: FAILED: return "failed"; + default: throw std::invalid_argument("Unknown ColumnStatus enum value"); + } +} + +inline ColumnStatus columnStatusFromString(const std::string& s) { + if (s == "available") return ColumnStatus::AVAILABLE; + if (s == "processing") return ColumnStatus::PROCESSING; + if (s == "deleting") return ColumnStatus::DELETING; + if (s == "stuck") return ColumnStatus::STUCK; + if (s == "failed") return ColumnStatus::FAILED; + throw std::invalid_argument("Unknown ColumnStatus value: " + s); +} + +inline void from_json(const nlohmann::json& j, ColumnStatus& v) { + v = columnStatusFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const ColumnStatus& v) { + j = toString(v); +} + +enum class IndexStatus { + AVAILABLE, + PROCESSING, + DELETING, + STUCK, + FAILED +}; + +inline std::string toString(IndexStatus value) { + switch (value) { + case IndexStatus :: AVAILABLE: return "available"; + case IndexStatus :: PROCESSING: return "processing"; + case IndexStatus :: DELETING: return "deleting"; + case IndexStatus :: STUCK: return "stuck"; + case IndexStatus :: FAILED: return "failed"; + default: throw std::invalid_argument("Unknown IndexStatus enum value"); + } +} + +inline IndexStatus indexStatusFromString(const std::string& s) { + if (s == "available") return IndexStatus::AVAILABLE; + if (s == "processing") return IndexStatus::PROCESSING; + if (s == "deleting") return IndexStatus::DELETING; + if (s == "stuck") return IndexStatus::STUCK; + if (s == "failed") return IndexStatus::FAILED; + throw std::invalid_argument("Unknown IndexStatus value: " + s); +} + +inline void from_json(const nlohmann::json& j, IndexStatus& v) { + v = indexStatusFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const IndexStatus& v) { + j = toString(v); +} + +enum class DeploymentStatus { + WAITING, + PROCESSING, + BUILDING, + READY, + CANCELED, + FAILED +}; + +inline std::string toString(DeploymentStatus value) { + switch (value) { + case DeploymentStatus :: WAITING: return "waiting"; + case DeploymentStatus :: PROCESSING: return "processing"; + case DeploymentStatus :: BUILDING: return "building"; + case DeploymentStatus :: READY: return "ready"; + case DeploymentStatus :: CANCELED: return "canceled"; + case DeploymentStatus :: FAILED: return "failed"; + default: throw std::invalid_argument("Unknown DeploymentStatus enum value"); + } +} + +inline DeploymentStatus deploymentStatusFromString(const std::string& s) { + if (s == "waiting") return DeploymentStatus::WAITING; + if (s == "processing") return DeploymentStatus::PROCESSING; + if (s == "building") return DeploymentStatus::BUILDING; + if (s == "ready") return DeploymentStatus::READY; + if (s == "canceled") return DeploymentStatus::CANCELED; + if (s == "failed") return DeploymentStatus::FAILED; + throw std::invalid_argument("Unknown DeploymentStatus value: " + s); +} + +inline void from_json(const nlohmann::json& j, DeploymentStatus& v) { + v = deploymentStatusFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const DeploymentStatus& v) { + j = toString(v); +} + +enum class ExecutionTrigger { + HTTP, + SCHEDULE, + EVENT +}; + +inline std::string toString(ExecutionTrigger value) { + switch (value) { + case ExecutionTrigger :: HTTP: return "http"; + case ExecutionTrigger :: SCHEDULE: return "schedule"; + case ExecutionTrigger :: EVENT: return "event"; + default: throw std::invalid_argument("Unknown ExecutionTrigger enum value"); + } +} + +inline ExecutionTrigger executionTriggerFromString(const std::string& s) { + if (s == "http") return ExecutionTrigger::HTTP; + if (s == "schedule") return ExecutionTrigger::SCHEDULE; + if (s == "event") return ExecutionTrigger::EVENT; + throw std::invalid_argument("Unknown ExecutionTrigger value: " + s); +} + +inline void from_json(const nlohmann::json& j, ExecutionTrigger& v) { + v = executionTriggerFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const ExecutionTrigger& v) { + j = toString(v); +} + +enum class ExecutionStatus { + WAITING, + PROCESSING, + COMPLETED, + FAILED, + SCHEDULED +}; + +inline std::string toString(ExecutionStatus value) { + switch (value) { + case ExecutionStatus :: WAITING: return "waiting"; + case ExecutionStatus :: PROCESSING: return "processing"; + case ExecutionStatus :: COMPLETED: return "completed"; + case ExecutionStatus :: FAILED: return "failed"; + case ExecutionStatus :: SCHEDULED: return "scheduled"; + default: throw std::invalid_argument("Unknown ExecutionStatus enum value"); + } +} + +inline ExecutionStatus executionStatusFromString(const std::string& s) { + if (s == "waiting") return ExecutionStatus::WAITING; + if (s == "processing") return ExecutionStatus::PROCESSING; + if (s == "completed") return ExecutionStatus::COMPLETED; + if (s == "failed") return ExecutionStatus::FAILED; + if (s == "scheduled") return ExecutionStatus::SCHEDULED; + throw std::invalid_argument("Unknown ExecutionStatus value: " + s); +} + +inline void from_json(const nlohmann::json& j, ExecutionStatus& v) { + v = executionStatusFromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const ExecutionStatus& v) { + j = toString(v); +} + +} // namespace enums +} // namespace appwrite diff --git a/examples/cpp/include/appwrite/models.hpp b/examples/cpp/include/appwrite/models.hpp new file mode 100755 index 0000000000..6de47ff800 --- /dev/null +++ b/examples/cpp/include/appwrite/models.hpp @@ -0,0 +1,11989 @@ +#pragma once + +#include +#include +#include +#include +#include "base.hpp" +#include "enums/enums.hpp" + +namespace appwrite { +namespace models { + +// Forward declarations — required because some structs reference types defined later +struct Row; +struct RowList; +struct Document; +struct DocumentList; +struct ColumnIndex; +struct Table; +struct TableList; +struct Index; +struct Collection; +struct CollectionList; +struct Database; +struct DatabaseList; +struct IndexList; +struct ColumnIndexList; +struct Preferences; +struct Target; +struct User; +struct UserList; +struct Session; +struct SessionList; +struct Identity; +struct IdentityList; +struct Log; +struct LogList; +struct File; +struct FileList; +struct Bucket; +struct BucketList; +struct Team; +struct TeamList; +struct Membership; +struct MembershipList; +struct Variable; +struct Function; +struct FunctionList; +struct Runtime; +struct RuntimeList; +struct Deployment; +struct DeploymentList; +struct Headers; +struct Execution; +struct ExecutionList; +struct Webhook; +struct WebhookList; +struct VariableList; +struct TargetList; +struct Transaction; +struct TransactionList; +struct Specification; +struct SpecificationList; +struct AttributeList; +struct AttributeString; +struct AttributeInteger; +struct AttributeFloat; +struct AttributeBoolean; +struct AttributeEmail; +struct AttributeEnum; +struct AttributeIp; +struct AttributeUrl; +struct AttributeDatetime; +struct AttributeRelationship; +struct AttributePoint; +struct AttributeLine; +struct AttributePolygon; +struct AttributeVarchar; +struct AttributeText; +struct AttributeMediumtext; +struct AttributeLongtext; +struct ColumnList; +struct ColumnString; +struct ColumnInteger; +struct ColumnFloat; +struct ColumnBoolean; +struct ColumnEmail; +struct ColumnEnum; +struct ColumnIp; +struct ColumnUrl; +struct ColumnDatetime; +struct ColumnRelationship; +struct ColumnPoint; +struct ColumnLine; +struct ColumnPolygon; +struct ColumnVarchar; +struct ColumnText; +struct ColumnMediumtext; +struct ColumnLongtext; +struct AlgoMd5; +struct AlgoSha; +struct AlgoPhpass; +struct AlgoBcrypt; +struct AlgoScrypt; +struct AlgoScryptModified; +struct AlgoArgon2; +struct Token; +struct Jwt; +struct MfaChallenge; +struct MfaRecoveryCodes; +struct MfaType; +struct MfaFactors; + +/** + * @brief Row + */ +struct Row { + /** @brief Row ID. */ + std::string id; + /** @brief Row sequence ID. */ + std::string sequence; + /** @brief Table ID. */ + std::string tableId; + /** @brief Database ID. */ + std::string databaseId; + /** @brief Row creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Row update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Row permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + std::vector permissions; + + /** @brief Deserialize from JSON */ + static Row fromJson(const nlohmann::json& j) { + Row obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$sequence")) { + if (j["$sequence"].is_null()) { + throw appwrite::DeserializationException("Required field '$sequence' is null"); + } else { + obj.sequence = j["$sequence"].get(); + } + } + if (j.contains("$tableId")) { + if (j["$tableId"].is_null()) { + throw appwrite::DeserializationException("Required field '$tableId' is null"); + } else { + obj.tableId = j["$tableId"].get(); + } + } + if (j.contains("$databaseId")) { + if (j["$databaseId"].is_null()) { + throw appwrite::DeserializationException("Required field '$databaseId' is null"); + } else { + obj.databaseId = j["$databaseId"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("$permissions")) { + if (j["$permissions"].is_null()) { + throw appwrite::DeserializationException("Required field '$permissions' is null"); + } else { + obj.permissions = j["$permissions"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$sequence"] = this->sequence; + } + { + j["$tableId"] = this->tableId; + } + { + j["$databaseId"] = this->databaseId; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["$permissions"] = this->permissions; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Row& x) { + x = Row::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Row& x) { + j = x.toJson(); +} + +/** + * @brief Rows List + */ +struct RowList { + /** @brief Total number of rows that matched your query. */ + int64_t total; + /** @brief List of rows. */ + std::vector rows; + + /** @brief Deserialize from JSON */ + static RowList fromJson(const nlohmann::json& j) { + RowList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("rows")) { + if (j["rows"].is_null()) { + throw appwrite::DeserializationException("Required field 'rows' is null"); + } else { + for (auto& item : j["rows"]) { + obj.rows.push_back(Row::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->rows) arr.push_back(item.toJson()); + j["rows"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, RowList& x) { + x = RowList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const RowList& x) { + j = x.toJson(); +} + +/** + * @brief Document + */ +struct Document { + /** @brief Document ID. */ + std::string id; + /** @brief Document sequence ID. */ + std::string sequence; + /** @brief Collection ID. */ + std::string collectionId; + /** @brief Database ID. */ + std::string databaseId; + /** @brief Document creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Document update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Document permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + std::vector permissions; + + /** @brief Deserialize from JSON */ + static Document fromJson(const nlohmann::json& j) { + Document obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$sequence")) { + if (j["$sequence"].is_null()) { + throw appwrite::DeserializationException("Required field '$sequence' is null"); + } else { + obj.sequence = j["$sequence"].get(); + } + } + if (j.contains("$collectionId")) { + if (j["$collectionId"].is_null()) { + throw appwrite::DeserializationException("Required field '$collectionId' is null"); + } else { + obj.collectionId = j["$collectionId"].get(); + } + } + if (j.contains("$databaseId")) { + if (j["$databaseId"].is_null()) { + throw appwrite::DeserializationException("Required field '$databaseId' is null"); + } else { + obj.databaseId = j["$databaseId"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("$permissions")) { + if (j["$permissions"].is_null()) { + throw appwrite::DeserializationException("Required field '$permissions' is null"); + } else { + obj.permissions = j["$permissions"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$sequence"] = this->sequence; + } + { + j["$collectionId"] = this->collectionId; + } + { + j["$databaseId"] = this->databaseId; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["$permissions"] = this->permissions; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Document& x) { + x = Document::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Document& x) { + j = x.toJson(); +} + +/** + * @brief Documents List + */ +struct DocumentList { + /** @brief Total number of documents that matched your query. */ + int64_t total; + /** @brief List of documents. */ + std::vector documents; + + /** @brief Deserialize from JSON */ + static DocumentList fromJson(const nlohmann::json& j) { + DocumentList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("documents")) { + if (j["documents"].is_null()) { + throw appwrite::DeserializationException("Required field 'documents' is null"); + } else { + for (auto& item : j["documents"]) { + obj.documents.push_back(Document::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->documents) arr.push_back(item.toJson()); + j["documents"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, DocumentList& x) { + x = DocumentList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const DocumentList& x) { + j = x.toJson(); +} + +/** + * @brief Index + */ +struct ColumnIndex { + /** @brief Index ID. */ + std::string id; + /** @brief Index creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Index update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Index Key. */ + std::string key; + /** @brief Index type. */ + std::string type; + /** @brief Index status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + std::string status; + /** @brief Error message. Displays error generated on failure of creating or deleting an index. */ + std::string error; + /** @brief Index columns. */ + std::vector columns; + /** @brief Index columns length. */ + std::vector lengths; + /** @brief Index orders. */ + std::optional> orders = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnIndex fromJson(const nlohmann::json& j) { + ColumnIndex obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("columns")) { + if (j["columns"].is_null()) { + throw appwrite::DeserializationException("Required field 'columns' is null"); + } else { + obj.columns = j["columns"].get>(); + } + } + if (j.contains("lengths")) { + if (j["lengths"].is_null()) { + throw appwrite::DeserializationException("Required field 'lengths' is null"); + } else { + obj.lengths = j["lengths"].get>(); + } + } + if (j.contains("orders")) { + if (j["orders"].is_null()) { + obj.orders = std::nullopt; + } else { + obj.orders = j["orders"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = this->status; + } + { + j["error"] = this->error; + } + { + j["columns"] = this->columns; + } + { + j["lengths"] = this->lengths; + } + if (this->orders.has_value()) { + j["orders"] = this->orders.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnIndex& x) { + x = ColumnIndex::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnIndex& x) { + j = x.toJson(); +} + +/** + * @brief Table + */ +struct Table { + /** @brief Table ID. */ + std::string id; + /** @brief Table creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Table update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Table permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + std::vector permissions; + /** @brief Database ID. */ + std::string databaseId; + /** @brief Table name. */ + std::string name; + /** @brief Table enabled. Can be 'enabled' or 'disabled'. When disabled, the table is inaccessible to users, but remains accessible to Server SDKs using API keys. */ + bool enabled; + /** @brief Whether row-level permissions are enabled. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + bool rowSecurity; + /** @brief Table columns. */ + std::vector columns; + /** @brief Table indexes. */ + std::vector indexes; + /** @brief Maximum row size in bytes. Returns 0 when no limit applies. */ + int64_t bytesMax; + /** @brief Currently used row size in bytes based on defined columns. */ + int64_t bytesUsed; + + /** @brief Deserialize from JSON */ + static Table fromJson(const nlohmann::json& j) { + Table obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("$permissions")) { + if (j["$permissions"].is_null()) { + throw appwrite::DeserializationException("Required field '$permissions' is null"); + } else { + obj.permissions = j["$permissions"].get>(); + } + } + if (j.contains("databaseId")) { + if (j["databaseId"].is_null()) { + throw appwrite::DeserializationException("Required field 'databaseId' is null"); + } else { + obj.databaseId = j["databaseId"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("enabled")) { + if (j["enabled"].is_null()) { + throw appwrite::DeserializationException("Required field 'enabled' is null"); + } else { + obj.enabled = j["enabled"].get(); + } + } + if (j.contains("rowSecurity")) { + if (j["rowSecurity"].is_null()) { + throw appwrite::DeserializationException("Required field 'rowSecurity' is null"); + } else { + obj.rowSecurity = j["rowSecurity"].get(); + } + } + if (j.contains("columns")) { + if (j["columns"].is_null()) { + throw appwrite::DeserializationException("Required field 'columns' is null"); + } else { + obj.columns = j["columns"].get>(); + } + } + if (j.contains("indexes")) { + if (j["indexes"].is_null()) { + throw appwrite::DeserializationException("Required field 'indexes' is null"); + } else { + for (auto& item : j["indexes"]) { + obj.indexes.push_back(ColumnIndex::fromJson(item)); + } + } + } + if (j.contains("bytesMax")) { + if (j["bytesMax"].is_null()) { + throw appwrite::DeserializationException("Required field 'bytesMax' is null"); + } else { + obj.bytesMax = j["bytesMax"].get(); + } + } + if (j.contains("bytesUsed")) { + if (j["bytesUsed"].is_null()) { + throw appwrite::DeserializationException("Required field 'bytesUsed' is null"); + } else { + obj.bytesUsed = j["bytesUsed"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["$permissions"] = this->permissions; + } + { + j["databaseId"] = this->databaseId; + } + { + j["name"] = this->name; + } + { + j["enabled"] = this->enabled; + } + { + j["rowSecurity"] = this->rowSecurity; + } + { + j["columns"] = this->columns; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->indexes) arr.push_back(item.toJson()); + j["indexes"] = arr; + } + { + j["bytesMax"] = this->bytesMax; + } + { + j["bytesUsed"] = this->bytesUsed; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Table& x) { + x = Table::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Table& x) { + j = x.toJson(); +} + +/** + * @brief Tables List + */ +struct TableList { + /** @brief Total number of tables that matched your query. */ + int64_t total; + /** @brief List of tables. */ + std::vector tables; + + /** @brief Deserialize from JSON */ + static TableList fromJson(const nlohmann::json& j) { + TableList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("tables")) { + if (j["tables"].is_null()) { + throw appwrite::DeserializationException("Required field 'tables' is null"); + } else { + for (auto& item : j["tables"]) { + obj.tables.push_back(Table::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->tables) arr.push_back(item.toJson()); + j["tables"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, TableList& x) { + x = TableList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const TableList& x) { + j = x.toJson(); +} + +/** + * @brief Index + */ +struct Index { + /** @brief Index ID. */ + std::string id; + /** @brief Index creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Index update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Index key. */ + std::string key; + /** @brief Index type. */ + std::string type; + /** @brief Index status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::IndexStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an index. */ + std::string error; + /** @brief Index attributes. */ + std::vector attributes; + /** @brief Index attributes length. */ + std::vector lengths; + /** @brief Index orders. */ + std::optional> orders = std::nullopt; + + /** @brief Deserialize from JSON */ + static Index fromJson(const nlohmann::json& j) { + Index obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("attributes")) { + if (j["attributes"].is_null()) { + throw appwrite::DeserializationException("Required field 'attributes' is null"); + } else { + obj.attributes = j["attributes"].get>(); + } + } + if (j.contains("lengths")) { + if (j["lengths"].is_null()) { + throw appwrite::DeserializationException("Required field 'lengths' is null"); + } else { + obj.lengths = j["lengths"].get>(); + } + } + if (j.contains("orders")) { + if (j["orders"].is_null()) { + obj.orders = std::nullopt; + } else { + obj.orders = j["orders"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["attributes"] = this->attributes; + } + { + j["lengths"] = this->lengths; + } + if (this->orders.has_value()) { + j["orders"] = this->orders.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Index& x) { + x = Index::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Index& x) { + j = x.toJson(); +} + +/** + * @brief Collection + */ +struct Collection { + /** @brief Collection ID. */ + std::string id; + /** @brief Collection creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Collection update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Collection permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + std::vector permissions; + /** @brief Database ID. */ + std::string databaseId; + /** @brief Collection name. */ + std::string name; + /** @brief Collection enabled. Can be 'enabled' or 'disabled'. When disabled, the collection is inaccessible to users, but remains accessible to Server SDKs using API keys. */ + bool enabled; + /** @brief Whether document-level permissions are enabled. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + bool documentSecurity; + /** @brief Collection attributes. */ + std::vector attributes; + /** @brief Collection indexes. */ + std::vector indexes; + /** @brief Maximum document size in bytes. Returns 0 when no limit applies. */ + int64_t bytesMax; + /** @brief Currently used document size in bytes based on defined attributes. */ + int64_t bytesUsed; + + /** @brief Deserialize from JSON */ + static Collection fromJson(const nlohmann::json& j) { + Collection obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("$permissions")) { + if (j["$permissions"].is_null()) { + throw appwrite::DeserializationException("Required field '$permissions' is null"); + } else { + obj.permissions = j["$permissions"].get>(); + } + } + if (j.contains("databaseId")) { + if (j["databaseId"].is_null()) { + throw appwrite::DeserializationException("Required field 'databaseId' is null"); + } else { + obj.databaseId = j["databaseId"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("enabled")) { + if (j["enabled"].is_null()) { + throw appwrite::DeserializationException("Required field 'enabled' is null"); + } else { + obj.enabled = j["enabled"].get(); + } + } + if (j.contains("documentSecurity")) { + if (j["documentSecurity"].is_null()) { + throw appwrite::DeserializationException("Required field 'documentSecurity' is null"); + } else { + obj.documentSecurity = j["documentSecurity"].get(); + } + } + if (j.contains("attributes")) { + if (j["attributes"].is_null()) { + throw appwrite::DeserializationException("Required field 'attributes' is null"); + } else { + obj.attributes = j["attributes"].get>(); + } + } + if (j.contains("indexes")) { + if (j["indexes"].is_null()) { + throw appwrite::DeserializationException("Required field 'indexes' is null"); + } else { + for (auto& item : j["indexes"]) { + obj.indexes.push_back(Index::fromJson(item)); + } + } + } + if (j.contains("bytesMax")) { + if (j["bytesMax"].is_null()) { + throw appwrite::DeserializationException("Required field 'bytesMax' is null"); + } else { + obj.bytesMax = j["bytesMax"].get(); + } + } + if (j.contains("bytesUsed")) { + if (j["bytesUsed"].is_null()) { + throw appwrite::DeserializationException("Required field 'bytesUsed' is null"); + } else { + obj.bytesUsed = j["bytesUsed"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["$permissions"] = this->permissions; + } + { + j["databaseId"] = this->databaseId; + } + { + j["name"] = this->name; + } + { + j["enabled"] = this->enabled; + } + { + j["documentSecurity"] = this->documentSecurity; + } + { + j["attributes"] = this->attributes; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->indexes) arr.push_back(item.toJson()); + j["indexes"] = arr; + } + { + j["bytesMax"] = this->bytesMax; + } + { + j["bytesUsed"] = this->bytesUsed; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Collection& x) { + x = Collection::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Collection& x) { + j = x.toJson(); +} + +/** + * @brief Collections List + */ +struct CollectionList { + /** @brief Total number of collections that matched your query. */ + int64_t total; + /** @brief List of collections. */ + std::vector collections; + + /** @brief Deserialize from JSON */ + static CollectionList fromJson(const nlohmann::json& j) { + CollectionList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("collections")) { + if (j["collections"].is_null()) { + throw appwrite::DeserializationException("Required field 'collections' is null"); + } else { + for (auto& item : j["collections"]) { + obj.collections.push_back(Collection::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->collections) arr.push_back(item.toJson()); + j["collections"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, CollectionList& x) { + x = CollectionList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const CollectionList& x) { + j = x.toJson(); +} + +/** + * @brief Database + */ +struct Database { + /** @brief Database ID. */ + std::string id; + /** @brief Database name. */ + std::string name; + /** @brief Database creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Database update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief If database is enabled. Can be 'enabled' or 'disabled'. When disabled, the database is inaccessible to users, but remains accessible to Server SDKs using API keys. */ + bool enabled; + /** @brief Database type. */ + appwrite::enums::DatabaseType type; + /** @brief Database backup policies. */ + std::vector policies; + /** @brief Database backup archives. */ + std::vector archives; + + /** @brief Deserialize from JSON */ + static Database fromJson(const nlohmann::json& j) { + Database obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("enabled")) { + if (j["enabled"].is_null()) { + throw appwrite::DeserializationException("Required field 'enabled' is null"); + } else { + obj.enabled = j["enabled"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("policies")) { + if (j["policies"].is_null()) { + throw appwrite::DeserializationException("Required field 'policies' is null"); + } else { + for (auto& item : j["policies"]) { + obj.policies.push_back(Index::fromJson(item)); + } + } + } + if (j.contains("archives")) { + if (j["archives"].is_null()) { + throw appwrite::DeserializationException("Required field 'archives' is null"); + } else { + for (auto& item : j["archives"]) { + obj.archives.push_back(Collection::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["name"] = this->name; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["enabled"] = this->enabled; + } + { + j["type"] = appwrite::enums::toString(this->type); + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->policies) arr.push_back(item.toJson()); + j["policies"] = arr; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->archives) arr.push_back(item.toJson()); + j["archives"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Database& x) { + x = Database::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Database& x) { + j = x.toJson(); +} + +/** + * @brief Databases List + */ +struct DatabaseList { + /** @brief Total number of databases that matched your query. */ + int64_t total; + /** @brief List of databases. */ + std::vector databases; + + /** @brief Deserialize from JSON */ + static DatabaseList fromJson(const nlohmann::json& j) { + DatabaseList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("databases")) { + if (j["databases"].is_null()) { + throw appwrite::DeserializationException("Required field 'databases' is null"); + } else { + for (auto& item : j["databases"]) { + obj.databases.push_back(Database::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->databases) arr.push_back(item.toJson()); + j["databases"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, DatabaseList& x) { + x = DatabaseList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const DatabaseList& x) { + j = x.toJson(); +} + +/** + * @brief Indexes List + */ +struct IndexList { + /** @brief Total number of indexes that matched your query. */ + int64_t total; + /** @brief List of indexes. */ + std::vector indexes; + + /** @brief Deserialize from JSON */ + static IndexList fromJson(const nlohmann::json& j) { + IndexList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("indexes")) { + if (j["indexes"].is_null()) { + throw appwrite::DeserializationException("Required field 'indexes' is null"); + } else { + for (auto& item : j["indexes"]) { + obj.indexes.push_back(Index::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->indexes) arr.push_back(item.toJson()); + j["indexes"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, IndexList& x) { + x = IndexList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const IndexList& x) { + j = x.toJson(); +} + +/** + * @brief Column Indexes List + */ +struct ColumnIndexList { + /** @brief Total number of indexes that matched your query. */ + int64_t total; + /** @brief List of indexes. */ + std::vector indexes; + + /** @brief Deserialize from JSON */ + static ColumnIndexList fromJson(const nlohmann::json& j) { + ColumnIndexList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("indexes")) { + if (j["indexes"].is_null()) { + throw appwrite::DeserializationException("Required field 'indexes' is null"); + } else { + for (auto& item : j["indexes"]) { + obj.indexes.push_back(ColumnIndex::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->indexes) arr.push_back(item.toJson()); + j["indexes"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnIndexList& x) { + x = ColumnIndexList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnIndexList& x) { + j = x.toJson(); +} + +/** + * @brief Preferences + */ +struct Preferences { + nlohmann::json data = nlohmann::json::object(); + + /** @brief Deserialize from JSON */ + static Preferences fromJson(const nlohmann::json& j) { + Preferences obj; + obj.data = j; + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + return data; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Preferences& x) { + x = Preferences::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Preferences& x) { + j = x.toJson(); +} + +/** + * @brief Target + */ +struct Target { + /** @brief Target ID. */ + std::string id; + /** @brief Target creation time in ISO 8601 format. */ + std::string createdAt; + /** @brief Target update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Target Name. */ + std::string name; + /** @brief User ID. */ + std::string userId; + /** @brief Provider ID. */ + std::optional providerId = std::nullopt; + /** @brief The target provider type. Can be one of the following: `email`, `sms` or `push`. */ + std::string providerType; + /** @brief The target identifier. */ + std::string identifier; + /** @brief Is the target expired. */ + bool expired; + + /** @brief Deserialize from JSON */ + static Target fromJson(const nlohmann::json& j) { + Target obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("userId")) { + if (j["userId"].is_null()) { + throw appwrite::DeserializationException("Required field 'userId' is null"); + } else { + obj.userId = j["userId"].get(); + } + } + if (j.contains("providerId")) { + if (j["providerId"].is_null()) { + obj.providerId = std::nullopt; + } else { + obj.providerId = j["providerId"].get>(); + } + } + if (j.contains("providerType")) { + if (j["providerType"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerType' is null"); + } else { + obj.providerType = j["providerType"].get(); + } + } + if (j.contains("identifier")) { + if (j["identifier"].is_null()) { + throw appwrite::DeserializationException("Required field 'identifier' is null"); + } else { + obj.identifier = j["identifier"].get(); + } + } + if (j.contains("expired")) { + if (j["expired"].is_null()) { + throw appwrite::DeserializationException("Required field 'expired' is null"); + } else { + obj.expired = j["expired"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["name"] = this->name; + } + { + j["userId"] = this->userId; + } + if (this->providerId.has_value()) { + j["providerId"] = this->providerId.value(); + } + { + j["providerType"] = this->providerType; + } + { + j["identifier"] = this->identifier; + } + { + j["expired"] = this->expired; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Target& x) { + x = Target::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Target& x) { + j = x.toJson(); +} + +/** + * @brief User + */ +struct User { + /** @brief User ID. */ + std::string id; + /** @brief User creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief User update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief User name. */ + std::string name; + /** @brief Hashed user password. */ + std::optional password = std::nullopt; + /** @brief Password hashing algorithm. */ + std::optional hash = std::nullopt; + /** @brief Password hashing algorithm configuration. */ + std::optional hashOptions = std::nullopt; + /** @brief User registration date in ISO 8601 format. */ + std::string registration; + /** @brief User status. Pass `true` for enabled and `false` for disabled. */ + bool status; + /** @brief Labels for the user. */ + std::vector labels; + /** @brief Password update time in ISO 8601 format. */ + std::string passwordUpdate; + /** @brief User email address. */ + std::string email; + /** @brief User phone number in E.164 format. */ + std::string phone; + /** @brief Email verification status. */ + bool emailVerification; + /** @brief Phone verification status. */ + bool phoneVerification; + /** @brief Multi factor authentication status. */ + bool mfa; + /** @brief User preferences as a key-value object */ + appwrite::models::Preferences prefs; + /** @brief A user-owned message receiver. A single user may have multiple e.g. emails, phones, and a browser. Each target is registered with a single provider. */ + std::vector targets; + /** @brief Most recent access date in ISO 8601 format. This attribute is only updated again after 24 hours. */ + std::string accessedAt; + /** @brief Whether the user can impersonate other users. */ + std::optional impersonator = std::nullopt; + /** @brief ID of the original actor performing the impersonation. Present only when the current request is impersonating another user. Internal audit logs attribute the action to this user, while the impersonated target is recorded only in internal audit payload data. */ + std::optional impersonatorUserId = std::nullopt; + + /** @brief Deserialize from JSON */ + static User fromJson(const nlohmann::json& j) { + User obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("password")) { + if (j["password"].is_null()) { + obj.password = std::nullopt; + } else { + obj.password = j["password"].get>(); + } + } + if (j.contains("hash")) { + if (j["hash"].is_null()) { + obj.hash = std::nullopt; + } else { + obj.hash = j["hash"].get>(); + } + } + if (j.contains("hashOptions")) { + if (j["hashOptions"].is_null()) { + obj.hashOptions = std::nullopt; + } else { + obj.hashOptions = j["hashOptions"].get>(); + } + } + if (j.contains("registration")) { + if (j["registration"].is_null()) { + throw appwrite::DeserializationException("Required field 'registration' is null"); + } else { + obj.registration = j["registration"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("labels")) { + if (j["labels"].is_null()) { + throw appwrite::DeserializationException("Required field 'labels' is null"); + } else { + obj.labels = j["labels"].get>(); + } + } + if (j.contains("passwordUpdate")) { + if (j["passwordUpdate"].is_null()) { + throw appwrite::DeserializationException("Required field 'passwordUpdate' is null"); + } else { + obj.passwordUpdate = j["passwordUpdate"].get(); + } + } + if (j.contains("email")) { + if (j["email"].is_null()) { + throw appwrite::DeserializationException("Required field 'email' is null"); + } else { + obj.email = j["email"].get(); + } + } + if (j.contains("phone")) { + if (j["phone"].is_null()) { + throw appwrite::DeserializationException("Required field 'phone' is null"); + } else { + obj.phone = j["phone"].get(); + } + } + if (j.contains("emailVerification")) { + if (j["emailVerification"].is_null()) { + throw appwrite::DeserializationException("Required field 'emailVerification' is null"); + } else { + obj.emailVerification = j["emailVerification"].get(); + } + } + if (j.contains("phoneVerification")) { + if (j["phoneVerification"].is_null()) { + throw appwrite::DeserializationException("Required field 'phoneVerification' is null"); + } else { + obj.phoneVerification = j["phoneVerification"].get(); + } + } + if (j.contains("mfa")) { + if (j["mfa"].is_null()) { + throw appwrite::DeserializationException("Required field 'mfa' is null"); + } else { + obj.mfa = j["mfa"].get(); + } + } + if (j.contains("prefs")) { + if (j["prefs"].is_null()) { + throw appwrite::DeserializationException("Required field 'prefs' is null"); + } else { + obj.prefs = Preferences::fromJson(j["prefs"]); + } + } + if (j.contains("targets")) { + if (j["targets"].is_null()) { + throw appwrite::DeserializationException("Required field 'targets' is null"); + } else { + for (auto& item : j["targets"]) { + obj.targets.push_back(Target::fromJson(item)); + } + } + } + if (j.contains("accessedAt")) { + if (j["accessedAt"].is_null()) { + throw appwrite::DeserializationException("Required field 'accessedAt' is null"); + } else { + obj.accessedAt = j["accessedAt"].get(); + } + } + if (j.contains("impersonator")) { + if (j["impersonator"].is_null()) { + obj.impersonator = std::nullopt; + } else { + obj.impersonator = j["impersonator"].get>(); + } + } + if (j.contains("impersonatorUserId")) { + if (j["impersonatorUserId"].is_null()) { + obj.impersonatorUserId = std::nullopt; + } else { + obj.impersonatorUserId = j["impersonatorUserId"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["name"] = this->name; + } + if (this->password.has_value()) { + j["password"] = this->password.value(); + } + if (this->hash.has_value()) { + j["hash"] = this->hash.value(); + } + if (this->hashOptions.has_value()) { + j["hashOptions"] = this->hashOptions.value(); + } + { + j["registration"] = this->registration; + } + { + j["status"] = this->status; + } + { + j["labels"] = this->labels; + } + { + j["passwordUpdate"] = this->passwordUpdate; + } + { + j["email"] = this->email; + } + { + j["phone"] = this->phone; + } + { + j["emailVerification"] = this->emailVerification; + } + { + j["phoneVerification"] = this->phoneVerification; + } + { + j["mfa"] = this->mfa; + } + { + j["prefs"] = this->prefs.toJson(); + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->targets) arr.push_back(item.toJson()); + j["targets"] = arr; + } + { + j["accessedAt"] = this->accessedAt; + } + if (this->impersonator.has_value()) { + j["impersonator"] = this->impersonator.value(); + } + if (this->impersonatorUserId.has_value()) { + j["impersonatorUserId"] = this->impersonatorUserId.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, User& x) { + x = User::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const User& x) { + j = x.toJson(); +} + +/** + * @brief Users List + */ +struct UserList { + /** @brief Total number of users that matched your query. */ + int64_t total; + /** @brief List of users. */ + std::vector users; + + /** @brief Deserialize from JSON */ + static UserList fromJson(const nlohmann::json& j) { + UserList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("users")) { + if (j["users"].is_null()) { + throw appwrite::DeserializationException("Required field 'users' is null"); + } else { + for (auto& item : j["users"]) { + obj.users.push_back(User::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->users) arr.push_back(item.toJson()); + j["users"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, UserList& x) { + x = UserList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const UserList& x) { + j = x.toJson(); +} + +/** + * @brief Session + */ +struct Session { + /** @brief Session ID. */ + std::string id; + /** @brief Session creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Session update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief User ID. */ + std::string userId; + /** @brief Session expiration date in ISO 8601 format. */ + std::string expire; + /** @brief Session Provider. */ + std::string provider; + /** @brief Session Provider User ID. */ + std::string providerUid; + /** @brief Session Provider Access Token. */ + std::string providerAccessToken; + /** @brief The date of when the access token expires in ISO 8601 format. */ + std::string providerAccessTokenExpiry; + /** @brief Session Provider Refresh Token. */ + std::string providerRefreshToken; + /** @brief IP in use when the session was created. */ + std::string ip; + /** @brief Operating system code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). */ + std::string osCode; + /** @brief Operating system name. */ + std::string osName; + /** @brief Operating system version. */ + std::string osVersion; + /** @brief Client type. */ + std::string clientType; + /** @brief Client code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). */ + std::string clientCode; + /** @brief Client name. */ + std::string clientName; + /** @brief Client version. */ + std::string clientVersion; + /** @brief Client engine name. */ + std::string clientEngine; + /** @brief Client engine name. */ + std::string clientEngineVersion; + /** @brief Device name. */ + std::string deviceName; + /** @brief Device brand name. */ + std::string deviceBrand; + /** @brief Device model name. */ + std::string deviceModel; + /** @brief Country two-character ISO 3166-1 alpha code. */ + std::string countryCode; + /** @brief Country name. */ + std::string countryName; + /** @brief Returns true if this the current user session. */ + bool current; + /** @brief Returns a list of active session factors. */ + std::vector factors; + /** @brief Secret used to authenticate the user. Only included if the request was made with an API key */ + std::string secret; + /** @brief Most recent date in ISO 8601 format when the session successfully passed MFA challenge. */ + std::string mfaUpdatedAt; + + /** @brief Deserialize from JSON */ + static Session fromJson(const nlohmann::json& j) { + Session obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("userId")) { + if (j["userId"].is_null()) { + throw appwrite::DeserializationException("Required field 'userId' is null"); + } else { + obj.userId = j["userId"].get(); + } + } + if (j.contains("expire")) { + if (j["expire"].is_null()) { + throw appwrite::DeserializationException("Required field 'expire' is null"); + } else { + obj.expire = j["expire"].get(); + } + } + if (j.contains("provider")) { + if (j["provider"].is_null()) { + throw appwrite::DeserializationException("Required field 'provider' is null"); + } else { + obj.provider = j["provider"].get(); + } + } + if (j.contains("providerUid")) { + if (j["providerUid"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerUid' is null"); + } else { + obj.providerUid = j["providerUid"].get(); + } + } + if (j.contains("providerAccessToken")) { + if (j["providerAccessToken"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerAccessToken' is null"); + } else { + obj.providerAccessToken = j["providerAccessToken"].get(); + } + } + if (j.contains("providerAccessTokenExpiry")) { + if (j["providerAccessTokenExpiry"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerAccessTokenExpiry' is null"); + } else { + obj.providerAccessTokenExpiry = j["providerAccessTokenExpiry"].get(); + } + } + if (j.contains("providerRefreshToken")) { + if (j["providerRefreshToken"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerRefreshToken' is null"); + } else { + obj.providerRefreshToken = j["providerRefreshToken"].get(); + } + } + if (j.contains("ip")) { + if (j["ip"].is_null()) { + throw appwrite::DeserializationException("Required field 'ip' is null"); + } else { + obj.ip = j["ip"].get(); + } + } + if (j.contains("osCode")) { + if (j["osCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'osCode' is null"); + } else { + obj.osCode = j["osCode"].get(); + } + } + if (j.contains("osName")) { + if (j["osName"].is_null()) { + throw appwrite::DeserializationException("Required field 'osName' is null"); + } else { + obj.osName = j["osName"].get(); + } + } + if (j.contains("osVersion")) { + if (j["osVersion"].is_null()) { + throw appwrite::DeserializationException("Required field 'osVersion' is null"); + } else { + obj.osVersion = j["osVersion"].get(); + } + } + if (j.contains("clientType")) { + if (j["clientType"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientType' is null"); + } else { + obj.clientType = j["clientType"].get(); + } + } + if (j.contains("clientCode")) { + if (j["clientCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientCode' is null"); + } else { + obj.clientCode = j["clientCode"].get(); + } + } + if (j.contains("clientName")) { + if (j["clientName"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientName' is null"); + } else { + obj.clientName = j["clientName"].get(); + } + } + if (j.contains("clientVersion")) { + if (j["clientVersion"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientVersion' is null"); + } else { + obj.clientVersion = j["clientVersion"].get(); + } + } + if (j.contains("clientEngine")) { + if (j["clientEngine"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientEngine' is null"); + } else { + obj.clientEngine = j["clientEngine"].get(); + } + } + if (j.contains("clientEngineVersion")) { + if (j["clientEngineVersion"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientEngineVersion' is null"); + } else { + obj.clientEngineVersion = j["clientEngineVersion"].get(); + } + } + if (j.contains("deviceName")) { + if (j["deviceName"].is_null()) { + throw appwrite::DeserializationException("Required field 'deviceName' is null"); + } else { + obj.deviceName = j["deviceName"].get(); + } + } + if (j.contains("deviceBrand")) { + if (j["deviceBrand"].is_null()) { + throw appwrite::DeserializationException("Required field 'deviceBrand' is null"); + } else { + obj.deviceBrand = j["deviceBrand"].get(); + } + } + if (j.contains("deviceModel")) { + if (j["deviceModel"].is_null()) { + throw appwrite::DeserializationException("Required field 'deviceModel' is null"); + } else { + obj.deviceModel = j["deviceModel"].get(); + } + } + if (j.contains("countryCode")) { + if (j["countryCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'countryCode' is null"); + } else { + obj.countryCode = j["countryCode"].get(); + } + } + if (j.contains("countryName")) { + if (j["countryName"].is_null()) { + throw appwrite::DeserializationException("Required field 'countryName' is null"); + } else { + obj.countryName = j["countryName"].get(); + } + } + if (j.contains("current")) { + if (j["current"].is_null()) { + throw appwrite::DeserializationException("Required field 'current' is null"); + } else { + obj.current = j["current"].get(); + } + } + if (j.contains("factors")) { + if (j["factors"].is_null()) { + throw appwrite::DeserializationException("Required field 'factors' is null"); + } else { + obj.factors = j["factors"].get>(); + } + } + if (j.contains("secret")) { + if (j["secret"].is_null()) { + throw appwrite::DeserializationException("Required field 'secret' is null"); + } else { + obj.secret = j["secret"].get(); + } + } + if (j.contains("mfaUpdatedAt")) { + if (j["mfaUpdatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field 'mfaUpdatedAt' is null"); + } else { + obj.mfaUpdatedAt = j["mfaUpdatedAt"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["userId"] = this->userId; + } + { + j["expire"] = this->expire; + } + { + j["provider"] = this->provider; + } + { + j["providerUid"] = this->providerUid; + } + { + j["providerAccessToken"] = this->providerAccessToken; + } + { + j["providerAccessTokenExpiry"] = this->providerAccessTokenExpiry; + } + { + j["providerRefreshToken"] = this->providerRefreshToken; + } + { + j["ip"] = this->ip; + } + { + j["osCode"] = this->osCode; + } + { + j["osName"] = this->osName; + } + { + j["osVersion"] = this->osVersion; + } + { + j["clientType"] = this->clientType; + } + { + j["clientCode"] = this->clientCode; + } + { + j["clientName"] = this->clientName; + } + { + j["clientVersion"] = this->clientVersion; + } + { + j["clientEngine"] = this->clientEngine; + } + { + j["clientEngineVersion"] = this->clientEngineVersion; + } + { + j["deviceName"] = this->deviceName; + } + { + j["deviceBrand"] = this->deviceBrand; + } + { + j["deviceModel"] = this->deviceModel; + } + { + j["countryCode"] = this->countryCode; + } + { + j["countryName"] = this->countryName; + } + { + j["current"] = this->current; + } + { + j["factors"] = this->factors; + } + { + j["secret"] = this->secret; + } + { + j["mfaUpdatedAt"] = this->mfaUpdatedAt; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Session& x) { + x = Session::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Session& x) { + j = x.toJson(); +} + +/** + * @brief Sessions List + */ +struct SessionList { + /** @brief Total number of sessions that matched your query. */ + int64_t total; + /** @brief List of sessions. */ + std::vector sessions; + + /** @brief Deserialize from JSON */ + static SessionList fromJson(const nlohmann::json& j) { + SessionList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("sessions")) { + if (j["sessions"].is_null()) { + throw appwrite::DeserializationException("Required field 'sessions' is null"); + } else { + for (auto& item : j["sessions"]) { + obj.sessions.push_back(Session::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->sessions) arr.push_back(item.toJson()); + j["sessions"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, SessionList& x) { + x = SessionList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const SessionList& x) { + j = x.toJson(); +} + +/** + * @brief Identity + */ +struct Identity { + /** @brief Identity ID. */ + std::string id; + /** @brief Identity creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Identity update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief User ID. */ + std::string userId; + /** @brief Identity Provider. */ + std::string provider; + /** @brief ID of the User in the Identity Provider. */ + std::string providerUid; + /** @brief Email of the User in the Identity Provider. */ + std::string providerEmail; + /** @brief Identity Provider Access Token. */ + std::string providerAccessToken; + /** @brief The date of when the access token expires in ISO 8601 format. */ + std::string providerAccessTokenExpiry; + /** @brief Identity Provider Refresh Token. */ + std::string providerRefreshToken; + + /** @brief Deserialize from JSON */ + static Identity fromJson(const nlohmann::json& j) { + Identity obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("userId")) { + if (j["userId"].is_null()) { + throw appwrite::DeserializationException("Required field 'userId' is null"); + } else { + obj.userId = j["userId"].get(); + } + } + if (j.contains("provider")) { + if (j["provider"].is_null()) { + throw appwrite::DeserializationException("Required field 'provider' is null"); + } else { + obj.provider = j["provider"].get(); + } + } + if (j.contains("providerUid")) { + if (j["providerUid"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerUid' is null"); + } else { + obj.providerUid = j["providerUid"].get(); + } + } + if (j.contains("providerEmail")) { + if (j["providerEmail"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerEmail' is null"); + } else { + obj.providerEmail = j["providerEmail"].get(); + } + } + if (j.contains("providerAccessToken")) { + if (j["providerAccessToken"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerAccessToken' is null"); + } else { + obj.providerAccessToken = j["providerAccessToken"].get(); + } + } + if (j.contains("providerAccessTokenExpiry")) { + if (j["providerAccessTokenExpiry"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerAccessTokenExpiry' is null"); + } else { + obj.providerAccessTokenExpiry = j["providerAccessTokenExpiry"].get(); + } + } + if (j.contains("providerRefreshToken")) { + if (j["providerRefreshToken"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerRefreshToken' is null"); + } else { + obj.providerRefreshToken = j["providerRefreshToken"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["userId"] = this->userId; + } + { + j["provider"] = this->provider; + } + { + j["providerUid"] = this->providerUid; + } + { + j["providerEmail"] = this->providerEmail; + } + { + j["providerAccessToken"] = this->providerAccessToken; + } + { + j["providerAccessTokenExpiry"] = this->providerAccessTokenExpiry; + } + { + j["providerRefreshToken"] = this->providerRefreshToken; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Identity& x) { + x = Identity::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Identity& x) { + j = x.toJson(); +} + +/** + * @brief Identities List + */ +struct IdentityList { + /** @brief Total number of identities that matched your query. */ + int64_t total; + /** @brief List of identities. */ + std::vector identities; + + /** @brief Deserialize from JSON */ + static IdentityList fromJson(const nlohmann::json& j) { + IdentityList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("identities")) { + if (j["identities"].is_null()) { + throw appwrite::DeserializationException("Required field 'identities' is null"); + } else { + for (auto& item : j["identities"]) { + obj.identities.push_back(Identity::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->identities) arr.push_back(item.toJson()); + j["identities"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, IdentityList& x) { + x = IdentityList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const IdentityList& x) { + j = x.toJson(); +} + +/** + * @brief Log + */ +struct Log { + /** @brief Event name. */ + std::string event; + /** @brief User ID of the actor recorded for this log. During impersonation, this is the original impersonator, not the impersonated target user. */ + std::string userId; + /** @brief User email of the actor recorded for this log. During impersonation, this is the original impersonator. */ + std::string userEmail; + /** @brief User name of the actor recorded for this log. During impersonation, this is the original impersonator. */ + std::string userName; + /** @brief API mode when event triggered. */ + std::string mode; + /** @brief User type who triggered the audit log. Possible values: user, admin, guest, keyProject, keyAccount, keyOrganization. */ + std::string userType; + /** @brief IP session in use when the session was created. */ + std::string ip; + /** @brief Log creation date in ISO 8601 format. */ + std::string time; + /** @brief Operating system code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/os.json). */ + std::string osCode; + /** @brief Operating system name. */ + std::string osName; + /** @brief Operating system version. */ + std::string osVersion; + /** @brief Client type. */ + std::string clientType; + /** @brief Client code name. View list of [available options](https://github.com/appwrite/appwrite/blob/master/docs/lists/clients.json). */ + std::string clientCode; + /** @brief Client name. */ + std::string clientName; + /** @brief Client version. */ + std::string clientVersion; + /** @brief Client engine name. */ + std::string clientEngine; + /** @brief Client engine name. */ + std::string clientEngineVersion; + /** @brief Device name. */ + std::string deviceName; + /** @brief Device brand name. */ + std::string deviceBrand; + /** @brief Device model name. */ + std::string deviceModel; + /** @brief Country two-character ISO 3166-1 alpha code. */ + std::string countryCode; + /** @brief Country name. */ + std::string countryName; + + /** @brief Deserialize from JSON */ + static Log fromJson(const nlohmann::json& j) { + Log obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("event")) { + if (j["event"].is_null()) { + throw appwrite::DeserializationException("Required field 'event' is null"); + } else { + obj.event = j["event"].get(); + } + } + if (j.contains("userId")) { + if (j["userId"].is_null()) { + throw appwrite::DeserializationException("Required field 'userId' is null"); + } else { + obj.userId = j["userId"].get(); + } + } + if (j.contains("userEmail")) { + if (j["userEmail"].is_null()) { + throw appwrite::DeserializationException("Required field 'userEmail' is null"); + } else { + obj.userEmail = j["userEmail"].get(); + } + } + if (j.contains("userName")) { + if (j["userName"].is_null()) { + throw appwrite::DeserializationException("Required field 'userName' is null"); + } else { + obj.userName = j["userName"].get(); + } + } + if (j.contains("mode")) { + if (j["mode"].is_null()) { + throw appwrite::DeserializationException("Required field 'mode' is null"); + } else { + obj.mode = j["mode"].get(); + } + } + if (j.contains("userType")) { + if (j["userType"].is_null()) { + throw appwrite::DeserializationException("Required field 'userType' is null"); + } else { + obj.userType = j["userType"].get(); + } + } + if (j.contains("ip")) { + if (j["ip"].is_null()) { + throw appwrite::DeserializationException("Required field 'ip' is null"); + } else { + obj.ip = j["ip"].get(); + } + } + if (j.contains("time")) { + if (j["time"].is_null()) { + throw appwrite::DeserializationException("Required field 'time' is null"); + } else { + obj.time = j["time"].get(); + } + } + if (j.contains("osCode")) { + if (j["osCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'osCode' is null"); + } else { + obj.osCode = j["osCode"].get(); + } + } + if (j.contains("osName")) { + if (j["osName"].is_null()) { + throw appwrite::DeserializationException("Required field 'osName' is null"); + } else { + obj.osName = j["osName"].get(); + } + } + if (j.contains("osVersion")) { + if (j["osVersion"].is_null()) { + throw appwrite::DeserializationException("Required field 'osVersion' is null"); + } else { + obj.osVersion = j["osVersion"].get(); + } + } + if (j.contains("clientType")) { + if (j["clientType"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientType' is null"); + } else { + obj.clientType = j["clientType"].get(); + } + } + if (j.contains("clientCode")) { + if (j["clientCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientCode' is null"); + } else { + obj.clientCode = j["clientCode"].get(); + } + } + if (j.contains("clientName")) { + if (j["clientName"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientName' is null"); + } else { + obj.clientName = j["clientName"].get(); + } + } + if (j.contains("clientVersion")) { + if (j["clientVersion"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientVersion' is null"); + } else { + obj.clientVersion = j["clientVersion"].get(); + } + } + if (j.contains("clientEngine")) { + if (j["clientEngine"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientEngine' is null"); + } else { + obj.clientEngine = j["clientEngine"].get(); + } + } + if (j.contains("clientEngineVersion")) { + if (j["clientEngineVersion"].is_null()) { + throw appwrite::DeserializationException("Required field 'clientEngineVersion' is null"); + } else { + obj.clientEngineVersion = j["clientEngineVersion"].get(); + } + } + if (j.contains("deviceName")) { + if (j["deviceName"].is_null()) { + throw appwrite::DeserializationException("Required field 'deviceName' is null"); + } else { + obj.deviceName = j["deviceName"].get(); + } + } + if (j.contains("deviceBrand")) { + if (j["deviceBrand"].is_null()) { + throw appwrite::DeserializationException("Required field 'deviceBrand' is null"); + } else { + obj.deviceBrand = j["deviceBrand"].get(); + } + } + if (j.contains("deviceModel")) { + if (j["deviceModel"].is_null()) { + throw appwrite::DeserializationException("Required field 'deviceModel' is null"); + } else { + obj.deviceModel = j["deviceModel"].get(); + } + } + if (j.contains("countryCode")) { + if (j["countryCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'countryCode' is null"); + } else { + obj.countryCode = j["countryCode"].get(); + } + } + if (j.contains("countryName")) { + if (j["countryName"].is_null()) { + throw appwrite::DeserializationException("Required field 'countryName' is null"); + } else { + obj.countryName = j["countryName"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["event"] = this->event; + } + { + j["userId"] = this->userId; + } + { + j["userEmail"] = this->userEmail; + } + { + j["userName"] = this->userName; + } + { + j["mode"] = this->mode; + } + { + j["userType"] = this->userType; + } + { + j["ip"] = this->ip; + } + { + j["time"] = this->time; + } + { + j["osCode"] = this->osCode; + } + { + j["osName"] = this->osName; + } + { + j["osVersion"] = this->osVersion; + } + { + j["clientType"] = this->clientType; + } + { + j["clientCode"] = this->clientCode; + } + { + j["clientName"] = this->clientName; + } + { + j["clientVersion"] = this->clientVersion; + } + { + j["clientEngine"] = this->clientEngine; + } + { + j["clientEngineVersion"] = this->clientEngineVersion; + } + { + j["deviceName"] = this->deviceName; + } + { + j["deviceBrand"] = this->deviceBrand; + } + { + j["deviceModel"] = this->deviceModel; + } + { + j["countryCode"] = this->countryCode; + } + { + j["countryName"] = this->countryName; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Log& x) { + x = Log::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Log& x) { + j = x.toJson(); +} + +/** + * @brief Logs List + */ +struct LogList { + /** @brief Total number of logs that matched your query. */ + int64_t total; + /** @brief List of logs. */ + std::vector logs; + + /** @brief Deserialize from JSON */ + static LogList fromJson(const nlohmann::json& j) { + LogList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("logs")) { + if (j["logs"].is_null()) { + throw appwrite::DeserializationException("Required field 'logs' is null"); + } else { + for (auto& item : j["logs"]) { + obj.logs.push_back(Log::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->logs) arr.push_back(item.toJson()); + j["logs"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, LogList& x) { + x = LogList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const LogList& x) { + j = x.toJson(); +} + +/** + * @brief File + */ +struct File { + /** @brief File ID. */ + std::string id; + /** @brief Bucket ID. */ + std::string bucketId; + /** @brief File creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief File update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief File permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + std::vector permissions; + /** @brief File name. */ + std::string name; + /** @brief File MD5 signature. */ + std::string signature; + /** @brief File mime type. */ + std::string mimeType; + /** @brief File original size in bytes. */ + int64_t sizeOriginal; + /** @brief Total number of chunks available */ + int64_t chunksTotal; + /** @brief Total number of chunks uploaded */ + int64_t chunksUploaded; + /** @brief Whether file contents are encrypted at rest. */ + bool encryption; + /** @brief Compression algorithm used for the file. Will be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd). */ + std::string compression; + + /** @brief Deserialize from JSON */ + static File fromJson(const nlohmann::json& j) { + File obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("bucketId")) { + if (j["bucketId"].is_null()) { + throw appwrite::DeserializationException("Required field 'bucketId' is null"); + } else { + obj.bucketId = j["bucketId"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("$permissions")) { + if (j["$permissions"].is_null()) { + throw appwrite::DeserializationException("Required field '$permissions' is null"); + } else { + obj.permissions = j["$permissions"].get>(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("signature")) { + if (j["signature"].is_null()) { + throw appwrite::DeserializationException("Required field 'signature' is null"); + } else { + obj.signature = j["signature"].get(); + } + } + if (j.contains("mimeType")) { + if (j["mimeType"].is_null()) { + throw appwrite::DeserializationException("Required field 'mimeType' is null"); + } else { + obj.mimeType = j["mimeType"].get(); + } + } + if (j.contains("sizeOriginal")) { + if (j["sizeOriginal"].is_null()) { + throw appwrite::DeserializationException("Required field 'sizeOriginal' is null"); + } else { + obj.sizeOriginal = j["sizeOriginal"].get(); + } + } + if (j.contains("chunksTotal")) { + if (j["chunksTotal"].is_null()) { + throw appwrite::DeserializationException("Required field 'chunksTotal' is null"); + } else { + obj.chunksTotal = j["chunksTotal"].get(); + } + } + if (j.contains("chunksUploaded")) { + if (j["chunksUploaded"].is_null()) { + throw appwrite::DeserializationException("Required field 'chunksUploaded' is null"); + } else { + obj.chunksUploaded = j["chunksUploaded"].get(); + } + } + if (j.contains("encryption")) { + if (j["encryption"].is_null()) { + throw appwrite::DeserializationException("Required field 'encryption' is null"); + } else { + obj.encryption = j["encryption"].get(); + } + } + if (j.contains("compression")) { + if (j["compression"].is_null()) { + throw appwrite::DeserializationException("Required field 'compression' is null"); + } else { + obj.compression = j["compression"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["bucketId"] = this->bucketId; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["$permissions"] = this->permissions; + } + { + j["name"] = this->name; + } + { + j["signature"] = this->signature; + } + { + j["mimeType"] = this->mimeType; + } + { + j["sizeOriginal"] = this->sizeOriginal; + } + { + j["chunksTotal"] = this->chunksTotal; + } + { + j["chunksUploaded"] = this->chunksUploaded; + } + { + j["encryption"] = this->encryption; + } + { + j["compression"] = this->compression; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, File& x) { + x = File::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const File& x) { + j = x.toJson(); +} + +/** + * @brief Files List + */ +struct FileList { + /** @brief Total number of files that matched your query. */ + int64_t total; + /** @brief List of files. */ + std::vector files; + + /** @brief Deserialize from JSON */ + static FileList fromJson(const nlohmann::json& j) { + FileList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("files")) { + if (j["files"].is_null()) { + throw appwrite::DeserializationException("Required field 'files' is null"); + } else { + for (auto& item : j["files"]) { + obj.files.push_back(File::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->files) arr.push_back(item.toJson()); + j["files"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, FileList& x) { + x = FileList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const FileList& x) { + j = x.toJson(); +} + +/** + * @brief Bucket + */ +struct Bucket { + /** @brief Bucket ID. */ + std::string id; + /** @brief Bucket creation time in ISO 8601 format. */ + std::string createdAt; + /** @brief Bucket update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Bucket permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + std::vector permissions; + /** @brief Whether file-level security is enabled. [Learn more about permissions](https://appwrite.io/docs/permissions). */ + bool fileSecurity; + /** @brief Bucket name. */ + std::string name; + /** @brief Bucket enabled. */ + bool enabled; + /** @brief Maximum file size supported. */ + int64_t maximumFileSize; + /** @brief Allowed file extensions. */ + std::vector allowedFileExtensions; + /** @brief Compression algorithm chosen for compression. Will be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd). */ + std::string compression; + /** @brief Bucket is encrypted. */ + bool encryption; + /** @brief Virus scanning is enabled. */ + bool antivirus; + /** @brief Image transformations are enabled. */ + bool transformations; + /** @brief Total size of this bucket in bytes. */ + int64_t totalSize; + + /** @brief Deserialize from JSON */ + static Bucket fromJson(const nlohmann::json& j) { + Bucket obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("$permissions")) { + if (j["$permissions"].is_null()) { + throw appwrite::DeserializationException("Required field '$permissions' is null"); + } else { + obj.permissions = j["$permissions"].get>(); + } + } + if (j.contains("fileSecurity")) { + if (j["fileSecurity"].is_null()) { + throw appwrite::DeserializationException("Required field 'fileSecurity' is null"); + } else { + obj.fileSecurity = j["fileSecurity"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("enabled")) { + if (j["enabled"].is_null()) { + throw appwrite::DeserializationException("Required field 'enabled' is null"); + } else { + obj.enabled = j["enabled"].get(); + } + } + if (j.contains("maximumFileSize")) { + if (j["maximumFileSize"].is_null()) { + throw appwrite::DeserializationException("Required field 'maximumFileSize' is null"); + } else { + obj.maximumFileSize = j["maximumFileSize"].get(); + } + } + if (j.contains("allowedFileExtensions")) { + if (j["allowedFileExtensions"].is_null()) { + throw appwrite::DeserializationException("Required field 'allowedFileExtensions' is null"); + } else { + obj.allowedFileExtensions = j["allowedFileExtensions"].get>(); + } + } + if (j.contains("compression")) { + if (j["compression"].is_null()) { + throw appwrite::DeserializationException("Required field 'compression' is null"); + } else { + obj.compression = j["compression"].get(); + } + } + if (j.contains("encryption")) { + if (j["encryption"].is_null()) { + throw appwrite::DeserializationException("Required field 'encryption' is null"); + } else { + obj.encryption = j["encryption"].get(); + } + } + if (j.contains("antivirus")) { + if (j["antivirus"].is_null()) { + throw appwrite::DeserializationException("Required field 'antivirus' is null"); + } else { + obj.antivirus = j["antivirus"].get(); + } + } + if (j.contains("transformations")) { + if (j["transformations"].is_null()) { + throw appwrite::DeserializationException("Required field 'transformations' is null"); + } else { + obj.transformations = j["transformations"].get(); + } + } + if (j.contains("totalSize")) { + if (j["totalSize"].is_null()) { + throw appwrite::DeserializationException("Required field 'totalSize' is null"); + } else { + obj.totalSize = j["totalSize"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["$permissions"] = this->permissions; + } + { + j["fileSecurity"] = this->fileSecurity; + } + { + j["name"] = this->name; + } + { + j["enabled"] = this->enabled; + } + { + j["maximumFileSize"] = this->maximumFileSize; + } + { + j["allowedFileExtensions"] = this->allowedFileExtensions; + } + { + j["compression"] = this->compression; + } + { + j["encryption"] = this->encryption; + } + { + j["antivirus"] = this->antivirus; + } + { + j["transformations"] = this->transformations; + } + { + j["totalSize"] = this->totalSize; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Bucket& x) { + x = Bucket::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Bucket& x) { + j = x.toJson(); +} + +/** + * @brief Buckets List + */ +struct BucketList { + /** @brief Total number of buckets that matched your query. */ + int64_t total; + /** @brief List of buckets. */ + std::vector buckets; + + /** @brief Deserialize from JSON */ + static BucketList fromJson(const nlohmann::json& j) { + BucketList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("buckets")) { + if (j["buckets"].is_null()) { + throw appwrite::DeserializationException("Required field 'buckets' is null"); + } else { + for (auto& item : j["buckets"]) { + obj.buckets.push_back(Bucket::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->buckets) arr.push_back(item.toJson()); + j["buckets"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, BucketList& x) { + x = BucketList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const BucketList& x) { + j = x.toJson(); +} + +/** + * @brief Team + */ +struct Team { + /** @brief Team ID. */ + std::string id; + /** @brief Team creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Team update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Team name. */ + std::string name; + /** @brief Total number of team members. */ + int64_t total; + /** @brief Team preferences as a key-value object */ + appwrite::models::Preferences prefs; + + /** @brief Deserialize from JSON */ + static Team fromJson(const nlohmann::json& j) { + Team obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("prefs")) { + if (j["prefs"].is_null()) { + throw appwrite::DeserializationException("Required field 'prefs' is null"); + } else { + obj.prefs = Preferences::fromJson(j["prefs"]); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["name"] = this->name; + } + { + j["total"] = this->total; + } + { + j["prefs"] = this->prefs.toJson(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Team& x) { + x = Team::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Team& x) { + j = x.toJson(); +} + +/** + * @brief Teams List + */ +struct TeamList { + /** @brief Total number of teams that matched your query. */ + int64_t total; + /** @brief List of teams. */ + std::vector teams; + + /** @brief Deserialize from JSON */ + static TeamList fromJson(const nlohmann::json& j) { + TeamList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("teams")) { + if (j["teams"].is_null()) { + throw appwrite::DeserializationException("Required field 'teams' is null"); + } else { + for (auto& item : j["teams"]) { + obj.teams.push_back(Team::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->teams) arr.push_back(item.toJson()); + j["teams"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, TeamList& x) { + x = TeamList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const TeamList& x) { + j = x.toJson(); +} + +/** + * @brief Membership + */ +struct Membership { + /** @brief Membership ID. */ + std::string id; + /** @brief Membership creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Membership update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief User ID. */ + std::string userId; + /** @brief User name. Hide this attribute by toggling membership privacy in the Console. */ + std::string userName; + /** @brief User email address. Hide this attribute by toggling membership privacy in the Console. */ + std::string userEmail; + /** @brief Team ID. */ + std::string teamId; + /** @brief Team name. */ + std::string teamName; + /** @brief Date, the user has been invited to join the team in ISO 8601 format. */ + std::string invited; + /** @brief Date, the user has accepted the invitation to join the team in ISO 8601 format. */ + std::string joined; + /** @brief User confirmation status, true if the user has joined the team or false otherwise. */ + bool confirm; + /** @brief Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console. */ + bool mfa; + /** @brief User list of roles */ + std::vector roles; + + /** @brief Deserialize from JSON */ + static Membership fromJson(const nlohmann::json& j) { + Membership obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("userId")) { + if (j["userId"].is_null()) { + throw appwrite::DeserializationException("Required field 'userId' is null"); + } else { + obj.userId = j["userId"].get(); + } + } + if (j.contains("userName")) { + if (j["userName"].is_null()) { + throw appwrite::DeserializationException("Required field 'userName' is null"); + } else { + obj.userName = j["userName"].get(); + } + } + if (j.contains("userEmail")) { + if (j["userEmail"].is_null()) { + throw appwrite::DeserializationException("Required field 'userEmail' is null"); + } else { + obj.userEmail = j["userEmail"].get(); + } + } + if (j.contains("teamId")) { + if (j["teamId"].is_null()) { + throw appwrite::DeserializationException("Required field 'teamId' is null"); + } else { + obj.teamId = j["teamId"].get(); + } + } + if (j.contains("teamName")) { + if (j["teamName"].is_null()) { + throw appwrite::DeserializationException("Required field 'teamName' is null"); + } else { + obj.teamName = j["teamName"].get(); + } + } + if (j.contains("invited")) { + if (j["invited"].is_null()) { + throw appwrite::DeserializationException("Required field 'invited' is null"); + } else { + obj.invited = j["invited"].get(); + } + } + if (j.contains("joined")) { + if (j["joined"].is_null()) { + throw appwrite::DeserializationException("Required field 'joined' is null"); + } else { + obj.joined = j["joined"].get(); + } + } + if (j.contains("confirm")) { + if (j["confirm"].is_null()) { + throw appwrite::DeserializationException("Required field 'confirm' is null"); + } else { + obj.confirm = j["confirm"].get(); + } + } + if (j.contains("mfa")) { + if (j["mfa"].is_null()) { + throw appwrite::DeserializationException("Required field 'mfa' is null"); + } else { + obj.mfa = j["mfa"].get(); + } + } + if (j.contains("roles")) { + if (j["roles"].is_null()) { + throw appwrite::DeserializationException("Required field 'roles' is null"); + } else { + obj.roles = j["roles"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["userId"] = this->userId; + } + { + j["userName"] = this->userName; + } + { + j["userEmail"] = this->userEmail; + } + { + j["teamId"] = this->teamId; + } + { + j["teamName"] = this->teamName; + } + { + j["invited"] = this->invited; + } + { + j["joined"] = this->joined; + } + { + j["confirm"] = this->confirm; + } + { + j["mfa"] = this->mfa; + } + { + j["roles"] = this->roles; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Membership& x) { + x = Membership::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Membership& x) { + j = x.toJson(); +} + +/** + * @brief Memberships List + */ +struct MembershipList { + /** @brief Total number of memberships that matched your query. */ + int64_t total; + /** @brief List of memberships. */ + std::vector memberships; + + /** @brief Deserialize from JSON */ + static MembershipList fromJson(const nlohmann::json& j) { + MembershipList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("memberships")) { + if (j["memberships"].is_null()) { + throw appwrite::DeserializationException("Required field 'memberships' is null"); + } else { + for (auto& item : j["memberships"]) { + obj.memberships.push_back(Membership::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->memberships) arr.push_back(item.toJson()); + j["memberships"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, MembershipList& x) { + x = MembershipList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const MembershipList& x) { + j = x.toJson(); +} + +/** + * @brief Variable + */ +struct Variable { + /** @brief Variable ID. */ + std::string id; + /** @brief Variable creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Variable creation date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Variable key. */ + std::string key; + /** @brief Variable value. */ + std::string value; + /** @brief Variable secret flag. Secret variables can only be updated or deleted, but never read. */ + bool secret; + /** @brief Service to which the variable belongs. Possible values are "project", "function" */ + std::string resourceType; + /** @brief ID of resource to which the variable belongs. If resourceType is "project", it is empty. If resourceType is "function", it is ID of the function. */ + std::string resourceId; + + /** @brief Deserialize from JSON */ + static Variable fromJson(const nlohmann::json& j) { + Variable obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("value")) { + if (j["value"].is_null()) { + throw appwrite::DeserializationException("Required field 'value' is null"); + } else { + obj.value = j["value"].get(); + } + } + if (j.contains("secret")) { + if (j["secret"].is_null()) { + throw appwrite::DeserializationException("Required field 'secret' is null"); + } else { + obj.secret = j["secret"].get(); + } + } + if (j.contains("resourceType")) { + if (j["resourceType"].is_null()) { + throw appwrite::DeserializationException("Required field 'resourceType' is null"); + } else { + obj.resourceType = j["resourceType"].get(); + } + } + if (j.contains("resourceId")) { + if (j["resourceId"].is_null()) { + throw appwrite::DeserializationException("Required field 'resourceId' is null"); + } else { + obj.resourceId = j["resourceId"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["key"] = this->key; + } + { + j["value"] = this->value; + } + { + j["secret"] = this->secret; + } + { + j["resourceType"] = this->resourceType; + } + { + j["resourceId"] = this->resourceId; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Variable& x) { + x = Variable::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Variable& x) { + j = x.toJson(); +} + +/** + * @brief Function + */ +struct Function { + /** @brief Function ID. */ + std::string id; + /** @brief Function creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Function update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Execution permissions. */ + std::vector execute; + /** @brief Function name. */ + std::string name; + /** @brief Function enabled. */ + bool enabled; + /** @brief Is the function deployed with the latest configuration? This is set to false if you've changed an environment variables, entrypoint, commands, or other settings that needs redeploy to be applied. When the value is false, redeploy the function to update it with the latest configuration. */ + bool live; + /** @brief When disabled, executions will exclude logs and errors, and will be slightly faster. */ + bool logging; + /** @brief Function execution and build runtime. */ + std::string runtime; + /** @brief How many days to keep the non-active deployments before they will be automatically deleted. */ + int64_t deploymentRetention; + /** @brief Function's active deployment ID. */ + std::string deploymentId; + /** @brief Active deployment creation date in ISO 8601 format. */ + std::string deploymentCreatedAt; + /** @brief Function's latest deployment ID. */ + std::string latestDeploymentId; + /** @brief Latest deployment creation date in ISO 8601 format. */ + std::string latestDeploymentCreatedAt; + /** @brief Status of latest deployment. Possible values are "waiting", "processing", "building", "ready", and "failed". */ + std::string latestDeploymentStatus; + /** @brief Allowed permission scopes. */ + std::vector scopes; + /** @brief Function variables. */ + std::vector vars; + /** @brief Function trigger events. */ + std::vector events; + /** @brief Function execution schedule in CRON format. */ + std::string schedule; + /** @brief Function execution timeout in seconds. */ + int64_t timeout; + /** @brief The entrypoint file used to execute the deployment. */ + std::string entrypoint; + /** @brief The build command used to build the deployment. */ + std::string commands; + /** @brief Version of Open Runtimes used for the function. */ + std::string version; + /** @brief Function VCS (Version Control System) installation id. */ + std::string installationId; + /** @brief VCS (Version Control System) Repository ID */ + std::string providerRepositoryId; + /** @brief VCS (Version Control System) branch name */ + std::string providerBranch; + /** @brief Path to function in VCS (Version Control System) repository */ + std::string providerRootDirectory; + /** @brief Is VCS (Version Control System) connection is in silent mode? When in silence mode, no comments will be posted on the repository pull or merge requests */ + bool providerSilentMode; + /** @brief Machine specification for deployment builds. */ + std::string buildSpecification; + /** @brief Machine specification for executions. */ + std::string runtimeSpecification; + + /** @brief Deserialize from JSON */ + static Function fromJson(const nlohmann::json& j) { + Function obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("execute")) { + if (j["execute"].is_null()) { + throw appwrite::DeserializationException("Required field 'execute' is null"); + } else { + obj.execute = j["execute"].get>(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("enabled")) { + if (j["enabled"].is_null()) { + throw appwrite::DeserializationException("Required field 'enabled' is null"); + } else { + obj.enabled = j["enabled"].get(); + } + } + if (j.contains("live")) { + if (j["live"].is_null()) { + throw appwrite::DeserializationException("Required field 'live' is null"); + } else { + obj.live = j["live"].get(); + } + } + if (j.contains("logging")) { + if (j["logging"].is_null()) { + throw appwrite::DeserializationException("Required field 'logging' is null"); + } else { + obj.logging = j["logging"].get(); + } + } + if (j.contains("runtime")) { + if (j["runtime"].is_null()) { + throw appwrite::DeserializationException("Required field 'runtime' is null"); + } else { + obj.runtime = j["runtime"].get(); + } + } + if (j.contains("deploymentRetention")) { + if (j["deploymentRetention"].is_null()) { + throw appwrite::DeserializationException("Required field 'deploymentRetention' is null"); + } else { + obj.deploymentRetention = j["deploymentRetention"].get(); + } + } + if (j.contains("deploymentId")) { + if (j["deploymentId"].is_null()) { + throw appwrite::DeserializationException("Required field 'deploymentId' is null"); + } else { + obj.deploymentId = j["deploymentId"].get(); + } + } + if (j.contains("deploymentCreatedAt")) { + if (j["deploymentCreatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field 'deploymentCreatedAt' is null"); + } else { + obj.deploymentCreatedAt = j["deploymentCreatedAt"].get(); + } + } + if (j.contains("latestDeploymentId")) { + if (j["latestDeploymentId"].is_null()) { + throw appwrite::DeserializationException("Required field 'latestDeploymentId' is null"); + } else { + obj.latestDeploymentId = j["latestDeploymentId"].get(); + } + } + if (j.contains("latestDeploymentCreatedAt")) { + if (j["latestDeploymentCreatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field 'latestDeploymentCreatedAt' is null"); + } else { + obj.latestDeploymentCreatedAt = j["latestDeploymentCreatedAt"].get(); + } + } + if (j.contains("latestDeploymentStatus")) { + if (j["latestDeploymentStatus"].is_null()) { + throw appwrite::DeserializationException("Required field 'latestDeploymentStatus' is null"); + } else { + obj.latestDeploymentStatus = j["latestDeploymentStatus"].get(); + } + } + if (j.contains("scopes")) { + if (j["scopes"].is_null()) { + throw appwrite::DeserializationException("Required field 'scopes' is null"); + } else { + obj.scopes = j["scopes"].get>(); + } + } + if (j.contains("vars")) { + if (j["vars"].is_null()) { + throw appwrite::DeserializationException("Required field 'vars' is null"); + } else { + for (auto& item : j["vars"]) { + obj.vars.push_back(Variable::fromJson(item)); + } + } + } + if (j.contains("events")) { + if (j["events"].is_null()) { + throw appwrite::DeserializationException("Required field 'events' is null"); + } else { + obj.events = j["events"].get>(); + } + } + if (j.contains("schedule")) { + if (j["schedule"].is_null()) { + throw appwrite::DeserializationException("Required field 'schedule' is null"); + } else { + obj.schedule = j["schedule"].get(); + } + } + if (j.contains("timeout")) { + if (j["timeout"].is_null()) { + throw appwrite::DeserializationException("Required field 'timeout' is null"); + } else { + obj.timeout = j["timeout"].get(); + } + } + if (j.contains("entrypoint")) { + if (j["entrypoint"].is_null()) { + throw appwrite::DeserializationException("Required field 'entrypoint' is null"); + } else { + obj.entrypoint = j["entrypoint"].get(); + } + } + if (j.contains("commands")) { + if (j["commands"].is_null()) { + throw appwrite::DeserializationException("Required field 'commands' is null"); + } else { + obj.commands = j["commands"].get(); + } + } + if (j.contains("version")) { + if (j["version"].is_null()) { + throw appwrite::DeserializationException("Required field 'version' is null"); + } else { + obj.version = j["version"].get(); + } + } + if (j.contains("installationId")) { + if (j["installationId"].is_null()) { + throw appwrite::DeserializationException("Required field 'installationId' is null"); + } else { + obj.installationId = j["installationId"].get(); + } + } + if (j.contains("providerRepositoryId")) { + if (j["providerRepositoryId"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerRepositoryId' is null"); + } else { + obj.providerRepositoryId = j["providerRepositoryId"].get(); + } + } + if (j.contains("providerBranch")) { + if (j["providerBranch"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerBranch' is null"); + } else { + obj.providerBranch = j["providerBranch"].get(); + } + } + if (j.contains("providerRootDirectory")) { + if (j["providerRootDirectory"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerRootDirectory' is null"); + } else { + obj.providerRootDirectory = j["providerRootDirectory"].get(); + } + } + if (j.contains("providerSilentMode")) { + if (j["providerSilentMode"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerSilentMode' is null"); + } else { + obj.providerSilentMode = j["providerSilentMode"].get(); + } + } + if (j.contains("buildSpecification")) { + if (j["buildSpecification"].is_null()) { + throw appwrite::DeserializationException("Required field 'buildSpecification' is null"); + } else { + obj.buildSpecification = j["buildSpecification"].get(); + } + } + if (j.contains("runtimeSpecification")) { + if (j["runtimeSpecification"].is_null()) { + throw appwrite::DeserializationException("Required field 'runtimeSpecification' is null"); + } else { + obj.runtimeSpecification = j["runtimeSpecification"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["execute"] = this->execute; + } + { + j["name"] = this->name; + } + { + j["enabled"] = this->enabled; + } + { + j["live"] = this->live; + } + { + j["logging"] = this->logging; + } + { + j["runtime"] = this->runtime; + } + { + j["deploymentRetention"] = this->deploymentRetention; + } + { + j["deploymentId"] = this->deploymentId; + } + { + j["deploymentCreatedAt"] = this->deploymentCreatedAt; + } + { + j["latestDeploymentId"] = this->latestDeploymentId; + } + { + j["latestDeploymentCreatedAt"] = this->latestDeploymentCreatedAt; + } + { + j["latestDeploymentStatus"] = this->latestDeploymentStatus; + } + { + j["scopes"] = this->scopes; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->vars) arr.push_back(item.toJson()); + j["vars"] = arr; + } + { + j["events"] = this->events; + } + { + j["schedule"] = this->schedule; + } + { + j["timeout"] = this->timeout; + } + { + j["entrypoint"] = this->entrypoint; + } + { + j["commands"] = this->commands; + } + { + j["version"] = this->version; + } + { + j["installationId"] = this->installationId; + } + { + j["providerRepositoryId"] = this->providerRepositoryId; + } + { + j["providerBranch"] = this->providerBranch; + } + { + j["providerRootDirectory"] = this->providerRootDirectory; + } + { + j["providerSilentMode"] = this->providerSilentMode; + } + { + j["buildSpecification"] = this->buildSpecification; + } + { + j["runtimeSpecification"] = this->runtimeSpecification; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Function& x) { + x = Function::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Function& x) { + j = x.toJson(); +} + +/** + * @brief Functions List + */ +struct FunctionList { + /** @brief Total number of functions that matched your query. */ + int64_t total; + /** @brief List of functions. */ + std::vector functions; + + /** @brief Deserialize from JSON */ + static FunctionList fromJson(const nlohmann::json& j) { + FunctionList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("functions")) { + if (j["functions"].is_null()) { + throw appwrite::DeserializationException("Required field 'functions' is null"); + } else { + for (auto& item : j["functions"]) { + obj.functions.push_back(Function::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->functions) arr.push_back(item.toJson()); + j["functions"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, FunctionList& x) { + x = FunctionList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const FunctionList& x) { + j = x.toJson(); +} + +/** + * @brief Runtime + */ +struct Runtime { + /** @brief Runtime ID. */ + std::string id; + /** @brief Parent runtime key. */ + std::string key; + /** @brief Runtime Name. */ + std::string name; + /** @brief Runtime version. */ + std::string version; + /** @brief Base Docker image used to build the runtime. */ + std::string base; + /** @brief Image name of Docker Hub. */ + std::string image; + /** @brief Name of the logo image. */ + std::string logo; + /** @brief List of supported architectures. */ + std::vector supports; + + /** @brief Deserialize from JSON */ + static Runtime fromJson(const nlohmann::json& j) { + Runtime obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("version")) { + if (j["version"].is_null()) { + throw appwrite::DeserializationException("Required field 'version' is null"); + } else { + obj.version = j["version"].get(); + } + } + if (j.contains("base")) { + if (j["base"].is_null()) { + throw appwrite::DeserializationException("Required field 'base' is null"); + } else { + obj.base = j["base"].get(); + } + } + if (j.contains("image")) { + if (j["image"].is_null()) { + throw appwrite::DeserializationException("Required field 'image' is null"); + } else { + obj.image = j["image"].get(); + } + } + if (j.contains("logo")) { + if (j["logo"].is_null()) { + throw appwrite::DeserializationException("Required field 'logo' is null"); + } else { + obj.logo = j["logo"].get(); + } + } + if (j.contains("supports")) { + if (j["supports"].is_null()) { + throw appwrite::DeserializationException("Required field 'supports' is null"); + } else { + obj.supports = j["supports"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["key"] = this->key; + } + { + j["name"] = this->name; + } + { + j["version"] = this->version; + } + { + j["base"] = this->base; + } + { + j["image"] = this->image; + } + { + j["logo"] = this->logo; + } + { + j["supports"] = this->supports; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Runtime& x) { + x = Runtime::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Runtime& x) { + j = x.toJson(); +} + +/** + * @brief Runtimes List + */ +struct RuntimeList { + /** @brief Total number of runtimes that matched your query. */ + int64_t total; + /** @brief List of runtimes. */ + std::vector runtimes; + + /** @brief Deserialize from JSON */ + static RuntimeList fromJson(const nlohmann::json& j) { + RuntimeList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("runtimes")) { + if (j["runtimes"].is_null()) { + throw appwrite::DeserializationException("Required field 'runtimes' is null"); + } else { + for (auto& item : j["runtimes"]) { + obj.runtimes.push_back(Runtime::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->runtimes) arr.push_back(item.toJson()); + j["runtimes"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, RuntimeList& x) { + x = RuntimeList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const RuntimeList& x) { + j = x.toJson(); +} + +/** + * @brief Deployment + */ +struct Deployment { + /** @brief Deployment ID. */ + std::string id; + /** @brief Deployment creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Deployment update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Type of deployment. */ + std::string type; + /** @brief Resource ID. */ + std::string resourceId; + /** @brief Resource type. */ + std::string resourceType; + /** @brief The entrypoint file to use to execute the deployment code. */ + std::string entrypoint; + /** @brief The code size in bytes. */ + int64_t sourceSize; + /** @brief The build output size in bytes. */ + int64_t buildSize; + /** @brief The total size in bytes (source and build output). */ + int64_t totalSize; + /** @brief The current build ID. */ + std::string buildId; + /** @brief Whether the deployment should be automatically activated. */ + bool activate; + /** @brief Screenshot with light theme preference file ID. */ + std::string screenshotLight; + /** @brief Screenshot with dark theme preference file ID. */ + std::string screenshotDark; + /** @brief The deployment status. Possible values are "waiting", "processing", "building", "ready", "canceled" and "failed". */ + appwrite::enums::DeploymentStatus status; + /** @brief The build logs. */ + std::string buildLogs; + /** @brief The current build time in seconds. */ + int64_t buildDuration; + /** @brief The name of the vcs provider repository */ + std::string providerRepositoryName; + /** @brief The name of the vcs provider repository owner */ + std::string providerRepositoryOwner; + /** @brief The url of the vcs provider repository */ + std::string providerRepositoryUrl; + /** @brief The commit hash of the vcs commit */ + std::string providerCommitHash; + /** @brief The url of vcs commit author */ + std::string providerCommitAuthorUrl; + /** @brief The name of vcs commit author */ + std::string providerCommitAuthor; + /** @brief The commit message */ + std::string providerCommitMessage; + /** @brief The url of the vcs commit */ + std::string providerCommitUrl; + /** @brief The branch of the vcs repository */ + std::string providerBranch; + /** @brief The branch of the vcs repository */ + std::string providerBranchUrl; + + /** @brief Deserialize from JSON */ + static Deployment fromJson(const nlohmann::json& j) { + Deployment obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("resourceId")) { + if (j["resourceId"].is_null()) { + throw appwrite::DeserializationException("Required field 'resourceId' is null"); + } else { + obj.resourceId = j["resourceId"].get(); + } + } + if (j.contains("resourceType")) { + if (j["resourceType"].is_null()) { + throw appwrite::DeserializationException("Required field 'resourceType' is null"); + } else { + obj.resourceType = j["resourceType"].get(); + } + } + if (j.contains("entrypoint")) { + if (j["entrypoint"].is_null()) { + throw appwrite::DeserializationException("Required field 'entrypoint' is null"); + } else { + obj.entrypoint = j["entrypoint"].get(); + } + } + if (j.contains("sourceSize")) { + if (j["sourceSize"].is_null()) { + throw appwrite::DeserializationException("Required field 'sourceSize' is null"); + } else { + obj.sourceSize = j["sourceSize"].get(); + } + } + if (j.contains("buildSize")) { + if (j["buildSize"].is_null()) { + throw appwrite::DeserializationException("Required field 'buildSize' is null"); + } else { + obj.buildSize = j["buildSize"].get(); + } + } + if (j.contains("totalSize")) { + if (j["totalSize"].is_null()) { + throw appwrite::DeserializationException("Required field 'totalSize' is null"); + } else { + obj.totalSize = j["totalSize"].get(); + } + } + if (j.contains("buildId")) { + if (j["buildId"].is_null()) { + throw appwrite::DeserializationException("Required field 'buildId' is null"); + } else { + obj.buildId = j["buildId"].get(); + } + } + if (j.contains("activate")) { + if (j["activate"].is_null()) { + throw appwrite::DeserializationException("Required field 'activate' is null"); + } else { + obj.activate = j["activate"].get(); + } + } + if (j.contains("screenshotLight")) { + if (j["screenshotLight"].is_null()) { + throw appwrite::DeserializationException("Required field 'screenshotLight' is null"); + } else { + obj.screenshotLight = j["screenshotLight"].get(); + } + } + if (j.contains("screenshotDark")) { + if (j["screenshotDark"].is_null()) { + throw appwrite::DeserializationException("Required field 'screenshotDark' is null"); + } else { + obj.screenshotDark = j["screenshotDark"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("buildLogs")) { + if (j["buildLogs"].is_null()) { + throw appwrite::DeserializationException("Required field 'buildLogs' is null"); + } else { + obj.buildLogs = j["buildLogs"].get(); + } + } + if (j.contains("buildDuration")) { + if (j["buildDuration"].is_null()) { + throw appwrite::DeserializationException("Required field 'buildDuration' is null"); + } else { + obj.buildDuration = j["buildDuration"].get(); + } + } + if (j.contains("providerRepositoryName")) { + if (j["providerRepositoryName"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerRepositoryName' is null"); + } else { + obj.providerRepositoryName = j["providerRepositoryName"].get(); + } + } + if (j.contains("providerRepositoryOwner")) { + if (j["providerRepositoryOwner"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerRepositoryOwner' is null"); + } else { + obj.providerRepositoryOwner = j["providerRepositoryOwner"].get(); + } + } + if (j.contains("providerRepositoryUrl")) { + if (j["providerRepositoryUrl"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerRepositoryUrl' is null"); + } else { + obj.providerRepositoryUrl = j["providerRepositoryUrl"].get(); + } + } + if (j.contains("providerCommitHash")) { + if (j["providerCommitHash"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerCommitHash' is null"); + } else { + obj.providerCommitHash = j["providerCommitHash"].get(); + } + } + if (j.contains("providerCommitAuthorUrl")) { + if (j["providerCommitAuthorUrl"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerCommitAuthorUrl' is null"); + } else { + obj.providerCommitAuthorUrl = j["providerCommitAuthorUrl"].get(); + } + } + if (j.contains("providerCommitAuthor")) { + if (j["providerCommitAuthor"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerCommitAuthor' is null"); + } else { + obj.providerCommitAuthor = j["providerCommitAuthor"].get(); + } + } + if (j.contains("providerCommitMessage")) { + if (j["providerCommitMessage"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerCommitMessage' is null"); + } else { + obj.providerCommitMessage = j["providerCommitMessage"].get(); + } + } + if (j.contains("providerCommitUrl")) { + if (j["providerCommitUrl"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerCommitUrl' is null"); + } else { + obj.providerCommitUrl = j["providerCommitUrl"].get(); + } + } + if (j.contains("providerBranch")) { + if (j["providerBranch"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerBranch' is null"); + } else { + obj.providerBranch = j["providerBranch"].get(); + } + } + if (j.contains("providerBranchUrl")) { + if (j["providerBranchUrl"].is_null()) { + throw appwrite::DeserializationException("Required field 'providerBranchUrl' is null"); + } else { + obj.providerBranchUrl = j["providerBranchUrl"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["type"] = this->type; + } + { + j["resourceId"] = this->resourceId; + } + { + j["resourceType"] = this->resourceType; + } + { + j["entrypoint"] = this->entrypoint; + } + { + j["sourceSize"] = this->sourceSize; + } + { + j["buildSize"] = this->buildSize; + } + { + j["totalSize"] = this->totalSize; + } + { + j["buildId"] = this->buildId; + } + { + j["activate"] = this->activate; + } + { + j["screenshotLight"] = this->screenshotLight; + } + { + j["screenshotDark"] = this->screenshotDark; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["buildLogs"] = this->buildLogs; + } + { + j["buildDuration"] = this->buildDuration; + } + { + j["providerRepositoryName"] = this->providerRepositoryName; + } + { + j["providerRepositoryOwner"] = this->providerRepositoryOwner; + } + { + j["providerRepositoryUrl"] = this->providerRepositoryUrl; + } + { + j["providerCommitHash"] = this->providerCommitHash; + } + { + j["providerCommitAuthorUrl"] = this->providerCommitAuthorUrl; + } + { + j["providerCommitAuthor"] = this->providerCommitAuthor; + } + { + j["providerCommitMessage"] = this->providerCommitMessage; + } + { + j["providerCommitUrl"] = this->providerCommitUrl; + } + { + j["providerBranch"] = this->providerBranch; + } + { + j["providerBranchUrl"] = this->providerBranchUrl; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Deployment& x) { + x = Deployment::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Deployment& x) { + j = x.toJson(); +} + +/** + * @brief Deployments List + */ +struct DeploymentList { + /** @brief Total number of deployments that matched your query. */ + int64_t total; + /** @brief List of deployments. */ + std::vector deployments; + + /** @brief Deserialize from JSON */ + static DeploymentList fromJson(const nlohmann::json& j) { + DeploymentList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("deployments")) { + if (j["deployments"].is_null()) { + throw appwrite::DeserializationException("Required field 'deployments' is null"); + } else { + for (auto& item : j["deployments"]) { + obj.deployments.push_back(Deployment::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->deployments) arr.push_back(item.toJson()); + j["deployments"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, DeploymentList& x) { + x = DeploymentList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const DeploymentList& x) { + j = x.toJson(); +} + +/** + * @brief Headers + */ +struct Headers { + /** @brief Header name. */ + std::string name; + /** @brief Header value. */ + std::string value; + + /** @brief Deserialize from JSON */ + static Headers fromJson(const nlohmann::json& j) { + Headers obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("value")) { + if (j["value"].is_null()) { + throw appwrite::DeserializationException("Required field 'value' is null"); + } else { + obj.value = j["value"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["name"] = this->name; + } + { + j["value"] = this->value; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Headers& x) { + x = Headers::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Headers& x) { + j = x.toJson(); +} + +/** + * @brief Execution + */ +struct Execution { + /** @brief Execution ID. */ + std::string id; + /** @brief Execution creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Execution update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Execution roles. */ + std::vector permissions; + /** @brief Function ID. */ + std::string functionId; + /** @brief Function's deployment ID used to create the execution. */ + std::string deploymentId; + /** @brief The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`. */ + appwrite::enums::ExecutionTrigger trigger; + /** @brief The status of the function execution. Possible values can be: `waiting`, `processing`, `completed`, `failed`, or `scheduled`. */ + appwrite::enums::ExecutionStatus status; + /** @brief HTTP request method type. */ + std::string requestMethod; + /** @brief HTTP request path and query. */ + std::string requestPath; + /** @brief HTTP request headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous. */ + std::vector requestHeaders; + /** @brief HTTP response status code. */ + int64_t responseStatusCode; + /** @brief HTTP response body. This will return empty unless execution is created as synchronous. */ + std::string responseBody; + /** @brief HTTP response headers as a key-value object. This will return only whitelisted headers. All headers are returned if execution is created as synchronous. */ + std::vector responseHeaders; + /** @brief Function logs. Includes the last 4,000 characters. This will return an empty string unless the response is returned using an API key or as part of a webhook payload. */ + std::string logs; + /** @brief Function errors. Includes the last 4,000 characters. This will return an empty string unless the response is returned using an API key or as part of a webhook payload. */ + std::string errors; + /** @brief Resource(function/site) execution duration in seconds. */ + double duration; + /** @brief The scheduled time for execution. If left empty, execution will be queued immediately. */ + std::optional scheduledAt = std::nullopt; + + /** @brief Deserialize from JSON */ + static Execution fromJson(const nlohmann::json& j) { + Execution obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("$permissions")) { + if (j["$permissions"].is_null()) { + throw appwrite::DeserializationException("Required field '$permissions' is null"); + } else { + obj.permissions = j["$permissions"].get>(); + } + } + if (j.contains("functionId")) { + if (j["functionId"].is_null()) { + throw appwrite::DeserializationException("Required field 'functionId' is null"); + } else { + obj.functionId = j["functionId"].get(); + } + } + if (j.contains("deploymentId")) { + if (j["deploymentId"].is_null()) { + throw appwrite::DeserializationException("Required field 'deploymentId' is null"); + } else { + obj.deploymentId = j["deploymentId"].get(); + } + } + if (j.contains("trigger")) { + if (j["trigger"].is_null()) { + throw appwrite::DeserializationException("Required field 'trigger' is null"); + } else { + obj.trigger = j["trigger"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("requestMethod")) { + if (j["requestMethod"].is_null()) { + throw appwrite::DeserializationException("Required field 'requestMethod' is null"); + } else { + obj.requestMethod = j["requestMethod"].get(); + } + } + if (j.contains("requestPath")) { + if (j["requestPath"].is_null()) { + throw appwrite::DeserializationException("Required field 'requestPath' is null"); + } else { + obj.requestPath = j["requestPath"].get(); + } + } + if (j.contains("requestHeaders")) { + if (j["requestHeaders"].is_null()) { + throw appwrite::DeserializationException("Required field 'requestHeaders' is null"); + } else { + for (auto& item : j["requestHeaders"]) { + obj.requestHeaders.push_back(Headers::fromJson(item)); + } + } + } + if (j.contains("responseStatusCode")) { + if (j["responseStatusCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'responseStatusCode' is null"); + } else { + obj.responseStatusCode = j["responseStatusCode"].get(); + } + } + if (j.contains("responseBody")) { + if (j["responseBody"].is_null()) { + throw appwrite::DeserializationException("Required field 'responseBody' is null"); + } else { + obj.responseBody = j["responseBody"].get(); + } + } + if (j.contains("responseHeaders")) { + if (j["responseHeaders"].is_null()) { + throw appwrite::DeserializationException("Required field 'responseHeaders' is null"); + } else { + for (auto& item : j["responseHeaders"]) { + obj.responseHeaders.push_back(Headers::fromJson(item)); + } + } + } + if (j.contains("logs")) { + if (j["logs"].is_null()) { + throw appwrite::DeserializationException("Required field 'logs' is null"); + } else { + obj.logs = j["logs"].get(); + } + } + if (j.contains("errors")) { + if (j["errors"].is_null()) { + throw appwrite::DeserializationException("Required field 'errors' is null"); + } else { + obj.errors = j["errors"].get(); + } + } + if (j.contains("duration")) { + if (j["duration"].is_null()) { + throw appwrite::DeserializationException("Required field 'duration' is null"); + } else { + obj.duration = j["duration"].get(); + } + } + if (j.contains("scheduledAt")) { + if (j["scheduledAt"].is_null()) { + obj.scheduledAt = std::nullopt; + } else { + obj.scheduledAt = j["scheduledAt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["$permissions"] = this->permissions; + } + { + j["functionId"] = this->functionId; + } + { + j["deploymentId"] = this->deploymentId; + } + { + j["trigger"] = appwrite::enums::toString(this->trigger); + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["requestMethod"] = this->requestMethod; + } + { + j["requestPath"] = this->requestPath; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->requestHeaders) arr.push_back(item.toJson()); + j["requestHeaders"] = arr; + } + { + j["responseStatusCode"] = this->responseStatusCode; + } + { + j["responseBody"] = this->responseBody; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->responseHeaders) arr.push_back(item.toJson()); + j["responseHeaders"] = arr; + } + { + j["logs"] = this->logs; + } + { + j["errors"] = this->errors; + } + { + j["duration"] = this->duration; + } + if (this->scheduledAt.has_value()) { + j["scheduledAt"] = this->scheduledAt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Execution& x) { + x = Execution::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Execution& x) { + j = x.toJson(); +} + +/** + * @brief Executions List + */ +struct ExecutionList { + /** @brief Total number of executions that matched your query. */ + int64_t total; + /** @brief List of executions. */ + std::vector executions; + + /** @brief Deserialize from JSON */ + static ExecutionList fromJson(const nlohmann::json& j) { + ExecutionList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("executions")) { + if (j["executions"].is_null()) { + throw appwrite::DeserializationException("Required field 'executions' is null"); + } else { + for (auto& item : j["executions"]) { + obj.executions.push_back(Execution::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->executions) arr.push_back(item.toJson()); + j["executions"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ExecutionList& x) { + x = ExecutionList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ExecutionList& x) { + j = x.toJson(); +} + +/** + * @brief Webhook + */ +struct Webhook { + /** @brief Webhook ID. */ + std::string id; + /** @brief Webhook creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Webhook update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Webhook name. */ + std::string name; + /** @brief Webhook URL endpoint. */ + std::string url; + /** @brief Webhook trigger events. */ + std::vector events; + /** @brief Indicates if SSL / TLS certificate verification is enabled. */ + bool tls; + /** @brief HTTP basic authentication username. */ + std::string authUsername; + /** @brief HTTP basic authentication password. */ + std::string authPassword; + /** @brief Signature key which can be used to validate incoming webhook payloads. Only returned on creation and secret rotation. */ + std::string secret; + /** @brief Indicates if this webhook is enabled. */ + bool enabled; + /** @brief Webhook error logs from the most recent failure. */ + std::string logs; + /** @brief Number of consecutive failed webhook attempts. */ + int64_t attempts; + + /** @brief Deserialize from JSON */ + static Webhook fromJson(const nlohmann::json& j) { + Webhook obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("name")) { + if (j["name"].is_null()) { + throw appwrite::DeserializationException("Required field 'name' is null"); + } else { + obj.name = j["name"].get(); + } + } + if (j.contains("url")) { + if (j["url"].is_null()) { + throw appwrite::DeserializationException("Required field 'url' is null"); + } else { + obj.url = j["url"].get(); + } + } + if (j.contains("events")) { + if (j["events"].is_null()) { + throw appwrite::DeserializationException("Required field 'events' is null"); + } else { + obj.events = j["events"].get>(); + } + } + if (j.contains("tls")) { + if (j["tls"].is_null()) { + throw appwrite::DeserializationException("Required field 'tls' is null"); + } else { + obj.tls = j["tls"].get(); + } + } + if (j.contains("authUsername")) { + if (j["authUsername"].is_null()) { + throw appwrite::DeserializationException("Required field 'authUsername' is null"); + } else { + obj.authUsername = j["authUsername"].get(); + } + } + if (j.contains("authPassword")) { + if (j["authPassword"].is_null()) { + throw appwrite::DeserializationException("Required field 'authPassword' is null"); + } else { + obj.authPassword = j["authPassword"].get(); + } + } + if (j.contains("secret")) { + if (j["secret"].is_null()) { + throw appwrite::DeserializationException("Required field 'secret' is null"); + } else { + obj.secret = j["secret"].get(); + } + } + if (j.contains("enabled")) { + if (j["enabled"].is_null()) { + throw appwrite::DeserializationException("Required field 'enabled' is null"); + } else { + obj.enabled = j["enabled"].get(); + } + } + if (j.contains("logs")) { + if (j["logs"].is_null()) { + throw appwrite::DeserializationException("Required field 'logs' is null"); + } else { + obj.logs = j["logs"].get(); + } + } + if (j.contains("attempts")) { + if (j["attempts"].is_null()) { + throw appwrite::DeserializationException("Required field 'attempts' is null"); + } else { + obj.attempts = j["attempts"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["name"] = this->name; + } + { + j["url"] = this->url; + } + { + j["events"] = this->events; + } + { + j["tls"] = this->tls; + } + { + j["authUsername"] = this->authUsername; + } + { + j["authPassword"] = this->authPassword; + } + { + j["secret"] = this->secret; + } + { + j["enabled"] = this->enabled; + } + { + j["logs"] = this->logs; + } + { + j["attempts"] = this->attempts; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Webhook& x) { + x = Webhook::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Webhook& x) { + j = x.toJson(); +} + +/** + * @brief Webhooks List + */ +struct WebhookList { + /** @brief Total number of webhooks that matched your query. */ + int64_t total; + /** @brief List of webhooks. */ + std::vector webhooks; + + /** @brief Deserialize from JSON */ + static WebhookList fromJson(const nlohmann::json& j) { + WebhookList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("webhooks")) { + if (j["webhooks"].is_null()) { + throw appwrite::DeserializationException("Required field 'webhooks' is null"); + } else { + for (auto& item : j["webhooks"]) { + obj.webhooks.push_back(Webhook::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->webhooks) arr.push_back(item.toJson()); + j["webhooks"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, WebhookList& x) { + x = WebhookList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const WebhookList& x) { + j = x.toJson(); +} + +/** + * @brief Variables List + */ +struct VariableList { + /** @brief Total number of variables that matched your query. */ + int64_t total; + /** @brief List of variables. */ + std::vector variables; + + /** @brief Deserialize from JSON */ + static VariableList fromJson(const nlohmann::json& j) { + VariableList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("variables")) { + if (j["variables"].is_null()) { + throw appwrite::DeserializationException("Required field 'variables' is null"); + } else { + for (auto& item : j["variables"]) { + obj.variables.push_back(Variable::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->variables) arr.push_back(item.toJson()); + j["variables"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, VariableList& x) { + x = VariableList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const VariableList& x) { + j = x.toJson(); +} + +/** + * @brief Target list + */ +struct TargetList { + /** @brief Total number of targets that matched your query. */ + int64_t total; + /** @brief List of targets. */ + std::vector targets; + + /** @brief Deserialize from JSON */ + static TargetList fromJson(const nlohmann::json& j) { + TargetList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("targets")) { + if (j["targets"].is_null()) { + throw appwrite::DeserializationException("Required field 'targets' is null"); + } else { + for (auto& item : j["targets"]) { + obj.targets.push_back(Target::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->targets) arr.push_back(item.toJson()); + j["targets"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, TargetList& x) { + x = TargetList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const TargetList& x) { + j = x.toJson(); +} + +/** + * @brief Transaction + */ +struct Transaction { + /** @brief Transaction ID. */ + std::string id; + /** @brief Transaction creation time in ISO 8601 format. */ + std::string createdAt; + /** @brief Transaction update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Current status of the transaction. One of: pending, committing, committed, rolled_back, failed. */ + std::string status; + /** @brief Number of operations in the transaction. */ + int64_t operations; + /** @brief Expiration time in ISO 8601 format. */ + std::string expiresAt; + + /** @brief Deserialize from JSON */ + static Transaction fromJson(const nlohmann::json& j) { + Transaction obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("operations")) { + if (j["operations"].is_null()) { + throw appwrite::DeserializationException("Required field 'operations' is null"); + } else { + obj.operations = j["operations"].get(); + } + } + if (j.contains("expiresAt")) { + if (j["expiresAt"].is_null()) { + throw appwrite::DeserializationException("Required field 'expiresAt' is null"); + } else { + obj.expiresAt = j["expiresAt"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["status"] = this->status; + } + { + j["operations"] = this->operations; + } + { + j["expiresAt"] = this->expiresAt; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Transaction& x) { + x = Transaction::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Transaction& x) { + j = x.toJson(); +} + +/** + * @brief Transaction List + */ +struct TransactionList { + /** @brief Total number of transactions that matched your query. */ + int64_t total; + /** @brief List of transactions. */ + std::vector transactions; + + /** @brief Deserialize from JSON */ + static TransactionList fromJson(const nlohmann::json& j) { + TransactionList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("transactions")) { + if (j["transactions"].is_null()) { + throw appwrite::DeserializationException("Required field 'transactions' is null"); + } else { + for (auto& item : j["transactions"]) { + obj.transactions.push_back(Transaction::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->transactions) arr.push_back(item.toJson()); + j["transactions"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, TransactionList& x) { + x = TransactionList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const TransactionList& x) { + j = x.toJson(); +} + +/** + * @brief Specification + */ +struct Specification { + /** @brief Memory size in MB. */ + int64_t memory; + /** @brief Number of CPUs. */ + double cpus; + /** @brief Is size enabled. */ + bool enabled; + /** @brief Size slug. */ + std::string slug; + + /** @brief Deserialize from JSON */ + static Specification fromJson(const nlohmann::json& j) { + Specification obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("memory")) { + if (j["memory"].is_null()) { + throw appwrite::DeserializationException("Required field 'memory' is null"); + } else { + obj.memory = j["memory"].get(); + } + } + if (j.contains("cpus")) { + if (j["cpus"].is_null()) { + throw appwrite::DeserializationException("Required field 'cpus' is null"); + } else { + obj.cpus = j["cpus"].get(); + } + } + if (j.contains("enabled")) { + if (j["enabled"].is_null()) { + throw appwrite::DeserializationException("Required field 'enabled' is null"); + } else { + obj.enabled = j["enabled"].get(); + } + } + if (j.contains("slug")) { + if (j["slug"].is_null()) { + throw appwrite::DeserializationException("Required field 'slug' is null"); + } else { + obj.slug = j["slug"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["memory"] = this->memory; + } + { + j["cpus"] = this->cpus; + } + { + j["enabled"] = this->enabled; + } + { + j["slug"] = this->slug; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Specification& x) { + x = Specification::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Specification& x) { + j = x.toJson(); +} + +/** + * @brief Specifications List + */ +struct SpecificationList { + /** @brief Total number of specifications that matched your query. */ + int64_t total; + /** @brief List of specifications. */ + std::vector specifications; + + /** @brief Deserialize from JSON */ + static SpecificationList fromJson(const nlohmann::json& j) { + SpecificationList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("specifications")) { + if (j["specifications"].is_null()) { + throw appwrite::DeserializationException("Required field 'specifications' is null"); + } else { + for (auto& item : j["specifications"]) { + obj.specifications.push_back(Specification::fromJson(item)); + } + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->specifications) arr.push_back(item.toJson()); + j["specifications"] = arr; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, SpecificationList& x) { + x = SpecificationList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const SpecificationList& x) { + j = x.toJson(); +} + +/** + * @brief Attributes List + */ +struct AttributeList { + /** @brief Total number of attributes in the given collection. */ + int64_t total; + /** @brief List of attributes. */ + std::vector attributes; + + /** @brief Deserialize from JSON */ + static AttributeList fromJson(const nlohmann::json& j) { + AttributeList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("attributes")) { + if (j["attributes"].is_null()) { + throw appwrite::DeserializationException("Required field 'attributes' is null"); + } else { + obj.attributes = j["attributes"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + j["attributes"] = this->attributes; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeList& x) { + x = AttributeList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeList& x) { + j = x.toJson(); +} + +/** + * @brief AttributeString + */ +struct AttributeString { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Attribute size. */ + int64_t size; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this attribute is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeString fromJson(const nlohmann::json& j) { + AttributeString obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("size")) { + if (j["size"].is_null()) { + throw appwrite::DeserializationException("Required field 'size' is null"); + } else { + obj.size = j["size"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["size"] = this->size; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeString& x) { + x = AttributeString::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeString& x) { + j = x.toJson(); +} + +/** + * @brief AttributeInteger + */ +struct AttributeInteger { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Minimum value to enforce for new documents. */ + std::optional min = std::nullopt; + /** @brief Maximum value to enforce for new documents. */ + std::optional max = std::nullopt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeInteger fromJson(const nlohmann::json& j) { + AttributeInteger obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("min")) { + if (j["min"].is_null()) { + obj.min = std::nullopt; + } else { + obj.min = j["min"].get>(); + } + } + if (j.contains("max")) { + if (j["max"].is_null()) { + obj.max = std::nullopt; + } else { + obj.max = j["max"].get>(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->min.has_value()) { + j["min"] = this->min.value(); + } + if (this->max.has_value()) { + j["max"] = this->max.value(); + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeInteger& x) { + x = AttributeInteger::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeInteger& x) { + j = x.toJson(); +} + +/** + * @brief AttributeFloat + */ +struct AttributeFloat { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Minimum value to enforce for new documents. */ + std::optional min = std::nullopt; + /** @brief Maximum value to enforce for new documents. */ + std::optional max = std::nullopt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeFloat fromJson(const nlohmann::json& j) { + AttributeFloat obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("min")) { + if (j["min"].is_null()) { + obj.min = std::nullopt; + } else { + obj.min = j["min"].get>(); + } + } + if (j.contains("max")) { + if (j["max"].is_null()) { + obj.max = std::nullopt; + } else { + obj.max = j["max"].get>(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->min.has_value()) { + j["min"] = this->min.value(); + } + if (this->max.has_value()) { + j["max"] = this->max.value(); + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeFloat& x) { + x = AttributeFloat::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeFloat& x) { + j = x.toJson(); +} + +/** + * @brief AttributeBoolean + */ +struct AttributeBoolean { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeBoolean fromJson(const nlohmann::json& j) { + AttributeBoolean obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeBoolean& x) { + x = AttributeBoolean::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeBoolean& x) { + j = x.toJson(); +} + +/** + * @brief AttributeEmail + */ +struct AttributeEmail { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief String format. */ + std::string format; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeEmail fromJson(const nlohmann::json& j) { + AttributeEmail obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeEmail& x) { + x = AttributeEmail::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeEmail& x) { + j = x.toJson(); +} + +/** + * @brief AttributeEnum + */ +struct AttributeEnum { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Array of elements in enumerated type. */ + std::vector elements; + /** @brief String format. */ + std::string format; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeEnum fromJson(const nlohmann::json& j) { + AttributeEnum obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("elements")) { + if (j["elements"].is_null()) { + throw appwrite::DeserializationException("Required field 'elements' is null"); + } else { + obj.elements = j["elements"].get>(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["elements"] = this->elements; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeEnum& x) { + x = AttributeEnum::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeEnum& x) { + j = x.toJson(); +} + +/** + * @brief AttributeIP + */ +struct AttributeIp { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief String format. */ + std::string format; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeIp fromJson(const nlohmann::json& j) { + AttributeIp obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeIp& x) { + x = AttributeIp::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeIp& x) { + j = x.toJson(); +} + +/** + * @brief AttributeURL + */ +struct AttributeUrl { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief String format. */ + std::string format; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeUrl fromJson(const nlohmann::json& j) { + AttributeUrl obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeUrl& x) { + x = AttributeUrl::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeUrl& x) { + j = x.toJson(); +} + +/** + * @brief AttributeDatetime + */ +struct AttributeDatetime { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief ISO 8601 format. */ + std::string format; + /** @brief Default value for attribute when not provided. Only null is optional */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeDatetime fromJson(const nlohmann::json& j) { + AttributeDatetime obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeDatetime& x) { + x = AttributeDatetime::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeDatetime& x) { + j = x.toJson(); +} + +/** + * @brief AttributeRelationship + */ +struct AttributeRelationship { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief The ID of the related collection. */ + std::string relatedCollection; + /** @brief The type of the relationship. */ + std::string relationType; + /** @brief Is the relationship two-way? */ + bool twoWay; + /** @brief The key of the two-way relationship. */ + std::string twoWayKey; + /** @brief How deleting the parent document will propagate to child documents. */ + std::string onDelete; + /** @brief Whether this is the parent or child side of the relationship */ + std::string side; + + /** @brief Deserialize from JSON */ + static AttributeRelationship fromJson(const nlohmann::json& j) { + AttributeRelationship obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("relatedCollection")) { + if (j["relatedCollection"].is_null()) { + throw appwrite::DeserializationException("Required field 'relatedCollection' is null"); + } else { + obj.relatedCollection = j["relatedCollection"].get(); + } + } + if (j.contains("relationType")) { + if (j["relationType"].is_null()) { + throw appwrite::DeserializationException("Required field 'relationType' is null"); + } else { + obj.relationType = j["relationType"].get(); + } + } + if (j.contains("twoWay")) { + if (j["twoWay"].is_null()) { + throw appwrite::DeserializationException("Required field 'twoWay' is null"); + } else { + obj.twoWay = j["twoWay"].get(); + } + } + if (j.contains("twoWayKey")) { + if (j["twoWayKey"].is_null()) { + throw appwrite::DeserializationException("Required field 'twoWayKey' is null"); + } else { + obj.twoWayKey = j["twoWayKey"].get(); + } + } + if (j.contains("onDelete")) { + if (j["onDelete"].is_null()) { + throw appwrite::DeserializationException("Required field 'onDelete' is null"); + } else { + obj.onDelete = j["onDelete"].get(); + } + } + if (j.contains("side")) { + if (j["side"].is_null()) { + throw appwrite::DeserializationException("Required field 'side' is null"); + } else { + obj.side = j["side"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["relatedCollection"] = this->relatedCollection; + } + { + j["relationType"] = this->relationType; + } + { + j["twoWay"] = this->twoWay; + } + { + j["twoWayKey"] = this->twoWayKey; + } + { + j["onDelete"] = this->onDelete; + } + { + j["side"] = this->side; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeRelationship& x) { + x = AttributeRelationship::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeRelationship& x) { + j = x.toJson(); +} + +/** + * @brief AttributePoint + */ +struct AttributePoint { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional> default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributePoint fromJson(const nlohmann::json& j) { + AttributePoint obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributePoint& x) { + x = AttributePoint::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributePoint& x) { + j = x.toJson(); +} + +/** + * @brief AttributeLine + */ +struct AttributeLine { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional> default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeLine fromJson(const nlohmann::json& j) { + AttributeLine obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeLine& x) { + x = AttributeLine::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeLine& x) { + j = x.toJson(); +} + +/** + * @brief AttributePolygon + */ +struct AttributePolygon { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional> default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributePolygon fromJson(const nlohmann::json& j) { + AttributePolygon obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributePolygon& x) { + x = AttributePolygon::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributePolygon& x) { + j = x.toJson(); +} + +/** + * @brief AttributeVarchar + */ +struct AttributeVarchar { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Attribute size. */ + int64_t size; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this attribute is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeVarchar fromJson(const nlohmann::json& j) { + AttributeVarchar obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("size")) { + if (j["size"].is_null()) { + throw appwrite::DeserializationException("Required field 'size' is null"); + } else { + obj.size = j["size"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["size"] = this->size; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeVarchar& x) { + x = AttributeVarchar::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeVarchar& x) { + j = x.toJson(); +} + +/** + * @brief AttributeText + */ +struct AttributeText { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this attribute is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeText fromJson(const nlohmann::json& j) { + AttributeText obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeText& x) { + x = AttributeText::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeText& x) { + j = x.toJson(); +} + +/** + * @brief AttributeMediumtext + */ +struct AttributeMediumtext { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this attribute is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeMediumtext fromJson(const nlohmann::json& j) { + AttributeMediumtext obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeMediumtext& x) { + x = AttributeMediumtext::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeMediumtext& x) { + j = x.toJson(); +} + +/** + * @brief AttributeLongtext + */ +struct AttributeLongtext { + /** @brief Attribute Key. */ + std::string key; + /** @brief Attribute type. */ + std::string type; + /** @brief Attribute status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::AttributeStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an attribute. */ + std::string error; + /** @brief Is attribute required? */ + bool required; + /** @brief Is attribute an array? */ + std::optional array = std::nullopt; + /** @brief Attribute creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Attribute update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for attribute when not provided. Cannot be set when attribute is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this attribute is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static AttributeLongtext fromJson(const nlohmann::json& j) { + AttributeLongtext obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AttributeLongtext& x) { + x = AttributeLongtext::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AttributeLongtext& x) { + j = x.toJson(); +} + +/** + * @brief Columns List + */ +struct ColumnList { + /** @brief Total number of columns in the given table. */ + int64_t total; + /** @brief List of columns. */ + std::vector columns; + + /** @brief Deserialize from JSON */ + static ColumnList fromJson(const nlohmann::json& j) { + ColumnList obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("total")) { + if (j["total"].is_null()) { + throw appwrite::DeserializationException("Required field 'total' is null"); + } else { + obj.total = j["total"].get(); + } + } + if (j.contains("columns")) { + if (j["columns"].is_null()) { + throw appwrite::DeserializationException("Required field 'columns' is null"); + } else { + obj.columns = j["columns"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["total"] = this->total; + } + { + j["columns"] = this->columns; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnList& x) { + x = ColumnList::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnList& x) { + j = x.toJson(); +} + +/** + * @brief ColumnString + */ +struct ColumnString { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Column size. */ + int64_t size; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this column is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnString fromJson(const nlohmann::json& j) { + ColumnString obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("size")) { + if (j["size"].is_null()) { + throw appwrite::DeserializationException("Required field 'size' is null"); + } else { + obj.size = j["size"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["size"] = this->size; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnString& x) { + x = ColumnString::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnString& x) { + j = x.toJson(); +} + +/** + * @brief ColumnInteger + */ +struct ColumnInteger { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Minimum value to enforce for new documents. */ + std::optional min = std::nullopt; + /** @brief Maximum value to enforce for new documents. */ + std::optional max = std::nullopt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnInteger fromJson(const nlohmann::json& j) { + ColumnInteger obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("min")) { + if (j["min"].is_null()) { + obj.min = std::nullopt; + } else { + obj.min = j["min"].get>(); + } + } + if (j.contains("max")) { + if (j["max"].is_null()) { + obj.max = std::nullopt; + } else { + obj.max = j["max"].get>(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->min.has_value()) { + j["min"] = this->min.value(); + } + if (this->max.has_value()) { + j["max"] = this->max.value(); + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnInteger& x) { + x = ColumnInteger::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnInteger& x) { + j = x.toJson(); +} + +/** + * @brief ColumnFloat + */ +struct ColumnFloat { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Minimum value to enforce for new documents. */ + std::optional min = std::nullopt; + /** @brief Maximum value to enforce for new documents. */ + std::optional max = std::nullopt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnFloat fromJson(const nlohmann::json& j) { + ColumnFloat obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("min")) { + if (j["min"].is_null()) { + obj.min = std::nullopt; + } else { + obj.min = j["min"].get>(); + } + } + if (j.contains("max")) { + if (j["max"].is_null()) { + obj.max = std::nullopt; + } else { + obj.max = j["max"].get>(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->min.has_value()) { + j["min"] = this->min.value(); + } + if (this->max.has_value()) { + j["max"] = this->max.value(); + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnFloat& x) { + x = ColumnFloat::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnFloat& x) { + j = x.toJson(); +} + +/** + * @brief ColumnBoolean + */ +struct ColumnBoolean { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnBoolean fromJson(const nlohmann::json& j) { + ColumnBoolean obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnBoolean& x) { + x = ColumnBoolean::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnBoolean& x) { + j = x.toJson(); +} + +/** + * @brief ColumnEmail + */ +struct ColumnEmail { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief String format. */ + std::string format; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnEmail fromJson(const nlohmann::json& j) { + ColumnEmail obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnEmail& x) { + x = ColumnEmail::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnEmail& x) { + j = x.toJson(); +} + +/** + * @brief ColumnEnum + */ +struct ColumnEnum { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Array of elements in enumerated type. */ + std::vector elements; + /** @brief String format. */ + std::string format; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnEnum fromJson(const nlohmann::json& j) { + ColumnEnum obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("elements")) { + if (j["elements"].is_null()) { + throw appwrite::DeserializationException("Required field 'elements' is null"); + } else { + obj.elements = j["elements"].get>(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["elements"] = this->elements; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnEnum& x) { + x = ColumnEnum::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnEnum& x) { + j = x.toJson(); +} + +/** + * @brief ColumnIP + */ +struct ColumnIp { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief String format. */ + std::string format; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnIp fromJson(const nlohmann::json& j) { + ColumnIp obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnIp& x) { + x = ColumnIp::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnIp& x) { + j = x.toJson(); +} + +/** + * @brief ColumnURL + */ +struct ColumnUrl { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief String format. */ + std::string format; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnUrl fromJson(const nlohmann::json& j) { + ColumnUrl obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnUrl& x) { + x = ColumnUrl::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnUrl& x) { + j = x.toJson(); +} + +/** + * @brief ColumnDatetime + */ +struct ColumnDatetime { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief ISO 8601 format. */ + std::string format; + /** @brief Default value for column when not provided. Only null is optional */ + std::optional default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnDatetime fromJson(const nlohmann::json& j) { + ColumnDatetime obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("format")) { + if (j["format"].is_null()) { + throw appwrite::DeserializationException("Required field 'format' is null"); + } else { + obj.format = j["format"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["format"] = this->format; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnDatetime& x) { + x = ColumnDatetime::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnDatetime& x) { + j = x.toJson(); +} + +/** + * @brief ColumnRelationship + */ +struct ColumnRelationship { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief The ID of the related table. */ + std::string relatedTable; + /** @brief The type of the relationship. */ + std::string relationType; + /** @brief Is the relationship two-way? */ + bool twoWay; + /** @brief The key of the two-way relationship. */ + std::string twoWayKey; + /** @brief How deleting the parent document will propagate to child documents. */ + std::string onDelete; + /** @brief Whether this is the parent or child side of the relationship */ + std::string side; + + /** @brief Deserialize from JSON */ + static ColumnRelationship fromJson(const nlohmann::json& j) { + ColumnRelationship obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("relatedTable")) { + if (j["relatedTable"].is_null()) { + throw appwrite::DeserializationException("Required field 'relatedTable' is null"); + } else { + obj.relatedTable = j["relatedTable"].get(); + } + } + if (j.contains("relationType")) { + if (j["relationType"].is_null()) { + throw appwrite::DeserializationException("Required field 'relationType' is null"); + } else { + obj.relationType = j["relationType"].get(); + } + } + if (j.contains("twoWay")) { + if (j["twoWay"].is_null()) { + throw appwrite::DeserializationException("Required field 'twoWay' is null"); + } else { + obj.twoWay = j["twoWay"].get(); + } + } + if (j.contains("twoWayKey")) { + if (j["twoWayKey"].is_null()) { + throw appwrite::DeserializationException("Required field 'twoWayKey' is null"); + } else { + obj.twoWayKey = j["twoWayKey"].get(); + } + } + if (j.contains("onDelete")) { + if (j["onDelete"].is_null()) { + throw appwrite::DeserializationException("Required field 'onDelete' is null"); + } else { + obj.onDelete = j["onDelete"].get(); + } + } + if (j.contains("side")) { + if (j["side"].is_null()) { + throw appwrite::DeserializationException("Required field 'side' is null"); + } else { + obj.side = j["side"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["relatedTable"] = this->relatedTable; + } + { + j["relationType"] = this->relationType; + } + { + j["twoWay"] = this->twoWay; + } + { + j["twoWayKey"] = this->twoWayKey; + } + { + j["onDelete"] = this->onDelete; + } + { + j["side"] = this->side; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnRelationship& x) { + x = ColumnRelationship::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnRelationship& x) { + j = x.toJson(); +} + +/** + * @brief ColumnPoint + */ +struct ColumnPoint { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional> default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnPoint fromJson(const nlohmann::json& j) { + ColumnPoint obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnPoint& x) { + x = ColumnPoint::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnPoint& x) { + j = x.toJson(); +} + +/** + * @brief ColumnLine + */ +struct ColumnLine { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional> default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnLine fromJson(const nlohmann::json& j) { + ColumnLine obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnLine& x) { + x = ColumnLine::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnLine& x) { + j = x.toJson(); +} + +/** + * @brief ColumnPolygon + */ +struct ColumnPolygon { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional> default_ = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnPolygon fromJson(const nlohmann::json& j) { + ColumnPolygon obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnPolygon& x) { + x = ColumnPolygon::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnPolygon& x) { + j = x.toJson(); +} + +/** + * @brief ColumnVarchar + */ +struct ColumnVarchar { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Column size. */ + int64_t size; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this column is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnVarchar fromJson(const nlohmann::json& j) { + ColumnVarchar obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("size")) { + if (j["size"].is_null()) { + throw appwrite::DeserializationException("Required field 'size' is null"); + } else { + obj.size = j["size"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + { + j["size"] = this->size; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnVarchar& x) { + x = ColumnVarchar::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnVarchar& x) { + j = x.toJson(); +} + +/** + * @brief ColumnText + */ +struct ColumnText { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this column is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnText fromJson(const nlohmann::json& j) { + ColumnText obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnText& x) { + x = ColumnText::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnText& x) { + j = x.toJson(); +} + +/** + * @brief ColumnMediumtext + */ +struct ColumnMediumtext { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this column is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnMediumtext fromJson(const nlohmann::json& j) { + ColumnMediumtext obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnMediumtext& x) { + x = ColumnMediumtext::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnMediumtext& x) { + j = x.toJson(); +} + +/** + * @brief ColumnLongtext + */ +struct ColumnLongtext { + /** @brief Column Key. */ + std::string key; + /** @brief Column type. */ + std::string type; + /** @brief Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed` */ + appwrite::enums::ColumnStatus status; + /** @brief Error message. Displays error generated on failure of creating or deleting an column. */ + std::string error; + /** @brief Is column required? */ + bool required; + /** @brief Is column an array? */ + std::optional array = std::nullopt; + /** @brief Column creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief Column update date in ISO 8601 format. */ + std::string updatedAt; + /** @brief Default value for column when not provided. Cannot be set when column is required. */ + std::optional default_ = std::nullopt; + /** @brief Defines whether this column is encrypted or not. */ + std::optional encrypt = std::nullopt; + + /** @brief Deserialize from JSON */ + static ColumnLongtext fromJson(const nlohmann::json& j) { + ColumnLongtext obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("key")) { + if (j["key"].is_null()) { + throw appwrite::DeserializationException("Required field 'key' is null"); + } else { + obj.key = j["key"].get(); + } + } + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("status")) { + if (j["status"].is_null()) { + throw appwrite::DeserializationException("Required field 'status' is null"); + } else { + obj.status = j["status"].get(); + } + } + if (j.contains("error")) { + if (j["error"].is_null()) { + throw appwrite::DeserializationException("Required field 'error' is null"); + } else { + obj.error = j["error"].get(); + } + } + if (j.contains("required")) { + if (j["required"].is_null()) { + throw appwrite::DeserializationException("Required field 'required' is null"); + } else { + obj.required = j["required"].get(); + } + } + if (j.contains("array")) { + if (j["array"].is_null()) { + obj.array = std::nullopt; + } else { + obj.array = j["array"].get>(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("$updatedAt")) { + if (j["$updatedAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$updatedAt' is null"); + } else { + obj.updatedAt = j["$updatedAt"].get(); + } + } + if (j.contains("default")) { + if (j["default"].is_null()) { + obj.default_ = std::nullopt; + } else { + obj.default_ = j["default"].get>(); + } + } + if (j.contains("encrypt")) { + if (j["encrypt"].is_null()) { + obj.encrypt = std::nullopt; + } else { + obj.encrypt = j["encrypt"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["key"] = this->key; + } + { + j["type"] = this->type; + } + { + j["status"] = appwrite::enums::toString(this->status); + } + { + j["error"] = this->error; + } + { + j["required"] = this->required; + } + if (this->array.has_value()) { + j["array"] = this->array.value(); + } + { + j["$createdAt"] = this->createdAt; + } + { + j["$updatedAt"] = this->updatedAt; + } + if (this->default_.has_value()) { + j["default"] = this->default_.value(); + } + if (this->encrypt.has_value()) { + j["encrypt"] = this->encrypt.value(); + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, ColumnLongtext& x) { + x = ColumnLongtext::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const ColumnLongtext& x) { + j = x.toJson(); +} + +/** + * @brief AlgoMD5 + */ +struct AlgoMd5 { + /** @brief Algo type. */ + std::string type; + + /** @brief Deserialize from JSON */ + static AlgoMd5 fromJson(const nlohmann::json& j) { + AlgoMd5 obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["type"] = this->type; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AlgoMd5& x) { + x = AlgoMd5::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AlgoMd5& x) { + j = x.toJson(); +} + +/** + * @brief AlgoSHA + */ +struct AlgoSha { + /** @brief Algo type. */ + std::string type; + + /** @brief Deserialize from JSON */ + static AlgoSha fromJson(const nlohmann::json& j) { + AlgoSha obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["type"] = this->type; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AlgoSha& x) { + x = AlgoSha::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AlgoSha& x) { + j = x.toJson(); +} + +/** + * @brief AlgoPHPass + */ +struct AlgoPhpass { + /** @brief Algo type. */ + std::string type; + + /** @brief Deserialize from JSON */ + static AlgoPhpass fromJson(const nlohmann::json& j) { + AlgoPhpass obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["type"] = this->type; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AlgoPhpass& x) { + x = AlgoPhpass::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AlgoPhpass& x) { + j = x.toJson(); +} + +/** + * @brief AlgoBcrypt + */ +struct AlgoBcrypt { + /** @brief Algo type. */ + std::string type; + + /** @brief Deserialize from JSON */ + static AlgoBcrypt fromJson(const nlohmann::json& j) { + AlgoBcrypt obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["type"] = this->type; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AlgoBcrypt& x) { + x = AlgoBcrypt::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AlgoBcrypt& x) { + j = x.toJson(); +} + +/** + * @brief AlgoScrypt + */ +struct AlgoScrypt { + /** @brief Algo type. */ + std::string type; + /** @brief CPU complexity of computed hash. */ + int64_t costCpu; + /** @brief Memory complexity of computed hash. */ + int64_t costMemory; + /** @brief Parallelization of computed hash. */ + int64_t costParallel; + /** @brief Length used to compute hash. */ + int64_t length; + + /** @brief Deserialize from JSON */ + static AlgoScrypt fromJson(const nlohmann::json& j) { + AlgoScrypt obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("costCpu")) { + if (j["costCpu"].is_null()) { + throw appwrite::DeserializationException("Required field 'costCpu' is null"); + } else { + obj.costCpu = j["costCpu"].get(); + } + } + if (j.contains("costMemory")) { + if (j["costMemory"].is_null()) { + throw appwrite::DeserializationException("Required field 'costMemory' is null"); + } else { + obj.costMemory = j["costMemory"].get(); + } + } + if (j.contains("costParallel")) { + if (j["costParallel"].is_null()) { + throw appwrite::DeserializationException("Required field 'costParallel' is null"); + } else { + obj.costParallel = j["costParallel"].get(); + } + } + if (j.contains("length")) { + if (j["length"].is_null()) { + throw appwrite::DeserializationException("Required field 'length' is null"); + } else { + obj.length = j["length"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["type"] = this->type; + } + { + j["costCpu"] = this->costCpu; + } + { + j["costMemory"] = this->costMemory; + } + { + j["costParallel"] = this->costParallel; + } + { + j["length"] = this->length; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AlgoScrypt& x) { + x = AlgoScrypt::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AlgoScrypt& x) { + j = x.toJson(); +} + +/** + * @brief AlgoScryptModified + */ +struct AlgoScryptModified { + /** @brief Algo type. */ + std::string type; + /** @brief Salt used to compute hash. */ + std::string salt; + /** @brief Separator used to compute hash. */ + std::string saltSeparator; + /** @brief Key used to compute hash. */ + std::string signerKey; + + /** @brief Deserialize from JSON */ + static AlgoScryptModified fromJson(const nlohmann::json& j) { + AlgoScryptModified obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("salt")) { + if (j["salt"].is_null()) { + throw appwrite::DeserializationException("Required field 'salt' is null"); + } else { + obj.salt = j["salt"].get(); + } + } + if (j.contains("saltSeparator")) { + if (j["saltSeparator"].is_null()) { + throw appwrite::DeserializationException("Required field 'saltSeparator' is null"); + } else { + obj.saltSeparator = j["saltSeparator"].get(); + } + } + if (j.contains("signerKey")) { + if (j["signerKey"].is_null()) { + throw appwrite::DeserializationException("Required field 'signerKey' is null"); + } else { + obj.signerKey = j["signerKey"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["type"] = this->type; + } + { + j["salt"] = this->salt; + } + { + j["saltSeparator"] = this->saltSeparator; + } + { + j["signerKey"] = this->signerKey; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AlgoScryptModified& x) { + x = AlgoScryptModified::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AlgoScryptModified& x) { + j = x.toJson(); +} + +/** + * @brief AlgoArgon2 + */ +struct AlgoArgon2 { + /** @brief Algo type. */ + std::string type; + /** @brief Memory used to compute hash. */ + int64_t memoryCost; + /** @brief Amount of time consumed to compute hash */ + int64_t timeCost; + /** @brief Number of threads used to compute hash. */ + int64_t threads; + + /** @brief Deserialize from JSON */ + static AlgoArgon2 fromJson(const nlohmann::json& j) { + AlgoArgon2 obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("type")) { + if (j["type"].is_null()) { + throw appwrite::DeserializationException("Required field 'type' is null"); + } else { + obj.type = j["type"].get(); + } + } + if (j.contains("memoryCost")) { + if (j["memoryCost"].is_null()) { + throw appwrite::DeserializationException("Required field 'memoryCost' is null"); + } else { + obj.memoryCost = j["memoryCost"].get(); + } + } + if (j.contains("timeCost")) { + if (j["timeCost"].is_null()) { + throw appwrite::DeserializationException("Required field 'timeCost' is null"); + } else { + obj.timeCost = j["timeCost"].get(); + } + } + if (j.contains("threads")) { + if (j["threads"].is_null()) { + throw appwrite::DeserializationException("Required field 'threads' is null"); + } else { + obj.threads = j["threads"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["type"] = this->type; + } + { + j["memoryCost"] = this->memoryCost; + } + { + j["timeCost"] = this->timeCost; + } + { + j["threads"] = this->threads; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, AlgoArgon2& x) { + x = AlgoArgon2::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const AlgoArgon2& x) { + j = x.toJson(); +} + +/** + * @brief Token + */ +struct Token { + /** @brief Token ID. */ + std::string id; + /** @brief Token creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief User ID. */ + std::string userId; + /** @brief Token secret key. This will return an empty string unless the response is returned using an API key or as part of a webhook payload. */ + std::string secret; + /** @brief Token expiration date in ISO 8601 format. */ + std::string expire; + /** @brief Security phrase of a token. Empty if security phrase was not requested when creating a token. It includes randomly generated phrase which is also sent in the external resource such as email. */ + std::string phrase; + + /** @brief Deserialize from JSON */ + static Token fromJson(const nlohmann::json& j) { + Token obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("userId")) { + if (j["userId"].is_null()) { + throw appwrite::DeserializationException("Required field 'userId' is null"); + } else { + obj.userId = j["userId"].get(); + } + } + if (j.contains("secret")) { + if (j["secret"].is_null()) { + throw appwrite::DeserializationException("Required field 'secret' is null"); + } else { + obj.secret = j["secret"].get(); + } + } + if (j.contains("expire")) { + if (j["expire"].is_null()) { + throw appwrite::DeserializationException("Required field 'expire' is null"); + } else { + obj.expire = j["expire"].get(); + } + } + if (j.contains("phrase")) { + if (j["phrase"].is_null()) { + throw appwrite::DeserializationException("Required field 'phrase' is null"); + } else { + obj.phrase = j["phrase"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["userId"] = this->userId; + } + { + j["secret"] = this->secret; + } + { + j["expire"] = this->expire; + } + { + j["phrase"] = this->phrase; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Token& x) { + x = Token::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Token& x) { + j = x.toJson(); +} + +/** + * @brief JWT + */ +struct Jwt { + /** @brief JWT encoded string. */ + std::string jwt; + + /** @brief Deserialize from JSON */ + static Jwt fromJson(const nlohmann::json& j) { + Jwt obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("jwt")) { + if (j["jwt"].is_null()) { + throw appwrite::DeserializationException("Required field 'jwt' is null"); + } else { + obj.jwt = j["jwt"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["jwt"] = this->jwt; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, Jwt& x) { + x = Jwt::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const Jwt& x) { + j = x.toJson(); +} + +/** + * @brief MFA Challenge + */ +struct MfaChallenge { + /** @brief Token ID. */ + std::string id; + /** @brief Token creation date in ISO 8601 format. */ + std::string createdAt; + /** @brief User ID. */ + std::string userId; + /** @brief Token expiration date in ISO 8601 format. */ + std::string expire; + + /** @brief Deserialize from JSON */ + static MfaChallenge fromJson(const nlohmann::json& j) { + MfaChallenge obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("$id")) { + if (j["$id"].is_null()) { + throw appwrite::DeserializationException("Required field '$id' is null"); + } else { + obj.id = j["$id"].get(); + } + } + if (j.contains("$createdAt")) { + if (j["$createdAt"].is_null()) { + throw appwrite::DeserializationException("Required field '$createdAt' is null"); + } else { + obj.createdAt = j["$createdAt"].get(); + } + } + if (j.contains("userId")) { + if (j["userId"].is_null()) { + throw appwrite::DeserializationException("Required field 'userId' is null"); + } else { + obj.userId = j["userId"].get(); + } + } + if (j.contains("expire")) { + if (j["expire"].is_null()) { + throw appwrite::DeserializationException("Required field 'expire' is null"); + } else { + obj.expire = j["expire"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["$id"] = this->id; + } + { + j["$createdAt"] = this->createdAt; + } + { + j["userId"] = this->userId; + } + { + j["expire"] = this->expire; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, MfaChallenge& x) { + x = MfaChallenge::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const MfaChallenge& x) { + j = x.toJson(); +} + +/** + * @brief MFA Recovery Codes + */ +struct MfaRecoveryCodes { + /** @brief Recovery codes. */ + std::vector recoveryCodes; + + /** @brief Deserialize from JSON */ + static MfaRecoveryCodes fromJson(const nlohmann::json& j) { + MfaRecoveryCodes obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("recoveryCodes")) { + if (j["recoveryCodes"].is_null()) { + throw appwrite::DeserializationException("Required field 'recoveryCodes' is null"); + } else { + obj.recoveryCodes = j["recoveryCodes"].get>(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["recoveryCodes"] = this->recoveryCodes; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, MfaRecoveryCodes& x) { + x = MfaRecoveryCodes::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const MfaRecoveryCodes& x) { + j = x.toJson(); +} + +/** + * @brief MFAType + */ +struct MfaType { + /** @brief Secret token used for TOTP factor. */ + std::string secret; + /** @brief URI for authenticator apps. */ + std::string uri; + + /** @brief Deserialize from JSON */ + static MfaType fromJson(const nlohmann::json& j) { + MfaType obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("secret")) { + if (j["secret"].is_null()) { + throw appwrite::DeserializationException("Required field 'secret' is null"); + } else { + obj.secret = j["secret"].get(); + } + } + if (j.contains("uri")) { + if (j["uri"].is_null()) { + throw appwrite::DeserializationException("Required field 'uri' is null"); + } else { + obj.uri = j["uri"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["secret"] = this->secret; + } + { + j["uri"] = this->uri; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, MfaType& x) { + x = MfaType::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const MfaType& x) { + j = x.toJson(); +} + +/** + * @brief MFAFactors + */ +struct MfaFactors { + /** @brief Can TOTP be used for MFA challenge for this account. */ + bool totp; + /** @brief Can phone (SMS) be used for MFA challenge for this account. */ + bool phone; + /** @brief Can email be used for MFA challenge for this account. */ + bool email; + /** @brief Can recovery code be used for MFA challenge for this account. */ + bool recoveryCode; + + /** @brief Deserialize from JSON */ + static MfaFactors fromJson(const nlohmann::json& j) { + MfaFactors obj{}; // value-init: zeroes bools, ints, enums + if (j.contains("totp")) { + if (j["totp"].is_null()) { + throw appwrite::DeserializationException("Required field 'totp' is null"); + } else { + obj.totp = j["totp"].get(); + } + } + if (j.contains("phone")) { + if (j["phone"].is_null()) { + throw appwrite::DeserializationException("Required field 'phone' is null"); + } else { + obj.phone = j["phone"].get(); + } + } + if (j.contains("email")) { + if (j["email"].is_null()) { + throw appwrite::DeserializationException("Required field 'email' is null"); + } else { + obj.email = j["email"].get(); + } + } + if (j.contains("recoveryCode")) { + if (j["recoveryCode"].is_null()) { + throw appwrite::DeserializationException("Required field 'recoveryCode' is null"); + } else { + obj.recoveryCode = j["recoveryCode"].get(); + } + } + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + { + j["totp"] = this->totp; + } + { + j["phone"] = this->phone; + } + { + j["email"] = this->email; + } + { + j["recoveryCode"] = this->recoveryCode; + } + return j; + } +}; + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, MfaFactors& x) { + x = MfaFactors::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const MfaFactors& x) { + j = x.toJson(); +} + +} // namespace models +} // namespace appwrite diff --git a/examples/cpp/include/appwrite/services.hpp b/examples/cpp/include/appwrite/services.hpp new file mode 100755 index 0000000000..db71957c1c --- /dev/null +++ b/examples/cpp/include/appwrite/services.hpp @@ -0,0 +1,15293 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include "client.hpp" +#include "models.hpp" +#include "enums/enums.hpp" + +namespace appwrite { + +/** + * @brief Base class for all Appwrite services. + */ +class Service { +public: + explicit Service(Client& client) : client_(client) {} +protected: + Client& client_; +}; + +namespace services { + +/** + * @brief The Account service allows you to authenticate and manage a user account. + */ +class Account : public Service { +public: + explicit Account(Client& client) : Service(client) {} + + /** + * Get the currently logged in user. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result get( ) { + std::string path_ = std::format("/account"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the currently logged in user. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAsync( ) { + std::string path_ = std::format("/account"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to allow a new user to register a new account in your + * project. After the user registration completes successfully, you can use + * the + * [/account/verfication](https://appwrite.io/docs/references/cloud/client-web/account#createVerification) + * route to start verifying the user email address. To allow the new user to + * login to their new account, you need to create a new [account + * session](https://appwrite.io/docs/references/cloud/client-web/account#createEmailSession). + * + * @param userId User 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 email User email. + * @param password New user password. Must be between 8 and 256 chars. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result create( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/account"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to allow a new user to register a new account in your + * project. After the user registration completes successfully, you can use + * the + * [/account/verfication](https://appwrite.io/docs/references/cloud/client-web/account#createVerification) + * route to start verifying the user email address. To allow the new user to + * login to their new account, you need to create a new [account + * session](https://appwrite.io/docs/references/cloud/client-web/account#createEmailSession). + * + * @param userId User 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 email User email. + * @param password New user password. Must be between 8 and 256 chars. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAsync( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/account"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update currently logged in user account email address. After changing user + * address, the user confirmation status will get reset. A new confirmation + * email is not sent automatically however you can use the send confirmation + * email endpoint again to send the confirmation email. For security measures, + * user password is required to complete this request. +This endpoint can also + * be used to convert an anonymous account to a normal one, by passing an + * email address and a new password. + * + * @param email User email. + * @param password User password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEmail( std::string_view email, std::string_view password ) { + std::string path_ = std::format("/account/email"); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update currently logged in user account email address. After changing user + * address, the user confirmation status will get reset. A new confirmation + * email is not sent automatically however you can use the send confirmation + * email endpoint again to send the confirmation email. For security measures, + * user password is required to complete this request. +This endpoint can also + * be used to convert an anonymous account to a normal one, by passing an + * email address and a new password. + * + * @param email User email. + * @param password User password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEmailAsync( std::string_view email, std::string_view password ) { + std::string path_ = std::format("/account/email"); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the list of identities for the currently logged in user. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listIdentities( std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/account/identities"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the list of identities for the currently logged in user. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listIdentitiesAsync( std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/account/identities"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an identity by its unique ID. + * + * @param identityId Identity ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteIdentity( std::string_view identityId ) { + std::string path_ = std::format("/account/identities/{}", identityId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an identity by its unique ID. + * + * @param identityId Identity ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteIdentityAsync( std::string_view identityId ) { + std::string path_ = std::format("/account/identities/{}", identityId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to create a JSON Web Token. You can use the resulting JWT + * to authenticate on behalf of the current user when working with the + * Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes + * from its creation and will be invalid if the user will logout in that time + * frame. + * + * @param duration Time in seconds before JWT expires. Default duration is 900 seconds, and maximum is 3600 seconds. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createJWT( std::optional duration = 900 ) { + std::string path_ = std::format("/account/jwts"); + + nlohmann::json params = nlohmann::json::object(); + if (duration.has_value()) { + params["duration"] = *duration; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to create a JSON Web Token. You can use the resulting JWT + * to authenticate on behalf of the current user when working with the + * Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes + * from its creation and will be invalid if the user will logout in that time + * frame. + * + * @param duration Time in seconds before JWT expires. Default duration is 900 seconds, and maximum is 3600 seconds. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createJWTAsync( std::optional duration = 900 ) { + std::string path_ = std::format("/account/jwts"); + + nlohmann::json params = nlohmann::json::object(); + if (duration.has_value()) { + params["duration"] = *duration; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * 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 appwrite::Result + */ + [[nodiscard]] appwrite::Result listLogs( std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/account/logs"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * 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 appwrite::Result + */ + [[nodiscard]] appwrite::Task> listLogsAsync( std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/account/logs"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Enable or disable MFA on an account. + * + * @param mfa Enable or disable MFA. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMFA( bool mfa ) { + std::string path_ = std::format("/account/mfa"); + + nlohmann::json params = nlohmann::json::object(); + params["mfa"] = mfa; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Enable or disable MFA on an account. + * + * @param mfa Enable or disable MFA. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMFAAsync( bool mfa ) { + std::string path_ = std::format("/account/mfa"); + + nlohmann::json params = nlohmann::json::object(); + params["mfa"] = mfa; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Add an authenticator app to be used as an MFA factor. Verify the + * authenticator using the [verify + * authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) + * method. + * + * @param type Type of authenticator. Must be `totp` + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMfaAuthenticator( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Add an authenticator app to be used as an MFA factor. Verify the + * authenticator using the [verify + * authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) + * method. + * + * @param type Type of authenticator. Must be `totp` + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMfaAuthenticatorAsync( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Add an authenticator app to be used as an MFA factor. Verify the + * authenticator using the [verify + * authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) + * method. + * + * @param type Type of authenticator. Must be `totp` + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMFAAuthenticator( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Add an authenticator app to be used as an MFA factor. Verify the + * authenticator using the [verify + * authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) + * method. + * + * @param type Type of authenticator. Must be `totp` + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMFAAuthenticatorAsync( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Verify an authenticator app after adding it using the [add + * authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) + * method. + * + * @param type Type of authenticator. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMfaAuthenticator( appwrite::enums::AuthenticatorType type, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Verify an authenticator app after adding it using the [add + * authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) + * method. + * + * @param type Type of authenticator. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMfaAuthenticatorAsync( appwrite::enums::AuthenticatorType type, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Verify an authenticator app after adding it using the [add + * authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) + * method. + * + * @param type Type of authenticator. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMFAAuthenticator( appwrite::enums::AuthenticatorType type, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Verify an authenticator app after adding it using the [add + * authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) + * method. + * + * @param type Type of authenticator. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMFAAuthenticatorAsync( appwrite::enums::AuthenticatorType type, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an authenticator for a user by ID. + * + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteMfaAuthenticator( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an authenticator for a user by ID. + * + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteMfaAuthenticatorAsync( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an authenticator for a user by ID. + * + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteMFAAuthenticator( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an authenticator for a user by ID. + * + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteMFAAuthenticatorAsync( appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/account/mfa/authenticators/{}", appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Begin the process of MFA verification after sign-in. Finish the flow with + * [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) + * method. + * + * @param factor Factor used for verification. Must be one of following: `email`, `phone`, `totp`, `recoveryCode`. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMfaChallenge( appwrite::enums::AuthenticationFactor factor ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["factor"] = factor; + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Begin the process of MFA verification after sign-in. Finish the flow with + * [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) + * method. + * + * @param factor Factor used for verification. Must be one of following: `email`, `phone`, `totp`, `recoveryCode`. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMfaChallengeAsync( appwrite::enums::AuthenticationFactor factor ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["factor"] = factor; + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Begin the process of MFA verification after sign-in. Finish the flow with + * [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) + * method. + * + * @param factor Factor used for verification. Must be one of following: `email`, `phone`, `totp`, `recoveryCode`. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMFAChallenge( appwrite::enums::AuthenticationFactor factor ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["factor"] = factor; + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Begin the process of MFA verification after sign-in. Finish the flow with + * [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge) + * method. + * + * @param factor Factor used for verification. Must be one of following: `email`, `phone`, `totp`, `recoveryCode`. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMFAChallengeAsync( appwrite::enums::AuthenticationFactor factor ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["factor"] = factor; + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Complete the MFA challenge by providing the one-time password. Finish the + * process of MFA verification by providing the one-time password. To begin + * the flow, use + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @param challengeId ID of the challenge. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMfaChallenge( std::string_view challengeId, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["challengeId"] = std::string(challengeId); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Complete the MFA challenge by providing the one-time password. Finish the + * process of MFA verification by providing the one-time password. To begin + * the flow, use + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @param challengeId ID of the challenge. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMfaChallengeAsync( std::string_view challengeId, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["challengeId"] = std::string(challengeId); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Complete the MFA challenge by providing the one-time password. Finish the + * process of MFA verification by providing the one-time password. To begin + * the flow, use + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @param challengeId ID of the challenge. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMFAChallenge( std::string_view challengeId, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["challengeId"] = std::string(challengeId); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Complete the MFA challenge by providing the one-time password. Finish the + * process of MFA verification by providing the one-time password. To begin + * the flow, use + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @param challengeId ID of the challenge. + * @param otp Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMFAChallengeAsync( std::string_view challengeId, std::string_view otp ) { + std::string path_ = std::format("/account/mfa/challenges"); + + nlohmann::json params = nlohmann::json::object(); + params["challengeId"] = std::string(challengeId); + params["otp"] = std::string(otp); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * List the factors available on the account to be used as a MFA challange. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listMfaFactors( ) { + std::string path_ = std::format("/account/mfa/factors"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List the factors available on the account to be used as a MFA challange. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listMfaFactorsAsync( ) { + std::string path_ = std::format("/account/mfa/factors"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * List the factors available on the account to be used as a MFA challange. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listMFAFactors( ) { + std::string path_ = std::format("/account/mfa/factors"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List the factors available on the account to be used as a MFA challange. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listMFAFactorsAsync( ) { + std::string path_ = std::format("/account/mfa/factors"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get recovery codes that can be used as backup for MFA flow. Before getting + * codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to read recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getMfaRecoveryCodes( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get recovery codes that can be used as backup for MFA flow. Before getting + * codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to read recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getMfaRecoveryCodesAsync( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get recovery codes that can be used as backup for MFA flow. Before getting + * codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to read recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getMFARecoveryCodes( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get recovery codes that can be used as backup for MFA flow. Before getting + * codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to read recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getMFARecoveryCodesAsync( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Generate recovery codes as backup for MFA flow. It's recommended to + * generate and show then immediately after user successfully adds their + * authehticator. Recovery codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMfaRecoveryCodes( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Generate recovery codes as backup for MFA flow. It's recommended to + * generate and show then immediately after user successfully adds their + * authehticator. Recovery codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMfaRecoveryCodesAsync( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Generate recovery codes as backup for MFA flow. It's recommended to + * generate and show then immediately after user successfully adds their + * authehticator. Recovery codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMFARecoveryCodes( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Generate recovery codes as backup for MFA flow. It's recommended to + * generate and show then immediately after user successfully adds their + * authehticator. Recovery codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMFARecoveryCodesAsync( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Regenerate recovery codes that can be used as backup for MFA flow. Before + * regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to regenreate recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMfaRecoveryCodes( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Regenerate recovery codes that can be used as backup for MFA flow. Before + * regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to regenreate recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMfaRecoveryCodesAsync( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Regenerate recovery codes that can be used as backup for MFA flow. Before + * regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to regenreate recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMFARecoveryCodes( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Regenerate recovery codes that can be used as backup for MFA flow. Before + * regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. An OTP challenge is required to regenreate recovery codes. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMFARecoveryCodesAsync( ) { + std::string path_ = std::format("/account/mfa/recovery-codes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update currently logged in user account name. + * + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateName( std::string_view name ) { + std::string path_ = std::format("/account/name"); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update currently logged in user account name. + * + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateNameAsync( std::string_view name ) { + std::string path_ = std::format("/account/name"); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update currently logged in user password. For validation, user is required + * to pass in the new password, and the old password. For users created with + * OAuth, Team Invites and Magic URL, oldPassword is optional. + * + * @param password New user password. Must be at least 8 chars. + * @param oldPassword Current user password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePassword( std::string_view password, std::optional oldPassword = std::nullopt ) { + std::string path_ = std::format("/account/password"); + + nlohmann::json params = nlohmann::json::object(); + params["password"] = std::string(password); + if (oldPassword.has_value()) { + params["oldPassword"] = std::string(oldPassword.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update currently logged in user password. For validation, user is required + * to pass in the new password, and the old password. For users created with + * OAuth, Team Invites and Magic URL, oldPassword is optional. + * + * @param password New user password. Must be at least 8 chars. + * @param oldPassword Current user password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePasswordAsync( std::string_view password, std::optional oldPassword = std::nullopt ) { + std::string path_ = std::format("/account/password"); + + nlohmann::json params = nlohmann::json::object(); + params["password"] = std::string(password); + if (oldPassword.has_value()) { + params["oldPassword"] = std::string(oldPassword.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the currently logged in user's phone number. After updating the + * phone number, the phone verification status will be reset. A confirmation + * SMS is not sent automatically, however you can use the [POST + * /account/verification/phone](https://appwrite.io/docs/references/cloud/client-web/account#createPhoneVerification) + * endpoint to send a confirmation SMS. + * + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @param password User password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePhone( std::string_view phone, std::string_view password ) { + std::string path_ = std::format("/account/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["phone"] = std::string(phone); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the currently logged in user's phone number. After updating the + * phone number, the phone verification status will be reset. A confirmation + * SMS is not sent automatically, however you can use the [POST + * /account/verification/phone](https://appwrite.io/docs/references/cloud/client-web/account#createPhoneVerification) + * endpoint to send a confirmation SMS. + * + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @param password User password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePhoneAsync( std::string_view phone, std::string_view password ) { + std::string path_ = std::format("/account/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["phone"] = std::string(phone); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the preferences as a key-value object for the currently logged in user. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getPrefs( ) { + std::string path_ = std::format("/account/prefs"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the preferences as a key-value object for the currently logged in user. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getPrefsAsync( ) { + std::string path_ = std::format("/account/prefs"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update currently logged in user account preferences. The object you pass is + * stored as is, and replaces any previous value. The maximum allowed prefs + * size is 64kB and throws error if exceeded. + * + * @param prefs Prefs key-value JSON object. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePrefs( const nlohmann::json& prefs = nlohmann::json::object() ) { + std::string path_ = std::format("/account/prefs"); + + nlohmann::json params = nlohmann::json::object(); + params["prefs"] = prefs; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update currently logged in user account preferences. The object you pass is + * stored as is, and replaces any previous value. The maximum allowed prefs + * size is 64kB and throws error if exceeded. + * + * @param prefs Prefs key-value JSON object. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePrefsAsync( const nlohmann::json& prefs = nlohmann::json::object() ) { + std::string path_ = std::format("/account/prefs"); + + nlohmann::json params = nlohmann::json::object(); + params["prefs"] = prefs; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Sends the user an email with a temporary secret key for password reset. + * When the user clicks the confirmation link he is redirected back to your + * app password reset URL with the secret key and email address values + * attached to the URL query string. Use the query string params to submit a + * request to the [PUT + * /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#updateRecovery) + * endpoint to complete the process. The verification link sent to the user's + * email address is valid for 1 hour. + * + * @param email User email. + * @param url URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createRecovery( std::string_view email, std::string_view url ) { + std::string path_ = std::format("/account/recovery"); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + params["url"] = std::string(url); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Sends the user an email with a temporary secret key for password reset. + * When the user clicks the confirmation link he is redirected back to your + * app password reset URL with the secret key and email address values + * attached to the URL query string. Use the query string params to submit a + * request to the [PUT + * /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#updateRecovery) + * endpoint to complete the process. The verification link sent to the user's + * email address is valid for 1 hour. + * + * @param email User email. + * @param url URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createRecoveryAsync( std::string_view email, std::string_view url ) { + std::string path_ = std::format("/account/recovery"); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + params["url"] = std::string(url); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to complete the user account password reset. Both the + * **userId** and **secret** arguments will be passed as query parameters to + * the redirect URL you have provided when sending your request to the [POST + * /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#createRecovery) + * endpoint. + +Please note that in order to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) + * the only valid redirect URLs are the ones from domains you have set when + * adding your platforms in the console interface. + * + * @param userId User ID. + * @param secret Valid reset token. + * @param password New user password. Must be between 8 and 256 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateRecovery( std::string_view userId, std::string_view secret, std::string_view password ) { + std::string path_ = std::format("/account/recovery"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to complete the user account password reset. Both the + * **userId** and **secret** arguments will be passed as query parameters to + * the redirect URL you have provided when sending your request to the [POST + * /account/recovery](https://appwrite.io/docs/references/cloud/client-web/account#createRecovery) + * endpoint. + +Please note that in order to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) + * the only valid redirect URLs are the ones from domains you have set when + * adding your platforms in the console interface. + * + * @param userId User ID. + * @param secret Valid reset token. + * @param password New user password. Must be between 8 and 256 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateRecoveryAsync( std::string_view userId, std::string_view secret, std::string_view password ) { + std::string path_ = std::format("/account/recovery"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the list of active sessions across different devices for the currently + * logged in user. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listSessions( ) { + std::string path_ = std::format("/account/sessions"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the list of active sessions across different devices for the currently + * logged in user. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listSessionsAsync( ) { + std::string path_ = std::format("/account/sessions"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete all sessions from the user account and remove any sessions cookies + * from the end client. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteSessions( ) { + std::string path_ = std::format("/account/sessions"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete all sessions from the user account and remove any sessions cookies + * from the end client. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteSessionsAsync( ) { + std::string path_ = std::format("/account/sessions"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to allow a new user to register an anonymous account in + * your project. This route will also create a new session for the user. To + * allow the new user to convert an anonymous account to a normal account, you + * need to update its [email and + * password](https://appwrite.io/docs/references/cloud/client-web/account#updateEmail) + * or create an [OAuth2 + * session](https://appwrite.io/docs/references/cloud/client-web/account#CreateOAuth2Session). + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createAnonymousSession( ) { + std::string path_ = std::format("/account/sessions/anonymous"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to allow a new user to register an anonymous account in + * your project. This route will also create a new session for the user. To + * allow the new user to convert an anonymous account to a normal account, you + * need to update its [email and + * password](https://appwrite.io/docs/references/cloud/client-web/account#updateEmail) + * or create an [OAuth2 + * session](https://appwrite.io/docs/references/cloud/client-web/account#CreateOAuth2Session). + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAnonymousSessionAsync( ) { + std::string path_ = std::format("/account/sessions/anonymous"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Allow the user to login into their account by providing a valid email and + * password combination. This route will create a new session for the user. + +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 email User email. + * @param password User password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createEmailPasswordSession( std::string_view email, std::string_view password ) { + std::string path_ = std::format("/account/sessions/email"); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Allow the user to login into their account by providing a valid email and + * password combination. This route will create a new session for the user. + +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 email User email. + * @param password User password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createEmailPasswordSessionAsync( std::string_view email, std::string_view password ) { + std::string path_ = std::format("/account/sessions/email"); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * 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. + * + * @param userId User 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 secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMagicURLSession( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/sessions/magic-url"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * 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. + * + * @param userId User 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 secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMagicURLSessionAsync( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/sessions/magic-url"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * 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. + * + * @param userId User 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 secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePhoneSession( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/sessions/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * 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. + * + * @param userId User 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 secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePhoneSessionAsync( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/sessions/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * 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. + * + * @param userId User 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 secret Secret of a token generated by login methods. For example, the `createMagicURLToken` or `createPhoneToken` methods. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createSession( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/sessions/token"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * 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. + * + * @param userId User 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 secret Secret of a token generated by login methods. For example, the `createMagicURLToken` or `createPhoneToken` methods. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createSessionAsync( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/sessions/token"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to get a logged in user's session using a Session ID. + * Inputting 'current' will return the current session being used. + * + * @param sessionId Session ID. Use the string 'current' to get the current device session. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getSession( std::string_view sessionId ) { + std::string path_ = std::format("/account/sessions/{}", sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to get a logged in user's session using a Session ID. + * Inputting 'current' will return the current session being used. + * + * @param sessionId Session ID. Use the string 'current' to get the current device session. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getSessionAsync( std::string_view sessionId ) { + std::string path_ = std::format("/account/sessions/{}", sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to extend a session's length. Extending a session is + * useful when session expiry is short. If the session was created using an + * OAuth provider, this endpoint refreshes the access token from the provider. + * + * @param sessionId Session ID. Use the string 'current' to update the current device session. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateSession( std::string_view sessionId ) { + std::string path_ = std::format("/account/sessions/{}", sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to extend a session's length. Extending a session is + * useful when session expiry is short. If the session was created using an + * OAuth provider, this endpoint refreshes the access token from the provider. + * + * @param sessionId Session ID. Use the string 'current' to update the current device session. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateSessionAsync( std::string_view sessionId ) { + std::string path_ = std::format("/account/sessions/{}", sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Logout the user. Use 'current' as the session ID to logout on this device, + * use a session ID to logout on another device. If you're looking to logout + * the user on all devices, use [Delete + * Sessions](https://appwrite.io/docs/references/cloud/client-web/account#deleteSessions) + * instead. + * + * @param sessionId Session ID. Use the string 'current' to delete the current device session. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteSession( std::string_view sessionId ) { + std::string path_ = std::format("/account/sessions/{}", sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Logout the user. Use 'current' as the session ID to logout on this device, + * use a session ID to logout on another device. If you're looking to logout + * the user on all devices, use [Delete + * Sessions](https://appwrite.io/docs/references/cloud/client-web/account#deleteSessions) + * instead. + * + * @param sessionId Session ID. Use the string 'current' to delete the current device session. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteSessionAsync( std::string_view sessionId ) { + std::string path_ = std::format("/account/sessions/{}", sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Block the currently logged in user account. Behind the scene, the user + * record is not deleted but permanently blocked from any access. To + * completely delete a user, use the Users API instead. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateStatus( ) { + std::string path_ = std::format("/account/status"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Block the currently logged in user account. Behind the scene, the user + * record is not deleted but permanently blocked from any access. To + * completely delete a user, use the Users API instead. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateStatusAsync( ) { + std::string path_ = std::format("/account/status"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Sends the user an email with a secret key for creating a session. If the + * email address has never been used, a **new account is created** using the + * provided `userId`. Otherwise, if the email address is already attached to + * an account, the **user ID is ignored**. Then, the user will receive an + * email with the one-time password. Use the returned user ID and secret and + * submit a request to the [POST + * /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. The secret sent to the user's email + * is valid for 15 minutes. + +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 userId User 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. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored. + * @param email User email. + * @param phrase Toggle for security phrase. If enabled, email will be send 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 appwrite::Result + */ + [[nodiscard]] appwrite::Result createEmailToken( std::string_view userId, std::string_view email, std::optional phrase = false ) { + std::string path_ = std::format("/account/tokens/email"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + if (phrase.has_value()) { + params["phrase"] = *phrase; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Sends the user an email with a secret key for creating a session. If the + * email address has never been used, a **new account is created** using the + * provided `userId`. Otherwise, if the email address is already attached to + * an account, the **user ID is ignored**. Then, the user will receive an + * email with the one-time password. Use the returned user ID and secret and + * submit a request to the [POST + * /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. The secret sent to the user's email + * is valid for 15 minutes. + +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 userId User 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. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored. + * @param email User email. + * @param phrase Toggle for security phrase. If enabled, email will be send 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 appwrite::Result + */ + [[nodiscard]] appwrite::Task> createEmailTokenAsync( std::string_view userId, std::string_view email, std::optional phrase = false ) { + std::string path_ = std::format("/account/tokens/email"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + if (phrase.has_value()) { + params["phrase"] = *phrase; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Sends the user an email with a secret key for creating a session. If the + * provided user ID has not been registered, a new user will be created. When + * the user clicks the link in the email, the user is redirected back to the + * URL you provided with the secret key and userId values attached to the URL + * query string. Use the query string parameters to submit a request to the + * [POST + * /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. The link sent to the user's email + * address is valid for 1 hour. + +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 userId Unique 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. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored. + * @param email User email. + * @param url URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project 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 phrase Toggle for security phrase. If enabled, email will be send 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 appwrite::Result + */ + [[nodiscard]] appwrite::Result createMagicURLToken( std::string_view userId, std::string_view email, std::optional url = std::nullopt, std::optional phrase = false ) { + std::string path_ = std::format("/account/tokens/magic-url"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + if (url.has_value()) { + params["url"] = std::string(url.value()); + } + if (phrase.has_value()) { + params["phrase"] = *phrase; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Sends the user an email with a secret key for creating a session. If the + * provided user ID has not been registered, a new user will be created. When + * the user clicks the link in the email, the user is redirected back to the + * URL you provided with the secret key and userId values attached to the URL + * query string. Use the query string parameters to submit a request to the + * [POST + * /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. The link sent to the user's email + * address is valid for 1 hour. + +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 userId Unique 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. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored. + * @param email User email. + * @param url URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project 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 phrase Toggle for security phrase. If enabled, email will be send 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 appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMagicURLTokenAsync( std::string_view userId, std::string_view email, std::optional url = std::nullopt, std::optional phrase = false ) { + std::string path_ = std::format("/account/tokens/magic-url"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + if (url.has_value()) { + params["url"] = std::string(url.value()); + } + if (phrase.has_value()) { + params["phrase"] = *phrase; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Allow the user to login to their account using the OAuth2 provider of their + * choice. Each OAuth2 provider should be enabled from the Appwrite console + * first. Use the success and failure arguments to provide a redirect URL's + * back to your app when login is completed. + +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. + +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, auth0, authentik, autodesk, bitbucket, bitly, box, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, github, gitlab, google, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, salesforce, slack, spotify, stripe, 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createOAuth2Token( appwrite::enums::OAuthProvider provider, std::optional success = std::nullopt, std::optional failure = std::nullopt, std::optional> scopes = std::vector{} ) { + std::string path_ = std::format("/account/tokens/oauth2/{}", appwrite::enums::toString(provider)); + + nlohmann::json params = nlohmann::json::object(); + if (success.has_value()) { + params["success"] = std::string(success.value()); + } + if (failure.has_value()) { + params["failure"] = std::string(failure.value()); + } + if (scopes.has_value()) { + params["scopes"] = *scopes; + } + + std::unordered_map local_headers_; + + return client_.callLocation("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Allow the user to login to their account using the OAuth2 provider of their + * choice. Each OAuth2 provider should be enabled from the Appwrite console + * first. Use the success and failure arguments to provide a redirect URL's + * back to your app when login is completed. + +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. + +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, auth0, authentik, autodesk, bitbucket, bitly, box, dailymotion, discord, disqus, dropbox, etsy, facebook, figma, github, gitlab, google, linkedin, microsoft, notion, oidc, okta, paypal, paypalSandbox, podio, salesforce, slack, spotify, stripe, 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createOAuth2TokenAsync( appwrite::enums::OAuthProvider provider, std::optional success = std::nullopt, std::optional failure = std::nullopt, std::optional> scopes = std::vector{} ) { + std::string path_ = std::format("/account/tokens/oauth2/{}", appwrite::enums::toString(provider)); + + nlohmann::json params = nlohmann::json::object(); + if (success.has_value()) { + params["success"] = std::string(success.value()); + } + if (failure.has_value()) { + params["failure"] = std::string(failure.value()); + } + if (scopes.has_value()) { + params["scopes"] = *scopes; + } + + std::unordered_map local_headers_; + + return client_.callLocationAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Sends the user an SMS with a secret key for creating a session. If the + * provided user ID has not be registered, a new user will be created. Use the + * returned user ID and secret and submit a request to the [POST + * /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. The secret sent to the user's phone + * is valid for 15 minutes. + +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 userId Unique 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. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored. + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createPhoneToken( std::string_view userId, std::string_view phone ) { + std::string path_ = std::format("/account/tokens/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["phone"] = std::string(phone); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Sends the user an SMS with a secret key for creating a session. If the + * provided user ID has not be registered, a new user will be created. Use the + * returned user ID and secret and submit a request to the [POST + * /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. The secret sent to the user's phone + * is valid for 15 minutes. + +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 userId Unique 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. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored. + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createPhoneTokenAsync( std::string_view userId, std::string_view phone ) { + std::string path_ = std::format("/account/tokens/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["phone"] = std::string(phone); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to send a verification message to your user email address + * to confirm they are the valid owners of that address. Both the **userId** + * and **secret** arguments will be passed as query parameters to the URL you + * have provided to be attached to the verification email. The provided URL + * should redirect the user back to your app and allow you to complete the + * verification process by verifying both the **userId** and **secret** + * parameters. Learn more about how to [complete the verification + * process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). + * The verification link sent to the user's email address is valid for 7 + * days. + +Please note that in order to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), + * the only valid redirect URLs are the ones from domains you have set when + * adding your platforms in the console interface. + * + * @param url URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createEmailVerification( std::string_view url ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["url"] = std::string(url); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to send a verification message to your user email address + * to confirm they are the valid owners of that address. Both the **userId** + * and **secret** arguments will be passed as query parameters to the URL you + * have provided to be attached to the verification email. The provided URL + * should redirect the user back to your app and allow you to complete the + * verification process by verifying both the **userId** and **secret** + * parameters. Learn more about how to [complete the verification + * process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). + * The verification link sent to the user's email address is valid for 7 + * days. + +Please note that in order to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), + * the only valid redirect URLs are the ones from domains you have set when + * adding your platforms in the console interface. + * + * @param url URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createEmailVerificationAsync( std::string_view url ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["url"] = std::string(url); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to send a verification message to your user email address + * to confirm they are the valid owners of that address. Both the **userId** + * and **secret** arguments will be passed as query parameters to the URL you + * have provided to be attached to the verification email. The provided URL + * should redirect the user back to your app and allow you to complete the + * verification process by verifying both the **userId** and **secret** + * parameters. Learn more about how to [complete the verification + * process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). + * The verification link sent to the user's email address is valid for 7 + * days. + +Please note that in order to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), + * the only valid redirect URLs are the ones from domains you have set when + * adding your platforms in the console interface. + * + * @param url URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createVerification( std::string_view url ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["url"] = std::string(url); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to send a verification message to your user email address + * to confirm they are the valid owners of that address. Both the **userId** + * and **secret** arguments will be passed as query parameters to the URL you + * have provided to be attached to the verification email. The provided URL + * should redirect the user back to your app and allow you to complete the + * verification process by verifying both the **userId** and **secret** + * parameters. Learn more about how to [complete the verification + * process](https://appwrite.io/docs/references/cloud/client-web/account#updateVerification). + * The verification link sent to the user's email address is valid for 7 + * days. + +Please note that in order to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), + * the only valid redirect URLs are the ones from domains you have set when + * adding your platforms in the console interface. + * + * @param url URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createVerificationAsync( std::string_view url ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["url"] = std::string(url); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to complete the user email verification process. Use both + * the **userId** and **secret** parameters that were attached to your app URL + * to verify the user email ownership. If confirmed this route will return a + * 200 status code. + * + * @param userId User ID. + * @param secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEmailVerification( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to complete the user email verification process. Use both + * the **userId** and **secret** parameters that were attached to your app URL + * to verify the user email ownership. If confirmed this route will return a + * 200 status code. + * + * @param userId User ID. + * @param secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEmailVerificationAsync( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to complete the user email verification process. Use both + * the **userId** and **secret** parameters that were attached to your app URL + * to verify the user email ownership. If confirmed this route will return a + * 200 status code. + * + * @param userId User ID. + * @param secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateVerification( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to complete the user email verification process. Use both + * the **userId** and **secret** parameters that were attached to your app URL + * to verify the user email ownership. If confirmed this route will return a + * 200 status code. + * + * @param userId User ID. + * @param secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateVerificationAsync( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/verifications/email"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * 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. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createPhoneVerification( ) { + std::string path_ = std::format("/account/verifications/phone"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * 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. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createPhoneVerificationAsync( ) { + std::string path_ = std::format("/account/verifications/phone"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to complete the user phone verification process. Use the + * **userId** and **secret** that were sent to your user's phone number to + * verify the user email ownership. If confirmed this route will return a 200 + * status code. + * + * @param userId User ID. + * @param secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePhoneVerification( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/verifications/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to complete the user phone verification process. Use the + * **userId** and **secret** that were sent to your user's phone number to + * verify the user email ownership. If confirmed this route will return a 200 + * status code. + * + * @param userId User ID. + * @param secret Valid verification token. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePhoneVerificationAsync( std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/account/verifications/phone"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } +}; + +/** + * @brief The Databases service allows you to create structured collections of documents, query and filter lists of documents + */ +class Databases : public Service { +public: + explicit Databases(Client& client) : Service(client) {} + + /** + * Get a list of all databases from the current Appwrite project. You can use + * the search parameter to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result list( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/databases"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all databases from the current Appwrite project. You can use + * the search parameter to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listAsync( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/databases"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new Database. + * + * @param databaseId Unique 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 name Database name. Max length: 128 chars. + * @param enabled Is the database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result create( std::string_view databaseId, std::string_view name, std::optional enabled = true ) { + std::string path_ = std::format("/databases"); + + nlohmann::json params = nlohmann::json::object(); + params["databaseId"] = std::string(databaseId); + params["name"] = std::string(name); + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new Database. + * + * @param databaseId Unique 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 name Database name. Max length: 128 chars. + * @param enabled Is the database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAsync( std::string_view databaseId, std::string_view name, std::optional enabled = true ) { + std::string path_ = std::format("/databases"); + + nlohmann::json params = nlohmann::json::object(); + params["databaseId"] = std::string(databaseId); + params["name"] = std::string(name); + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * List transactions across all databases. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listTransactions( std::optional> queries = std::vector{} ) { + std::string path_ = std::format("/databases/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List transactions across all databases. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listTransactionsAsync( std::optional> queries = std::vector{} ) { + std::string path_ = std::format("/databases/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new transaction. + * + * @param ttl Seconds before the transaction expires. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createTransaction( std::optional ttl = 300 ) { + std::string path_ = std::format("/databases/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new transaction. + * + * @param ttl Seconds before the transaction expires. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTransactionAsync( std::optional ttl = 300 ) { + std::string path_ = std::format("/databases/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getTransaction( std::string_view transactionId ) { + std::string path_ = std::format("/databases/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getTransactionAsync( std::string_view transactionId ) { + std::string path_ = std::format("/databases/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a transaction, to either commit or roll back its operations. + * + * @param transactionId Transaction ID. + * @param commit Commit transaction? + * @param rollback Rollback transaction? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateTransaction( std::string_view transactionId, std::optional commit = false, std::optional rollback = false ) { + std::string path_ = std::format("/databases/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (commit.has_value()) { + params["commit"] = *commit; + } + if (rollback.has_value()) { + params["rollback"] = *rollback; + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a transaction, to either commit or roll back its operations. + * + * @param transactionId Transaction ID. + * @param commit Commit transaction? + * @param rollback Rollback transaction? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateTransactionAsync( std::string_view transactionId, std::optional commit = false, std::optional rollback = false ) { + std::string path_ = std::format("/databases/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (commit.has_value()) { + params["commit"] = *commit; + } + if (rollback.has_value()) { + params["rollback"] = *rollback; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteTransaction( std::string_view transactionId ) { + std::string path_ = std::format("/databases/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteTransactionAsync( std::string_view transactionId ) { + std::string path_ = std::format("/databases/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create multiple operations in a single transaction. + * + * @param transactionId Transaction ID. + * @param operations Array of staged operations. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createOperations( std::string_view transactionId, std::optional> operations = std::vector{} ) { + std::string path_ = std::format("/databases/transactions/{}/operations", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (operations.has_value()) { + params["operations"] = *operations; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create multiple operations in a single transaction. + * + * @param transactionId Transaction ID. + * @param operations Array of staged operations. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createOperationsAsync( std::string_view transactionId, std::optional> operations = std::vector{} ) { + std::string path_ = std::format("/databases/transactions/{}/operations", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (operations.has_value()) { + params["operations"] = *operations; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a database by its unique ID. This endpoint response returns a JSON + * object with the database metadata. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result get( std::string_view databaseId ) { + std::string path_ = std::format("/databases/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a database by its unique ID. This endpoint response returns a JSON + * object with the database metadata. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAsync( std::string_view databaseId ) { + std::string path_ = std::format("/databases/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a database by its unique ID. + * + * @param databaseId Database ID. + * @param name Database name. Max length: 128 chars. + * @param enabled Is database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result update( std::string_view databaseId, std::optional name = std::nullopt, std::optional enabled = true ) { + std::string path_ = std::format("/databases/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a database by its unique ID. + * + * @param databaseId Database ID. + * @param name Database name. Max length: 128 chars. + * @param enabled Is database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateAsync( std::string_view databaseId, std::optional name = std::nullopt, std::optional enabled = true ) { + std::string path_ = std::format("/databases/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a database by its unique ID. Only API keys with with databases.write + * scope can delete a database. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result delete_( std::string_view databaseId ) { + std::string path_ = std::format("/databases/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a database by its unique ID. Only API keys with with databases.write + * scope can delete a database. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> delete_Async( std::string_view databaseId ) { + std::string path_ = std::format("/databases/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all collections that belong to the provided databaseId. You + * can use the search parameter to filter your results. + * + * @param databaseId Database ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, documentSecurity + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listCollections( std::string_view databaseId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/databases/{}/collections", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all collections that belong to the provided databaseId. You + * can use the search parameter to filter your results. + * + * @param databaseId Database ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, documentSecurity + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listCollectionsAsync( std::string_view databaseId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/databases/{}/collections", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new Collection. Before using this route, you should create a new + * database resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Unique 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 name Collection name. Max length: 128 chars. + * @param permissions An array of permissions strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param documentSecurity Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is collection enabled? When set to 'disabled', users cannot access the collection but Server SDKs with and API key can still read and write to the collection. No data is lost when this is toggled. + * @param attributes Array of attribute definitions to create. Each attribute should contain: key (string), type (string: string, integer, float, boolean, datetime), size (integer, required for string type), required (boolean, optional), default (mixed, optional), array (boolean, optional), and type-specific options. + * @param indexes Array of index definitions to create. Each index should contain: key (string), type (string: key, fulltext, unique, spatial), attributes (array of attribute keys), orders (array of ASC/DESC, optional), and lengths (array of integers, optional). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createCollection( std::string_view databaseId, std::string_view collectionId, std::string_view name, std::optional> permissions = std::nullopt, std::optional documentSecurity = false, std::optional enabled = true, std::optional> attributes = std::vector{}, std::optional> indexes = std::vector{} ) { + std::string path_ = std::format("/databases/{}/collections", databaseId); + + nlohmann::json params = nlohmann::json::object(); + params["collectionId"] = std::string(collectionId); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (documentSecurity.has_value()) { + params["documentSecurity"] = *documentSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (attributes.has_value()) { + params["attributes"] = *attributes; + } + if (indexes.has_value()) { + params["indexes"] = *indexes; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new Collection. Before using this route, you should create a new + * database resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Unique 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 name Collection name. Max length: 128 chars. + * @param permissions An array of permissions strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param documentSecurity Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is collection enabled? When set to 'disabled', users cannot access the collection but Server SDKs with and API key can still read and write to the collection. No data is lost when this is toggled. + * @param attributes Array of attribute definitions to create. Each attribute should contain: key (string), type (string: string, integer, float, boolean, datetime), size (integer, required for string type), required (boolean, optional), default (mixed, optional), array (boolean, optional), and type-specific options. + * @param indexes Array of index definitions to create. Each index should contain: key (string), type (string: key, fulltext, unique, spatial), attributes (array of attribute keys), orders (array of ASC/DESC, optional), and lengths (array of integers, optional). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createCollectionAsync( std::string_view databaseId, std::string_view collectionId, std::string_view name, std::optional> permissions = std::nullopt, std::optional documentSecurity = false, std::optional enabled = true, std::optional> attributes = std::vector{}, std::optional> indexes = std::vector{} ) { + std::string path_ = std::format("/databases/{}/collections", databaseId); + + nlohmann::json params = nlohmann::json::object(); + params["collectionId"] = std::string(collectionId); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (documentSecurity.has_value()) { + params["documentSecurity"] = *documentSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (attributes.has_value()) { + params["attributes"] = *attributes; + } + if (indexes.has_value()) { + params["indexes"] = *indexes; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a collection by its unique ID. This endpoint response returns a JSON + * object with the collection metadata. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getCollection( std::string_view databaseId, std::string_view collectionId ) { + std::string path_ = std::format("/databases/{}/collections/{}", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a collection by its unique ID. This endpoint response returns a JSON + * object with the collection metadata. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getCollectionAsync( std::string_view databaseId, std::string_view collectionId ) { + std::string path_ = std::format("/databases/{}/collections/{}", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a collection by its unique ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param name Collection name. Max length: 128 chars. + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param documentSecurity Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is collection enabled? When set to 'disabled', users cannot access the collection but Server SDKs with and API key can still read and write to the collection. No data is lost when this is toggled. + * @param purge When true, purge all cached list responses for this collection as part of the update. Use this to force readers to see fresh data immediately instead of waiting for the cache TTL to expire. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateCollection( std::string_view databaseId, std::string_view collectionId, std::optional name = std::nullopt, std::optional> permissions = std::nullopt, std::optional documentSecurity = false, std::optional enabled = true, std::optional purge = false ) { + std::string path_ = std::format("/databases/{}/collections/{}", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (documentSecurity.has_value()) { + params["documentSecurity"] = *documentSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (purge.has_value()) { + params["purge"] = *purge; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a collection by its unique ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param name Collection name. Max length: 128 chars. + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param documentSecurity Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is collection enabled? When set to 'disabled', users cannot access the collection but Server SDKs with and API key can still read and write to the collection. No data is lost when this is toggled. + * @param purge When true, purge all cached list responses for this collection as part of the update. Use this to force readers to see fresh data immediately instead of waiting for the cache TTL to expire. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateCollectionAsync( std::string_view databaseId, std::string_view collectionId, std::optional name = std::nullopt, std::optional> permissions = std::nullopt, std::optional documentSecurity = false, std::optional enabled = true, std::optional purge = false ) { + std::string path_ = std::format("/databases/{}/collections/{}", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (documentSecurity.has_value()) { + params["documentSecurity"] = *documentSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (purge.has_value()) { + params["purge"] = *purge; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a collection by its unique ID. Only users with write permissions + * have access to delete this resource. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteCollection( std::string_view databaseId, std::string_view collectionId ) { + std::string path_ = std::format("/databases/{}/collections/{}", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a collection by its unique ID. Only users with write permissions + * have access to delete this resource. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteCollectionAsync( std::string_view databaseId, std::string_view collectionId ) { + std::string path_ = std::format("/databases/{}/collections/{}", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * List attributes in the collection. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, size, required, array, status, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listAttributes( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List attributes in the collection. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, size, required, array, status, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listAttributesAsync( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a boolean attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createBooleanAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/boolean", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a boolean attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createBooleanAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/boolean", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a boolean attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateBooleanAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, bool default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/boolean/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a boolean attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateBooleanAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, bool default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/boolean/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a date time attribute according to the ISO 8601 standard. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for the attribute in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createDatetimeAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/datetime", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a date time attribute according to the ISO 8601 standard. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for the attribute in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createDatetimeAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/datetime", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a date time attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateDatetimeAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/datetime/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a date time attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateDatetimeAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/datetime/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create an email attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createEmailAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/email", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create an email attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createEmailAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/email", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an email attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEmailAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/email/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an email attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEmailAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/email/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create an enum attribute. The `elements` param acts as a white-list of + * accepted values for this attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param elements Array of enum values. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createEnumAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, std::vector elements, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/enum", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["elements"] = elements; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create an enum attribute. The `elements` param acts as a white-list of + * accepted values for this attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param elements Array of enum values. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createEnumAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, std::vector elements, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/enum", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["elements"] = elements; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an enum attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param elements Updated list of enum values. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEnumAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, std::vector elements, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/enum/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["elements"] = elements; + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an enum attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param elements Updated list of enum values. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEnumAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, std::vector elements, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/enum/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["elements"] = elements; + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a float attribute. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param min Minimum value. + * @param max Maximum value. + * @param default_ Default value. Cannot be set when required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createFloatAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/float", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a float attribute. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param min Minimum value. + * @param max Maximum value. + * @param default_ Default value. Cannot be set when required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createFloatAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/float", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a float attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when required. + * @param min Minimum value. + * @param max Maximum value. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateFloatAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, double default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/float/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a float attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when required. + * @param min Minimum value. + * @param max Maximum value. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateFloatAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, double default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/float/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create an integer attribute. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param min Minimum value + * @param max Maximum value + * @param default_ Default value. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createIntegerAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/integer", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create an integer attribute. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param min Minimum value + * @param max Maximum value + * @param default_ Default value. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createIntegerAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/integer", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an integer attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when attribute is required. + * @param min Minimum value + * @param max Maximum value + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateIntegerAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, int64_t default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/integer/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an integer attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when attribute is required. + * @param min Minimum value + * @param max Maximum value + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateIntegerAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, int64_t default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/integer/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create IP address attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createIpAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/ip", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create IP address attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createIpAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/ip", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an ip attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateIpAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/ip/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an ip attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateIpAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/ip/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a geometric line attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when attribute is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createLineAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/line", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a geometric line attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when attribute is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createLineAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/line", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a line attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateLineAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/line/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a line attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateLineAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/line/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a longtext attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createLongtextAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/longtext", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a longtext attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createLongtextAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/longtext", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a longtext attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateLongtextAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/longtext/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a longtext attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateLongtextAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/longtext/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a mediumtext attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMediumtextAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/mediumtext", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a mediumtext attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMediumtextAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/mediumtext", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a mediumtext attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMediumtextAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/mediumtext/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a mediumtext attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMediumtextAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/mediumtext/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a geometric point attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when attribute is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createPointAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/point", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a geometric point attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when attribute is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createPointAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/point", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a point attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePointAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/point/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a point attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePointAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/point/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a geometric polygon attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when attribute is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createPolygonAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/polygon", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a geometric polygon attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when attribute is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createPolygonAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/polygon", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a polygon attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePolygonAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/polygon/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a polygon attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#createCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when attribute is required. + * @param newKey New attribute key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePolygonAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/polygon/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create relationship attribute. [Learn more about relationship + * attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param relatedCollectionId Related Collection ID. + * @param type Relation type + * @param twoWay Is Two Way? + * @param key Attribute Key. + * @param twoWayKey Two Way Attribute Key. + * @param onDelete Constraints option + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createRelationshipAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view relatedCollectionId, appwrite::enums::RelationshipType type, std::optional twoWay = false, std::optional key = std::nullopt, std::optional twoWayKey = std::nullopt, std::optional onDelete = appwrite::enums::RelationMutate::RESTRICT ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/relationship", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["relatedCollectionId"] = std::string(relatedCollectionId); + params["type"] = type; + if (twoWay.has_value()) { + params["twoWay"] = *twoWay; + } + if (key.has_value()) { + params["key"] = std::string(key.value()); + } + if (twoWayKey.has_value()) { + params["twoWayKey"] = std::string(twoWayKey.value()); + } + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create relationship attribute. [Learn more about relationship + * attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param relatedCollectionId Related Collection ID. + * @param type Relation type + * @param twoWay Is Two Way? + * @param key Attribute Key. + * @param twoWayKey Two Way Attribute Key. + * @param onDelete Constraints option + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createRelationshipAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view relatedCollectionId, appwrite::enums::RelationshipType type, std::optional twoWay = false, std::optional key = std::nullopt, std::optional twoWayKey = std::nullopt, std::optional onDelete = appwrite::enums::RelationMutate::RESTRICT ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/relationship", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["relatedCollectionId"] = std::string(relatedCollectionId); + params["type"] = type; + if (twoWay.has_value()) { + params["twoWay"] = *twoWay; + } + if (key.has_value()) { + params["key"] = std::string(key.value()); + } + if (twoWayKey.has_value()) { + params["twoWayKey"] = std::string(twoWayKey.value()); + } + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update relationship attribute. [Learn more about relationship + * attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param onDelete Constraints option + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateRelationshipAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, std::optional onDelete = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/relationship/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update relationship attribute. [Learn more about relationship + * attributes](https://appwrite.io/docs/databases-relationships#relationship-attributes). + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param onDelete Constraints option + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateRelationshipAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, std::optional onDelete = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/relationship/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a string attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param size Attribute size for text attributes, in number of characters. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createStringAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/string", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a string attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param size Attribute size for text attributes, in number of characters. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createStringAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/string", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a string attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param size Maximum size of the string attribute. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateStringAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/string/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a string attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param size Maximum size of the string attribute. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateStringAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/string/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a text attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createTextAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/text", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a text attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTextAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/text", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a text attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateTextAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/text/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a text attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateTextAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/text/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a URL attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createUrlAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/url", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a URL attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createUrlAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/url", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an url attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateUrlAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/url/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an url attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateUrlAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/url/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a varchar attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param size Attribute size for varchar attributes, in number of characters. Maximum size is 16381. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createVarcharAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/varchar", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a varchar attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param size Attribute size for varchar attributes, in number of characters. Maximum size is 16381. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param array Is attribute an array? + * @param encrypt Toggle encryption for the attribute. Encryption enhances security by not storing any plain text values in the database. However, encrypted attributes cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createVarcharAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/varchar", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a varchar attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param size Maximum size of the varchar attribute. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateVarcharAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/varchar/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a varchar attribute. Changing the `default` value will not update + * already existing documents. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Attribute Key. + * @param required Is attribute required? + * @param default_ Default value for attribute when not provided. Cannot be set when attribute is required. + * @param size Maximum size of the varchar attribute. + * @param newKey New Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateVarcharAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/varchar/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get attribute by ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get attribute by ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Deletes an attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Deletes an attribute. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param key Attribute Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/attributes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all the user's documents in a given collection. You can use + * the query params to filter your results. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @param ttl TTL (seconds) for caching list responses. Responses are stored in an in-memory key-value cache, keyed per project, collection, schema version (attributes and indexes), caller authorization roles, and the exact query — so users with different permissions never share cached entries. Schema changes invalidate cached entries automatically; document writes do not, so choose a TTL you are comfortable serving as stale data. Set to 0 to disable caching. Must be between 0 and 86400 (24 hours). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listDocuments( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt, std::optional total = true, std::optional ttl = 0 ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the user's documents in a given collection. You can use + * the query params to filter your results. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @param ttl TTL (seconds) for caching list responses. Responses are stored in an in-memory key-value cache, keyed per project, collection, schema version (attributes and indexes), caller authorization roles, and the exact query — so users with different permissions never share cached entries. Schema changes invalidate cached entries automatically; document writes do not, so choose a TTL you are comfortable serving as stale data. Set to 0 to disable caching. Must be between 0 and 86400 (24 hours). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listDocumentsAsync( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt, std::optional total = true, std::optional ttl = 0 ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new Document. Before using this route, you should create a new + * collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents. + * @param documentId Document 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 data Document data as JSON object. + * @param permissions An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createDocument( std::string_view databaseId, std::string_view collectionId, std::string_view documentId = "", const nlohmann::json& data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["documentId"] = std::string(documentId); + params["data"] = data; + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new Document. Before using this route, you should create a new + * collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents. + * @param documentId Document 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 data Document data as JSON object. + * @param permissions An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createDocumentAsync( std::string_view databaseId, std::string_view collectionId, std::string_view documentId = "", const nlohmann::json& data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["documentId"] = std::string(documentId); + params["data"] = data; + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create new Documents. Before using this route, you should create a new + * collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents. + * @param documents Array of documents data as JSON objects. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createDocuments( std::string_view databaseId, std::string_view collectionId, std::vector documents = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["documents"] = documents; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create new Documents. Before using this route, you should create a new + * collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents. + * @param documents Array of documents data as JSON objects. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createDocumentsAsync( std::string_view databaseId, std::string_view collectionId, std::vector documents = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["documents"] = documents; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create or update Documents. Before using this route, you should create a + * new collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documents Array of document data as JSON objects. May contain partial documents. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result upsertDocuments( std::string_view databaseId, std::string_view collectionId, std::vector documents, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["documents"] = documents; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create or update Documents. Before using this route, you should create a + * new collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documents Array of document data as JSON objects. May contain partial documents. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> upsertDocumentsAsync( std::string_view databaseId, std::string_view collectionId, std::vector documents, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["documents"] = documents; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update all documents that match your queries, if no queries are submitted + * then all documents are updated. You can pass only specific fields to be + * updated. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param data Document data as JSON object. Include only attribute and value pairs to be updated. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateDocuments( std::string_view databaseId, std::string_view collectionId, std::optional data = nlohmann::json::object(), std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update all documents that match your queries, if no queries are submitted + * then all documents are updated. You can pass only specific fields to be + * updated. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param data Document data as JSON object. Include only attribute and value pairs to be updated. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateDocumentsAsync( std::string_view databaseId, std::string_view collectionId, std::optional data = nlohmann::json::object(), std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Bulk delete documents using queries, if no queries are passed then all + * documents are deleted. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteDocuments( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Bulk delete documents using queries, if no queries are passed then all + * documents are deleted. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteDocumentsAsync( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a document by its unique ID. This endpoint response returns a JSON + * object with the document data. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param documentId Document ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getDocument( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a document by its unique ID. This endpoint response returns a JSON + * object with the document data. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param documentId Document ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getDocumentAsync( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create or update a Document. Before using this route, you should create a + * new collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param data Document data as JSON object. Include all required attributes of the document to be created or updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result upsertDocument( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create or update a Document. Before using this route, you should create a + * new collection resource using either a [server + * integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param data Document data as JSON object. Include all required attributes of the document to be created or updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> upsertDocumentAsync( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a document by its unique ID. Using the patch method you can pass + * only specific fields that will get updated. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param data Document data as JSON object. Include only attribute and value pairs to be updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateDocument( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a document by its unique ID. Using the patch method you can pass + * only specific fields that will get updated. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param data Document data as JSON object. Include only attribute and value pairs to be updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateDocumentAsync( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a document by its unique ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param documentId Document ID. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteDocument( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a document by its unique ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param documentId Document ID. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteDocumentAsync( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}", databaseId, collectionId, documentId); + + nlohmann::json params = nlohmann::json::object(); + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Decrement a specific attribute of a document by a given value. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param attribute Attribute key. + * @param value Value to increment the attribute by. The value must be a number. + * @param min Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result decrementDocumentAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::string_view attribute, std::optional value = 1, std::optional min = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}/{}/decrement", databaseId, collectionId, documentId, attribute); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (min.has_value()) { + params["min"] = *min; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Decrement a specific attribute of a document by a given value. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param attribute Attribute key. + * @param value Value to increment the attribute by. The value must be a number. + * @param min Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> decrementDocumentAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::string_view attribute, std::optional value = 1, std::optional min = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}/{}/decrement", databaseId, collectionId, documentId, attribute); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (min.has_value()) { + params["min"] = *min; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Increment a specific attribute of a document by a given value. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param attribute Attribute key. + * @param value Value to increment the attribute by. The value must be a number. + * @param max Maximum value for the attribute. If the current value is greater than this value, an error will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result incrementDocumentAttribute( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::string_view attribute, std::optional value = 1, std::optional max = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}/{}/increment", databaseId, collectionId, documentId, attribute); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (max.has_value()) { + params["max"] = *max; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Increment a specific attribute of a document by a given value. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. + * @param documentId Document ID. + * @param attribute Attribute key. + * @param value Value to increment the attribute by. The value must be a number. + * @param max Maximum value for the attribute. If the current value is greater than this value, an error will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> incrementDocumentAttributeAsync( std::string_view databaseId, std::string_view collectionId, std::string_view documentId, std::string_view attribute, std::optional value = 1, std::optional max = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/databases/{}/collections/{}/documents/{}/{}/increment", databaseId, collectionId, documentId, attribute); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (max.has_value()) { + params["max"] = *max; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * List indexes in the collection. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, status, attributes, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listIndexes( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List indexes in the collection. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, status, attributes, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listIndexesAsync( std::string_view databaseId, std::string_view collectionId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Creates an index on the attributes listed. Your index should include all + * the attributes you will query in a single request. +Attributes can be `key`, + * `fulltext`, and `unique`. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Index Key. + * @param type Index type. + * @param attributes Array of attributes to index. Maximum of 100 attributes are allowed, each 32 characters long. + * @param orders Array of index orders. Maximum of 100 orders are allowed. + * @param lengths Length of index. Maximum of 100 + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createIndex( std::string_view databaseId, std::string_view collectionId, std::string_view key, appwrite::enums::DatabasesIndexType type, std::vector attributes, std::optional> orders = {}, std::optional> lengths = std::vector{} ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["type"] = type; + params["attributes"] = attributes; + if (orders.has_value()) { + params["orders"] = *orders; + } + if (lengths.has_value()) { + params["lengths"] = *lengths; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Creates an index on the attributes listed. Your index should include all + * the attributes you will query in a single request. +Attributes can be `key`, + * `fulltext`, and `unique`. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Index Key. + * @param type Index type. + * @param attributes Array of attributes to index. Maximum of 100 attributes are allowed, each 32 characters long. + * @param orders Array of index orders. Maximum of 100 orders are allowed. + * @param lengths Length of index. Maximum of 100 + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createIndexAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key, appwrite::enums::DatabasesIndexType type, std::vector attributes, std::optional> orders = {}, std::optional> lengths = std::vector{} ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes", databaseId, collectionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["type"] = type; + params["attributes"] = attributes; + if (orders.has_value()) { + params["orders"] = *orders; + } + if (lengths.has_value()) { + params["lengths"] = *lengths; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get an index by its unique ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getIndex( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get an index by its unique ID. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getIndexAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an index. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteIndex( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an index. + * + * @param databaseId Database ID. + * @param collectionId Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteIndexAsync( std::string_view databaseId, std::string_view collectionId, std::string_view key ) { + std::string path_ = std::format("/databases/{}/collections/{}/indexes/{}", databaseId, collectionId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } +}; + +/** + * @brief The Functions Service allows you view, create and manage your Cloud Functions. + */ +class Functions : public Service { +public: + explicit Functions(Client& client) : Service(client) {} + + /** + * Get a list of all the project's functions. You can use the query params to + * filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, runtime, deploymentId, schedule, scheduleNext, schedulePrevious, timeout, entrypoint, commands, installationId + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result list( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/functions"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the project's functions. You can use the query params to + * filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, runtime, deploymentId, schedule, scheduleNext, schedulePrevious, timeout, entrypoint, commands, installationId + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listAsync( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/functions"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new function. You can pass a list of + * [permissions](https://appwrite.io/docs/permissions) to allow different + * project users or team with access to execute the function using the client + * API. + * + * @param functionId Function 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 name Function name. Max length: 128 chars. + * @param runtime Execution runtime. + * @param execute An array of role strings with execution permissions. By default no user is granted with any execute permissions. [learn more about roles](https://appwrite.io/docs/permissions#permission-roles). Maximum of 100 roles are allowed, each 64 characters long. + * @param events Events list. Maximum of 100 events are allowed. + * @param schedule Schedule CRON syntax. + * @param timeout Function maximum execution time in seconds. + * @param enabled Is function enabled? When set to 'disabled', users cannot access the function but Server SDKs with and API key can still access the function. No data is lost when this is toggled. + * @param logging When disabled, executions will exclude logs and errors, and will be slightly faster. + * @param entrypoint Entrypoint File. This path is relative to the "providerRootDirectory". + * @param commands Build Commands. + * @param scopes List of scopes allowed for API key auto-generated for every execution. Maximum of 100 scopes are allowed. + * @param installationId Appwrite Installation ID for VCS (Version Control System) deployment. + * @param providerRepositoryId Repository ID of the repo linked to the function. + * @param providerBranch Production branch for the repo linked to the function. + * @param providerSilentMode Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests. + * @param providerRootDirectory Path to function code in the linked repo. + * @param buildSpecification Build specification for the function deployments. + * @param runtimeSpecification Runtime specification for the function executions. + * @param deploymentRetention Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result create( std::string_view functionId, std::string_view name, appwrite::enums::Runtime runtime, std::optional> execute = std::vector{}, std::optional> events = std::vector{}, std::optional schedule = std::nullopt, std::optional timeout = 15, std::optional enabled = true, std::optional logging = true, std::optional entrypoint = std::nullopt, std::optional commands = std::nullopt, std::optional> scopes = {}, std::optional installationId = std::nullopt, std::optional providerRepositoryId = std::nullopt, std::optional providerBranch = std::nullopt, std::optional providerSilentMode = false, std::optional providerRootDirectory = std::nullopt, std::optional buildSpecification = "[]", std::optional runtimeSpecification = "[]", std::optional deploymentRetention = 0 ) { + std::string path_ = std::format("/functions"); + + nlohmann::json params = nlohmann::json::object(); + params["functionId"] = std::string(functionId); + params["name"] = std::string(name); + params["runtime"] = runtime; + if (execute.has_value()) { + params["execute"] = *execute; + } + if (events.has_value()) { + params["events"] = *events; + } + if (schedule.has_value()) { + params["schedule"] = std::string(schedule.value()); + } + if (timeout.has_value()) { + params["timeout"] = *timeout; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (logging.has_value()) { + params["logging"] = *logging; + } + if (entrypoint.has_value()) { + params["entrypoint"] = std::string(entrypoint.value()); + } + if (commands.has_value()) { + params["commands"] = std::string(commands.value()); + } + if (scopes.has_value()) { + params["scopes"] = *scopes; + } + if (installationId.has_value()) { + params["installationId"] = std::string(installationId.value()); + } + if (providerRepositoryId.has_value()) { + params["providerRepositoryId"] = std::string(providerRepositoryId.value()); + } + if (providerBranch.has_value()) { + params["providerBranch"] = std::string(providerBranch.value()); + } + if (providerSilentMode.has_value()) { + params["providerSilentMode"] = *providerSilentMode; + } + if (providerRootDirectory.has_value()) { + params["providerRootDirectory"] = std::string(providerRootDirectory.value()); + } + if (buildSpecification.has_value()) { + params["buildSpecification"] = std::string(buildSpecification.value()); + } + if (runtimeSpecification.has_value()) { + params["runtimeSpecification"] = std::string(runtimeSpecification.value()); + } + if (deploymentRetention.has_value()) { + params["deploymentRetention"] = *deploymentRetention; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new function. You can pass a list of + * [permissions](https://appwrite.io/docs/permissions) to allow different + * project users or team with access to execute the function using the client + * API. + * + * @param functionId Function 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 name Function name. Max length: 128 chars. + * @param runtime Execution runtime. + * @param execute An array of role strings with execution permissions. By default no user is granted with any execute permissions. [learn more about roles](https://appwrite.io/docs/permissions#permission-roles). Maximum of 100 roles are allowed, each 64 characters long. + * @param events Events list. Maximum of 100 events are allowed. + * @param schedule Schedule CRON syntax. + * @param timeout Function maximum execution time in seconds. + * @param enabled Is function enabled? When set to 'disabled', users cannot access the function but Server SDKs with and API key can still access the function. No data is lost when this is toggled. + * @param logging When disabled, executions will exclude logs and errors, and will be slightly faster. + * @param entrypoint Entrypoint File. This path is relative to the "providerRootDirectory". + * @param commands Build Commands. + * @param scopes List of scopes allowed for API key auto-generated for every execution. Maximum of 100 scopes are allowed. + * @param installationId Appwrite Installation ID for VCS (Version Control System) deployment. + * @param providerRepositoryId Repository ID of the repo linked to the function. + * @param providerBranch Production branch for the repo linked to the function. + * @param providerSilentMode Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests. + * @param providerRootDirectory Path to function code in the linked repo. + * @param buildSpecification Build specification for the function deployments. + * @param runtimeSpecification Runtime specification for the function executions. + * @param deploymentRetention Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAsync( std::string_view functionId, std::string_view name, appwrite::enums::Runtime runtime, std::optional> execute = std::vector{}, std::optional> events = std::vector{}, std::optional schedule = std::nullopt, std::optional timeout = 15, std::optional enabled = true, std::optional logging = true, std::optional entrypoint = std::nullopt, std::optional commands = std::nullopt, std::optional> scopes = {}, std::optional installationId = std::nullopt, std::optional providerRepositoryId = std::nullopt, std::optional providerBranch = std::nullopt, std::optional providerSilentMode = false, std::optional providerRootDirectory = std::nullopt, std::optional buildSpecification = "[]", std::optional runtimeSpecification = "[]", std::optional deploymentRetention = 0 ) { + std::string path_ = std::format("/functions"); + + nlohmann::json params = nlohmann::json::object(); + params["functionId"] = std::string(functionId); + params["name"] = std::string(name); + params["runtime"] = runtime; + if (execute.has_value()) { + params["execute"] = *execute; + } + if (events.has_value()) { + params["events"] = *events; + } + if (schedule.has_value()) { + params["schedule"] = std::string(schedule.value()); + } + if (timeout.has_value()) { + params["timeout"] = *timeout; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (logging.has_value()) { + params["logging"] = *logging; + } + if (entrypoint.has_value()) { + params["entrypoint"] = std::string(entrypoint.value()); + } + if (commands.has_value()) { + params["commands"] = std::string(commands.value()); + } + if (scopes.has_value()) { + params["scopes"] = *scopes; + } + if (installationId.has_value()) { + params["installationId"] = std::string(installationId.value()); + } + if (providerRepositoryId.has_value()) { + params["providerRepositoryId"] = std::string(providerRepositoryId.value()); + } + if (providerBranch.has_value()) { + params["providerBranch"] = std::string(providerBranch.value()); + } + if (providerSilentMode.has_value()) { + params["providerSilentMode"] = *providerSilentMode; + } + if (providerRootDirectory.has_value()) { + params["providerRootDirectory"] = std::string(providerRootDirectory.value()); + } + if (buildSpecification.has_value()) { + params["buildSpecification"] = std::string(buildSpecification.value()); + } + if (runtimeSpecification.has_value()) { + params["runtimeSpecification"] = std::string(runtimeSpecification.value()); + } + if (deploymentRetention.has_value()) { + params["deploymentRetention"] = *deploymentRetention; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all runtimes that are currently active on your instance. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listRuntimes( ) { + std::string path_ = std::format("/functions/runtimes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all runtimes that are currently active on your instance. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listRuntimesAsync( ) { + std::string path_ = std::format("/functions/runtimes"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * List allowed function specifications for this instance. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listSpecifications( ) { + std::string path_ = std::format("/functions/specifications"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List allowed function specifications for this instance. + * + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listSpecificationsAsync( ) { + std::string path_ = std::format("/functions/specifications"); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a function by its unique ID. + * + * @param functionId Function ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result get( std::string_view functionId ) { + std::string path_ = std::format("/functions/{}", functionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a function by its unique ID. + * + * @param functionId Function ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAsync( std::string_view functionId ) { + std::string path_ = std::format("/functions/{}", functionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update function by its unique ID. + * + * @param functionId Function ID. + * @param name Function name. Max length: 128 chars. + * @param runtime Execution runtime. + * @param execute An array of role strings with execution permissions. By default no user is granted with any execute permissions. [learn more about roles](https://appwrite.io/docs/permissions#permission-roles). Maximum of 100 roles are allowed, each 64 characters long. + * @param events Events list. Maximum of 100 events are allowed. + * @param schedule Schedule CRON syntax. + * @param timeout Maximum execution time in seconds. + * @param enabled Is function enabled? When set to 'disabled', users cannot access the function but Server SDKs with and API key can still access the function. No data is lost when this is toggled. + * @param logging When disabled, executions will exclude logs and errors, and will be slightly faster. + * @param entrypoint Entrypoint File. This path is relative to the "providerRootDirectory". + * @param commands Build Commands. + * @param scopes List of scopes allowed for API Key auto-generated for every execution. Maximum of 100 scopes are allowed. + * @param installationId Appwrite Installation ID for VCS (Version Controle System) deployment. + * @param providerRepositoryId Repository ID of the repo linked to the function + * @param providerBranch Production branch for the repo linked to the function + * @param providerSilentMode Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests. + * @param providerRootDirectory Path to function code in the linked repo. + * @param buildSpecification Build specification for the function deployments. + * @param runtimeSpecification Runtime specification for the function executions. + * @param deploymentRetention Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result update( std::string_view functionId, std::string_view name, std::optional runtime = std::nullopt, std::optional> execute = std::vector{}, std::optional> events = std::vector{}, std::optional schedule = std::nullopt, std::optional timeout = 15, std::optional enabled = true, std::optional logging = true, std::optional entrypoint = std::nullopt, std::optional commands = std::nullopt, std::optional> scopes = {}, std::optional installationId = std::nullopt, std::optional providerRepositoryId = std::nullopt, std::optional providerBranch = std::nullopt, std::optional providerSilentMode = false, std::optional providerRootDirectory = std::nullopt, std::optional buildSpecification = "[]", std::optional runtimeSpecification = "[]", std::optional deploymentRetention = 0 ) { + std::string path_ = std::format("/functions/{}", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + if (runtime.has_value()) { + params["runtime"] = *runtime; + } + if (execute.has_value()) { + params["execute"] = *execute; + } + if (events.has_value()) { + params["events"] = *events; + } + if (schedule.has_value()) { + params["schedule"] = std::string(schedule.value()); + } + if (timeout.has_value()) { + params["timeout"] = *timeout; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (logging.has_value()) { + params["logging"] = *logging; + } + if (entrypoint.has_value()) { + params["entrypoint"] = std::string(entrypoint.value()); + } + if (commands.has_value()) { + params["commands"] = std::string(commands.value()); + } + if (scopes.has_value()) { + params["scopes"] = *scopes; + } + if (installationId.has_value()) { + params["installationId"] = std::string(installationId.value()); + } + if (providerRepositoryId.has_value()) { + params["providerRepositoryId"] = std::string(providerRepositoryId.value()); + } + if (providerBranch.has_value()) { + params["providerBranch"] = std::string(providerBranch.value()); + } + if (providerSilentMode.has_value()) { + params["providerSilentMode"] = *providerSilentMode; + } + if (providerRootDirectory.has_value()) { + params["providerRootDirectory"] = std::string(providerRootDirectory.value()); + } + if (buildSpecification.has_value()) { + params["buildSpecification"] = std::string(buildSpecification.value()); + } + if (runtimeSpecification.has_value()) { + params["runtimeSpecification"] = std::string(runtimeSpecification.value()); + } + if (deploymentRetention.has_value()) { + params["deploymentRetention"] = *deploymentRetention; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update function by its unique ID. + * + * @param functionId Function ID. + * @param name Function name. Max length: 128 chars. + * @param runtime Execution runtime. + * @param execute An array of role strings with execution permissions. By default no user is granted with any execute permissions. [learn more about roles](https://appwrite.io/docs/permissions#permission-roles). Maximum of 100 roles are allowed, each 64 characters long. + * @param events Events list. Maximum of 100 events are allowed. + * @param schedule Schedule CRON syntax. + * @param timeout Maximum execution time in seconds. + * @param enabled Is function enabled? When set to 'disabled', users cannot access the function but Server SDKs with and API key can still access the function. No data is lost when this is toggled. + * @param logging When disabled, executions will exclude logs and errors, and will be slightly faster. + * @param entrypoint Entrypoint File. This path is relative to the "providerRootDirectory". + * @param commands Build Commands. + * @param scopes List of scopes allowed for API Key auto-generated for every execution. Maximum of 100 scopes are allowed. + * @param installationId Appwrite Installation ID for VCS (Version Controle System) deployment. + * @param providerRepositoryId Repository ID of the repo linked to the function + * @param providerBranch Production branch for the repo linked to the function + * @param providerSilentMode Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests. + * @param providerRootDirectory Path to function code in the linked repo. + * @param buildSpecification Build specification for the function deployments. + * @param runtimeSpecification Runtime specification for the function executions. + * @param deploymentRetention Days to keep non-active deployments before deletion. Value 0 means all deployments will be kept. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateAsync( std::string_view functionId, std::string_view name, std::optional runtime = std::nullopt, std::optional> execute = std::vector{}, std::optional> events = std::vector{}, std::optional schedule = std::nullopt, std::optional timeout = 15, std::optional enabled = true, std::optional logging = true, std::optional entrypoint = std::nullopt, std::optional commands = std::nullopt, std::optional> scopes = {}, std::optional installationId = std::nullopt, std::optional providerRepositoryId = std::nullopt, std::optional providerBranch = std::nullopt, std::optional providerSilentMode = false, std::optional providerRootDirectory = std::nullopt, std::optional buildSpecification = "[]", std::optional runtimeSpecification = "[]", std::optional deploymentRetention = 0 ) { + std::string path_ = std::format("/functions/{}", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + if (runtime.has_value()) { + params["runtime"] = *runtime; + } + if (execute.has_value()) { + params["execute"] = *execute; + } + if (events.has_value()) { + params["events"] = *events; + } + if (schedule.has_value()) { + params["schedule"] = std::string(schedule.value()); + } + if (timeout.has_value()) { + params["timeout"] = *timeout; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (logging.has_value()) { + params["logging"] = *logging; + } + if (entrypoint.has_value()) { + params["entrypoint"] = std::string(entrypoint.value()); + } + if (commands.has_value()) { + params["commands"] = std::string(commands.value()); + } + if (scopes.has_value()) { + params["scopes"] = *scopes; + } + if (installationId.has_value()) { + params["installationId"] = std::string(installationId.value()); + } + if (providerRepositoryId.has_value()) { + params["providerRepositoryId"] = std::string(providerRepositoryId.value()); + } + if (providerBranch.has_value()) { + params["providerBranch"] = std::string(providerBranch.value()); + } + if (providerSilentMode.has_value()) { + params["providerSilentMode"] = *providerSilentMode; + } + if (providerRootDirectory.has_value()) { + params["providerRootDirectory"] = std::string(providerRootDirectory.value()); + } + if (buildSpecification.has_value()) { + params["buildSpecification"] = std::string(buildSpecification.value()); + } + if (runtimeSpecification.has_value()) { + params["runtimeSpecification"] = std::string(runtimeSpecification.value()); + } + if (deploymentRetention.has_value()) { + params["deploymentRetention"] = *deploymentRetention; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a function by its unique ID. + * + * @param functionId Function ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result delete_( std::string_view functionId ) { + std::string path_ = std::format("/functions/{}", functionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a function by its unique ID. + * + * @param functionId Function ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> delete_Async( std::string_view functionId ) { + std::string path_ = std::format("/functions/{}", functionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the function active deployment. Use this endpoint to switch the code + * deployment that should be used when visitor opens your function. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateFunctionDeployment( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployment", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["deploymentId"] = std::string(deploymentId); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the function active deployment. Use this endpoint to switch the code + * deployment that should be used when visitor opens your function. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateFunctionDeploymentAsync( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployment", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["deploymentId"] = std::string(deploymentId); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all the function's code deployments. You can use the query + * params to filter your results. + * + * @param functionId Function ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listDeployments( std::string_view functionId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/functions/{}/deployments", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the function's code deployments. You can use the query + * params to filter your results. + * + * @param functionId Function ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listDeploymentsAsync( std::string_view functionId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/functions/{}/deployments", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new function code deployment. Use this endpoint to upload a new + * version of your code function. To execute your newly uploaded code, you'll + * need to update the function's deployment to use your new deployment + * UID. + +This endpoint accepts a tar.gz file compressed with your code. Make + * sure to include any dependencies your code has within the compressed file. + * You can learn more about code packaging in the [Appwrite Cloud Functions + * tutorial](https://appwrite.io/docs/functions). + +Use the "command" param to + * set the entrypoint used to execute your code. + * + * @param functionId Function ID. + * @param code Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory. + * @param activate Automatically activate the deployment when it is finished building. + * @param entrypoint Entrypoint File. + * @param commands Build Commands. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createDeployment( std::string_view functionId, appwrite::InputFile code, bool activate, std::optional entrypoint = std::nullopt, std::optional commands = std::nullopt , Client::ProgressCallback onProgress = nullptr ) { + std::string path_ = std::format("/functions/{}/deployments", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (entrypoint.has_value()) { + params["entrypoint"] = std::string(entrypoint.value()); + } + if (commands.has_value()) { + params["commands"] = std::string(commands.value()); + } + params["activate"] = activate; + + std::unordered_map local_headers_; + + return client_.fileUpload("POST", path_, "code", std::move(code), std::move(local_headers_), std::move(params), std::move(onProgress)); + } + + /** + * Create a new function code deployment. Use this endpoint to upload a new + * version of your code function. To execute your newly uploaded code, you'll + * need to update the function's deployment to use your new deployment + * UID. + +This endpoint accepts a tar.gz file compressed with your code. Make + * sure to include any dependencies your code has within the compressed file. + * You can learn more about code packaging in the [Appwrite Cloud Functions + * tutorial](https://appwrite.io/docs/functions). + +Use the "command" param to + * set the entrypoint used to execute your code. + * + * @param functionId Function ID. + * @param code Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory. + * @param activate Automatically activate the deployment when it is finished building. + * @param entrypoint Entrypoint File. + * @param commands Build Commands. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createDeploymentAsync( std::string_view functionId, appwrite::InputFile code, bool activate, std::optional entrypoint = std::nullopt, std::optional commands = std::nullopt , Client::ProgressCallback onProgress = nullptr ) { + std::string path_ = std::format("/functions/{}/deployments", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (entrypoint.has_value()) { + params["entrypoint"] = std::string(entrypoint.value()); + } + if (commands.has_value()) { + params["commands"] = std::string(commands.value()); + } + params["activate"] = activate; + + std::unordered_map local_headers_; + + return client_.fileUploadAsync("POST", path_, "code", std::move(code), std::move(local_headers_), std::move(params), std::move(onProgress)); + } + /** + * Create a new build for an existing function deployment. This endpoint + * allows you to rebuild a deployment with the updated function configuration, + * including its entrypoint and build commands if they have been modified. The + * build process will be queued and executed asynchronously. The original + * deployment's code will be preserved and used for the new build. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @param buildId Build unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createDuplicateDeployment( std::string_view functionId, std::string_view deploymentId, std::optional buildId = std::nullopt ) { + std::string path_ = std::format("/functions/{}/deployments/duplicate", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["deploymentId"] = std::string(deploymentId); + if (buildId.has_value()) { + params["buildId"] = std::string(buildId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new build for an existing function deployment. This endpoint + * allows you to rebuild a deployment with the updated function configuration, + * including its entrypoint and build commands if they have been modified. The + * build process will be queued and executed asynchronously. The original + * deployment's code will be preserved and used for the new build. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @param buildId Build unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createDuplicateDeploymentAsync( std::string_view functionId, std::string_view deploymentId, std::optional buildId = std::nullopt ) { + std::string path_ = std::format("/functions/{}/deployments/duplicate", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["deploymentId"] = std::string(deploymentId); + if (buildId.has_value()) { + params["buildId"] = std::string(buildId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a deployment based on a template. + +Use this endpoint with + * combination of + * [listTemplates](https://appwrite.io/docs/products/functions/templates) to + * find the template details. + * + * @param functionId Function ID. + * @param repository Repository name of the template. + * @param owner The name of the owner of the template. + * @param rootDirectory Path to function code in the template repo. + * @param type Type for the reference provided. Can be commit, branch, or tag + * @param reference Reference value, can be a commit hash, branch name, or release tag + * @param activate Automatically activate the deployment when it is finished building. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createTemplateDeployment( std::string_view functionId, std::string_view repository, std::string_view owner, std::string_view rootDirectory, appwrite::enums::TemplateReferenceType type, std::string_view reference, std::optional activate = false ) { + std::string path_ = std::format("/functions/{}/deployments/template", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["repository"] = std::string(repository); + params["owner"] = std::string(owner); + params["rootDirectory"] = std::string(rootDirectory); + params["type"] = type; + params["reference"] = std::string(reference); + if (activate.has_value()) { + params["activate"] = *activate; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a deployment based on a template. + +Use this endpoint with + * combination of + * [listTemplates](https://appwrite.io/docs/products/functions/templates) to + * find the template details. + * + * @param functionId Function ID. + * @param repository Repository name of the template. + * @param owner The name of the owner of the template. + * @param rootDirectory Path to function code in the template repo. + * @param type Type for the reference provided. Can be commit, branch, or tag + * @param reference Reference value, can be a commit hash, branch name, or release tag + * @param activate Automatically activate the deployment when it is finished building. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTemplateDeploymentAsync( std::string_view functionId, std::string_view repository, std::string_view owner, std::string_view rootDirectory, appwrite::enums::TemplateReferenceType type, std::string_view reference, std::optional activate = false ) { + std::string path_ = std::format("/functions/{}/deployments/template", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["repository"] = std::string(repository); + params["owner"] = std::string(owner); + params["rootDirectory"] = std::string(rootDirectory); + params["type"] = type; + params["reference"] = std::string(reference); + if (activate.has_value()) { + params["activate"] = *activate; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a deployment when a function is connected to VCS. + +This endpoint + * lets you create deployment from a branch, commit, or a tag. + * + * @param functionId Function ID. + * @param type Type of reference passed. Allowed values are: branch, commit + * @param reference VCS reference to create deployment from. Depending on type this can be: branch name, commit hash + * @param activate Automatically activate the deployment when it is finished building. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createVcsDeployment( std::string_view functionId, appwrite::enums::VCSReferenceType type, std::string_view reference, std::optional activate = false ) { + std::string path_ = std::format("/functions/{}/deployments/vcs", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["type"] = type; + params["reference"] = std::string(reference); + if (activate.has_value()) { + params["activate"] = *activate; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a deployment when a function is connected to VCS. + +This endpoint + * lets you create deployment from a branch, commit, or a tag. + * + * @param functionId Function ID. + * @param type Type of reference passed. Allowed values are: branch, commit + * @param reference VCS reference to create deployment from. Depending on type this can be: branch name, commit hash + * @param activate Automatically activate the deployment when it is finished building. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createVcsDeploymentAsync( std::string_view functionId, appwrite::enums::VCSReferenceType type, std::string_view reference, std::optional activate = false ) { + std::string path_ = std::format("/functions/{}/deployments/vcs", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["type"] = type; + params["reference"] = std::string(reference); + if (activate.has_value()) { + params["activate"] = *activate; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a function deployment by its unique ID. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getDeployment( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployments/{}", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a function deployment by its unique ID. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getDeploymentAsync( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployments/{}", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a code deployment by its unique ID. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteDeployment( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployments/{}", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a code deployment by its unique ID. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteDeploymentAsync( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployments/{}", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a function deployment content by its unique ID. The endpoint response + * return with a 'Content-Disposition: attachment' header that tells the + * browser to start downloading the file to user downloads directory. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @param type Deployment file to download. Can be: "source", "output". + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getDeploymentDownload( std::string_view functionId, std::string_view deploymentId, std::optional type = appwrite::enums::DeploymentDownloadType::SOURCE ) { + std::string path_ = std::format("/functions/{}/deployments/{}/download", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + if (type.has_value()) { + params["type"] = *type; + } + + std::unordered_map local_headers_; + + return client_.callBytes("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a function deployment content by its unique ID. The endpoint response + * return with a 'Content-Disposition: attachment' header that tells the + * browser to start downloading the file to user downloads directory. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @param type Deployment file to download. Can be: "source", "output". + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getDeploymentDownloadAsync( std::string_view functionId, std::string_view deploymentId, std::optional type = appwrite::enums::DeploymentDownloadType::SOURCE ) { + std::string path_ = std::format("/functions/{}/deployments/{}/download", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + if (type.has_value()) { + params["type"] = *type; + } + + std::unordered_map local_headers_; + + return client_.callBytesAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Cancel an ongoing function deployment build. If the build is already in + * progress, it will be stopped and marked as canceled. If the build hasn't + * started yet, it will be marked as canceled without executing. You cannot + * cancel builds that have already completed (status 'ready') or failed. The + * response includes the final build status and details. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateDeploymentStatus( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployments/{}/status", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Cancel an ongoing function deployment build. If the build is already in + * progress, it will be stopped and marked as canceled. If the build hasn't + * started yet, it will be marked as canceled without executing. You cannot + * cancel builds that have already completed (status 'ready') or failed. The + * response includes the final build status and details. + * + * @param functionId Function ID. + * @param deploymentId Deployment ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateDeploymentStatusAsync( std::string_view functionId, std::string_view deploymentId ) { + std::string path_ = std::format("/functions/{}/deployments/{}/status", functionId, deploymentId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all the current user function execution logs. You can use the + * query params to filter your results. + * + * @param functionId Function ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: trigger, status, responseStatusCode, duration, requestMethod, requestPath, deploymentId + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listExecutions( std::string_view functionId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/functions/{}/executions", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the current user function execution logs. You can use the + * query params to filter your results. + * + * @param functionId Function ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: trigger, status, responseStatusCode, duration, requestMethod, requestPath, deploymentId + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listExecutionsAsync( std::string_view functionId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/functions/{}/executions", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Trigger a function execution. The returned object will return you the + * current execution status. You can ping the `Get Execution` endpoint to get + * updates on the current execution status. Once this endpoint is called, your + * function execution process will start asynchronously. + * + * @param functionId Function ID. + * @param body HTTP body of execution. Default value is empty string. + * @param async Execute code in the background. Default value is false. + * @param path HTTP path of execution. Path can include query params. Default value is / + * @param method HTTP method of execution. Default value is POST. + * @param headers HTTP headers of execution. Defaults to empty. + * @param scheduledAt Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createExecution( std::string_view functionId, std::optional body = std::nullopt, std::optional async = false, std::optional path = "/", std::optional method = appwrite::enums::ExecutionMethod::POST, std::optional headers = nlohmann::json::object(), std::optional scheduledAt = std::nullopt ) { + std::string path_ = std::format("/functions/{}/executions", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (body.has_value()) { + params["body"] = std::string(body.value()); + } + if (async.has_value()) { + params["async"] = *async; + } + if (path.has_value()) { + params["path"] = std::string(path.value()); + } + if (method.has_value()) { + params["method"] = *method; + } + if (headers.has_value()) { + params["headers"] = *headers; + } + if (scheduledAt.has_value()) { + params["scheduledAt"] = std::string(scheduledAt.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Trigger a function execution. The returned object will return you the + * current execution status. You can ping the `Get Execution` endpoint to get + * updates on the current execution status. Once this endpoint is called, your + * function execution process will start asynchronously. + * + * @param functionId Function ID. + * @param body HTTP body of execution. Default value is empty string. + * @param async Execute code in the background. Default value is false. + * @param path HTTP path of execution. Path can include query params. Default value is / + * @param method HTTP method of execution. Default value is POST. + * @param headers HTTP headers of execution. Defaults to empty. + * @param scheduledAt Scheduled execution time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future with precision in minutes. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createExecutionAsync( std::string_view functionId, std::optional body = std::nullopt, std::optional async = false, std::optional path = "/", std::optional method = appwrite::enums::ExecutionMethod::POST, std::optional headers = nlohmann::json::object(), std::optional scheduledAt = std::nullopt ) { + std::string path_ = std::format("/functions/{}/executions", functionId); + + nlohmann::json params = nlohmann::json::object(); + if (body.has_value()) { + params["body"] = std::string(body.value()); + } + if (async.has_value()) { + params["async"] = *async; + } + if (path.has_value()) { + params["path"] = std::string(path.value()); + } + if (method.has_value()) { + params["method"] = *method; + } + if (headers.has_value()) { + params["headers"] = *headers; + } + if (scheduledAt.has_value()) { + params["scheduledAt"] = std::string(scheduledAt.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a function execution log by its unique ID. + * + * @param functionId Function ID. + * @param executionId Execution ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getExecution( std::string_view functionId, std::string_view executionId ) { + std::string path_ = std::format("/functions/{}/executions/{}", functionId, executionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a function execution log by its unique ID. + * + * @param functionId Function ID. + * @param executionId Execution ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getExecutionAsync( std::string_view functionId, std::string_view executionId ) { + std::string path_ = std::format("/functions/{}/executions/{}", functionId, executionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a function execution by its unique ID. + * + * @param functionId Function ID. + * @param executionId Execution ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteExecution( std::string_view functionId, std::string_view executionId ) { + std::string path_ = std::format("/functions/{}/executions/{}", functionId, executionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a function execution by its unique ID. + * + * @param functionId Function ID. + * @param executionId Execution ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteExecutionAsync( std::string_view functionId, std::string_view executionId ) { + std::string path_ = std::format("/functions/{}/executions/{}", functionId, executionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all variables of a specific function. + * + * @param functionId Function unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listVariables( std::string_view functionId ) { + std::string path_ = std::format("/functions/{}/variables", functionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all variables of a specific function. + * + * @param functionId Function unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listVariablesAsync( std::string_view functionId ) { + std::string path_ = std::format("/functions/{}/variables", functionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new function environment variable. These variables can be accessed + * in the function at runtime as environment variables. + * + * @param functionId Function unique ID. + * @param key Variable key. Max length: 255 chars. + * @param value Variable value. Max length: 8192 chars. + * @param secret Secret variables can be updated or deleted, but only functions can read them during build and runtime. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createVariable( std::string_view functionId, std::string_view key, std::string_view value, std::optional secret = true ) { + std::string path_ = std::format("/functions/{}/variables", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["value"] = std::string(value); + if (secret.has_value()) { + params["secret"] = *secret; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new function environment variable. These variables can be accessed + * in the function at runtime as environment variables. + * + * @param functionId Function unique ID. + * @param key Variable key. Max length: 255 chars. + * @param value Variable value. Max length: 8192 chars. + * @param secret Secret variables can be updated or deleted, but only functions can read them during build and runtime. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createVariableAsync( std::string_view functionId, std::string_view key, std::string_view value, std::optional secret = true ) { + std::string path_ = std::format("/functions/{}/variables", functionId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["value"] = std::string(value); + if (secret.has_value()) { + params["secret"] = *secret; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a variable by its unique ID. + * + * @param functionId Function unique ID. + * @param variableId Variable unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getVariable( std::string_view functionId, std::string_view variableId ) { + std::string path_ = std::format("/functions/{}/variables/{}", functionId, variableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a variable by its unique ID. + * + * @param functionId Function unique ID. + * @param variableId Variable unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getVariableAsync( std::string_view functionId, std::string_view variableId ) { + std::string path_ = std::format("/functions/{}/variables/{}", functionId, variableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update variable by its unique ID. + * + * @param functionId Function unique ID. + * @param variableId Variable unique ID. + * @param key Variable key. Max length: 255 chars. + * @param value Variable value. Max length: 8192 chars. + * @param secret Secret variables can be updated or deleted, but only functions can read them during build and runtime. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateVariable( std::string_view functionId, std::string_view variableId, std::string_view key, std::optional value = std::nullopt, std::optional secret = std::nullopt ) { + std::string path_ = std::format("/functions/{}/variables/{}", functionId, variableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + if (value.has_value()) { + params["value"] = std::string(value.value()); + } + if (secret.has_value()) { + params["secret"] = *secret; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update variable by its unique ID. + * + * @param functionId Function unique ID. + * @param variableId Variable unique ID. + * @param key Variable key. Max length: 255 chars. + * @param value Variable value. Max length: 8192 chars. + * @param secret Secret variables can be updated or deleted, but only functions can read them during build and runtime. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateVariableAsync( std::string_view functionId, std::string_view variableId, std::string_view key, std::optional value = std::nullopt, std::optional secret = std::nullopt ) { + std::string path_ = std::format("/functions/{}/variables/{}", functionId, variableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + if (value.has_value()) { + params["value"] = std::string(value.value()); + } + if (secret.has_value()) { + params["secret"] = *secret; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a variable by its unique ID. + * + * @param functionId Function unique ID. + * @param variableId Variable unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteVariable( std::string_view functionId, std::string_view variableId ) { + std::string path_ = std::format("/functions/{}/variables/{}", functionId, variableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a variable by its unique ID. + * + * @param functionId Function unique ID. + * @param variableId Variable unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteVariableAsync( std::string_view functionId, std::string_view variableId ) { + std::string path_ = std::format("/functions/{}/variables/{}", functionId, variableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } +}; + +/** + * @brief The Storage service allows you to manage your project files. + */ +class Storage : public Service { +public: + explicit Storage(Client& client) : Service(client) {} + + /** + * Get a list of all the storage buckets. You can use the query params to + * filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: enabled, name, fileSecurity, maximumFileSize, encryption, antivirus, transformations + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listBuckets( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/storage/buckets"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the storage buckets. You can use the query params to + * filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: enabled, name, fileSecurity, maximumFileSize, encryption, antivirus, transformations + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listBucketsAsync( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/storage/buckets"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new storage bucket. + * + * @param bucketId Unique 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 name Bucket name + * @param permissions An array of permission strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param fileSecurity Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is bucket enabled? When set to 'disabled', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled. + * @param maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 5GB. + * @param allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long. + * @param compression Compression algorithm chosen for compression. Can be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd), For file size above 20MB compression is skipped even if it's enabled + * @param encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled + * @param antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled + * @param transformations Are image transformations enabled? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createBucket( std::string_view bucketId, std::string_view name, std::optional> permissions = std::nullopt, std::optional fileSecurity = false, std::optional enabled = true, std::optional maximumFileSize = 0, std::optional> allowedFileExtensions = std::vector{}, std::optional compression = appwrite::enums::Compression::NONE, std::optional encryption = true, std::optional antivirus = true, std::optional transformations = true ) { + std::string path_ = std::format("/storage/buckets"); + + nlohmann::json params = nlohmann::json::object(); + params["bucketId"] = std::string(bucketId); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (fileSecurity.has_value()) { + params["fileSecurity"] = *fileSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (maximumFileSize.has_value()) { + params["maximumFileSize"] = *maximumFileSize; + } + if (allowedFileExtensions.has_value()) { + params["allowedFileExtensions"] = *allowedFileExtensions; + } + if (compression.has_value()) { + params["compression"] = *compression; + } + if (encryption.has_value()) { + params["encryption"] = *encryption; + } + if (antivirus.has_value()) { + params["antivirus"] = *antivirus; + } + if (transformations.has_value()) { + params["transformations"] = *transformations; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new storage bucket. + * + * @param bucketId Unique 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 name Bucket name + * @param permissions An array of permission strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param fileSecurity Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is bucket enabled? When set to 'disabled', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled. + * @param maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 5GB. + * @param allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long. + * @param compression Compression algorithm chosen for compression. Can be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd), For file size above 20MB compression is skipped even if it's enabled + * @param encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled + * @param antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled + * @param transformations Are image transformations enabled? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createBucketAsync( std::string_view bucketId, std::string_view name, std::optional> permissions = std::nullopt, std::optional fileSecurity = false, std::optional enabled = true, std::optional maximumFileSize = 0, std::optional> allowedFileExtensions = std::vector{}, std::optional compression = appwrite::enums::Compression::NONE, std::optional encryption = true, std::optional antivirus = true, std::optional transformations = true ) { + std::string path_ = std::format("/storage/buckets"); + + nlohmann::json params = nlohmann::json::object(); + params["bucketId"] = std::string(bucketId); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (fileSecurity.has_value()) { + params["fileSecurity"] = *fileSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (maximumFileSize.has_value()) { + params["maximumFileSize"] = *maximumFileSize; + } + if (allowedFileExtensions.has_value()) { + params["allowedFileExtensions"] = *allowedFileExtensions; + } + if (compression.has_value()) { + params["compression"] = *compression; + } + if (encryption.has_value()) { + params["encryption"] = *encryption; + } + if (antivirus.has_value()) { + params["antivirus"] = *antivirus; + } + if (transformations.has_value()) { + params["transformations"] = *transformations; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a storage bucket by its unique ID. This endpoint response returns a + * JSON object with the storage bucket metadata. + * + * @param bucketId Bucket unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getBucket( std::string_view bucketId ) { + std::string path_ = std::format("/storage/buckets/{}", bucketId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a storage bucket by its unique ID. This endpoint response returns a + * JSON object with the storage bucket metadata. + * + * @param bucketId Bucket unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getBucketAsync( std::string_view bucketId ) { + std::string path_ = std::format("/storage/buckets/{}", bucketId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a storage bucket by its unique ID. + * + * @param bucketId Bucket unique ID. + * @param name Bucket name + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param fileSecurity Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is bucket enabled? When set to 'disabled', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled. + * @param maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 5GB. + * @param allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long. + * @param compression Compression algorithm chosen for compression. Can be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd), For file size above 20MB compression is skipped even if it's enabled + * @param encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled + * @param antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled + * @param transformations Are image transformations enabled? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateBucket( std::string_view bucketId, std::string_view name, std::optional> permissions = std::nullopt, std::optional fileSecurity = false, std::optional enabled = true, std::optional maximumFileSize = 0, std::optional> allowedFileExtensions = std::vector{}, std::optional compression = appwrite::enums::Compression::NONE, std::optional encryption = true, std::optional antivirus = true, std::optional transformations = true ) { + std::string path_ = std::format("/storage/buckets/{}", bucketId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (fileSecurity.has_value()) { + params["fileSecurity"] = *fileSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (maximumFileSize.has_value()) { + params["maximumFileSize"] = *maximumFileSize; + } + if (allowedFileExtensions.has_value()) { + params["allowedFileExtensions"] = *allowedFileExtensions; + } + if (compression.has_value()) { + params["compression"] = *compression; + } + if (encryption.has_value()) { + params["encryption"] = *encryption; + } + if (antivirus.has_value()) { + params["antivirus"] = *antivirus; + } + if (transformations.has_value()) { + params["transformations"] = *transformations; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a storage bucket by its unique ID. + * + * @param bucketId Bucket unique ID. + * @param name Bucket name + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param fileSecurity Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is bucket enabled? When set to 'disabled', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled. + * @param maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 5GB. + * @param allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long. + * @param compression Compression algorithm chosen for compression. Can be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd), For file size above 20MB compression is skipped even if it's enabled + * @param encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled + * @param antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled + * @param transformations Are image transformations enabled? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateBucketAsync( std::string_view bucketId, std::string_view name, std::optional> permissions = std::nullopt, std::optional fileSecurity = false, std::optional enabled = true, std::optional maximumFileSize = 0, std::optional> allowedFileExtensions = std::vector{}, std::optional compression = appwrite::enums::Compression::NONE, std::optional encryption = true, std::optional antivirus = true, std::optional transformations = true ) { + std::string path_ = std::format("/storage/buckets/{}", bucketId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (fileSecurity.has_value()) { + params["fileSecurity"] = *fileSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (maximumFileSize.has_value()) { + params["maximumFileSize"] = *maximumFileSize; + } + if (allowedFileExtensions.has_value()) { + params["allowedFileExtensions"] = *allowedFileExtensions; + } + if (compression.has_value()) { + params["compression"] = *compression; + } + if (encryption.has_value()) { + params["encryption"] = *encryption; + } + if (antivirus.has_value()) { + params["antivirus"] = *antivirus; + } + if (transformations.has_value()) { + params["transformations"] = *transformations; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a storage bucket by its unique ID. + * + * @param bucketId Bucket unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteBucket( std::string_view bucketId ) { + std::string path_ = std::format("/storage/buckets/{}", bucketId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a storage bucket by its unique ID. + * + * @param bucketId Bucket unique ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteBucketAsync( std::string_view bucketId ) { + std::string path_ = std::format("/storage/buckets/{}", bucketId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all the user files. You can use the query params to filter + * your results. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, signature, mimeType, sizeOriginal, chunksTotal, chunksUploaded + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listFiles( std::string_view bucketId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/storage/buckets/{}/files", bucketId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the user files. You can use the query params to filter + * your results. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, signature, mimeType, sizeOriginal, chunksTotal, chunksUploaded + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listFilesAsync( std::string_view bucketId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/storage/buckets/{}/files", bucketId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new file. Before using this route, you should create a new bucket + * resource using either a [server + * integration](https://appwrite.io/docs/server/storage#storageCreateBucket) + * API or directly from your Appwrite console. + +Larger files should be + * uploaded using multiple requests with the + * [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) + * header to send a partial request with a maximum supported chunk of `5MB`. + * The `content-range` header values should always be in bytes. + +When the + * first request is sent, the server will return the **File** object, and the + * subsequent part request must include the file's **id** in `x-appwrite-id` + * header to allow the server to know that the partial upload is for the + * existing file and not for a new one. + +If you're creating a new file using + * one of the Appwrite SDKs, all the chunking logic will be managed by the SDK + * internally. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File 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 file Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/products/storage/upload-download#input-file). + * @param permissions An array of permission strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createFile( std::string_view bucketId, std::string_view fileId, appwrite::InputFile file, std::optional> permissions = std::nullopt , Client::ProgressCallback onProgress = nullptr ) { + std::string path_ = std::format("/storage/buckets/{}/files", bucketId); + + nlohmann::json params = nlohmann::json::object(); + params["fileId"] = std::string(fileId); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + + std::unordered_map local_headers_; + + return client_.fileUpload("POST", path_, "file", std::move(file), std::move(local_headers_), std::move(params), std::move(onProgress)); + } + + /** + * Create a new file. Before using this route, you should create a new bucket + * resource using either a [server + * integration](https://appwrite.io/docs/server/storage#storageCreateBucket) + * API or directly from your Appwrite console. + +Larger files should be + * uploaded using multiple requests with the + * [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) + * header to send a partial request with a maximum supported chunk of `5MB`. + * The `content-range` header values should always be in bytes. + +When the + * first request is sent, the server will return the **File** object, and the + * subsequent part request must include the file's **id** in `x-appwrite-id` + * header to allow the server to know that the partial upload is for the + * existing file and not for a new one. + +If you're creating a new file using + * one of the Appwrite SDKs, all the chunking logic will be managed by the SDK + * internally. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File 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 file Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/products/storage/upload-download#input-file). + * @param permissions An array of permission strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createFileAsync( std::string_view bucketId, std::string_view fileId, appwrite::InputFile file, std::optional> permissions = std::nullopt , Client::ProgressCallback onProgress = nullptr ) { + std::string path_ = std::format("/storage/buckets/{}/files", bucketId); + + nlohmann::json params = nlohmann::json::object(); + params["fileId"] = std::string(fileId); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + + std::unordered_map local_headers_; + + return client_.fileUploadAsync("POST", path_, "file", std::move(file), std::move(local_headers_), std::move(params), std::move(onProgress)); + } + /** + * Get a file by its unique ID. This endpoint response returns a JSON object + * with the file metadata. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getFile( std::string_view bucketId, std::string_view fileId ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a file by its unique ID. This endpoint response returns a JSON object + * with the file metadata. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getFileAsync( std::string_view bucketId, std::string_view fileId ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a file by its unique ID. Only users with write permissions have + * access to update this resource. + * + * @param bucketId Bucket unique ID. + * @param fileId File ID. + * @param name File name. + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateFile( std::string_view bucketId, std::string_view fileId, std::optional name = std::nullopt, std::optional> permissions = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a file by its unique ID. Only users with write permissions have + * access to update this resource. + * + * @param bucketId Bucket unique ID. + * @param fileId File ID. + * @param name File name. + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateFileAsync( std::string_view bucketId, std::string_view fileId, std::optional name = std::nullopt, std::optional> permissions = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a file by its unique ID. Only users with write permissions have + * access to delete this resource. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteFile( std::string_view bucketId, std::string_view fileId ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a file by its unique ID. Only users with write permissions have + * access to delete this resource. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteFileAsync( std::string_view bucketId, std::string_view fileId ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a file content by its unique ID. The endpoint response return with a + * 'Content-Disposition: attachment' header that tells the browser to start + * downloading the file to user downloads directory. + * + * @param bucketId Storage bucket ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @param token File token for accessing this file. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getFileDownload( std::string_view bucketId, std::string_view fileId, std::optional token = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}/download", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (token.has_value()) { + params["token"] = std::string(token.value()); + } + + std::unordered_map local_headers_; + + return client_.callBytes("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a file content by its unique ID. The endpoint response return with a + * 'Content-Disposition: attachment' header that tells the browser to start + * downloading the file to user downloads directory. + * + * @param bucketId Storage bucket ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @param token File token for accessing this file. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getFileDownloadAsync( std::string_view bucketId, std::string_view fileId, std::optional token = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}/download", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (token.has_value()) { + params["token"] = std::string(token.value()); + } + + std::unordered_map local_headers_; + + return client_.callBytesAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a file preview image. Currently, this method supports preview for image + * files (jpg, png, and gif), other supported formats, like pdf, docs, slides, + * and spreadsheets, will return the file icon image. You can also pass query + * string arguments for cutting and resizing your preview image. Preview is + * supported only for image files smaller than 10MB. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID + * @param width Resize preview image width, Pass an integer between 0 to 4000. + * @param height Resize preview image height, Pass an integer between 0 to 4000. + * @param gravity Image crop gravity. Can be one of center,top-left,top,top-right,left,right,bottom-left,bottom,bottom-right + * @param quality Preview image quality. Pass an integer between 0 to 100. Defaults to keep existing image quality. + * @param borderWidth Preview image border in pixels. Pass an integer between 0 to 100. Defaults to 0. + * @param borderColor Preview image border color. Use a valid HEX color, no # is needed for prefix. + * @param borderRadius Preview image border radius in pixels. Pass an integer between 0 to 4000. + * @param opacity Preview image opacity. Only works with images having an alpha channel (like png). Pass a number between 0 to 1. + * @param rotation Preview image rotation in degrees. Pass an integer between -360 and 360. + * @param background Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix. + * @param output Output format type (jpeg, jpg, png, gif and webp). + * @param token File token for accessing this file. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getFilePreview( std::string_view bucketId, std::string_view fileId, std::optional width = 0, std::optional height = 0, std::optional gravity = appwrite::enums::ImageGravity::CENTER, std::optional quality = -1, std::optional borderWidth = 0, std::optional borderColor = std::nullopt, std::optional borderRadius = 0, std::optional opacity = 1, std::optional rotation = 0, std::optional background = std::nullopt, std::optional output = std::nullopt, std::optional token = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}/preview", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (width.has_value()) { + params["width"] = *width; + } + if (height.has_value()) { + params["height"] = *height; + } + if (gravity.has_value()) { + params["gravity"] = *gravity; + } + if (quality.has_value()) { + params["quality"] = *quality; + } + if (borderWidth.has_value()) { + params["borderWidth"] = *borderWidth; + } + if (borderColor.has_value()) { + params["borderColor"] = std::string(borderColor.value()); + } + if (borderRadius.has_value()) { + params["borderRadius"] = *borderRadius; + } + if (opacity.has_value()) { + params["opacity"] = *opacity; + } + if (rotation.has_value()) { + params["rotation"] = *rotation; + } + if (background.has_value()) { + params["background"] = std::string(background.value()); + } + if (output.has_value()) { + params["output"] = *output; + } + if (token.has_value()) { + params["token"] = std::string(token.value()); + } + + std::unordered_map local_headers_; + + return client_.callBytes("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a file preview image. Currently, this method supports preview for image + * files (jpg, png, and gif), other supported formats, like pdf, docs, slides, + * and spreadsheets, will return the file icon image. You can also pass query + * string arguments for cutting and resizing your preview image. Preview is + * supported only for image files smaller than 10MB. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID + * @param width Resize preview image width, Pass an integer between 0 to 4000. + * @param height Resize preview image height, Pass an integer between 0 to 4000. + * @param gravity Image crop gravity. Can be one of center,top-left,top,top-right,left,right,bottom-left,bottom,bottom-right + * @param quality Preview image quality. Pass an integer between 0 to 100. Defaults to keep existing image quality. + * @param borderWidth Preview image border in pixels. Pass an integer between 0 to 100. Defaults to 0. + * @param borderColor Preview image border color. Use a valid HEX color, no # is needed for prefix. + * @param borderRadius Preview image border radius in pixels. Pass an integer between 0 to 4000. + * @param opacity Preview image opacity. Only works with images having an alpha channel (like png). Pass a number between 0 to 1. + * @param rotation Preview image rotation in degrees. Pass an integer between -360 and 360. + * @param background Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix. + * @param output Output format type (jpeg, jpg, png, gif and webp). + * @param token File token for accessing this file. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getFilePreviewAsync( std::string_view bucketId, std::string_view fileId, std::optional width = 0, std::optional height = 0, std::optional gravity = appwrite::enums::ImageGravity::CENTER, std::optional quality = -1, std::optional borderWidth = 0, std::optional borderColor = std::nullopt, std::optional borderRadius = 0, std::optional opacity = 1, std::optional rotation = 0, std::optional background = std::nullopt, std::optional output = std::nullopt, std::optional token = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}/preview", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (width.has_value()) { + params["width"] = *width; + } + if (height.has_value()) { + params["height"] = *height; + } + if (gravity.has_value()) { + params["gravity"] = *gravity; + } + if (quality.has_value()) { + params["quality"] = *quality; + } + if (borderWidth.has_value()) { + params["borderWidth"] = *borderWidth; + } + if (borderColor.has_value()) { + params["borderColor"] = std::string(borderColor.value()); + } + if (borderRadius.has_value()) { + params["borderRadius"] = *borderRadius; + } + if (opacity.has_value()) { + params["opacity"] = *opacity; + } + if (rotation.has_value()) { + params["rotation"] = *rotation; + } + if (background.has_value()) { + params["background"] = std::string(background.value()); + } + if (output.has_value()) { + params["output"] = *output; + } + if (token.has_value()) { + params["token"] = std::string(token.value()); + } + + std::unordered_map local_headers_; + + return client_.callBytesAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a file content by its unique ID. This endpoint is similar to the + * download method but returns with no 'Content-Disposition: attachment' + * header. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @param token File token for accessing this file. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getFileView( std::string_view bucketId, std::string_view fileId, std::optional token = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}/view", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (token.has_value()) { + params["token"] = std::string(token.value()); + } + + std::unordered_map local_headers_; + + return client_.callBytes("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a file content by its unique ID. This endpoint is similar to the + * download method but returns with no 'Content-Disposition: attachment' + * header. + * + * @param bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket). + * @param fileId File ID. + * @param token File token for accessing this file. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getFileViewAsync( std::string_view bucketId, std::string_view fileId, std::optional token = std::nullopt ) { + std::string path_ = std::format("/storage/buckets/{}/files/{}/view", bucketId, fileId); + + nlohmann::json params = nlohmann::json::object(); + if (token.has_value()) { + params["token"] = std::string(token.value()); + } + + std::unordered_map local_headers_; + + return client_.callBytesAsync("GET", path_, std::move(local_headers_), std::move(params)); + } +}; + +/** + * @brief + */ +class TablesDB : public Service { +public: + explicit TablesDB(Client& client) : Service(client) {} + + /** + * Get a list of all databases from the current Appwrite project. You can use + * the search parameter to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result list( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/tablesdb"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all databases from the current Appwrite project. You can use + * the search parameter to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listAsync( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/tablesdb"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new Database. + * + * @param databaseId Unique 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 name Database name. Max length: 128 chars. + * @param enabled Is the database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result create( std::string_view databaseId, std::string_view name, std::optional enabled = true ) { + std::string path_ = std::format("/tablesdb"); + + nlohmann::json params = nlohmann::json::object(); + params["databaseId"] = std::string(databaseId); + params["name"] = std::string(name); + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new Database. + * + * @param databaseId Unique 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 name Database name. Max length: 128 chars. + * @param enabled Is the database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAsync( std::string_view databaseId, std::string_view name, std::optional enabled = true ) { + std::string path_ = std::format("/tablesdb"); + + nlohmann::json params = nlohmann::json::object(); + params["databaseId"] = std::string(databaseId); + params["name"] = std::string(name); + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * List transactions across all databases. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listTransactions( std::optional> queries = std::vector{} ) { + std::string path_ = std::format("/tablesdb/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List transactions across all databases. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listTransactionsAsync( std::optional> queries = std::vector{} ) { + std::string path_ = std::format("/tablesdb/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new transaction. + * + * @param ttl Seconds before the transaction expires. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createTransaction( std::optional ttl = 300 ) { + std::string path_ = std::format("/tablesdb/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new transaction. + * + * @param ttl Seconds before the transaction expires. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTransactionAsync( std::optional ttl = 300 ) { + std::string path_ = std::format("/tablesdb/transactions"); + + nlohmann::json params = nlohmann::json::object(); + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getTransaction( std::string_view transactionId ) { + std::string path_ = std::format("/tablesdb/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getTransactionAsync( std::string_view transactionId ) { + std::string path_ = std::format("/tablesdb/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a transaction, to either commit or roll back its operations. + * + * @param transactionId Transaction ID. + * @param commit Commit transaction? + * @param rollback Rollback transaction? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateTransaction( std::string_view transactionId, std::optional commit = false, std::optional rollback = false ) { + std::string path_ = std::format("/tablesdb/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (commit.has_value()) { + params["commit"] = *commit; + } + if (rollback.has_value()) { + params["rollback"] = *rollback; + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a transaction, to either commit or roll back its operations. + * + * @param transactionId Transaction ID. + * @param commit Commit transaction? + * @param rollback Rollback transaction? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateTransactionAsync( std::string_view transactionId, std::optional commit = false, std::optional rollback = false ) { + std::string path_ = std::format("/tablesdb/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (commit.has_value()) { + params["commit"] = *commit; + } + if (rollback.has_value()) { + params["rollback"] = *rollback; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteTransaction( std::string_view transactionId ) { + std::string path_ = std::format("/tablesdb/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a transaction by its unique ID. + * + * @param transactionId Transaction ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteTransactionAsync( std::string_view transactionId ) { + std::string path_ = std::format("/tablesdb/transactions/{}", transactionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create multiple operations in a single transaction. + * + * @param transactionId Transaction ID. + * @param operations Array of staged operations. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createOperations( std::string_view transactionId, std::optional> operations = std::vector{} ) { + std::string path_ = std::format("/tablesdb/transactions/{}/operations", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (operations.has_value()) { + params["operations"] = *operations; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create multiple operations in a single transaction. + * + * @param transactionId Transaction ID. + * @param operations Array of staged operations. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createOperationsAsync( std::string_view transactionId, std::optional> operations = std::vector{} ) { + std::string path_ = std::format("/tablesdb/transactions/{}/operations", transactionId); + + nlohmann::json params = nlohmann::json::object(); + if (operations.has_value()) { + params["operations"] = *operations; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a database by its unique ID. This endpoint response returns a JSON + * object with the database metadata. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result get( std::string_view databaseId ) { + std::string path_ = std::format("/tablesdb/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a database by its unique ID. This endpoint response returns a JSON + * object with the database metadata. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAsync( std::string_view databaseId ) { + std::string path_ = std::format("/tablesdb/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a database by its unique ID. + * + * @param databaseId Database ID. + * @param name Database name. Max length: 128 chars. + * @param enabled Is database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result update( std::string_view databaseId, std::optional name = std::nullopt, std::optional enabled = true ) { + std::string path_ = std::format("/tablesdb/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a database by its unique ID. + * + * @param databaseId Database ID. + * @param name Database name. Max length: 128 chars. + * @param enabled Is database enabled? When set to 'disabled', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateAsync( std::string_view databaseId, std::optional name = std::nullopt, std::optional enabled = true ) { + std::string path_ = std::format("/tablesdb/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a database by its unique ID. Only API keys with with databases.write + * scope can delete a database. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result delete_( std::string_view databaseId ) { + std::string path_ = std::format("/tablesdb/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a database by its unique ID. Only API keys with with databases.write + * scope can delete a database. + * + * @param databaseId Database ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> delete_Async( std::string_view databaseId ) { + std::string path_ = std::format("/tablesdb/{}", databaseId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all tables that belong to the provided databaseId. You can + * use the search parameter to filter your results. + * + * @param databaseId Database ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name, enabled, rowSecurity + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listTables( std::string_view databaseId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/tablesdb/{}/tables", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all tables that belong to the provided databaseId. You can + * use the search parameter to filter your results. + * + * @param databaseId Database ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name, enabled, rowSecurity + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listTablesAsync( std::string_view databaseId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/tablesdb/{}/tables", databaseId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new Table. Before using this route, you should create a new + * database resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Unique 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 name Table name. Max length: 128 chars. + * @param permissions An array of permissions strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param rowSecurity Enables configuring permissions for individual rows. A user needs one of row or table level permissions to access a row. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is table enabled? When set to 'disabled', users cannot access the table but Server SDKs with and API key can still read and write to the table. No data is lost when this is toggled. + * @param columns Array of column definitions to create. Each column should contain: key (string), type (string: string, integer, float, boolean, datetime, relationship), size (integer, required for string type), required (boolean, optional), default (mixed, optional), array (boolean, optional), and type-specific options. + * @param indexes Array of index definitions to create. Each index should contain: key (string), type (string: key, fulltext, unique, spatial), attributes (array of column keys), orders (array of ASC/DESC, optional), and lengths (array of integers, optional). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createTable( std::string_view databaseId, std::string_view tableId, std::string_view name, std::optional> permissions = std::nullopt, std::optional rowSecurity = false, std::optional enabled = true, std::optional> columns = std::vector{}, std::optional> indexes = std::vector{} ) { + std::string path_ = std::format("/tablesdb/{}/tables", databaseId); + + nlohmann::json params = nlohmann::json::object(); + params["tableId"] = std::string(tableId); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (rowSecurity.has_value()) { + params["rowSecurity"] = *rowSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (columns.has_value()) { + params["columns"] = *columns; + } + if (indexes.has_value()) { + params["indexes"] = *indexes; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new Table. Before using this route, you should create a new + * database resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Unique 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 name Table name. Max length: 128 chars. + * @param permissions An array of permissions strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param rowSecurity Enables configuring permissions for individual rows. A user needs one of row or table level permissions to access a row. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is table enabled? When set to 'disabled', users cannot access the table but Server SDKs with and API key can still read and write to the table. No data is lost when this is toggled. + * @param columns Array of column definitions to create. Each column should contain: key (string), type (string: string, integer, float, boolean, datetime, relationship), size (integer, required for string type), required (boolean, optional), default (mixed, optional), array (boolean, optional), and type-specific options. + * @param indexes Array of index definitions to create. Each index should contain: key (string), type (string: key, fulltext, unique, spatial), attributes (array of column keys), orders (array of ASC/DESC, optional), and lengths (array of integers, optional). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTableAsync( std::string_view databaseId, std::string_view tableId, std::string_view name, std::optional> permissions = std::nullopt, std::optional rowSecurity = false, std::optional enabled = true, std::optional> columns = std::vector{}, std::optional> indexes = std::vector{} ) { + std::string path_ = std::format("/tablesdb/{}/tables", databaseId); + + nlohmann::json params = nlohmann::json::object(); + params["tableId"] = std::string(tableId); + params["name"] = std::string(name); + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (rowSecurity.has_value()) { + params["rowSecurity"] = *rowSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (columns.has_value()) { + params["columns"] = *columns; + } + if (indexes.has_value()) { + params["indexes"] = *indexes; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a table by its unique ID. This endpoint response returns a JSON object + * with the table metadata. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getTable( std::string_view databaseId, std::string_view tableId ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a table by its unique ID. This endpoint response returns a JSON object + * with the table metadata. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getTableAsync( std::string_view databaseId, std::string_view tableId ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a table by its unique ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param name Table name. Max length: 128 chars. + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param rowSecurity Enables configuring permissions for individual rows. A user needs one of row or table-level permissions to access a row. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is table enabled? When set to 'disabled', users cannot access the table but Server SDKs with and API key can still read and write to the table. No data is lost when this is toggled. + * @param purge When true, purge all cached list responses for this table as part of the update. Use this to force readers to see fresh data immediately instead of waiting for the cache TTL to expire. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateTable( std::string_view databaseId, std::string_view tableId, std::optional name = std::nullopt, std::optional> permissions = std::nullopt, std::optional rowSecurity = false, std::optional enabled = true, std::optional purge = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (rowSecurity.has_value()) { + params["rowSecurity"] = *rowSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (purge.has_value()) { + params["purge"] = *purge; + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a table by its unique ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param name Table name. Max length: 128 chars. + * @param permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param rowSecurity Enables configuring permissions for individual rows. A user needs one of row or table-level permissions to access a row. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param enabled Is table enabled? When set to 'disabled', users cannot access the table but Server SDKs with and API key can still read and write to the table. No data is lost when this is toggled. + * @param purge When true, purge all cached list responses for this table as part of the update. Use this to force readers to see fresh data immediately instead of waiting for the cache TTL to expire. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateTableAsync( std::string_view databaseId, std::string_view tableId, std::optional name = std::nullopt, std::optional> permissions = std::nullopt, std::optional rowSecurity = false, std::optional enabled = true, std::optional purge = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (rowSecurity.has_value()) { + params["rowSecurity"] = *rowSecurity; + } + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (purge.has_value()) { + params["purge"] = *purge; + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a table by its unique ID. Only users with write permissions have + * access to delete this resource. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteTable( std::string_view databaseId, std::string_view tableId ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a table by its unique ID. Only users with write permissions have + * access to delete this resource. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteTableAsync( std::string_view databaseId, std::string_view tableId ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * List columns in the table. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, size, required, array, status, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listColumns( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List columns in the table. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, size, required, array, status, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listColumnsAsync( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a boolean column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createBooleanColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/boolean", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a boolean column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createBooleanColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/boolean", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a boolean column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateBooleanColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, bool default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/boolean/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a boolean column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateBooleanColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, bool default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/boolean/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a date time column according to the ISO 8601 standard. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for the column in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createDatetimeColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/datetime", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a date time column according to the ISO 8601 standard. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for the column in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createDatetimeColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/datetime", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a date time column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateDatetimeColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/datetime/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a date time column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateDatetimeColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/datetime/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create an email column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createEmailColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/email", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create an email column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createEmailColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/email", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an email column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEmailColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/email/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an email column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEmailColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/email/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create an enumeration column. The `elements` param acts as a white-list of + * accepted values for this column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param elements Array of enum values. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createEnumColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, std::vector elements, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/enum", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["elements"] = elements; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create an enumeration column. The `elements` param acts as a white-list of + * accepted values for this column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param elements Array of enum values. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createEnumColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, std::vector elements, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/enum", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["elements"] = elements; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an enum column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param elements Updated list of enum values. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEnumColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, std::vector elements, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/enum/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["elements"] = elements; + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an enum column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param elements Updated list of enum values. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEnumColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, std::vector elements, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/enum/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["elements"] = elements; + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a float column. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param min Minimum value + * @param max Maximum value + * @param default_ Default value. Cannot be set when required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createFloatColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/float", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a float column. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param min Minimum value + * @param max Maximum value + * @param default_ Default value. Cannot be set when required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createFloatColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/float", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a float column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when required. + * @param min Minimum value + * @param max Maximum value + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateFloatColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, double default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/float/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a float column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when required. + * @param min Minimum value + * @param max Maximum value + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateFloatColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, double default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/float/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create an integer column. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param min Minimum value + * @param max Maximum value + * @param default_ Default value. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createIntegerColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/integer", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create an integer column. Optionally, minimum and maximum values can be + * provided. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param min Minimum value + * @param max Maximum value + * @param default_ Default value. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createIntegerColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/integer", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + if (default_.has_value()) { + params["default"] = *default_; + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an integer column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when column is required. + * @param min Minimum value + * @param max Maximum value + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateIntegerColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, int64_t default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/integer/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an integer column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when column is required. + * @param min Minimum value + * @param max Maximum value + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateIntegerColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, int64_t default_, std::optional min = std::nullopt, std::optional max = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/integer/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (min.has_value()) { + params["min"] = *min; + } + if (max.has_value()) { + params["max"] = *max; + } + params["default"] = default_; + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create IP address column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createIpColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/ip", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create IP address column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createIpColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/ip", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an ip column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateIpColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/ip/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an ip column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateIpColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/ip/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a geometric line column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when column is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createLineColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/line", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a geometric line column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when column is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createLineColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/line", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a line column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateLineColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/line/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a line column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, two-dimensional array of coordinate pairs, [[longitude, latitude], [longitude, latitude], …], listing the vertices of the line in order. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateLineColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/line/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a longtext column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createLongtextColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/longtext", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a longtext column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createLongtextColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/longtext", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a longtext column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateLongtextColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/longtext/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a longtext column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateLongtextColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/longtext/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a mediumtext column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMediumtextColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/mediumtext", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a mediumtext column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMediumtextColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/mediumtext", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a mediumtext column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMediumtextColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/mediumtext/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a mediumtext column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMediumtextColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/mediumtext/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a geometric point column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when column is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createPointColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/point", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a geometric point column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when column is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createPointColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/point", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a point column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePointColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/point/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a point column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePointColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/point/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a geometric polygon column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when column is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createPolygonColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/polygon", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a geometric polygon column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when column is required. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createPolygonColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/polygon", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a polygon column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePolygonColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/polygon/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a polygon column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided, three-dimensional array where the outer array holds one or more linear rings, [[[longitude, latitude], …], …], the first ring is the exterior boundary, any additional rings are interior holes, and each ring must start and end with the same coordinate pair. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePolygonColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional> default_ = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/polygon/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + if (default_.has_value()) { + params["default"] = *default_; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create relationship column. [Learn more about relationship + * columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param relatedTableId Related Table ID. + * @param type Relation type + * @param twoWay Is Two Way? + * @param key Column Key. + * @param twoWayKey Two Way Column Key. + * @param onDelete Constraints option + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createRelationshipColumn( std::string_view databaseId, std::string_view tableId, std::string_view relatedTableId, appwrite::enums::RelationshipType type, std::optional twoWay = false, std::optional key = std::nullopt, std::optional twoWayKey = std::nullopt, std::optional onDelete = appwrite::enums::RelationMutate::RESTRICT ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/relationship", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["relatedTableId"] = std::string(relatedTableId); + params["type"] = type; + if (twoWay.has_value()) { + params["twoWay"] = *twoWay; + } + if (key.has_value()) { + params["key"] = std::string(key.value()); + } + if (twoWayKey.has_value()) { + params["twoWayKey"] = std::string(twoWayKey.value()); + } + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create relationship column. [Learn more about relationship + * columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param relatedTableId Related Table ID. + * @param type Relation type + * @param twoWay Is Two Way? + * @param key Column Key. + * @param twoWayKey Two Way Column Key. + * @param onDelete Constraints option + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createRelationshipColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view relatedTableId, appwrite::enums::RelationshipType type, std::optional twoWay = false, std::optional key = std::nullopt, std::optional twoWayKey = std::nullopt, std::optional onDelete = appwrite::enums::RelationMutate::RESTRICT ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/relationship", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["relatedTableId"] = std::string(relatedTableId); + params["type"] = type; + if (twoWay.has_value()) { + params["twoWay"] = *twoWay; + } + if (key.has_value()) { + params["key"] = std::string(key.value()); + } + if (twoWayKey.has_value()) { + params["twoWayKey"] = std::string(twoWayKey.value()); + } + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a string column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param size Column size for text columns, in number of characters. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createStringColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/string", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a string column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param size Column size for text columns, in number of characters. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createStringColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/string", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a string column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param size Maximum size of the string column. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateStringColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/string/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a string column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param size Maximum size of the string column. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateStringColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/string/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a text column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createTextColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/text", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a text column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTextColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/text", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a text column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateTextColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/text/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a text column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateTextColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/text/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a URL column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createUrlColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/url", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a URL column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createUrlColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::optional default_ = std::nullopt, std::optional array = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/url", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update an url column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateUrlColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/url/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update an url column. Changing the `default` value will not update already + * existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateUrlColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/url/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a varchar column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param size Column size for varchar columns, in number of characters. Maximum size is 16381. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createVarcharColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/varchar", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a varchar column. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param size Column size for varchar columns, in number of characters. Maximum size is 16381. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param array Is column an array? + * @param encrypt Toggle encryption for the column. Encryption enhances security by not storing any plain text values in the database. However, encrypted columns cannot be queried. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createVarcharColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, int64_t size, bool required, std::optional default_ = std::nullopt, std::optional array = false, std::optional encrypt = false ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/varchar", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["size"] = size; + params["required"] = required; + if (default_.has_value()) { + params["default"] = std::string(default_.value()); + } + if (array.has_value()) { + params["array"] = *array; + } + if (encrypt.has_value()) { + params["encrypt"] = *encrypt; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a varchar column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param size Maximum size of the varchar column. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateVarcharColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/varchar/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a varchar column. Changing the `default` value will not update + * already existing rows. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Column Key. + * @param required Is column required? + * @param default_ Default value for column when not provided. Cannot be set when column is required. + * @param size Maximum size of the varchar column. + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateVarcharColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, bool required, std::string_view default_, std::optional size = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/varchar/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + params["required"] = required; + params["default"] = std::string(default_); + if (size.has_value()) { + params["size"] = *size; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get column by ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getColumn( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get column by ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Deletes a column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteColumn( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Deletes a column. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update relationship column. [Learn more about relationship + * columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param onDelete Constraints option + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateRelationshipColumn( std::string_view databaseId, std::string_view tableId, std::string_view key, std::optional onDelete = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/{}/relationship", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update relationship column. [Learn more about relationship + * columns](https://appwrite.io/docs/databases-relationships#relationship-columns). + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param key Column Key. + * @param onDelete Constraints option + * @param newKey New Column Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateRelationshipColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, std::optional onDelete = std::nullopt, std::optional newKey = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/columns/{}/relationship", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + if (onDelete.has_value()) { + params["onDelete"] = *onDelete; + } + if (newKey.has_value()) { + params["newKey"] = std::string(newKey.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * List indexes on the table. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, status, attributes, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listIndexes( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List indexes on the table. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, status, attributes, error + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listIndexesAsync( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Creates an index on the columns listed. Your index should include all the + * columns you will query in a single request. +Type can be `key`, `fulltext`, + * or `unique`. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Index Key. + * @param type Index type. + * @param columns Array of columns to index. Maximum of 100 columns are allowed, each 32 characters long. + * @param orders Array of index orders. Maximum of 100 orders are allowed. + * @param lengths Length of index. Maximum of 100 + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createIndex( std::string_view databaseId, std::string_view tableId, std::string_view key, appwrite::enums::TablesDBIndexType type, std::vector columns, std::optional> orders = {}, std::optional> lengths = std::vector{} ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["type"] = type; + params["columns"] = columns; + if (orders.has_value()) { + params["orders"] = *orders; + } + if (lengths.has_value()) { + params["lengths"] = *lengths; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Creates an index on the columns listed. Your index should include all the + * columns you will query in a single request. +Type can be `key`, `fulltext`, + * or `unique`. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Index Key. + * @param type Index type. + * @param columns Array of columns to index. Maximum of 100 columns are allowed, each 32 characters long. + * @param orders Array of index orders. Maximum of 100 orders are allowed. + * @param lengths Length of index. Maximum of 100 + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createIndexAsync( std::string_view databaseId, std::string_view tableId, std::string_view key, appwrite::enums::TablesDBIndexType type, std::vector columns, std::optional> orders = {}, std::optional> lengths = std::vector{} ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["key"] = std::string(key); + params["type"] = type; + params["columns"] = columns; + if (orders.has_value()) { + params["orders"] = *orders; + } + if (lengths.has_value()) { + params["lengths"] = *lengths; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get index by ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getIndex( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get index by ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getIndexAsync( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an index. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteIndex( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an index. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param key Index Key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteIndexAsync( std::string_view databaseId, std::string_view tableId, std::string_view key ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/indexes/{}", databaseId, tableId, key); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a list of all the user's rows in a given table. You can use the query + * params to filter your results. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/products/databases/tables#create-table). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @param ttl TTL (seconds) for caching list responses. Responses are stored in an in-memory key-value cache, keyed per project, table, schema version (columns and indexes), caller authorization roles, and the exact query — so users with different permissions never share cached entries. Schema changes invalidate cached entries automatically; row writes do not, so choose a TTL you are comfortable serving as stale data. Set to 0 to disable caching. Must be between 0 and 86400 (24 hours). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listRows( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt, std::optional total = true, std::optional ttl = 0 ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the user's rows in a given table. You can use the query + * params to filter your results. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/products/databases/tables#create-table). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @param ttl TTL (seconds) for caching list responses. Responses are stored in an in-memory key-value cache, keyed per project, table, schema version (columns and indexes), caller authorization roles, and the exact query — so users with different permissions never share cached entries. Schema changes invalidate cached entries automatically; row writes do not, so choose a TTL you are comfortable serving as stale data. Set to 0 to disable caching. Must be between 0 and 86400 (24 hours). + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listRowsAsync( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt, std::optional total = true, std::optional ttl = 0 ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + if (ttl.has_value()) { + params["ttl"] = *ttl; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new Row. Before using this route, you should create a new table + * resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). Make sure to define columns before creating rows. + * @param rowId Row 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 data Row data as JSON object. + * @param permissions An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createRow( std::string_view databaseId, std::string_view tableId, std::string_view rowId = "", const nlohmann::json& data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["rowId"] = std::string(rowId); + params["data"] = data; + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new Row. Before using this route, you should create a new table + * resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). Make sure to define columns before creating rows. + * @param rowId Row 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 data Row data as JSON object. + * @param permissions An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createRowAsync( std::string_view databaseId, std::string_view tableId, std::string_view rowId = "", const nlohmann::json& data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["rowId"] = std::string(rowId); + params["data"] = data; + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create new Rows. Before using this route, you should create a new table + * resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). Make sure to define columns before creating rows. + * @param rows Array of rows data as JSON objects. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createRows( std::string_view databaseId, std::string_view tableId, std::vector rows = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["rows"] = rows; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create new Rows. Before using this route, you should create a new table + * resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). Make sure to define columns before creating rows. + * @param rows Array of rows data as JSON objects. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createRowsAsync( std::string_view databaseId, std::string_view tableId, std::vector rows = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["rows"] = rows; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create or update Rows. Before using this route, you should create a new + * table resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rows Array of row data as JSON objects. May contain partial rows. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result upsertRows( std::string_view databaseId, std::string_view tableId, std::vector rows, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["rows"] = rows; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create or update Rows. Before using this route, you should create a new + * table resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rows Array of row data as JSON objects. May contain partial rows. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> upsertRowsAsync( std::string_view databaseId, std::string_view tableId, std::vector rows, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + params["rows"] = rows; + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update all rows that match your queries, if no queries are submitted then + * all rows are updated. You can pass only specific fields to be updated. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param data Row data as JSON object. Include only column and value pairs to be updated. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateRows( std::string_view databaseId, std::string_view tableId, std::optional data = nlohmann::json::object(), std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update all rows that match your queries, if no queries are submitted then + * all rows are updated. You can pass only specific fields to be updated. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param data Row data as JSON object. Include only column and value pairs to be updated. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateRowsAsync( std::string_view databaseId, std::string_view tableId, std::optional data = nlohmann::json::object(), std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Bulk delete rows using queries, if no queries are passed then all rows are + * deleted. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteRows( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Bulk delete rows using queries, if no queries are passed then all rows are + * deleted. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteRowsAsync( std::string_view databaseId, std::string_view tableId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows", databaseId, tableId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a row by its unique ID. This endpoint response returns a JSON object + * with the row data. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param rowId Row ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getRow( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a row by its unique ID. This endpoint response returns a JSON object + * with the row data. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param rowId Row ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. + * @param transactionId Transaction ID to read uncommitted changes within the transaction. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getRowAsync( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional> queries = std::vector{}, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create or update a Row. Before using this route, you should create a new + * table resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param data Row data as JSON object. Include all required columns of the row to be created or updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result upsertRow( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create or update a Row. Before using this route, you should create a new + * table resource using either a [server + * integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable) + * API or directly from your database console. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param data Row data as JSON object. Include all required columns of the row to be created or updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> upsertRowAsync( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a row by its unique ID. Using the patch method you can pass only + * specific fields that will get updated. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param data Row data as JSON object. Include only columns and value pairs to be updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateRow( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a row by its unique ID. Using the patch method you can pass only + * specific fields that will get updated. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param data Row data as JSON object. Include only columns and value pairs to be updated. + * @param permissions An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions). + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateRowAsync( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional data = nlohmann::json::object(), std::optional> permissions = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (data.has_value()) { + params["data"] = *data; + } + if (permissions.has_value()) { + params["permissions"] = *permissions; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a row by its unique ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param rowId Row ID. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteRow( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a row by its unique ID. + * + * @param databaseId Database ID. + * @param tableId Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable). + * @param rowId Row ID. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteRowAsync( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}", databaseId, tableId, rowId); + + nlohmann::json params = nlohmann::json::object(); + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Decrement a specific column of a row by a given value. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param column Column key. + * @param value Value to increment the column by. The value must be a number. + * @param min Minimum value for the column. If the current value is lesser than this value, an exception will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result decrementRowColumn( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::string_view column, std::optional value = 1, std::optional min = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}/{}/decrement", databaseId, tableId, rowId, column); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (min.has_value()) { + params["min"] = *min; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Decrement a specific column of a row by a given value. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param column Column key. + * @param value Value to increment the column by. The value must be a number. + * @param min Minimum value for the column. If the current value is lesser than this value, an exception will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> decrementRowColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::string_view column, std::optional value = 1, std::optional min = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}/{}/decrement", databaseId, tableId, rowId, column); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (min.has_value()) { + params["min"] = *min; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Increment a specific column of a row by a given value. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param column Column key. + * @param value Value to increment the column by. The value must be a number. + * @param max Maximum value for the column. If the current value is greater than this value, an error will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result incrementRowColumn( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::string_view column, std::optional value = 1, std::optional max = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}/{}/increment", databaseId, tableId, rowId, column); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (max.has_value()) { + params["max"] = *max; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Increment a specific column of a row by a given value. + * + * @param databaseId Database ID. + * @param tableId Table ID. + * @param rowId Row ID. + * @param column Column key. + * @param value Value to increment the column by. The value must be a number. + * @param max Maximum value for the column. If the current value is greater than this value, an error will be thrown. + * @param transactionId Transaction ID for staging the operation. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> incrementRowColumnAsync( std::string_view databaseId, std::string_view tableId, std::string_view rowId, std::string_view column, std::optional value = 1, std::optional max = std::nullopt, std::optional transactionId = std::nullopt ) { + std::string path_ = std::format("/tablesdb/{}/tables/{}/rows/{}/{}/increment", databaseId, tableId, rowId, column); + + nlohmann::json params = nlohmann::json::object(); + if (value.has_value()) { + params["value"] = *value; + } + if (max.has_value()) { + params["max"] = *max; + } + if (transactionId.has_value()) { + params["transactionId"] = std::string(transactionId.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } +}; + +/** + * @brief The Teams service allows you to group users of your project and to enable them to share read and write access to your project resources + */ +class Teams : public Service { +public: + explicit Teams(Client& client) : Service(client) {} + + /** + * Get a list of all the teams in which the current user is a member. You can + * use the parameters to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, total, billingPlan + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result list( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/teams"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the teams in which the current user is a member. You can + * use the parameters to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, total, billingPlan + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listAsync( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/teams"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new team. The user who creates the team will automatically be + * assigned as the owner of the team. Only the users with the owner role can + * invite new members, add new owners and delete or update the team. + * + * @param teamId Team 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 name Team name. Max length: 128 chars. + * @param roles Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 32 characters long. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result create( std::string_view teamId, std::string_view name, std::optional> roles = std::vector{"owner"} ) { + std::string path_ = std::format("/teams"); + + nlohmann::json params = nlohmann::json::object(); + params["teamId"] = std::string(teamId); + params["name"] = std::string(name); + if (roles.has_value()) { + params["roles"] = *roles; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new team. The user who creates the team will automatically be + * assigned as the owner of the team. Only the users with the owner role can + * invite new members, add new owners and delete or update the team. + * + * @param teamId Team 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 name Team name. Max length: 128 chars. + * @param roles Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 32 characters long. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAsync( std::string_view teamId, std::string_view name, std::optional> roles = std::vector{"owner"} ) { + std::string path_ = std::format("/teams"); + + nlohmann::json params = nlohmann::json::object(); + params["teamId"] = std::string(teamId); + params["name"] = std::string(name); + if (roles.has_value()) { + params["roles"] = *roles; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a team by its ID. All team members have read access for this resource. + * + * @param teamId Team ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result get( std::string_view teamId ) { + std::string path_ = std::format("/teams/{}", teamId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a team by its ID. All team members have read access for this resource. + * + * @param teamId Team ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAsync( std::string_view teamId ) { + std::string path_ = std::format("/teams/{}", teamId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the team's name by its unique ID. + * + * @param teamId Team ID. + * @param name New team name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateName( std::string_view teamId, std::string_view name ) { + std::string path_ = std::format("/teams/{}", teamId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the team's name by its unique ID. + * + * @param teamId Team ID. + * @param name New team name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateNameAsync( std::string_view teamId, std::string_view name ) { + std::string path_ = std::format("/teams/{}", teamId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a team using its ID. Only team members with the owner role can + * delete the team. + * + * @param teamId Team ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result delete_( std::string_view teamId ) { + std::string path_ = std::format("/teams/{}", teamId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a team using its ID. Only team members with the owner role can + * delete the team. + * + * @param teamId Team ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> delete_Async( std::string_view teamId ) { + std::string path_ = std::format("/teams/{}", teamId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to list a team's members using the team's ID. All team + * members have read access to this endpoint. Hide sensitive attributes from + * the response by toggling membership privacy in the Console. + * + * @param teamId Team ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listMemberships( std::string_view teamId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/teams/{}/memberships", teamId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to list a team's members using the team's ID. All team + * members have read access to this endpoint. Hide sensitive attributes from + * the response by toggling membership privacy in the Console. + * + * @param teamId Team ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listMembershipsAsync( std::string_view teamId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/teams/{}/memberships", teamId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Invite a new member to join your team. Provide an ID for existing users, or + * invite unregistered users using an email or phone number. If initiated from + * a Client SDK, Appwrite will send an email or sms with a link to join the + * team to the invited user, and an account will be created for them if one + * doesn't exist. If initiated from a Server SDK, the new member will be added + * automatically to the team. + +You only need to provide one of a user ID, + * email, or phone number. Appwrite will prioritize accepting the user ID > + * email > phone number if you provide more than one of these parameters. + +Use + * the `url` parameter to redirect the user from the invitation email to your + * app. After the user is redirected, use the [Update Team Membership + * Status](https://appwrite.io/docs/references/cloud/client-web/teams#updateMembershipStatus) + * endpoint to allow the user to accept the invitation to the team. + +Please + * note that to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) + * Appwrite will accept the only redirect URLs under the domains you have + * added as a platform on the Appwrite Console. + * + * @param teamId Team ID. + * @param roles Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. + * @param email Email of the new team member. + * @param userId ID of the user to be added to a team. + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @param url URL to redirect the user back to your app from the invitation email. This parameter is not required when an API key is supplied. Only URLs from hostnames in your project 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 name Name of the new team member. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMembership( std::string_view teamId, std::vector roles, std::optional email = std::nullopt, std::optional userId = std::nullopt, std::optional phone = std::nullopt, std::optional url = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/teams/{}/memberships", teamId); + + nlohmann::json params = nlohmann::json::object(); + if (email.has_value()) { + params["email"] = std::string(email.value()); + } + if (userId.has_value()) { + params["userId"] = std::string(userId.value()); + } + if (phone.has_value()) { + params["phone"] = std::string(phone.value()); + } + params["roles"] = roles; + if (url.has_value()) { + params["url"] = std::string(url.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Invite a new member to join your team. Provide an ID for existing users, or + * invite unregistered users using an email or phone number. If initiated from + * a Client SDK, Appwrite will send an email or sms with a link to join the + * team to the invited user, and an account will be created for them if one + * doesn't exist. If initiated from a Server SDK, the new member will be added + * automatically to the team. + +You only need to provide one of a user ID, + * email, or phone number. Appwrite will prioritize accepting the user ID > + * email > phone number if you provide more than one of these parameters. + +Use + * the `url` parameter to redirect the user from the invitation email to your + * app. After the user is redirected, use the [Update Team Membership + * Status](https://appwrite.io/docs/references/cloud/client-web/teams#updateMembershipStatus) + * endpoint to allow the user to accept the invitation to the team. + +Please + * note that to avoid a [Redirect + * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) + * Appwrite will accept the only redirect URLs under the domains you have + * added as a platform on the Appwrite Console. + * + * @param teamId Team ID. + * @param roles Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. + * @param email Email of the new team member. + * @param userId ID of the user to be added to a team. + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @param url URL to redirect the user back to your app from the invitation email. This parameter is not required when an API key is supplied. Only URLs from hostnames in your project 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 name Name of the new team member. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMembershipAsync( std::string_view teamId, std::vector roles, std::optional email = std::nullopt, std::optional userId = std::nullopt, std::optional phone = std::nullopt, std::optional url = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/teams/{}/memberships", teamId); + + nlohmann::json params = nlohmann::json::object(); + if (email.has_value()) { + params["email"] = std::string(email.value()); + } + if (userId.has_value()) { + params["userId"] = std::string(userId.value()); + } + if (phone.has_value()) { + params["phone"] = std::string(phone.value()); + } + params["roles"] = roles; + if (url.has_value()) { + params["url"] = std::string(url.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a team member by the membership unique id. All team members have read + * access for this resource. Hide sensitive attributes from the response by + * toggling membership privacy in the Console. + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getMembership( std::string_view teamId, std::string_view membershipId ) { + std::string path_ = std::format("/teams/{}/memberships/{}", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a team member by the membership unique id. All team members have read + * access for this resource. Hide sensitive attributes from the response by + * toggling membership privacy in the Console. + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getMembershipAsync( std::string_view teamId, std::string_view membershipId ) { + std::string path_ = std::format("/teams/{}/memberships/{}", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Modify the roles of a team member. Only team members with the owner role + * have access to this endpoint. Learn more about [roles and + * permissions](https://appwrite.io/docs/permissions). + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @param roles An array of strings. Use this param to set the user's roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMembership( std::string_view teamId, std::string_view membershipId, std::vector roles ) { + std::string path_ = std::format("/teams/{}/memberships/{}", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + params["roles"] = roles; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Modify the roles of a team member. Only team members with the owner role + * have access to this endpoint. Learn more about [roles and + * permissions](https://appwrite.io/docs/permissions). + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @param roles An array of strings. Use this param to set the user's roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 81 characters long. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMembershipAsync( std::string_view teamId, std::string_view membershipId, std::vector roles ) { + std::string path_ = std::format("/teams/{}/memberships/{}", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + params["roles"] = roles; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * This endpoint allows a user to leave a team or for a team owner to delete + * the membership of any other team member. You can also use this endpoint to + * delete a user membership even if it is not accepted. + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteMembership( std::string_view teamId, std::string_view membershipId ) { + std::string path_ = std::format("/teams/{}/memberships/{}", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * This endpoint allows a user to leave a team or for a team owner to delete + * the membership of any other team member. You can also use this endpoint to + * delete a user membership even if it is not accepted. + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteMembershipAsync( std::string_view teamId, std::string_view membershipId ) { + std::string path_ = std::format("/teams/{}/memberships/{}", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to allow a user to accept an invitation to join a team + * after being redirected back to your app from the invitation email received + * by the user. + +If the request is successful, a session for the user is + * automatically created. + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @param userId User ID. + * @param secret Secret key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMembershipStatus( std::string_view teamId, std::string_view membershipId, std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/teams/{}/memberships/{}/status", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to allow a user to accept an invitation to join a team + * after being redirected back to your app from the invitation email received + * by the user. + +If the request is successful, a session for the user is + * automatically created. + * + * @param teamId Team ID. + * @param membershipId Membership ID. + * @param userId User ID. + * @param secret Secret key. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMembershipStatusAsync( std::string_view teamId, std::string_view membershipId, std::string_view userId, std::string_view secret ) { + std::string path_ = std::format("/teams/{}/memberships/{}/status", teamId, membershipId); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["secret"] = std::string(secret); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the team's shared preferences by its unique ID. If a preference doesn't + * need to be shared by all team members, prefer storing them in [user + * preferences](https://appwrite.io/docs/references/cloud/client-web/account#getPrefs). + * + * @param teamId Team ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getPrefs( std::string_view teamId ) { + std::string path_ = std::format("/teams/{}/prefs", teamId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the team's shared preferences by its unique ID. If a preference doesn't + * need to be shared by all team members, prefer storing them in [user + * preferences](https://appwrite.io/docs/references/cloud/client-web/account#getPrefs). + * + * @param teamId Team ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getPrefsAsync( std::string_view teamId ) { + std::string path_ = std::format("/teams/{}/prefs", teamId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the team's preferences by its unique ID. The object you pass is + * stored as is and replaces any previous value. The maximum allowed prefs + * size is 64kB and throws an error if exceeded. + * + * @param teamId Team ID. + * @param prefs Prefs key-value JSON object. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePrefs( std::string_view teamId, const nlohmann::json& prefs = nlohmann::json::object() ) { + std::string path_ = std::format("/teams/{}/prefs", teamId); + + nlohmann::json params = nlohmann::json::object(); + params["prefs"] = prefs; + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the team's preferences by its unique ID. The object you pass is + * stored as is and replaces any previous value. The maximum allowed prefs + * size is 64kB and throws an error if exceeded. + * + * @param teamId Team ID. + * @param prefs Prefs key-value JSON object. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePrefsAsync( std::string_view teamId, const nlohmann::json& prefs = nlohmann::json::object() ) { + std::string path_ = std::format("/teams/{}/prefs", teamId); + + nlohmann::json params = nlohmann::json::object(); + params["prefs"] = prefs; + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } +}; + +/** + * @brief The Users service allows you to manage your project users. + */ +class Users : public Service { +public: + explicit Users(Client& client) : Service(client) {} + + /** + * Get a list of all the project's users. You can use the query params to + * filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels, impersonator + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result list( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/users"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all the project's users. You can use the query params to + * filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels, impersonator + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listAsync( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/users"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. + * + * @param userId User 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 email User email. + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @param password Plain text user password. Must be at least 8 chars. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result create( std::string_view userId, std::optional email = std::nullopt, std::optional phone = std::nullopt, std::optional password = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + if (email.has_value()) { + params["email"] = std::string(email.value()); + } + if (phone.has_value()) { + params["phone"] = std::string(phone.value()); + } + if (password.has_value()) { + params["password"] = std::string(password.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. + * + * @param userId User 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 email User email. + * @param phone Phone number. Format this number with a leading '+' and a country code, e.g., +16175551212. + * @param password Plain text user password. Must be at least 8 chars. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAsync( std::string_view userId, std::optional email = std::nullopt, std::optional phone = std::nullopt, std::optional password = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + if (email.has_value()) { + params["email"] = std::string(email.value()); + } + if (phone.has_value()) { + params["phone"] = std::string(phone.value()); + } + if (password.has_value()) { + params["password"] = std::string(password.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. Password provided must be hashed with the + * [Argon2](https://en.wikipedia.org/wiki/Argon2) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Argon2. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createArgon2User( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/argon2"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. Password provided must be hashed with the + * [Argon2](https://en.wikipedia.org/wiki/Argon2) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Argon2. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createArgon2UserAsync( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/argon2"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. Password provided must be hashed with the + * [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Bcrypt. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createBcryptUser( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/bcrypt"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. Password provided must be hashed with the + * [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Bcrypt. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createBcryptUserAsync( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/bcrypt"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get identities for all users. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listIdentities( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/users/identities"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get identities for all users. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listIdentitiesAsync( std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/users/identities"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an identity by its unique ID. + * + * @param identityId Identity ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteIdentity( std::string_view identityId ) { + std::string path_ = std::format("/users/identities/{}", identityId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an identity by its unique ID. + * + * @param identityId Identity ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteIdentityAsync( std::string_view identityId ) { + std::string path_ = std::format("/users/identities/{}", identityId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. Password provided must be hashed with the + * [MD5](https://en.wikipedia.org/wiki/MD5) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using MD5. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMD5User( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/md5"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. Password provided must be hashed with the + * [MD5](https://en.wikipedia.org/wiki/MD5) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using MD5. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMD5UserAsync( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/md5"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. Password provided must be hashed with the + * [PHPass](https://www.openwall.com/phpass/) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User ID. Choose a custom ID or pass the string `ID.unique()`to auto generate it. 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 email User email. + * @param password User password hashed using PHPass. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createPHPassUser( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/phpass"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. Password provided must be hashed with the + * [PHPass](https://www.openwall.com/phpass/) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User ID. Choose a custom ID or pass the string `ID.unique()`to auto generate it. 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 email User email. + * @param password User password hashed using PHPass. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createPHPassUserAsync( std::string_view userId, std::string_view email, std::string_view password, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/phpass"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. Password provided must be hashed with the + * [Scrypt](https://github.com/Tarsnap/scrypt) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Scrypt. + * @param passwordSalt Optional salt used to hash password. + * @param passwordCpu Optional CPU cost used to hash password. + * @param passwordMemory Optional memory cost used to hash password. + * @param passwordParallel Optional parallelization cost used to hash password. + * @param passwordLength Optional hash length used to hash password. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createScryptUser( std::string_view userId, std::string_view email, std::string_view password, std::string_view passwordSalt, int64_t passwordCpu, int64_t passwordMemory, int64_t passwordParallel, int64_t passwordLength, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/scrypt"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + params["passwordSalt"] = std::string(passwordSalt); + params["passwordCpu"] = passwordCpu; + params["passwordMemory"] = passwordMemory; + params["passwordParallel"] = passwordParallel; + params["passwordLength"] = passwordLength; + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. Password provided must be hashed with the + * [Scrypt](https://github.com/Tarsnap/scrypt) algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Scrypt. + * @param passwordSalt Optional salt used to hash password. + * @param passwordCpu Optional CPU cost used to hash password. + * @param passwordMemory Optional memory cost used to hash password. + * @param passwordParallel Optional parallelization cost used to hash password. + * @param passwordLength Optional hash length used to hash password. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createScryptUserAsync( std::string_view userId, std::string_view email, std::string_view password, std::string_view passwordSalt, int64_t passwordCpu, int64_t passwordMemory, int64_t passwordParallel, int64_t passwordLength, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/scrypt"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + params["passwordSalt"] = std::string(passwordSalt); + params["passwordCpu"] = passwordCpu; + params["passwordMemory"] = passwordMemory; + params["passwordParallel"] = passwordParallel; + params["passwordLength"] = passwordLength; + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. Password provided must be hashed with the [Scrypt + * Modified](https://gist.github.com/Meldiron/eecf84a0225eccb5a378d45bb27462cc) + * algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Scrypt Modified. + * @param passwordSalt Salt used to hash password. + * @param passwordSaltSeparator Salt separator used to hash password. + * @param passwordSignerKey Signer key used to hash password. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createScryptModifiedUser( std::string_view userId, std::string_view email, std::string_view password, std::string_view passwordSalt, std::string_view passwordSaltSeparator, std::string_view passwordSignerKey, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/scrypt-modified"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + params["passwordSalt"] = std::string(passwordSalt); + params["passwordSaltSeparator"] = std::string(passwordSaltSeparator); + params["passwordSignerKey"] = std::string(passwordSignerKey); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. Password provided must be hashed with the [Scrypt + * Modified](https://gist.github.com/Meldiron/eecf84a0225eccb5a378d45bb27462cc) + * algorithm. Use the [POST + * /users](https://appwrite.io/docs/server/users#usersCreate) endpoint to + * create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using Scrypt Modified. + * @param passwordSalt Salt used to hash password. + * @param passwordSaltSeparator Salt separator used to hash password. + * @param passwordSignerKey Signer key used to hash password. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createScryptModifiedUserAsync( std::string_view userId, std::string_view email, std::string_view password, std::string_view passwordSalt, std::string_view passwordSaltSeparator, std::string_view passwordSignerKey, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/scrypt-modified"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + params["passwordSalt"] = std::string(passwordSalt); + params["passwordSaltSeparator"] = std::string(passwordSaltSeparator); + params["passwordSignerKey"] = std::string(passwordSignerKey); + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new user. Password provided must be hashed with the + * [SHA](https://en.wikipedia.org/wiki/Secure_Hash_Algorithm) algorithm. Use + * the [POST /users](https://appwrite.io/docs/server/users#usersCreate) + * endpoint to create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using SHA. + * @param passwordVersion Optional SHA version used to hash password. Allowed values are: 'sha1', 'sha224', 'sha256', 'sha384', 'sha512/224', 'sha512/256', 'sha512', 'sha3-224', 'sha3-256', 'sha3-384', 'sha3-512' + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createSHAUser( std::string_view userId, std::string_view email, std::string_view password, std::optional passwordVersion = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/sha"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (passwordVersion.has_value()) { + params["passwordVersion"] = *passwordVersion; + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new user. Password provided must be hashed with the + * [SHA](https://en.wikipedia.org/wiki/Secure_Hash_Algorithm) algorithm. Use + * the [POST /users](https://appwrite.io/docs/server/users#usersCreate) + * endpoint to create users with a plain text password. + * + * @param userId User 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 email User email. + * @param password User password hashed using SHA. + * @param passwordVersion Optional SHA version used to hash password. Allowed values are: 'sha1', 'sha224', 'sha256', 'sha384', 'sha512/224', 'sha512/256', 'sha512', 'sha3-224', 'sha3-256', 'sha3-384', 'sha3-512' + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createSHAUserAsync( std::string_view userId, std::string_view email, std::string_view password, std::optional passwordVersion = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/sha"); + + nlohmann::json params = nlohmann::json::object(); + params["userId"] = std::string(userId); + params["email"] = std::string(email); + params["password"] = std::string(password); + if (passwordVersion.has_value()) { + params["passwordVersion"] = *passwordVersion; + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a user by its unique ID. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result get( std::string_view userId ) { + std::string path_ = std::format("/users/{}", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a user by its unique ID. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a user by its unique ID, thereby releasing it's ID. Since ID is + * released and can be reused, all user-related resources like documents or + * storage files should be deleted before user deletion. If you want to keep + * ID reserved, use the + * [updateStatus](https://appwrite.io/docs/server/users#usersUpdateStatus) + * endpoint instead. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result delete_( std::string_view userId ) { + std::string path_ = std::format("/users/{}", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a user by its unique ID, thereby releasing it's ID. Since ID is + * released and can be reused, all user-related resources like documents or + * storage files should be deleted before user deletion. If you want to keep + * ID reserved, use the + * [updateStatus](https://appwrite.io/docs/server/users#usersUpdateStatus) + * endpoint instead. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> delete_Async( std::string_view userId ) { + std::string path_ = std::format("/users/{}", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user email by its unique ID. + * + * @param userId User ID. + * @param email User email. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEmail( std::string_view userId, std::string_view email ) { + std::string path_ = std::format("/users/{}/email", userId); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user email by its unique ID. + * + * @param userId User ID. + * @param email User email. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEmailAsync( std::string_view userId, std::string_view email ) { + std::string path_ = std::format("/users/{}/email", userId); + + nlohmann::json params = nlohmann::json::object(); + params["email"] = std::string(email); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Enable or disable whether a user can impersonate other users. When + * impersonation headers are used, the request runs as the target user for API + * behavior, while internal audit logs still attribute the action to the + * original impersonator and store the impersonated target details only in + * internal audit payload data. + * + * @param userId User ID. + * @param impersonator Whether the user can impersonate other users. When true, the user can browse project users to choose a target and can pass impersonation headers to act as that user. Internal audit logs still attribute impersonated actions to the original impersonator and store the target user details only in internal audit payload data. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateImpersonator( std::string_view userId, bool impersonator ) { + std::string path_ = std::format("/users/{}/impersonator", userId); + + nlohmann::json params = nlohmann::json::object(); + params["impersonator"] = impersonator; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Enable or disable whether a user can impersonate other users. When + * impersonation headers are used, the request runs as the target user for API + * behavior, while internal audit logs still attribute the action to the + * original impersonator and store the impersonated target details only in + * internal audit payload data. + * + * @param userId User ID. + * @param impersonator Whether the user can impersonate other users. When true, the user can browse project users to choose a target and can pass impersonation headers to act as that user. Internal audit logs still attribute impersonated actions to the original impersonator and store the target user details only in internal audit payload data. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateImpersonatorAsync( std::string_view userId, bool impersonator ) { + std::string path_ = std::format("/users/{}/impersonator", userId); + + nlohmann::json params = nlohmann::json::object(); + params["impersonator"] = impersonator; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Use this endpoint to create a JSON Web Token for user by its unique ID. You + * can use the resulting JWT to authenticate on behalf of the user. The JWT + * secret will become invalid if the session it uses gets deleted. + * + * @param userId User ID. + * @param sessionId Session ID. Use the string 'recent' to use the most recent session. Defaults to the most recent session. + * @param duration Time in seconds before JWT expires. Default duration is 900 seconds, and maximum is 3600 seconds. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createJWT( std::string_view userId, std::optional sessionId = std::nullopt, std::optional duration = 900 ) { + std::string path_ = std::format("/users/{}/jwts", userId); + + nlohmann::json params = nlohmann::json::object(); + if (sessionId.has_value()) { + params["sessionId"] = std::string(sessionId.value()); + } + if (duration.has_value()) { + params["duration"] = *duration; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Use this endpoint to create a JSON Web Token for user by its unique ID. You + * can use the resulting JWT to authenticate on behalf of the user. The JWT + * secret will become invalid if the session it uses gets deleted. + * + * @param userId User ID. + * @param sessionId Session ID. Use the string 'recent' to use the most recent session. Defaults to the most recent session. + * @param duration Time in seconds before JWT expires. Default duration is 900 seconds, and maximum is 3600 seconds. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createJWTAsync( std::string_view userId, std::optional sessionId = std::nullopt, std::optional duration = 900 ) { + std::string path_ = std::format("/users/{}/jwts", userId); + + nlohmann::json params = nlohmann::json::object(); + if (sessionId.has_value()) { + params["sessionId"] = std::string(sessionId.value()); + } + if (duration.has_value()) { + params["duration"] = *duration; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user labels by its unique ID. + +Labels can be used to grant + * access to resources. While teams are a way for user's to share access to a + * resource, labels can be defined by the developer to grant access without an + * invitation. See the [Permissions + * docs](https://appwrite.io/docs/permissions) for more info. + * + * @param userId User ID. + * @param labels Array of user labels. Replaces the previous labels. Maximum of 1000 labels are allowed, each up to 36 alphanumeric characters long. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateLabels( std::string_view userId, std::vector labels ) { + std::string path_ = std::format("/users/{}/labels", userId); + + nlohmann::json params = nlohmann::json::object(); + params["labels"] = labels; + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user labels by its unique ID. + +Labels can be used to grant + * access to resources. While teams are a way for user's to share access to a + * resource, labels can be defined by the developer to grant access without an + * invitation. See the [Permissions + * docs](https://appwrite.io/docs/permissions) for more info. + * + * @param userId User ID. + * @param labels Array of user labels. Replaces the previous labels. Maximum of 1000 labels are allowed, each up to 36 alphanumeric characters long. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateLabelsAsync( std::string_view userId, std::vector labels ) { + std::string path_ = std::format("/users/{}/labels", userId); + + nlohmann::json params = nlohmann::json::object(); + params["labels"] = labels; + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the user activity logs list by its unique ID. + * + * @param userId User ID. + * @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 appwrite::Result + */ + [[nodiscard]] appwrite::Result listLogs( std::string_view userId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/users/{}/logs", userId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the user activity logs list by its unique ID. + * + * @param userId User ID. + * @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 appwrite::Result + */ + [[nodiscard]] appwrite::Task> listLogsAsync( std::string_view userId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/users/{}/logs", userId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the user membership list by its unique ID. + * + * @param userId User ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listMemberships( std::string_view userId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/users/{}/memberships", userId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the user membership list by its unique ID. + * + * @param userId User ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles + * @param search Search term to filter your list results. Max length: 256 chars. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listMembershipsAsync( std::string_view userId, std::optional> queries = std::vector{}, std::optional search = std::nullopt, std::optional total = true ) { + std::string path_ = std::format("/users/{}/memberships", userId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (search.has_value()) { + params["search"] = std::string(search.value()); + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Enable or disable MFA on a user account. + * + * @param userId User ID. + * @param mfa Enable or disable MFA. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMfa( std::string_view userId, bool mfa ) { + std::string path_ = std::format("/users/{}/mfa", userId); + + nlohmann::json params = nlohmann::json::object(); + params["mfa"] = mfa; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Enable or disable MFA on a user account. + * + * @param userId User ID. + * @param mfa Enable or disable MFA. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMfaAsync( std::string_view userId, bool mfa ) { + std::string path_ = std::format("/users/{}/mfa", userId); + + nlohmann::json params = nlohmann::json::object(); + params["mfa"] = mfa; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Enable or disable MFA on a user account. + * + * @param userId User ID. + * @param mfa Enable or disable MFA. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMFA( std::string_view userId, bool mfa ) { + std::string path_ = std::format("/users/{}/mfa", userId); + + nlohmann::json params = nlohmann::json::object(); + params["mfa"] = mfa; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Enable or disable MFA on a user account. + * + * @param userId User ID. + * @param mfa Enable or disable MFA. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMFAAsync( std::string_view userId, bool mfa ) { + std::string path_ = std::format("/users/{}/mfa", userId); + + nlohmann::json params = nlohmann::json::object(); + params["mfa"] = mfa; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an authenticator app. + * + * @param userId User ID. + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteMfaAuthenticator( std::string_view userId, appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/users/{}/mfa/authenticators/{}", userId, appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an authenticator app. + * + * @param userId User ID. + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteMfaAuthenticatorAsync( std::string_view userId, appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/users/{}/mfa/authenticators/{}", userId, appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete an authenticator app. + * + * @param userId User ID. + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteMFAAuthenticator( std::string_view userId, appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/users/{}/mfa/authenticators/{}", userId, appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete an authenticator app. + * + * @param userId User ID. + * @param type Type of authenticator. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteMFAAuthenticatorAsync( std::string_view userId, appwrite::enums::AuthenticatorType type ) { + std::string path_ = std::format("/users/{}/mfa/authenticators/{}", userId, appwrite::enums::toString(type)); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * List the factors available on the account to be used as a MFA challange. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listMfaFactors( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/factors", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List the factors available on the account to be used as a MFA challange. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listMfaFactorsAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/factors", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * List the factors available on the account to be used as a MFA challange. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listMFAFactors( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/factors", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List the factors available on the account to be used as a MFA challange. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listMFAFactorsAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/factors", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get recovery codes that can be used as backup for MFA flow by User ID. + * Before getting codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getMfaRecoveryCodes( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get recovery codes that can be used as backup for MFA flow by User ID. + * Before getting codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getMfaRecoveryCodesAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get recovery codes that can be used as backup for MFA flow by User ID. + * Before getting codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getMFARecoveryCodes( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get recovery codes that can be used as backup for MFA flow by User ID. + * Before getting codes, they must be generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getMFARecoveryCodesAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Regenerate recovery codes that can be used as backup for MFA flow by User + * ID. Before regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMfaRecoveryCodes( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Regenerate recovery codes that can be used as backup for MFA flow by User + * ID. Before regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMfaRecoveryCodesAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Regenerate recovery codes that can be used as backup for MFA flow by User + * ID. Before regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateMFARecoveryCodes( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Regenerate recovery codes that can be used as backup for MFA flow by User + * ID. Before regenerating codes, they must be first generated using + * [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) + * method. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateMFARecoveryCodesAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Generate recovery codes used as backup for MFA flow for User ID. Recovery + * codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method by client SDK. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMfaRecoveryCodes( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Generate recovery codes used as backup for MFA flow for User ID. Recovery + * codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method by client SDK. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMfaRecoveryCodesAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Generate recovery codes used as backup for MFA flow for User ID. Recovery + * codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method by client SDK. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createMFARecoveryCodes( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Generate recovery codes used as backup for MFA flow for User ID. Recovery + * codes can be used as a MFA verification type in + * [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) + * method by client SDK. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createMFARecoveryCodesAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/mfa/recovery-codes", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user name by its unique ID. + * + * @param userId User ID. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateName( std::string_view userId, std::string_view name ) { + std::string path_ = std::format("/users/{}/name", userId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user name by its unique ID. + * + * @param userId User ID. + * @param name User name. Max length: 128 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateNameAsync( std::string_view userId, std::string_view name ) { + std::string path_ = std::format("/users/{}/name", userId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user password by its unique ID. + * + * @param userId User ID. + * @param password New user password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePassword( std::string_view userId, std::string_view password ) { + std::string path_ = std::format("/users/{}/password", userId); + + nlohmann::json params = nlohmann::json::object(); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user password by its unique ID. + * + * @param userId User ID. + * @param password New user password. Must be at least 8 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePasswordAsync( std::string_view userId, std::string_view password ) { + std::string path_ = std::format("/users/{}/password", userId); + + nlohmann::json params = nlohmann::json::object(); + params["password"] = std::string(password); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user phone by its unique ID. + * + * @param userId User ID. + * @param number User phone number. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePhone( std::string_view userId, std::string_view number ) { + std::string path_ = std::format("/users/{}/phone", userId); + + nlohmann::json params = nlohmann::json::object(); + params["number"] = std::string(number); + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user phone by its unique ID. + * + * @param userId User ID. + * @param number User phone number. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePhoneAsync( std::string_view userId, std::string_view number ) { + std::string path_ = std::format("/users/{}/phone", userId); + + nlohmann::json params = nlohmann::json::object(); + params["number"] = std::string(number); + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the user preferences by its unique ID. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getPrefs( std::string_view userId ) { + std::string path_ = std::format("/users/{}/prefs", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the user preferences by its unique ID. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getPrefsAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/prefs", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user preferences by its unique ID. The object you pass is stored + * as is, and replaces any previous value. The maximum allowed prefs size is + * 64kB and throws error if exceeded. + * + * @param userId User ID. + * @param prefs Prefs key-value JSON object. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePrefs( std::string_view userId, const nlohmann::json& prefs = nlohmann::json::object() ) { + std::string path_ = std::format("/users/{}/prefs", userId); + + nlohmann::json params = nlohmann::json::object(); + params["prefs"] = prefs; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user preferences by its unique ID. The object you pass is stored + * as is, and replaces any previous value. The maximum allowed prefs size is + * 64kB and throws error if exceeded. + * + * @param userId User ID. + * @param prefs Prefs key-value JSON object. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePrefsAsync( std::string_view userId, const nlohmann::json& prefs = nlohmann::json::object() ) { + std::string path_ = std::format("/users/{}/prefs", userId); + + nlohmann::json params = nlohmann::json::object(); + params["prefs"] = prefs; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get the user sessions list by its unique ID. + * + * @param userId User ID. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listSessions( std::string_view userId, std::optional total = true ) { + std::string path_ = std::format("/users/{}/sessions", userId); + + nlohmann::json params = nlohmann::json::object(); + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get the user sessions list by its unique ID. + * + * @param userId User ID. + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listSessionsAsync( std::string_view userId, std::optional total = true ) { + std::string path_ = std::format("/users/{}/sessions", userId); + + nlohmann::json params = nlohmann::json::object(); + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Creates a session for a user. Returns an immediately usable session + * object. + +If you want to generate a token for a custom authentication flow, + * use the [POST + * /users/{userId}/tokens](https://appwrite.io/docs/server/users#createToken) + * endpoint. + * + * @param userId User 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createSession( std::string_view userId ) { + std::string path_ = std::format("/users/{}/sessions", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Creates a session for a user. Returns an immediately usable session + * object. + +If you want to generate a token for a custom authentication flow, + * use the [POST + * /users/{userId}/tokens](https://appwrite.io/docs/server/users#createToken) + * endpoint. + * + * @param userId User 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. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createSessionAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/sessions", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete all user's sessions by using the user's unique ID. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteSessions( std::string_view userId ) { + std::string path_ = std::format("/users/{}/sessions", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete all user's sessions by using the user's unique ID. + * + * @param userId User ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteSessionsAsync( std::string_view userId ) { + std::string path_ = std::format("/users/{}/sessions", userId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a user sessions by its unique ID. + * + * @param userId User ID. + * @param sessionId Session ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteSession( std::string_view userId, std::string_view sessionId ) { + std::string path_ = std::format("/users/{}/sessions/{}", userId, sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a user sessions by its unique ID. + * + * @param userId User ID. + * @param sessionId Session ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteSessionAsync( std::string_view userId, std::string_view sessionId ) { + std::string path_ = std::format("/users/{}/sessions/{}", userId, sessionId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user status by its unique ID. Use this endpoint as an + * alternative to deleting a user if you want to keep user's ID reserved. + * + * @param userId User ID. + * @param status User Status. To activate the user pass `true` and to block the user pass `false`. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateStatus( std::string_view userId, bool status ) { + std::string path_ = std::format("/users/{}/status", userId); + + nlohmann::json params = nlohmann::json::object(); + params["status"] = status; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user status by its unique ID. Use this endpoint as an + * alternative to deleting a user if you want to keep user's ID reserved. + * + * @param userId User ID. + * @param status User Status. To activate the user pass `true` and to block the user pass `false`. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateStatusAsync( std::string_view userId, bool status ) { + std::string path_ = std::format("/users/{}/status", userId); + + nlohmann::json params = nlohmann::json::object(); + params["status"] = status; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * List the messaging targets that are associated with a user. + * + * @param userId User ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result listTargets( std::string_view userId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/users/{}/targets", userId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * List the messaging targets that are associated with a user. + * + * @param userId User ID. + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listTargetsAsync( std::string_view userId, std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/users/{}/targets", userId); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a messaging target. + * + * @param userId User ID. + * @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 providerType The target provider type. Can be one of the following: `email`, `sms` or `push`. + * @param identifier The target identifier (token, email, phone etc.) + * @param providerId Provider ID. Message will be sent to this target from the specified provider ID. If no provider ID is set the first setup provider will be used. + * @param name Target name. Max length: 128 chars. For example: My Awesome App Galaxy S23. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createTarget( std::string_view userId, std::string_view targetId, appwrite::enums::MessagingProviderType providerType, std::string_view identifier, std::optional providerId = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/{}/targets", userId); + + nlohmann::json params = nlohmann::json::object(); + params["targetId"] = std::string(targetId); + params["providerType"] = providerType; + params["identifier"] = std::string(identifier); + if (providerId.has_value()) { + params["providerId"] = std::string(providerId.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a messaging target. + * + * @param userId User ID. + * @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 providerType The target provider type. Can be one of the following: `email`, `sms` or `push`. + * @param identifier The target identifier (token, email, phone etc.) + * @param providerId Provider ID. Message will be sent to this target from the specified provider ID. If no provider ID is set the first setup provider will be used. + * @param name Target name. Max length: 128 chars. For example: My Awesome App Galaxy S23. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTargetAsync( std::string_view userId, std::string_view targetId, appwrite::enums::MessagingProviderType providerType, std::string_view identifier, std::optional providerId = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/{}/targets", userId); + + nlohmann::json params = nlohmann::json::object(); + params["targetId"] = std::string(targetId); + params["providerType"] = providerType; + params["identifier"] = std::string(identifier); + if (providerId.has_value()) { + params["providerId"] = std::string(providerId.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a user's push notification target by ID. + * + * @param userId User ID. + * @param targetId Target ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result getTarget( std::string_view userId, std::string_view targetId ) { + std::string path_ = std::format("/users/{}/targets/{}", userId, targetId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a user's push notification target by ID. + * + * @param userId User ID. + * @param targetId Target ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getTargetAsync( std::string_view userId, std::string_view targetId ) { + std::string path_ = std::format("/users/{}/targets/{}", userId, targetId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a messaging target. + * + * @param userId User ID. + * @param targetId Target ID. + * @param identifier The target identifier (token, email, phone etc.) + * @param providerId Provider ID. Message will be sent to this target from the specified provider ID. If no provider ID is set the first setup provider will be used. + * @param name Target name. Max length: 128 chars. For example: My Awesome App Galaxy S23. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateTarget( std::string_view userId, std::string_view targetId, std::optional identifier = std::nullopt, std::optional providerId = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/{}/targets/{}", userId, targetId); + + nlohmann::json params = nlohmann::json::object(); + if (identifier.has_value()) { + params["identifier"] = std::string(identifier.value()); + } + if (providerId.has_value()) { + params["providerId"] = std::string(providerId.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a messaging target. + * + * @param userId User ID. + * @param targetId Target ID. + * @param identifier The target identifier (token, email, phone etc.) + * @param providerId Provider ID. Message will be sent to this target from the specified provider ID. If no provider ID is set the first setup provider will be used. + * @param name Target name. Max length: 128 chars. For example: My Awesome App Galaxy S23. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateTargetAsync( std::string_view userId, std::string_view targetId, std::optional identifier = std::nullopt, std::optional providerId = std::nullopt, std::optional name = std::nullopt ) { + std::string path_ = std::format("/users/{}/targets/{}", userId, targetId); + + nlohmann::json params = nlohmann::json::object(); + if (identifier.has_value()) { + params["identifier"] = std::string(identifier.value()); + } + if (providerId.has_value()) { + params["providerId"] = std::string(providerId.value()); + } + if (name.has_value()) { + params["name"] = std::string(name.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a messaging target. + * + * @param userId User ID. + * @param targetId Target ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result deleteTarget( std::string_view userId, std::string_view targetId ) { + std::string path_ = std::format("/users/{}/targets/{}", userId, targetId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a messaging target. + * + * @param userId User ID. + * @param targetId Target ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> deleteTargetAsync( std::string_view userId, std::string_view targetId ) { + std::string path_ = std::format("/users/{}/targets/{}", userId, targetId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Returns a token with a secret key for creating a session. Use the user ID + * and secret and submit a request to the [PUT + * /account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. + * + * @param userId User ID. + * @param length Token length in characters. The default length is 6 characters + * @param expire Token expiration period in seconds. The default expiration is 15 minutes. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result createToken( std::string_view userId, std::optional length = 6, std::optional expire = 900 ) { + std::string path_ = std::format("/users/{}/tokens", userId); + + nlohmann::json params = nlohmann::json::object(); + if (length.has_value()) { + params["length"] = *length; + } + if (expire.has_value()) { + params["expire"] = *expire; + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Returns a token with a secret key for creating a session. Use the user ID + * and secret and submit a request to the [PUT + * /account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) + * endpoint to complete the login process. + * + * @param userId User ID. + * @param length Token length in characters. The default length is 6 characters + * @param expire Token expiration period in seconds. The default expiration is 15 minutes. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createTokenAsync( std::string_view userId, std::optional length = 6, std::optional expire = 900 ) { + std::string path_ = std::format("/users/{}/tokens", userId); + + nlohmann::json params = nlohmann::json::object(); + if (length.has_value()) { + params["length"] = *length; + } + if (expire.has_value()) { + params["expire"] = *expire; + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user email verification status by its unique ID. + * + * @param userId User ID. + * @param emailVerification User email verification status. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateEmailVerification( std::string_view userId, bool emailVerification ) { + std::string path_ = std::format("/users/{}/verification", userId); + + nlohmann::json params = nlohmann::json::object(); + params["emailVerification"] = emailVerification; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user email verification status by its unique ID. + * + * @param userId User ID. + * @param emailVerification User email verification status. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateEmailVerificationAsync( std::string_view userId, bool emailVerification ) { + std::string path_ = std::format("/users/{}/verification", userId); + + nlohmann::json params = nlohmann::json::object(); + params["emailVerification"] = emailVerification; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the user phone verification status by its unique ID. + * + * @param userId User ID. + * @param phoneVerification User phone verification status. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updatePhoneVerification( std::string_view userId, bool phoneVerification ) { + std::string path_ = std::format("/users/{}/verification/phone", userId); + + nlohmann::json params = nlohmann::json::object(); + params["phoneVerification"] = phoneVerification; + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the user phone verification status by its unique ID. + * + * @param userId User ID. + * @param phoneVerification User phone verification status. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updatePhoneVerificationAsync( std::string_view userId, bool phoneVerification ) { + std::string path_ = std::format("/users/{}/verification/phone", userId); + + nlohmann::json params = nlohmann::json::object(); + params["phoneVerification"] = phoneVerification; + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } +}; + +/** + * @brief + */ +class Webhooks : public Service { +public: + explicit Webhooks(Client& client) : Service(client) {} + + /** + * Get a list of all webhooks belonging to the project. You can use the query + * params to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, url, authUsername, tls, events, enabled, logs, attempts + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result list( std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/webhooks"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a list of all webhooks belonging to the project. You can use the query + * params to filter your results. + * + * @param queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, url, authUsername, tls, events, enabled, logs, attempts + * @param total When set to false, the total count returned will be 0 and will not be calculated. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> listAsync( std::optional> queries = std::vector{}, std::optional total = true ) { + std::string path_ = std::format("/webhooks"); + + nlohmann::json params = nlohmann::json::object(); + if (queries.has_value()) { + params["queries"] = *queries; + } + if (total.has_value()) { + params["total"] = *total; + } + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Create a new webhook. Use this endpoint to configure a URL that will + * receive events from Appwrite when specific events occur. + * + * @param webhookId Webhook 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 url Webhook URL. + * @param name Webhook name. Max length: 128 chars. + * @param events Events list. Maximum of 100 events are allowed. + * @param enabled Enable or disable a webhook. + * @param tls Certificate verification, false for disabled or true for enabled. + * @param authUsername Webhook HTTP user. Max length: 256 chars. + * @param authPassword Webhook HTTP password. Max length: 256 chars. + * @param secret Webhook secret key. If not provided, a new key will be generated automatically. Key must be at least 8 characters long, and at max 256 characters. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result create( std::string_view webhookId, std::string_view url, std::string_view name, std::vector events, std::optional enabled = true, std::optional tls = false, std::optional authUsername = std::nullopt, std::optional authPassword = std::nullopt, std::optional secret = std::nullopt ) { + std::string path_ = std::format("/webhooks"); + + nlohmann::json params = nlohmann::json::object(); + params["webhookId"] = std::string(webhookId); + params["url"] = std::string(url); + params["name"] = std::string(name); + params["events"] = events; + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (tls.has_value()) { + params["tls"] = *tls; + } + if (authUsername.has_value()) { + params["authUsername"] = std::string(authUsername.value()); + } + if (authPassword.has_value()) { + params["authPassword"] = std::string(authPassword.value()); + } + if (secret.has_value()) { + params["secret"] = std::string(secret.value()); + } + + std::unordered_map local_headers_; + + return client_.call("POST", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Create a new webhook. Use this endpoint to configure a URL that will + * receive events from Appwrite when specific events occur. + * + * @param webhookId Webhook 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 url Webhook URL. + * @param name Webhook name. Max length: 128 chars. + * @param events Events list. Maximum of 100 events are allowed. + * @param enabled Enable or disable a webhook. + * @param tls Certificate verification, false for disabled or true for enabled. + * @param authUsername Webhook HTTP user. Max length: 256 chars. + * @param authPassword Webhook HTTP password. Max length: 256 chars. + * @param secret Webhook secret key. If not provided, a new key will be generated automatically. Key must be at least 8 characters long, and at max 256 characters. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> createAsync( std::string_view webhookId, std::string_view url, std::string_view name, std::vector events, std::optional enabled = true, std::optional tls = false, std::optional authUsername = std::nullopt, std::optional authPassword = std::nullopt, std::optional secret = std::nullopt ) { + std::string path_ = std::format("/webhooks"); + + nlohmann::json params = nlohmann::json::object(); + params["webhookId"] = std::string(webhookId); + params["url"] = std::string(url); + params["name"] = std::string(name); + params["events"] = events; + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (tls.has_value()) { + params["tls"] = *tls; + } + if (authUsername.has_value()) { + params["authUsername"] = std::string(authUsername.value()); + } + if (authPassword.has_value()) { + params["authPassword"] = std::string(authPassword.value()); + } + if (secret.has_value()) { + params["secret"] = std::string(secret.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("POST", path_, std::move(local_headers_), std::move(params)); + } + /** + * Get a webhook by its unique ID. This endpoint returns details about a + * specific webhook configured for a project. + * + * @param webhookId Webhook ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result get( std::string_view webhookId ) { + std::string path_ = std::format("/webhooks/{}", webhookId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.call("GET", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Get a webhook by its unique ID. This endpoint returns details about a + * specific webhook configured for a project. + * + * @param webhookId Webhook ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> getAsync( std::string_view webhookId ) { + std::string path_ = std::format("/webhooks/{}", webhookId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callAsync("GET", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update a webhook by its unique ID. Use this endpoint to update the URL, + * events, or status of an existing webhook. + * + * @param webhookId Webhook ID. + * @param name Webhook name. Max length: 128 chars. + * @param url Webhook URL. + * @param events Events list. Maximum of 100 events are allowed. + * @param enabled Enable or disable a webhook. + * @param tls Certificate verification, false for disabled or true for enabled. + * @param authUsername Webhook HTTP user. Max length: 256 chars. + * @param authPassword Webhook HTTP password. Max length: 256 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result update( std::string_view webhookId, std::string_view name, std::string_view url, std::vector events, std::optional enabled = true, std::optional tls = false, std::optional authUsername = std::nullopt, std::optional authPassword = std::nullopt ) { + std::string path_ = std::format("/webhooks/{}", webhookId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + params["url"] = std::string(url); + params["events"] = events; + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (tls.has_value()) { + params["tls"] = *tls; + } + if (authUsername.has_value()) { + params["authUsername"] = std::string(authUsername.value()); + } + if (authPassword.has_value()) { + params["authPassword"] = std::string(authPassword.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PUT", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update a webhook by its unique ID. Use this endpoint to update the URL, + * events, or status of an existing webhook. + * + * @param webhookId Webhook ID. + * @param name Webhook name. Max length: 128 chars. + * @param url Webhook URL. + * @param events Events list. Maximum of 100 events are allowed. + * @param enabled Enable or disable a webhook. + * @param tls Certificate verification, false for disabled or true for enabled. + * @param authUsername Webhook HTTP user. Max length: 256 chars. + * @param authPassword Webhook HTTP password. Max length: 256 chars. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateAsync( std::string_view webhookId, std::string_view name, std::string_view url, std::vector events, std::optional enabled = true, std::optional tls = false, std::optional authUsername = std::nullopt, std::optional authPassword = std::nullopt ) { + std::string path_ = std::format("/webhooks/{}", webhookId); + + nlohmann::json params = nlohmann::json::object(); + params["name"] = std::string(name); + params["url"] = std::string(url); + params["events"] = events; + if (enabled.has_value()) { + params["enabled"] = *enabled; + } + if (tls.has_value()) { + params["tls"] = *tls; + } + if (authUsername.has_value()) { + params["authUsername"] = std::string(authUsername.value()); + } + if (authPassword.has_value()) { + params["authPassword"] = std::string(authPassword.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PUT", path_, std::move(local_headers_), std::move(params)); + } + /** + * Delete a webhook by its unique ID. Once deleted, the webhook will no longer + * receive project events. + * + * @param webhookId Webhook ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result delete_( std::string_view webhookId ) { + std::string path_ = std::format("/webhooks/{}", webhookId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoid("DELETE", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Delete a webhook by its unique ID. Once deleted, the webhook will no longer + * receive project events. + * + * @param webhookId Webhook ID. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> delete_Async( std::string_view webhookId ) { + std::string path_ = std::format("/webhooks/{}", webhookId); + + nlohmann::json params = nlohmann::json::object(); + + std::unordered_map local_headers_; + + return client_.callVoidAsync("DELETE", path_, std::move(local_headers_), std::move(params)); + } + /** + * Update the webhook signing key. This endpoint can be used to regenerate the + * signing key used to sign and validate payload deliveries for a specific + * webhook. + * + * @param webhookId Webhook ID. + * @param secret Webhook secret key. If not provided, a new key will be generated automatically. Key must be at least 8 characters long, and at max 256 characters. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Result updateSecret( std::string_view webhookId, std::optional secret = std::nullopt ) { + std::string path_ = std::format("/webhooks/{}/secret", webhookId); + + nlohmann::json params = nlohmann::json::object(); + if (secret.has_value()) { + params["secret"] = std::string(secret.value()); + } + + std::unordered_map local_headers_; + + return client_.call("PATCH", path_, std::move(local_headers_), std::move(params)); + } + + /** + * Update the webhook signing key. This endpoint can be used to regenerate the + * signing key used to sign and validate payload deliveries for a specific + * webhook. + * + * @param webhookId Webhook ID. + * @param secret Webhook secret key. If not provided, a new key will be generated automatically. Key must be at least 8 characters long, and at max 256 characters. + * @return appwrite::Result + */ + [[nodiscard]] appwrite::Task> updateSecretAsync( std::string_view webhookId, std::optional secret = std::nullopt ) { + std::string path_ = std::format("/webhooks/{}/secret", webhookId); + + nlohmann::json params = nlohmann::json::object(); + if (secret.has_value()) { + params["secret"] = std::string(secret.value()); + } + + std::unordered_map local_headers_; + + return client_.callAsync("PATCH", path_, std::move(local_headers_), std::move(params)); + } +}; + + +} // namespace services + +/** + * @brief Response payload received from the Appwrite Realtime service. + */ +struct RealtimeResponse { + std::string event; + std::string timestamp; + std::vector channels; + nlohmann::json data; +}; + +namespace services { + +/** + * @brief Realtime Service for subscribing to Appwrite events. + * + * @note WebSocket support requires a SocketBackend implementation. + * Enable by defining APPWRITE_ENABLE_REALTIME and providing + * a SocketBackend implementation before including this header. + */ +#ifdef APPWRITE_ENABLE_REALTIME + +class Realtime : public Service { +public: + using MessageCallback = std::function; + + struct Subscription { + std::vector channels; + MessageCallback callback; + std::string id; + void unsubscribe() { if (onUnsubscribe) onUnsubscribe(id); } + private: + friend class Realtime; + std::function onUnsubscribe; + }; + + explicit Realtime(Client& client) : Service(client) {} + + Subscription subscribe(std::vector channels, MessageCallback callback) { + std::lock_guard lock(mutex_); + static uint64_t subIdCounter = 0; + std::string subId = std::to_string(++subIdCounter); + + Subscription sub; + sub.id = subId; + sub.channels = channels; + sub.callback = std::move(callback); + sub.onUnsubscribe = [this](const std::string& id) { this->unsubscribe(id); }; + + subscriptions_[subId] = sub; + refresh(); + return sub; + } + +private: + std::mutex mutex_; + std::unordered_map subscriptions_; + std::shared_ptr socket_; + + void unsubscribe(const std::string& subId) { + std::lock_guard lock(mutex_); + subscriptions_.erase(subId); + refresh(); + } + + void refresh() { + if (subscriptions_.empty()) { + if (socket_) { socket_->close(); socket_.reset(); } + return; + } + + std::vector allChannels; + for (const auto& [id, sub] : subscriptions_) { + for (const auto& chan : sub.channels) { + if (std::find(allChannels.begin(), allChannels.end(), chan) == allChannels.end()) { + allChannels.push_back(chan); + } + } + } + + if (!socket_) { + socket_ = client_.createSocket(); + socket_->onMessage([this](const std::string& msg) { this->handleMessage(msg); }); + socket_->connect(client_.getRealtimeEndpoint(), client_.getProject()); + } + socket_->subscribe(allChannels); + } + + void handleMessage(const std::string& msg) { + try { + auto j = nlohmann::json::parse(msg); + RealtimeResponse resp; + resp.event = j.value("event", ""); + resp.timestamp = j.value("timestamp", ""); + resp.data = j.value("data", nlohmann::json::object()); + if (j.contains("channels")) { + for (auto& c : j["channels"]) resp.channels.push_back(c.get()); + } + + std::lock_guard lock(mutex_); + for (const auto& [id, sub] : subscriptions_) { + for (const auto& subChan : sub.channels) { + if (std::find(resp.channels.begin(), resp.channels.end(), subChan) != resp.channels.end()) { + sub.callback(resp); + break; + } + } + } + } catch (...) {} + } +}; + +#else + +class Realtime : public Service { +public: + using MessageCallback = std::function; + + struct Subscription { + std::string id; + std::vector channels; + void unsubscribe() {} + }; + + explicit Realtime(Client& client) : Service(client) {} + + template + Subscription subscribe( + std::vector /*channels*/, + MessageCallback /*callback*/ + ) { + static_assert( + !std::is_same_v, + "Realtime requires APPWRITE_ENABLE_REALTIME. " + "Define it and provide a SocketBackend before including services.hpp." + ); + return {}; + } +}; + +#endif // APPWRITE_ENABLE_REALTIME + +} // namespace services +} // namespace appwrite diff --git a/examples/cpp/tests/integration.cpp b/examples/cpp/tests/integration.cpp new file mode 100755 index 0000000000..d22b4f1ee3 --- /dev/null +++ b/examples/cpp/tests/integration.cpp @@ -0,0 +1,140 @@ +/** + * Appwrite C++ SDK Integration Test + * + * This binary has two modes: + * - When the APPWRITE_MOCK_ENDPOINT env var is set: runs full integration tests against the mock server. + * - Otherwise (in CI build validation): compiles and exits cleanly (verifies headers compile correctly). + * + * The mock-server tests (FOO_RESPONSES, BAR_RESPONSES, etc.) are run by test.sh via Docker + * with --network=mockapi. The build-validation CI step only needs this file to compile. + */ +#include +#include +#include +#include +#include +#include + +using namespace appwrite; + +#ifdef APPWRITE_RUN_INTEGRATION + +// Included only when compiled with -DAPPWRITE_RUN_INTEGRATION +// (set by test.sh, not by the build-validation CI step) + +extern int runIntegration(Client& client); + +#endif + +int main() { + // == Standalone helper verification == + // These don't need a running server — they only test local string-building logic. + + std::cout << "Test Started" << std::endl; + + Client client; + + int integration_result = 0; +#ifdef APPWRITE_RUN_INTEGRATION + const char* mock_endpoint = std::getenv("APPWRITE_MOCK_ENDPOINT"); + client + .setEndpoint(mock_endpoint ? mock_endpoint : "http://mockapi") + .setProject("123456"); + integration_result = runIntegration(client); +#endif + + // == QUERY_HELPER_RESPONSES == + std::cout << Query::equal("released", true) << "\n"; + std::cout << Query::equal("title", std::vector{"Spiderman", "Dr. Strange"}) << "\n"; + std::cout << Query::notEqual("title", "Spiderman") << "\n"; + std::cout << Query::lessThan("releasedYear", 1990) << "\n"; + std::cout << Query::greaterThan("releasedYear", 1990) << "\n"; + std::cout << Query::search("name", "john") << "\n"; + std::cout << Query::isNull("name") << "\n"; + std::cout << Query::isNotNull("name") << "\n"; + std::cout << Query::between("age", 50, 100) << "\n"; + std::cout << Query::between("age", 50.5, 100.5) << "\n"; + std::cout << Query::between("name", "Anna", "Brad") << "\n"; + std::cout << Query::startsWith("name", "Ann") << "\n"; + std::cout << Query::endsWith("name", "nne") << "\n"; + std::cout << Query::select(std::vector{"name", "age"}) << "\n"; + std::cout << Query::orderAsc("title") << "\n"; + std::cout << Query::orderDesc("title") << "\n"; + std::cout << Query::orderRandom() << "\n"; + std::cout << Query::cursorAfter("my_movie_id") << "\n"; + std::cout << Query::cursorBefore("my_movie_id") << "\n"; + std::cout << Query::limit(50) << "\n"; + std::cout << Query::offset(20) << "\n"; + std::cout << Query::contains("title", "Spider") << "\n"; + std::cout << Query::contains("labels", "first") << "\n"; + std::cout << Query::containsAny("labels", std::vector{"first", "second"}) << "\n"; + std::cout << Query::containsAll("labels", std::vector{"first", "second"}) << "\n"; + std::cout << Query::notContains("title", "Spider") << "\n"; + std::cout << Query::notSearch("name", "john") << "\n"; + std::cout << Query::notBetween("age", 50, 100) << "\n"; + std::cout << Query::notStartsWith("name", "Ann") << "\n"; + std::cout << Query::notEndsWith("name", "nne") << "\n"; + std::cout << Query::lessThan("$createdAt", "2023-01-01") << "\n"; + std::cout << Query::greaterThan("$createdAt", "2023-01-01") << "\n"; + std::cout << Query::between("$createdAt", "2023-01-01", "2023-12-31") << "\n"; + std::cout << Query::lessThan("$updatedAt", "2023-01-01") << "\n"; + std::cout << Query::greaterThan("$updatedAt", "2023-01-01") << "\n"; + std::cout << Query::between("$updatedAt", "2023-01-01", "2023-12-31") << "\n"; + + std::cout << Query::distanceEqual("location", 40.7128, -74.0, 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceEqual("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceNotEqual("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceNotEqual("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceGreaterThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceGreaterThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceLessThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceLessThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::intersects("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notIntersects("location", 40.7128, -74.0) << "\n"; + std::cout << Query::crosses("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notCrosses("location", 40.7128, -74.0) << "\n"; + std::cout << Query::overlaps("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notOverlaps("location", 40.7128, -74.0) << "\n"; + std::cout << Query::touches("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notTouches("location", 40.7128, -74.0) << "\n"; + + std::cout << "{\"method\":\"contains\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + std::cout << "{\"method\":\"notContains\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + std::cout << "{\"method\":\"equal\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + std::cout << "{\"method\":\"notEqual\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + + std::cout << Query::or_(std::vector{ + Query::equal("released", true), + Query::lessThan("releasedYear", 1990) + }) << "\n"; + std::cout << Query::and_(std::vector{ + Query::equal("released", false), + Query::greaterThan("releasedYear", 2015) + }) << "\n"; + + std::cout << Query::regex("name", "pattern.*") << "\n"; + std::cout << Query::exists(std::vector{"attr1", "attr2"}) << "\n"; + std::cout << Query::notExists(std::vector{"attr1", "attr2"}) << "\n"; + std::cout << Query::elemMatch("friends", std::vector{ + Query::equal("name", "Alice"), + Query::greaterThan("age", 18) + }) << "\n"; + + // == PERMISSION_HELPER_RESPONSES == + std::cout << Permission::read(Role::any()) << "\n"; + std::cout << Permission::write(Role::user("userid")) << "\n"; + std::cout << Permission::create(Role::users()) << "\n"; + std::cout << Permission::update(Role::guests()) << "\n"; + std::cout << Permission::delete_(Role::team("teamId", "owner")) << "\n"; + std::cout << Permission::delete_(Role::team("teamId")) << "\n"; + std::cout << Permission::create(Role::member("memberId")) << "\n"; + std::cout << Permission::update(Role::users("verified")) << "\n"; + std::cout << Permission::update(Role::user("userid", "unverified")) << "\n"; + std::cout << Permission::create(Role::label("admin")) << "\n"; + + // == ID_HELPER_RESPONSES == + std::cout << ID::unique().str() << "\n"; + std::cout << ID::custom("custom_id").str() << "\n"; + + return integration_result; +} diff --git a/examples/cpp/tests/integration_logic.cpp b/examples/cpp/tests/integration_logic.cpp new file mode 100755 index 0000000000..70f531d5ef --- /dev/null +++ b/examples/cpp/tests/integration_logic.cpp @@ -0,0 +1,149 @@ +#ifdef APPWRITE_RUN_INTEGRATION +#include +#include +#include +#include +#include +#include + +using namespace appwrite; + +static nlohmann::json fooParams() { + return { + {"x", "string"}, + {"y", 123}, + {"z", nlohmann::json::array({"string in array"})} + }; +} + +static nlohmann::json barParams() { + return { + {"required", "string"}, + {"default", 123}, + {"z", nlohmann::json::array({"string in array"})} + }; +} + +static void printResult(const Result& res, const char* label) { + if (res) { + std::cout << res.value().at("result").get() << "\n"; + } else { + try { res.value(); } + catch (const std::exception& e) { std::cerr << label << " failed: " << e.what() << "\n"; } + catch (...) { std::cerr << label << " failed (unknown)\n"; } + } +} + +int runIntegration(Client& client) { + try { + // ===== FOO_RESPONSES (5) ===== + printResult(client.call("GET", "/v1/mock/tests/foo", {}, fooParams()), "GET /foo"); + printResult(client.call("POST", "/v1/mock/tests/foo", {}, fooParams()), "POST /foo"); + printResult(client.call("PUT", "/v1/mock/tests/foo", {}, fooParams()), "PUT /foo"); + printResult(client.call("PATCH", "/v1/mock/tests/foo", {}, fooParams()), "PATCH /foo"); + printResult(client.call("DELETE", "/v1/mock/tests/foo", {}, fooParams()), "DELETE /foo"); + + // ===== BAR_RESPONSES (5) ===== + printResult(client.call("GET", "/v1/mock/tests/bar", {}, barParams()), "GET /bar"); + printResult(client.call("POST", "/v1/mock/tests/bar", {}, barParams()), "POST /bar"); + printResult(client.call("PUT", "/v1/mock/tests/bar", {}, barParams()), "PUT /bar"); + printResult(client.call("PATCH", "/v1/mock/tests/bar", {}, barParams()), "PATCH /bar"); + printResult(client.call("DELETE", "/v1/mock/tests/bar", {}, barParams()), "DELETE /bar"); + + // ===== GENERAL_RESPONSES (1) ===== + printResult(client.call("GET", "/v1/mock/tests/general/redirect", {}, {}), "GET /redirect"); + + // ===== UPLOAD_RESPONSES (4) ===== + nlohmann::json upload_pms = { + {"x", "string"}, + {"y", 123}, + {"z", nlohmann::json::array({"string in array"})} + }; + + static const char* resource_dir = []() { + const char* d = std::getenv("APPWRITE_RESOURCE_DIR"); + return d ? d : "tests/resources"; + }(); + + for (int i = 0; i < 2; ++i) { + auto f = InputFile::fromPath(std::string(resource_dir) + "/file.png"); + printResult( + client.fileUpload( + "POST", "/v1/mock/tests/general/upload", "file", + std::move(f), {}, upload_pms, nullptr), + "small upload"); + } + for (int i = 0; i < 2; ++i) { + auto f = InputFile::fromPath(std::string(resource_dir) + "/large_file.mp4"); + printResult( + client.fileUpload( + "POST", "/v1/mock/tests/general/upload", "file", + std::move(f), {}, upload_pms, nullptr), + "large upload"); + } + + // ===== DOWNLOAD_RESPONSES (1) ===== + auto dl = client.callBytes("GET", "/v1/mock/tests/general/download", {}, {}); + if (dl) { + const auto& bytes = dl.value().data(); + std::cout << std::string(bytes.begin(), bytes.end()) << "\n"; + } + + // ===== EXCEPTION_RESPONSES (7) ===== + { + auto res = client.call("GET", "/v1/mock/tests/general/400-error", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + std::cout << e.response() << "\n"; + } + } + } + { + auto res = client.call("GET", "/v1/mock/tests/general/500-error", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + std::cout << e.response() << "\n"; + } + } + } + { + auto res = client.call("GET", "/v1/mock/tests/general/502-error", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + std::cout << e.response() << "\n"; + } + } + } + + { + try { + Client badClient; + auto res = badClient.setProject("123456") + .setEndpoint("htp://cloud.appwrite.io/v1") + .call("GET", "/v1/mock/tests/foo", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + } + } + } catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + } catch (const std::exception& e) { + std::cout << e.what() << "\n"; + } + } + + return 0; + } catch (const std::exception& ex) { + std::cerr << "Fatal integration error: " << ex.what() << "\n"; + return 1; + } +} +#endif diff --git a/examples/cpp/tests/model_tests.cpp b/examples/cpp/tests/model_tests.cpp new file mode 100755 index 0000000000..cc2ca704df --- /dev/null +++ b/examples/cpp/tests/model_tests.cpp @@ -0,0 +1,1687 @@ +#include +#include +#include "appwrite/models.hpp" + +TEST(RowListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "rows": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::RowList model; + try { + model = appwrite::models::RowList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::RowList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(DocumentListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "documents": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::DocumentList model; + try { + model = appwrite::models::DocumentList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::DocumentList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TableListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "tables": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::TableList model; + try { + model = appwrite::models::TableList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::TableList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(CollectionListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "collections": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::CollectionList model; + try { + model = appwrite::models::CollectionList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::CollectionList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(DatabaseListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "databases": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::DatabaseList model; + try { + model = appwrite::models::DatabaseList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::DatabaseList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(IndexListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "indexes": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::IndexList model; + try { + model = appwrite::models::IndexList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::IndexList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnIndexListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "indexes": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnIndexList model; + try { + model = appwrite::models::ColumnIndexList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnIndexList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(UserListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "users": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::UserList model; + try { + model = appwrite::models::UserList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::UserList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(SessionListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "sessions": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::SessionList model; + try { + model = appwrite::models::SessionList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::SessionList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(IdentityListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "identities": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::IdentityList model; + try { + model = appwrite::models::IdentityList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::IdentityList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(LogListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "logs": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::LogList model; + try { + model = appwrite::models::LogList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::LogList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(FileListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "files": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::FileList model; + try { + model = appwrite::models::FileList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::FileList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(BucketListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "buckets": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::BucketList model; + try { + model = appwrite::models::BucketList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::BucketList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TeamListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "teams": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::TeamList model; + try { + model = appwrite::models::TeamList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::TeamList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(MembershipListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "memberships": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::MembershipList model; + try { + model = appwrite::models::MembershipList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::MembershipList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(FunctionListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "functions": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::FunctionList model; + try { + model = appwrite::models::FunctionList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::FunctionList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(RuntimeListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "runtimes": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::RuntimeList model; + try { + model = appwrite::models::RuntimeList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::RuntimeList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(DeploymentListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "deployments": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::DeploymentList model; + try { + model = appwrite::models::DeploymentList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::DeploymentList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ExecutionListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "executions": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ExecutionList model; + try { + model = appwrite::models::ExecutionList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ExecutionList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(WebhookListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "webhooks": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::WebhookList model; + try { + model = appwrite::models::WebhookList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::WebhookList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(VariableListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "variables": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::VariableList model; + try { + model = appwrite::models::VariableList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::VariableList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TargetListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "targets": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::TargetList model; + try { + model = appwrite::models::TargetList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::TargetList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TransactionListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "transactions": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::TransactionList model; + try { + model = appwrite::models::TransactionList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::TransactionList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(SpecificationListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "specifications": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::SpecificationList model; + try { + model = appwrite::models::SpecificationList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::SpecificationList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(DatabaseTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "name": "My Database", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "enabled": false, "type": "legacy", "policies": [{}], "archives": [{}] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Database model; + try { + model = appwrite::models::Database::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Database::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(CollectionTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "$permissions": ["read(\"any\")"], "databaseId": "5e5ea5c16897e", "name": "My Collection", "enabled": false, "documentSecurity": true, "attributes": [], "indexes": [{}], "bytesMax": 65535, "bytesUsed": 1500 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Collection model; + try { + model = appwrite::models::Collection::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Collection::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "attributes": [""] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeList model; + try { + model = appwrite::models::AttributeList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeStringTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "size": 128, "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeString model; + try { + model = appwrite::models::AttributeString::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeString::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeIntegerTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "count", "type": "integer", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "min": 1, "max": 10, "default": 10 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeInteger model; + try { + model = appwrite::models::AttributeInteger::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeInteger::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeFloatTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "percentageCompleted", "type": "double", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "min": 1.5, "max": 10.5, "default": 2.5 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeFloat model; + try { + model = appwrite::models::AttributeFloat::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeFloat::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeBooleanTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "isEnabled", "type": "boolean", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeBoolean model; + try { + model = appwrite::models::AttributeBoolean::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeBoolean::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeEmailTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "userEmail", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "email", "default": "default@example.com" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeEmail model; + try { + model = appwrite::models::AttributeEmail::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeEmail::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeEnumTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "status", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "elements": ["element"], "format": "enum", "default": "element" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeEnum model; + try { + model = appwrite::models::AttributeEnum::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeEnum::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeIpTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "ipAddress", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "ip", "default": "192.0.2.0" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeIp model; + try { + model = appwrite::models::AttributeIp::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeIp::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeUrlTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "githubUrl", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "url", "default": "http:\/\/example.com" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeUrl model; + try { + model = appwrite::models::AttributeUrl::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeUrl::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeDatetimeTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "birthDay", "type": "datetime", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "datetime", "default": "2020-10-15T06:38:00.000+00:00" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeDatetime model; + try { + model = appwrite::models::AttributeDatetime::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeDatetime::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeRelationshipTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "relatedCollection": "collection", "relationType": "oneToOne|oneToMany|manyToOne|manyToMany", "twoWay": false, "twoWayKey": "string", "onDelete": "restrict|cascade|setNull", "side": "parent|child" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeRelationship model; + try { + model = appwrite::models::AttributeRelationship::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeRelationship::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributePointTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": [0,0] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributePoint model; + try { + model = appwrite::models::AttributePoint::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributePoint::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeLineTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": [[0,0],[1,1]] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeLine model; + try { + model = appwrite::models::AttributeLine::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeLine::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributePolygonTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": [[[0,0],[0,10]],[[10,10],[0,0]]] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributePolygon model; + try { + model = appwrite::models::AttributePolygon::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributePolygon::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeVarcharTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "size": 128, "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeVarchar model; + try { + model = appwrite::models::AttributeVarchar::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeVarchar::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeTextTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeText model; + try { + model = appwrite::models::AttributeText::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeText::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeMediumtextTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeMediumtext model; + try { + model = appwrite::models::AttributeMediumtext::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeMediumtext::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AttributeLongtextTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AttributeLongtext model; + try { + model = appwrite::models::AttributeLongtext::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AttributeLongtext::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TableTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "$permissions": ["read(\"any\")"], "databaseId": "5e5ea5c16897e", "name": "My Table", "enabled": false, "rowSecurity": true, "columns": [], "indexes": [{}], "bytesMax": 65535, "bytesUsed": 1500 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Table model; + try { + model = appwrite::models::Table::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Table::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnListTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "total": 5, "columns": [""] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnList model; + try { + model = appwrite::models::ColumnList::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnList::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnStringTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "size": 128, "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnString model; + try { + model = appwrite::models::ColumnString::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnString::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnIntegerTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "count", "type": "integer", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "min": 1, "max": 10, "default": 10 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnInteger model; + try { + model = appwrite::models::ColumnInteger::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnInteger::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnFloatTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "percentageCompleted", "type": "double", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "min": 1.5, "max": 10.5, "default": 2.5 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnFloat model; + try { + model = appwrite::models::ColumnFloat::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnFloat::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnBooleanTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "isEnabled", "type": "boolean", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnBoolean model; + try { + model = appwrite::models::ColumnBoolean::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnBoolean::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnEmailTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "userEmail", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "email", "default": "default@example.com" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnEmail model; + try { + model = appwrite::models::ColumnEmail::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnEmail::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnEnumTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "status", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "elements": ["element"], "format": "enum", "default": "element" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnEnum model; + try { + model = appwrite::models::ColumnEnum::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnEnum::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnIpTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "ipAddress", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "ip", "default": "192.0.2.0" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnIp model; + try { + model = appwrite::models::ColumnIp::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnIp::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnUrlTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "githubUrl", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "url", "default": "https:\/\/example.com" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnUrl model; + try { + model = appwrite::models::ColumnUrl::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnUrl::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnDatetimeTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "birthDay", "type": "datetime", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "format": "datetime", "default": "2020-10-15T06:38:00.000+00:00" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnDatetime model; + try { + model = appwrite::models::ColumnDatetime::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnDatetime::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnRelationshipTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "relatedTable": "table", "relationType": "oneToOne|oneToMany|manyToOne|manyToMany", "twoWay": false, "twoWayKey": "string", "onDelete": "restrict|cascade|setNull", "side": "parent|child" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnRelationship model; + try { + model = appwrite::models::ColumnRelationship::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnRelationship::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnPointTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": [0,0] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnPoint model; + try { + model = appwrite::models::ColumnPoint::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnPoint::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnLineTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": [[0,0],[1,1]] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnLine model; + try { + model = appwrite::models::ColumnLine::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnLine::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnPolygonTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": [[[0,0],[0,10]],[[10,10],[0,0]]] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnPolygon model; + try { + model = appwrite::models::ColumnPolygon::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnPolygon::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnVarcharTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "size": 128, "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnVarchar model; + try { + model = appwrite::models::ColumnVarchar::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnVarchar::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnTextTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnText model; + try { + model = appwrite::models::ColumnText::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnText::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnMediumtextTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnMediumtext model; + try { + model = appwrite::models::ColumnMediumtext::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnMediumtext::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnLongtextTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "key": "fullName", "type": "string", "status": "available", "error": "string", "required": true, "array": false, "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "default": "default", "encrypt": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnLongtext model; + try { + model = appwrite::models::ColumnLongtext::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnLongtext::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(IndexTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "key": "index1", "type": "primary", "status": "available", "error": "string", "attributes": [], "lengths": [], "orders": [] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Index model; + try { + model = appwrite::models::Index::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Index::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ColumnIndexTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "key": "index1", "type": "primary", "status": "available", "error": "string", "columns": [], "lengths": [], "orders": [] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::ColumnIndex model; + try { + model = appwrite::models::ColumnIndex::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::ColumnIndex::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(RowTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$sequence": "1", "$tableId": "5e5ea5c15117e", "$databaseId": "5e5ea5c15117e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "$permissions": ["read(\"any\")"] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Row model; + try { + model = appwrite::models::Row::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Row::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(DocumentTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$sequence": "1", "$collectionId": "5e5ea5c15117e", "$databaseId": "5e5ea5c15117e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "$permissions": ["read(\"any\")"] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Document model; + try { + model = appwrite::models::Document::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Document::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(LogTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "event": "account.sessions.create", "userId": "610fc2f985ee0", "userEmail": "john@appwrite.io", "userName": "John Doe", "mode": "admin", "userType": "user", "ip": "127.0.0.1", "time": "2020-10-15T06:38:00.000+00:00", "osCode": "Mac", "osName": "Mac", "osVersion": "Mac", "clientType": "browser", "clientCode": "CM", "clientName": "Chrome Mobile iOS", "clientVersion": "84.0", "clientEngine": "WebKit", "clientEngineVersion": "605.1.15", "deviceName": "smartphone", "deviceBrand": "Google", "deviceModel": "Nexus 5", "countryCode": "US", "countryName": "United States" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Log model; + try { + model = appwrite::models::Log::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Log::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(UserTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "John Doe", "password": "$argon2id$v=19$m=2048,t=4,p=3$aUZjLnliVWRINmFNTWMudg$5S+x+7uA31xFnrHFT47yFwcJeaP0w92L\/4LdgrVRXxE", "hash": "argon2", "hashOptions": [], "registration": "2020-10-15T06:38:00.000+00:00", "status": true, "labels": ["vip"], "passwordUpdate": "2020-10-15T06:38:00.000+00:00", "email": "john@appwrite.io", "phone": "+4930901820", "emailVerification": true, "phoneVerification": true, "mfa": true, "prefs": {"theme":"pink","timezone":"UTC"}, "targets": [{}], "accessedAt": "2020-10-15T06:38:00.000+00:00", "impersonator": false, "impersonatorUserId": "5e5ea5c16897e" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::User model; + try { + model = appwrite::models::User::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::User::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AlgoMd5Test, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "type": "md5" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AlgoMd5 model; + try { + model = appwrite::models::AlgoMd5::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AlgoMd5::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AlgoShaTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "type": "sha" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AlgoSha model; + try { + model = appwrite::models::AlgoSha::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AlgoSha::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AlgoPhpassTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "type": "phpass" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AlgoPhpass model; + try { + model = appwrite::models::AlgoPhpass::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AlgoPhpass::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AlgoBcryptTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "type": "bcrypt" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AlgoBcrypt model; + try { + model = appwrite::models::AlgoBcrypt::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AlgoBcrypt::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AlgoScryptTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "type": "scrypt", "costCpu": 8, "costMemory": 14, "costParallel": 1, "length": 64 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AlgoScrypt model; + try { + model = appwrite::models::AlgoScrypt::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AlgoScrypt::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AlgoScryptModifiedTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "type": "scryptMod", "salt": "UxLMreBr6tYyjQ==", "saltSeparator": "Bw==", "signerKey": "XyEKE9RcTDeLEsL\/RjwPDBv\/RqDl8fb3gpYEOQaPihbxf1ZAtSOHCjuAAa7Q3oHpCYhXSN9tizHgVOwn6krflQ==" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AlgoScryptModified model; + try { + model = appwrite::models::AlgoScryptModified::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AlgoScryptModified::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(AlgoArgon2Test, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "type": "argon2", "memoryCost": 65536, "timeCost": 4, "threads": 3 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::AlgoArgon2 model; + try { + model = appwrite::models::AlgoArgon2::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::AlgoArgon2::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(PreferencesTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Preferences model; + try { + model = appwrite::models::Preferences::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Preferences::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(SessionTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "userId": "5e5bb8c16897e", "expire": "2020-10-15T06:38:00.000+00:00", "provider": "email", "providerUid": "user@example.com", "providerAccessToken": "MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", "providerAccessTokenExpiry": "2020-10-15T06:38:00.000+00:00", "providerRefreshToken": "MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", "ip": "127.0.0.1", "osCode": "Mac", "osName": "Mac", "osVersion": "Mac", "clientType": "browser", "clientCode": "CM", "clientName": "Chrome Mobile iOS", "clientVersion": "84.0", "clientEngine": "WebKit", "clientEngineVersion": "605.1.15", "deviceName": "smartphone", "deviceBrand": "Google", "deviceModel": "Nexus 5", "countryCode": "US", "countryName": "United States", "current": true, "factors": ["email"], "secret": "5e5bb8c16897e", "mfaUpdatedAt": "2020-10-15T06:38:00.000+00:00" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Session model; + try { + model = appwrite::models::Session::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Session::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(IdentityTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "userId": "5e5bb8c16897e", "provider": "email", "providerUid": "5e5bb8c16897e", "providerEmail": "user@example.com", "providerAccessToken": "MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", "providerAccessTokenExpiry": "2020-10-15T06:38:00.000+00:00", "providerRefreshToken": "MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Identity model; + try { + model = appwrite::models::Identity::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Identity::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TokenTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "bb8ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "userId": "5e5ea5c168bb8", "secret": "", "expire": "2020-10-15T06:38:00.000+00:00", "phrase": "Golden Fox" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Token model; + try { + model = appwrite::models::Token::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Token::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(JwtTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Jwt model; + try { + model = appwrite::models::Jwt::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Jwt::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(FileTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "bucketId": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "$permissions": ["read(\"any\")"], "name": "Pink.png", "signature": "5d529fd02b544198ae075bd57c1762bb", "mimeType": "image\/png", "sizeOriginal": 17890, "chunksTotal": 17890, "chunksUploaded": 17890, "encryption": true, "compression": "gzip" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::File model; + try { + model = appwrite::models::File::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::File::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(BucketTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "$permissions": ["read(\"any\")"], "fileSecurity": true, "name": "Documents", "enabled": false, "maximumFileSize": 100, "allowedFileExtensions": ["jpg","png"], "compression": "gzip", "encryption": false, "antivirus": false, "transformations": false, "totalSize": 128 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Bucket model; + try { + model = appwrite::models::Bucket::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Bucket::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TeamTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "VIP", "total": 7, "prefs": {"theme":"pink","timezone":"UTC"} })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Team model; + try { + model = appwrite::models::Team::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Team::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(MembershipTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "userId": "5e5ea5c16897e", "userName": "John Doe", "userEmail": "john@appwrite.io", "teamId": "5e5ea5c16897e", "teamName": "VIP", "invited": "2020-10-15T06:38:00.000+00:00", "joined": "2020-10-15T06:38:00.000+00:00", "confirm": false, "mfa": false, "roles": ["owner"] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Membership model; + try { + model = appwrite::models::Membership::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Membership::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(FunctionTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "execute": ["users"], "name": "My Function", "enabled": false, "live": false, "logging": false, "runtime": "python-3.8", "deploymentRetention": 7, "deploymentId": "5e5ea5c16897e", "deploymentCreatedAt": "2020-10-15T06:38:00.000+00:00", "latestDeploymentId": "5e5ea5c16897e", "latestDeploymentCreatedAt": "2020-10-15T06:38:00.000+00:00", "latestDeploymentStatus": "ready", "scopes": ["users.read"], "vars": [{}], "events": ["account.create"], "schedule": "5 4 * * *", "timeout": 300, "entrypoint": "index.js", "commands": "npm install", "version": "v2", "installationId": "6m40at4ejk5h2u9s1hboo", "providerRepositoryId": "appwrite", "providerBranch": "main", "providerRootDirectory": "functions\/helloWorld", "providerSilentMode": false, "buildSpecification": "s-1vcpu-512mb", "runtimeSpecification": "s-1vcpu-512mb" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Function model; + try { + model = appwrite::models::Function::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Function::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(RuntimeTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "python-3.8", "key": "python", "name": "Python", "version": "3.8", "base": "python:3.8-alpine", "image": "appwrite\\\/runtime-for-python:3.8", "logo": "python.png", "supports": ["amd64"] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Runtime model; + try { + model = appwrite::models::Runtime::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Runtime::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(DeploymentTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "type": "vcs", "resourceId": "5e5ea6g16897e", "resourceType": "functions", "entrypoint": "index.js", "sourceSize": 128, "buildSize": 128, "totalSize": 128, "buildId": "5e5ea5c16897e", "activate": true, "screenshotLight": "5e5ea5c16897e", "screenshotDark": "5e5ea5c16897e", "status": "ready", "buildLogs": "Compiling source files...", "buildDuration": 128, "providerRepositoryName": "database", "providerRepositoryOwner": "utopia", "providerRepositoryUrl": "https:\/\/github.com\/vermakhushboo\/g4-node-function", "providerCommitHash": "7c3f25d", "providerCommitAuthorUrl": "https:\/\/github.com\/vermakhushboo", "providerCommitAuthor": "Khushboo Verma", "providerCommitMessage": "Update index.js", "providerCommitUrl": "https:\/\/github.com\/vermakhushboo\/g4-node-function\/commit\/60c0416257a9cbcdd96b2d370c38d8f8d150ccfb", "providerBranch": "0.7.x", "providerBranchUrl": "https:\/\/github.com\/vermakhushboo\/appwrite\/tree\/0.7.x" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Deployment model; + try { + model = appwrite::models::Deployment::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Deployment::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(ExecutionTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "$permissions": ["any"], "functionId": "5e5ea6g16897e", "deploymentId": "5e5ea5c16897e", "trigger": "http", "status": "processing", "requestMethod": "GET", "requestPath": "\/articles?id=5", "requestHeaders": [{}], "responseStatusCode": 200, "responseBody": "", "responseHeaders": [{}], "logs": "", "errors": "", "duration": 0.4, "scheduledAt": "2020-10-15T06:38:00.000+00:00" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Execution model; + try { + model = appwrite::models::Execution::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Execution::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(WebhookTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "My Webhook", "url": "https:\/\/example.com\/webhook", "events": ["databases.tables.update","databases.collections.update"], "tls": true, "authUsername": "username", "authPassword": "password", "secret": "ad3d581ca230e2b7059c545e5a", "enabled": true, "logs": "Failed to connect to remote server.", "attempts": 10 })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Webhook model; + try { + model = appwrite::models::Webhook::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Webhook::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(VariableTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "5e5ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "key": "API_KEY", "value": "myPa$$word1", "secret": false, "resourceType": "function", "resourceId": "myAwesomeFunction" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Variable model; + try { + model = appwrite::models::Variable::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Variable::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(HeadersTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "name": "Content-Type", "value": "application\/json" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Headers model; + try { + model = appwrite::models::Headers::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Headers::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(SpecificationTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "memory": 512, "cpus": 1, "enabled": true, "slug": "s-1vcpu-512mb" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Specification model; + try { + model = appwrite::models::Specification::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Specification::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(MfaChallengeTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "bb8ea5c16897e", "$createdAt": "2020-10-15T06:38:00.000+00:00", "userId": "5e5ea5c168bb8", "expire": "2020-10-15T06:38:00.000+00:00" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::MfaChallenge model; + try { + model = appwrite::models::MfaChallenge::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::MfaChallenge::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(MfaRecoveryCodesTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "recoveryCodes": ["a3kf0-s0cl2","s0co1-as98s"] })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::MfaRecoveryCodes model; + try { + model = appwrite::models::MfaRecoveryCodes::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::MfaRecoveryCodes::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(MfaTypeTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "secret": "[SHARED_SECRET]", "uri": "otpauth:\/\/totp\/appwrite:user@example.com?secret=[SHARED_SECRET]&issuer=appwrite" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::MfaType model; + try { + model = appwrite::models::MfaType::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::MfaType::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(MfaFactorsTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "totp": true, "phone": true, "email": true, "recoveryCode": true })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::MfaFactors model; + try { + model = appwrite::models::MfaFactors::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::MfaFactors::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TransactionTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "259125845563242502", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "status": "pending", "operations": 5, "expiresAt": "2020-10-15T06:38:00.000+00:00" })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Transaction model; + try { + model = appwrite::models::Transaction::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Transaction::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +TEST(TargetTest, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ "$id": "259125845563242502", "$createdAt": "2020-10-15T06:38:00.000+00:00", "$updatedAt": "2020-10-15T06:38:00.000+00:00", "name": "Apple iPhone 12", "userId": "259125845563242502", "providerId": "259125845563242502", "providerType": "email", "identifier": "token", "expired": false })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::Target model; + try { + model = appwrite::models::Target::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::Target::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} diff --git a/examples/cpp/tests/tests.cpp b/examples/cpp/tests/tests.cpp new file mode 100755 index 0000000000..fc3e434db2 --- /dev/null +++ b/examples/cpp/tests/tests.cpp @@ -0,0 +1,38 @@ +#include +#include +#include + +using namespace appwrite; + +TEST(IDTest, UniqueID) { + // We expect a hex string, not literal "unique()" as ID::unique() generates it locally now + EXPECT_FALSE(ID::unique().str().empty()); + EXPECT_EQ(ID::custom("test").str(), "test"); +} + +TEST(PermissionTest, BasicPermissions) { + EXPECT_EQ(Permission::read(Role::any()), "read(\"any\")"); + EXPECT_EQ(Permission::write(Role::user("123")), "write(\"user:123\")"); +} + +TEST(QueryTest, Serialization) { + EXPECT_EQ(Query::equal("name", "John"), "{\"method\":\"equal\",\"attribute\":\"name\",\"values\":[\"John\"]}"); + EXPECT_EQ(Query::limit(25), "{\"method\":\"limit\",\"values\":[25]}"); + EXPECT_EQ(Query::orderRandom(), "{\"method\":\"orderRandom\"}"); +} + +TEST(QueryTest, NewMethods) { + EXPECT_EQ(Query::contains("tags", "a"), "{\"method\":\"contains\",\"attribute\":\"tags\",\"values\":[\"a\"]}"); + EXPECT_EQ(Query::regex("name", "^A"), "{\"method\":\"regex\",\"attribute\":\"name\",\"values\":[\"^A\"]}"); +} + +TEST(QueryTest, Geolocation) { + std::string q = Query::distanceEqual("location", 40.7, -74.0, 5000.0); + EXPECT_TRUE(q.find("distanceEqual") != std::string::npos); + EXPECT_TRUE(q.find("40.7") != std::string::npos); +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mock-server/Dockerfile b/mock-server/Dockerfile index a1c3ed8aac..52447c0abe 100644 --- a/mock-server/Dockerfile +++ b/mock-server/Dockerfile @@ -16,7 +16,7 @@ RUN composer install --ignore-platform-reqs --optimize-autoloader \ FROM phpswoole/swoole:5.1.2-php8.3-alpine as final -RUN apk add docker +RUN apk add docker curl ENV _APP_REDIS_HOST=redis \ _APP_REDIS_PORT=6379 diff --git a/src/SDK/Language/Cpp.php b/src/SDK/Language/Cpp.php new file mode 100644 index 0000000000..2cadd57523 --- /dev/null +++ b/src/SDK/Language/Cpp.php @@ -0,0 +1,979 @@ +escapeKeyword($this->toCamelCase($parameter['name'])); + if (!empty($parameter['enumValues']) || !empty($parameter['enumName'])) { + $pathParams[] = 'appwrite::enums::toString(' . $name . ')'; + } else { + $pathParams[] = $name; + } + } + + return 'std::string path_ = std::format("' . addslashes($pathFormat) . '"' . (empty($pathParams) ? '' : ', ' . implode(', ', $pathParams)) . ");"; + } + + /** + * @return string + */ + public function getName(): string + { + return 'C++'; + } + + /** + * Get Language Keywords List + * + * @return array + */ + public function getKeywords(): array + { + return [ + 'alignas', + 'alignof', + 'and', + 'and_eq', + 'asm', + 'atomic_cancel', + 'atomic_commit', + 'atomic_noexcept', + 'auto', + 'bitand', + 'bitor', + 'bool', + 'break', + 'case', + 'catch', + 'char', + 'char8_t', + 'char16_t', + 'char32_t', + 'class', + 'compl', + 'concept', + 'const', + 'consteval', + 'constexpr', + 'constinit', + 'const_cast', + 'continue', + 'co_await', + 'co_return', + 'co_yield', + 'decltype', + 'default', + 'delete', + 'do', + 'double', + 'dynamic_cast', + 'else', + 'enum', + 'explicit', + 'export', + 'extern', + 'false', + 'float', + 'for', + 'friend', + 'goto', + 'if', + 'inline', + 'int', + 'long', + 'mutable', + 'namespace', + 'new', + 'noexcept', + 'not', + 'not_eq', + 'nullptr', + 'operator', + 'or', + 'or_eq', + 'private', + 'protected', + 'public', + 'reflexpr', + 'register', + 'reinterpret_cast', + 'requires', + 'return', + 'short', + 'signed', + 'sizeof', + 'static', + 'static_assert', + 'static_cast', + 'struct', + 'switch', + 'template', + 'this', + 'thread_local', + 'throw', + 'try', + 'typedef', + 'typeid', + 'typename', + 'union', + 'unsigned', + 'using', + 'virtual', + 'void', + 'volatile', + 'wchar_t', + 'while', + 'xor', + 'xor_eq', + + // Context-sensitive - safe to add defensively + 'final', + 'override', + 'import', + 'module' + ]; + } + + /** + * @return array + */ + public function getIdentifierOverrides(): array + { + if ($this->identifierOverridesCache !== null) { + return $this->identifierOverridesCache; + } + + // Only truly special cases that need a specific name + $special = [ + 'default' => 'default_', + ]; + + // Auto-generate the rest from keywords list + $auto = []; + foreach ($this->getKeywords() as $keyword) { + if (!isset($special[$keyword])) { + $auto[$keyword] = $keyword . '_'; + } + } + + return $this->identifierOverridesCache = array_merge($auto, $special); + } + + public function escapeKeyword(string $value): string + { + $overrides = $this->getIdentifierOverrides(); + + if (isset($overrides[$value])) { + return $overrides[$value]; + } + + // Safety net: name wasn't in overrides but IS a keyword + if (in_array($value, $this->getKeywords(), true)) { + return $value . '_'; + } + + return $value; + } + + /** + * @return array + */ + public function getFiles(): array + { + return [ + [ + 'scope' => 'default', + 'destination' => 'CMakeLists.txt', + 'template' => 'cpp/CMakeLists.txt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'README.md', + 'template' => 'cpp/README.md.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'include/appwrite/client.hpp', + 'template' => 'cpp/include/client.hpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'include/appwrite/base.hpp', + 'template' => 'cpp/include/base.hpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'include/appwrite/core.hpp', + 'template' => 'cpp/include/core.hpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'include/appwrite/models.hpp', + 'template' => 'cpp/include/models.hpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'include/appwrite/services.hpp', + 'template' => 'cpp/include/services.hpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'include/appwrite/appwrite.hpp', + 'template' => 'cpp/include/appwrite.hpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'tests/tests.cpp', + 'template' => 'cpp/tests/tests_main.cpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'tests/model_tests.cpp', + 'template' => 'cpp/tests/model_test.cpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'tests/integration.cpp', + 'template' => 'cpp/tests/integration.cpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'tests/integration_logic.cpp', + 'template' => 'cpp/tests/integration_logic.cpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'include/appwrite/enums/enums.hpp', + 'template' => 'cpp/include/enums/enums.hpp.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'CHANGELOG.md', + 'template' => 'cpp/CHANGELOG.md.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'LICENSE', + 'template' => 'cpp/LICENSE.twig', + ], + [ + 'scope' => 'copy', + 'destination' => '.github/workflows/stale.yml', + 'template' => 'cpp/.github/workflows/stale.yml', + ], + [ + 'scope' => 'copy', + 'destination' => '.github/workflows/autoclose.yml', + 'template' => 'cpp/.github/workflows/autoclose.yml', + ], + [ + 'scope' => 'default', + 'destination' => '.github/workflows/publish.yml', + 'template' => 'cpp/.github/workflows/publish.yml.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'examples/basic_usage.cpp', + 'template' => 'cpp/examples/basic_usage.cpp.twig', + ], + ]; + } + + /** + * @param array $parameter + * @param array $spec + * @return string + */ + public function getTypeName(array $parameter, array $spec = []): string + { + return $this->getTypeNameInternal($parameter); + } + + /** + * @param array $parameter + * @return string + */ + private function getTypeNameInternal(array $parameter): string + { + $isArray = (($parameter['type'] ?? null) === self::TYPE_ARRAY); + $baseType = ''; + + if (!$isArray && isset($parameter['enumName'])) { + $baseType = 'appwrite::enums::' . $this->toPascalCase($parameter['enumName']); + } elseif ($isArray && isset($parameter['enumName'])) { + $baseType = 'std::vectortoPascalCase($parameter['enumName']) . '>'; + } else { + if (isset($parameter['items'])) { + $parameter['array'] = $parameter['items']; + } + + $baseType = match ($parameter['type']) { + self::TYPE_INTEGER => 'int64_t', + self::TYPE_NUMBER => 'double', + self::TYPE_FILE => 'appwrite::InputFile', + self::TYPE_STRING => 'std::string', + self::TYPE_BOOLEAN => 'bool', + self::TYPE_OBJECT => 'nlohmann::json', + self::TYPE_ARRAY => isset($parameter['array']['model']) + ? 'std::vectortoPascalCase($parameter['array']['model']) . '>' + : (!empty(($parameter['array'] ?? [])['type']) && !\is_array($parameter['array']['type']) + ? 'std::vector<' . $this->getTypeNameInternal($parameter['array']) . '>' + : 'std::vector'), + default => isset($parameter['model']) + ? 'appwrite::models::' . $this->toPascalCase($parameter['model']) + : $parameter['type'], + }; + } + + if (!($parameter['required'] ?? true) && $baseType !== 'appwrite::InputFile') { + return 'std::optional<' . $baseType . '>'; + } + + return $baseType; + } + + /** + * @param array $parameter + * @return string + */ + private function getInputTypeInternal(array $parameter): string + { + return $this->toInputType($this->getTypeNameInternal($parameter)); + } + + /** + * @param string $type + * @return string + */ + protected function toInputType(string $type): string + { + // 1. Base case: std::string -> std::string_view + if ($type === 'std::string') { + return 'std::string_view'; + } + + if ($type === 'nlohmann::json') { + return 'const nlohmann::json&'; + } + + // 2. Recursive Case: std::optional -> std::optional + if (str_starts_with($type, 'std::optional<') && str_ends_with($type, '>')) { + $inner = substr($type, 14, -1); + $innerMapped = ($inner === 'nlohmann::json') ? 'nlohmann::json' : $this->toInputType($inner); + return 'std::optional<' . $innerMapped . '>'; + } + + // 3. Recursive Case: std::vector -> std::vector (keep std::string, don't recurse to string_view) + if (str_starts_with($type, 'std::vector<') && str_ends_with($type, '>')) { + $inner = substr($type, 12, -1); + // Keep std::string (not std::string_view) inside vectors: brace-init from literals must work + $innerMapped = ($inner === 'nlohmann::json') ? 'nlohmann::json' : $inner; + return 'std::vector<' . $innerMapped . '>'; + } + + return $type; + } + + private function getReturnTypeInternal(array $method, array $spec, string $namespace = 'appwrite', bool $async = false): string + { + $raw = $this->getRawReturnTypeInternal($method, $spec, $namespace); + $result = $namespace . '::Result<' . $raw . '>'; + + return $async ? $namespace . '::Task<' . $result . '>' : $result; + } + + private function getRawReturnTypeInternal(array $method, array $spec, string $namespace = 'appwrite'): string + { + if ($method['type'] === 'webAuth') { + return 'std::string'; + } + if ($method['type'] === 'location') { + return $namespace . '::BinaryResponse'; + } + + if (isset($method['responseModels']) && count($method['responseModels']) > 1) { + return 'nlohmann::json'; + } + + $isEmpty = empty($method['produces']) || + (isset($method['responses']) && $this->isEmptyResponse($method['responses'])); + + if (empty($method['responseModel']) || $method['responseModel'] === 'any') { + return $isEmpty ? 'void' : 'nlohmann::json'; + } + + return $namespace . '::models::' . $this->toPascalCase($method['responseModel']); + } + + /** + * @return string + */ + public function getStaticAccessOperator(): string + { + return '::'; + } + + /** + * @return string + */ + public function getStringQuote(): string + { + return '"'; + } + + /** + * @param string $elements Comma-separated elements + * @return string + */ + public function getArrayOf(string $elements): string + { + return 'std::vector{' . $elements . '}'; + } + + /** + * @param array $parameter + * @return string + */ + public function getParamDefault(array $parameter): string + { + return $this->getParamDefaultInternal($parameter); + } + + /** + * @param array $parameter + * @return string + */ + private function getParamDefaultInternal(array $parameter): string + { + $type = $parameter['type'] ?? ''; + $default = $parameter['default'] ?? null; + $required = $parameter['required'] ?? true; + + if (!$required && $default === null) { + return ' = std::nullopt'; + } + + if ($default === null) { + return ''; + } + + $output = ' = '; + + if (isset($parameter['enumValues']) && !empty($parameter['enumValues'])) { + if (!$required && ($default === null || $default === '')) { + return ' = std::nullopt'; + } + + $enumValues = $parameter['enumValues']; + $enumKeys = $parameter['enumKeys'] ?? []; + $enumName = $this->toPascalCase($parameter['enumName'] ?? $parameter['name'] ?? ''); + + $resolveKey = function ($value) use ($enumValues, $enumKeys) { + $index = array_search($value, $enumValues, true); + if ($index !== false && isset($enumKeys[$index]) && $enumKeys[$index] !== '') { + return $this->toUpperSnakeCase($enumKeys[$index]); + } + if ($index !== false && isset($enumValues[$index])) { + return $this->toUpperSnakeCase($enumValues[$index]); + } + $fallback = $enumKeys[0] ?? $enumValues[0] ?? $value; + return $this->toUpperSnakeCase((string) $fallback); + }; + + if ($type === self::TYPE_ARRAY) { + $values = []; + if (\is_string($default) && $default !== '') { + $decoded = json_decode($default, true); + if (\is_array($decoded)) { + $values = $decoded; + } + } elseif (\is_array($default)) { + $values = $default; + } + + if (empty($values)) { + // return empty vector for array array initialization without default + return $output . '{}'; + } + + $items = array_map(function ($value) use ($enumName, $resolveKey) { + return 'appwrite::enums::' . $enumName . '::' . $resolveKey($value); + }, $values); + + return $output . '{ ' . implode(', ', $items) . ' }'; + } + + $value = ($default !== null && $default !== '') ? $default : $enumValues[0]; + return $output . 'appwrite::enums::' . $enumName . '::' . $resolveKey($value); + } + + switch ($type) { + case self::TYPE_NUMBER: + case self::TYPE_INTEGER: + $output .= (is_numeric($default)) ? $default : '0'; + break; + case self::TYPE_BOOLEAN: + if (is_bool($default)) { + $output .= $default ? 'true' : 'false'; + } else { + $output .= ($default === 'true' || $default === '1') ? 'true' : 'false'; + } + break; + case self::TYPE_STRING: + if (!$required && $default === '') { + return ' = std::nullopt'; + } + $output .= '"' . addslashes((string) $default) . '"'; + break; + case self::TYPE_OBJECT: + if ($default === '' || $default === '[]' || $default === '{}') { + $output .= 'nlohmann::json::object()'; + } else { + $output .= 'nlohmann::json::parse("' . addslashes(is_string($default) ? $default : json_encode($default)) . '")'; + } + break; + case self::TYPE_ARRAY: + // Determine correct vector type to avoid brace-init mismatch + $innerItemType = $parameter['array']['type'] ?? self::TYPE_STRING; + $isModel = isset($parameter['array']['model']); + $vecType = 'std::vector'; + if ($innerItemType === self::TYPE_OBJECT || $isModel) { + $vecType = 'std::vector'; + } elseif ($innerItemType === self::TYPE_INTEGER) { + $vecType = 'std::vector'; + } + + if ($default === '' || $default === '[]') { + $output .= $vecType . '{}'; + } else { + $decoded = is_string($default) ? json_decode($default, true) : $default; + if (is_array($decoded)) { + $items = array_map(function ($v) { + if (is_bool($v)) { + return $v ? 'true' : 'false'; + } + if (is_numeric($v)) { + return (string)$v; + } + return '"' . addslashes((string) $v) . '"'; + }, $decoded); + $output .= $vecType . '{' . implode(', ', $items) . '}'; + } else { + $output .= $vecType . '{}'; + } + } + break; + case self::TYPE_FILE: + $output .= 'appwrite::InputFile()'; + break; + } + + return $output; + } + + /** + * @param array $param + * @param string $lang + * @return string + */ + public function getParamExample(array $param, string $lang = ''): string + { + $type = $param['type'] ?? ''; + $example = $param['example'] ?? ''; + + $output = ''; + + switch ($type) { + case self::TYPE_NUMBER: + case self::TYPE_INTEGER: + $output .= ($example === '') ? '0' : $example; + break; + case self::TYPE_BOOLEAN: + if ($example === '') { + $output .= 'false'; + } elseif (is_bool($example)) { + $output .= $example ? 'true' : 'false'; + } else { + $output .= ($example === 'true' || $example === '1') ? 'true' : 'false'; + } + break; + case self::TYPE_STRING: + $output .= ($example === '') ? '""' : '"' . addslashes((string) $example) . '"'; + break; + case self::TYPE_OBJECT: + if ($example === '') { + $output .= '{}'; + } else { + $parsed = is_string($example) ? json_decode($example) : $example; + if ($parsed !== null || json_last_error() === JSON_ERROR_NONE) { + $output .= 'nlohmann::json::parse("' . addslashes(is_string($example) ? $example : json_encode($example)) . '")'; + } else { + $output .= 'nlohmann::json::object()'; + } + } + break; + case self::TYPE_ARRAY: + if ($example === '' || $example === '[]') { + $output .= '{}'; + } else { + $decoded = is_string($example) ? json_decode($example, true) : $example; + if (is_array($decoded)) { + $items = array_map(function ($v) { + if (is_bool($v)) { + return $v ? 'true' : 'false'; + } + if (is_numeric($v)) { + return $v; + } + return '"' . addslashes((string) $v) . '"'; + }, $decoded); + $output .= '{' . implode(', ', $items) . '}'; + } else { + $output .= '{}'; + } + } + break; + case self::TYPE_FILE: + $output .= 'appwrite::InputFile::fromPath("file.png")'; + break; + } + + return $output; + } + + /** + * @return array + */ + public function getFilters(): array + { + return [ + new TwigFilter('cppdocComment', function (array $method, array $spec, int $indent = 0) { + $indentStr = str_repeat(' ', $indent); + $result = $indentStr . "/**\n"; + + // Description + $description = wordwrap(trim($method['description'] ?? $method['title'] ?? ''), 75, "\n" . $indentStr . " * "); + $result .= $indentStr . " * " . $description . "\n"; + $result .= $indentStr . " *\n"; + + // Parameters + foreach ($method['parameters']['all'] ?? [] as $parameter) { + $name = $this->escapeKeyword($this->toCamelCase($parameter['name'])); + $desc = trim($parameter['description'] ?? ''); + $result .= $indentStr . " * @param " . $name . " " . $desc . "\n"; + } + + // Return type + $returnType = $this->getReturnTypeInternal($method, $spec); + $result .= $indentStr . " * @return " . $returnType . "\n"; + + $result .= $indentStr . " */"; + return $result; + }, ['is_safe' => ['html']]), + new TwigFilter('casePascal', function (string $value) { + return $this->toPascalCase($value); + }), + new TwigFilter('propertyType', function (array $property, array $spec = []) { + return $this->getPropertyType($property, $spec); + }), + new TwigFilter('caseUpperSnakeCase', function (string $value) { + return $this->toUpperSnakeCase($value); + }), + new TwigFilter('inputType', function (array $property, array $spec = []) { + return $this->getInputTypeInternal($property); + }), + + new TwigFilter('nodiscardDoc', function ($value) { + return '[[nodiscard]] ' . $value; + }), + new TwigFilter('returnType', function (array $method, array $spec, string $namespace = 'appwrite', bool $async = false) { + return $this->getReturnTypeInternal($method, $spec, $namespace, $async); + }), + new TwigFilter('rawReturnType', function (array $method, array $spec, string $namespace = 'appwrite') { + return $this->getRawReturnTypeInternal($method, $spec, $namespace); + }), + new TwigFilter('pathFormattingBlock', function (array $method) { + return $this->buildPathLine($method); + }), + new TwigFilter('parameterBuildingBlock', function (array $method, array $spec) { + $output = $this->buildPathLine($method) . "\n\n"; + + $output .= "nlohmann::json params = nlohmann::json::object();\n"; + foreach ($method['parameters']['query'] ?? [] as $parameter) { + $name = $this->escapeKeyword($this->toCamelCase($parameter['name'])); + // Only plain strings need the std::string() cast; enums are already typed + $isPlainStr = ($parameter['type'] ?? '') === self::TYPE_STRING + && empty($parameter['enumValues']); + if (!($parameter['required'] ?? true)) { + $output .= 'if (' . $name . '.has_value()) {' . "\n"; + if ($isPlainStr) { + $val = 'std::string(' . $name . '.value())'; + } else { + $val = '*' . $name; + } + $output .= ' params["' . $parameter['name'] . '"] = ' . $val . ";\n"; + $output .= "}\n"; + } else { + $val = $isPlainStr ? 'std::string(' . $name . ')' : $name; + $output .= 'params["' . $parameter['name'] . '"] = ' . $val . ";\n"; + } + } + + foreach ($method['parameters']['body'] ?? [] as $parameter) { + $name = $this->escapeKeyword($this->toCamelCase($parameter['name'])); + $isOptional = !($parameter['required'] ?? true); + $indent = $isOptional ? ' ' : ''; + if ($isOptional) { + $output .= 'if (' . $name . '.has_value()) {' . "\n"; + } + + if ($parameter['type'] === 'file') { + if ($method['type'] !== 'upload') { + $output .= $indent . 'params["' . $parameter['name'] . '"] = ' . ($isOptional ? '*' . $name : $name) . ".toJson();\n"; + } + } else { + // Only plain strings need std::string() cast; enums are C++ enum class types + $isPlainStr = ($parameter['type'] ?? '') === self::TYPE_STRING + && empty($parameter['enumValues']); + if ($isOptional) { + $val = $isPlainStr ? 'std::string(' . $name . '.value())' : '*' . $name; + } else { + $val = $isPlainStr ? 'std::string(' . $name . ')' : $name; + } + $output .= $indent . 'params["' . $parameter['name'] . '"] = ' . $val . ";\n"; + } + + if ($isOptional) { + $output .= "}\n"; + } + } + + $output .= "\nstd::unordered_map local_headers_;\n"; + foreach ($method['parameters']['header'] ?? [] as $parameter) { + $name = $this->escapeKeyword($this->toCamelCase($parameter['name'])); + if (!($parameter['required'] ?? true)) { + $output .= 'if (' . $name . '.has_value()) {' . "\n"; + $output .= ' local_headers_["' . $parameter['name'] . '"] = *' . $name . ";\n"; + $output .= "}\n"; + } else { + $output .= 'local_headers_["' . $parameter['name'] . '"] = ' . $name . ";\n"; + } + } + + return $output; + }), + new TwigFilter('parameterDispatchBlock', function (array $method, array $spec) { + return $this->getDispatchBlock($method, $spec, false); + }), + new TwigFilter('parameterDispatchAsyncBlock', function (array $method, array $spec) { + return $this->getDispatchBlock($method, $spec, true); + }), + new TwigFilter('exampleJson', function (array $property) { + $type = $property['type'] ?? ''; + $example = $property['example'] ?? null; + $subSchema = $property['sub_schema'] ?? null; + + if ($example !== null) { + if ($type === self::TYPE_ARRAY) { + // Already a JSON array string + if (is_string($example) && str_starts_with(ltrim($example), '[')) { + return $example; + } + // If the array element type is a sub_schema (object), emit [{}] instead + if ($subSchema !== null) { + return '[{}]'; + } + // Wrap scalar / non-array example into a JSON array + if (is_array($example)) { + return json_encode($example); + } + return '[' . json_encode($example) . ']'; + } + if ($type === self::TYPE_OBJECT) { + if (is_string($example) && str_starts_with(ltrim($example), '{')) { + return $example; + } + if (is_array($example)) { + return json_encode($example); + } + return '{}'; + } + return json_encode($example); + } + + switch ($type) { + case self::TYPE_INTEGER: + case self::TYPE_NUMBER: + return "0"; + case self::TYPE_BOOLEAN: + return "false"; + case self::TYPE_STRING: + return '""'; + case self::TYPE_ARRAY: + // For arrays of sub_schema objects, emit minimal object array + return $subSchema !== null ? '[{}]' : '[]'; + case self::TYPE_OBJECT: + return "{}"; + default: + return "null"; + } + }, ['is_safe' => ['html']]), + + + new TwigFilter('indent', function ($value, $count = 4) { + return str_repeat(' ', $count) . str_replace("\n", "\n" . str_repeat(' ', $count), $value); + }), + new TwigFilter('enumName', function (array $property) { + if (isset($property['enumName']) && $property['enumName'] !== '') { + return $this->toPascalCase($property['enumName']); + } + return null; + }), + + new TwigFilter('topoSort', function (array $definitions) { + // Build a map from definition name -> definition + $byName = []; + foreach ($definitions as $def) { + $name = $def['name'] ?? ''; + if ($name !== '') { + $byName[$name] = $def; + } + } + + // Kahn's algorithm: compute dependencies + $deps = []; // name -> set of names this depends on + foreach ($byName as $name => $def) { + $deps[$name] = []; + foreach ($def['properties'] ?? [] as $prop) { + $sub = $prop['sub_schema'] ?? null; + if ($sub !== null && isset($byName[$sub]) && $sub !== $name) { + $deps[$name][$sub] = true; + } + } + } + + // Topological sort (DFS post-order) + $visited = []; + $sorted = []; + + $visit = null; + $visit = function (string $name) use (&$visit, &$visited, &$sorted, &$deps, &$byName) { + if (isset($visited[$name])) { + return; + } + $visited[$name] = true; + foreach (array_keys($deps[$name] ?? []) as $dep) { + $visit($dep); + } + if (isset($byName[$name])) { + $sorted[] = $byName[$name]; + } + }; + + foreach (array_keys($byName) as $name) { + $visit($name); + } + + return $sorted; + }), + ]; + } + + /** + * @param array $method + * @param array $spec + * @param bool $async + * @return string + */ + protected function getDispatchBlock(array $method, array $spec, bool $async): string + { + $verb = strtoupper($method['method']); + $suffix = $async ? 'Async' : ''; + $inner = $this->getRawReturnTypeInternal($method, $spec); + + if ($method['type'] === 'upload') { + $fileKey = ''; + $fileParam = ''; + foreach ($method['parameters']['all'] ?? [] as $p) { + if (($p['type'] ?? '') === 'file') { + $fileKey = $p['name']; + $fileParam = $this->escapeKeyword($this->toCamelCase($p['name'])); + break; + } + } + if ($fileParam === '') { + throw new \Exception("Upload method '{$method['name']}' has no file parameter."); + } + $progress = ', std::move(onProgress)'; + return "return client_.fileUpload{$suffix}<{$inner}>(\"{$verb}\", path_, \"{$fileKey}\", std::move({$fileParam}), std::move(local_headers_), std::move(params){$progress});"; + } + + if ($method['type'] === 'webAuth') { + return "return client_.callLocation{$suffix}(\"{$verb}\", path_, std::move(local_headers_), std::move(params));"; + } + if ($method['type'] === 'location') { + return "return client_.callBytes{$suffix}(\"{$verb}\", path_, std::move(local_headers_), std::move(params));"; + } + if ($inner === 'void') { + return "return client_.callVoid{$suffix}(\"{$verb}\", path_, std::move(local_headers_), std::move(params));"; + } + + return "return client_.call{$suffix}<{$inner}>(\"{$verb}\", path_, std::move(local_headers_), std::move(params));"; + } + + /** + * @param array $property + * @param array $spec + * @return string + */ + protected function getPropertyType(array $property, array $spec): string + { + if (\array_key_exists('sub_schema', $property)) { + $type = 'appwrite::models::' . $this->toPascalCase($property['sub_schema']); + + if ($property['type'] === 'array') { + $type = 'std::vector<' . $type . '>'; + } + + if (!($property['required'] ?? true)) { + $type = 'std::optional<' . $type . '>'; + } + } else { + $type = $this->getTypeName($property, $spec); + } + + return $type; + } + + /** + * @param array $responses + * @return bool + */ + private function isEmptyResponse(array $responses): bool + { + foreach ($responses as $code => $response) { + if ((int) $code !== 204) { + return false; + } + } + return !empty($responses); + } +} diff --git a/templates/cpp/.github/workflows/autoclose.yml b/templates/cpp/.github/workflows/autoclose.yml new file mode 100755 index 0000000000..d9629e1667 --- /dev/null +++ b/templates/cpp/.github/workflows/autoclose.yml @@ -0,0 +1,12 @@ +name: Auto-close External Pull Requests + +on: + pull_request_target: + types: [opened, reopened] + +jobs: + auto_close: + if: github.head_ref != 'dev' + uses: appwrite/.github/.github/workflows/autoclose.yml@main + secrets: + GH_AUTO_CLOSE_PR_TOKEN: ${{ secrets.GH_AUTO_CLOSE_PR_TOKEN }} diff --git a/templates/cpp/.github/workflows/publish.yml.twig b/templates/cpp/.github/workflows/publish.yml.twig new file mode 100755 index 0000000000..94e4eb6093 --- /dev/null +++ b/templates/cpp/.github/workflows/publish.yml.twig @@ -0,0 +1,35 @@ +name: Publish Release + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + publish: + name: Tag and publish release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup C++ build environment + run: | + sudo apt-get update + sudo apt-get install -y build-essential cmake libcurl4-openssl-dev + + - name: Build and validate SDK + run: | + cmake -S . -B build -DAPPWRITE_BUILD_TESTS=ON + cmake --build build + ctest --test-dir build --output-on-failure + + - name: Create GitHub Release archive + run: | + git archive --format=tar.gz --prefix={{ sdk.gitRepoName }}/ HEAD \ + > {{ sdk.gitRepoName }}-{{ '${{ github.ref_name }}' }}.tar.gz + + - name: Upload release artifact + uses: softprops/action-gh-release@v2 + with: + files: {{ sdk.gitRepoName }}-{{ '${{ github.ref_name }}' }}.tar.gz diff --git a/templates/cpp/.github/workflows/stale.yml b/templates/cpp/.github/workflows/stale.yml new file mode 100755 index 0000000000..5888b6156f --- /dev/null +++ b/templates/cpp/.github/workflows/stale.yml @@ -0,0 +1,9 @@ +name: Mark stale issues + +on: + schedule: + - cron: "0 0 * * *" # Midnight Runtime + +jobs: + stale: + uses: appwrite/.github/.github/workflows/stale.yml@main diff --git a/templates/cpp/CHANGELOG.md.twig b/templates/cpp/CHANGELOG.md.twig new file mode 100755 index 0000000000..4df439ffb6 --- /dev/null +++ b/templates/cpp/CHANGELOG.md.twig @@ -0,0 +1,46 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [{{ sdk.version }}] - TBD + +### Added +- Initial release of {{ spec.title }} C++ SDK +- Full support for {{ spec.title }} API {{ spec.version }} +- Header-only library for easy integration +- Modern C++20 API with coroutine/async support via C++20 coroutines +- Built-in `Result` error handling (no exceptions required in calling code) +- File upload support with automatic chunking for large files +- Query builder (`Query::equal`, `Query::between`, geo queries, etc.) +- Permission and role management utilities +- ID generation utilities +- Comprehensive model structs with JSON serialization/deserialization +- Enum types for all API parameters +- Realtime event subscription support +- Self-signed certificate support +- Custom header support +- CMake FetchContent integration for zero-install setup + +### Services +{% for service in spec.services %} +#### {{ service.name | casePascal }} +{{ service.description }} +{% for method in service.methods %} +- `{{ method.name | caseCamel }}()` - {{ method.description }} +{% endfor %} + +{% endfor %} + +### Models +{% for definition in spec.definitions %} +- `{{ definition.name | casePascal }}` - {{ definition.description }} +{% endfor %} + +### Dependencies +- [cpr](https://github.com/libcpr/cpr) 1.10.5+ for HTTP client +- [nlohmann/json](https://github.com/nlohmann/json) 3.11.3+ for JSON serialization + +[{{ sdk.version }}]: https://github.com/{{ sdk.gitUserName }}/sdk-for-cpp/releases/tag/{{ sdk.version }} diff --git a/templates/cpp/CMakeLists.txt.twig b/templates/cpp/CMakeLists.txt.twig new file mode 100755 index 0000000000..2501863d26 --- /dev/null +++ b/templates/cpp/CMakeLists.txt.twig @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.14) + +project({{ sdk.name | caseSnake }} VERSION {{ sdk.version }}) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(FetchContent) + +find_package(cpr QUIET) +if(NOT cpr_FOUND) + set(CPR_USE_SYSTEM_CURL ON CACHE BOOL "" FORCE) + FetchContent_Declare(cpr + GIT_REPOSITORY https://github.com/libcpr/cpr.git + GIT_TAG 3b15fa82ea74739b574d705fea44959b58142eb8) # sync with CI Dockerfile + FetchContent_MakeAvailable(cpr) +endif() + +find_package(nlohmann_json QUIET) +if(NOT nlohmann_json_FOUND) + FetchContent_Declare(nlohmann_json + GIT_REPOSITORY https://github.com/nlohmann/json.git + GIT_TAG 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03) # sync with CI Dockerfile + FetchContent_MakeAvailable(nlohmann_json) +endif() + +# Compiler warnings +if(MSVC) + add_compile_options(/W4) +else() + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# Header-only library +add_library(${PROJECT_NAME} INTERFACE) +target_include_directories(${PROJECT_NAME} INTERFACE + $ + $ +) +target_link_libraries(${PROJECT_NAME} INTERFACE + cpr::cpr + nlohmann_json::nlohmann_json +) + +# Automated Tests +option(APPWRITE_BUILD_TESTS "Build automated tests" OFF) +option(APPWRITE_RUN_INTEGRATION "Run integration tests" OFF) +if(APPWRITE_BUILD_TESTS) + enable_testing() + find_package(GTest QUIET) + if(NOT GTest_FOUND) + FetchContent_Declare(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571) # sync with CI Dockerfile + FetchContent_MakeAvailable(googletest) + endif() + + add_executable(test_appwrite + tests/tests.cpp + tests/model_tests.cpp + ) + target_link_libraries(test_appwrite PRIVATE ${PROJECT_NAME} GTest::gtest) + + add_executable(integration_test + tests/integration.cpp + tests/integration_logic.cpp + ) + if(APPWRITE_RUN_INTEGRATION) + target_compile_definitions(integration_test PRIVATE APPWRITE_RUN_INTEGRATION) + endif() + target_link_libraries(integration_test PRIVATE ${PROJECT_NAME} nlohmann_json::nlohmann_json) + + add_test(NAME sdk_tests COMMAND test_appwrite) + add_test(NAME integration_tests COMMAND integration_test) +endif() + +# Installation +include(GNUInstallDirs) +install(DIRECTORY include/appwrite DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + diff --git a/templates/cpp/LICENSE.twig b/templates/cpp/LICENSE.twig new file mode 100755 index 0000000000..ce6435c386 --- /dev/null +++ b/templates/cpp/LICENSE.twig @@ -0,0 +1 @@ +{{sdk.licenseContent | raw}} diff --git a/templates/cpp/README.md.twig b/templates/cpp/README.md.twig new file mode 100755 index 0000000000..c75fa97eb4 --- /dev/null +++ b/templates/cpp/README.md.twig @@ -0,0 +1,148 @@ +# {{ sdk.name }} + +**The official C++ SDK for {{ spec.title }}.** + +A production-ready, modern C++20 SDK for {{ spec.title }}, designed for game engines, IoT, and high-concurrency backend environments. + +## ✨ Features + +- **Header-Only**: Drop in via CMake FetchContent — no precompilation required. +- **Thread-Safe by Design**: Mutex-guarded configuration, per-request HTTP sessions — no state leakage. +- **Concurrent API**: Thread-pool dispatch with C++20 coroutine syntax (`co_await`). Each call runs on a background thread; `.get()` blocks until complete. True non-blocking I/O requires an async runtime (Asio/libuv), which is out of scope. +- **Result Error Model**: Errors are surfaced as values. Chainable and composable. +- **Resumable Uploads**: Automatic chunked upload with progress callbacks. +- **Realtime Support**: Pluggable `SocketBackend` for WebSocket event subscriptions. +- **Rich Query Builder**: `Query::equal`, `Query::between`, geo queries, `or_`, `and_`, `elemMatch`, and more. + +## 🚀 Installation + +### CMake (FetchContent) + +Add the following to your `CMakeLists.txt`: + +```cmake +include(FetchContent) +FetchContent_Declare( + {{ sdk.name | caseSnake }} + GIT_REPOSITORY https://github.com/{{ sdk.gitUserName }}/sdk-for-cpp.git + GIT_TAG v{{ sdk.version }} +) +FetchContent_MakeAvailable({{ sdk.name | caseSnake }}) + +target_link_libraries(my_app PRIVATE {{ sdk.name | caseSnake }}) +``` + +## 🛠 Usage + +### Initialization + +```cpp +#include + +appwrite::Client client; +client + .setEndpoint("{{ spec.endpoint }}") + .setProject("5df5dec0e45d4") + .setKey("your-api-key"); +``` + +### Calling a Service + +```cpp +appwrite::services::Users users(client); + +auto result = users.list({}); +if (result) { + std::cout << "Total users: " << result->toJson()["total"] << std::endl; +} else { + std::cerr << "Error " << result.error().code() + << ": " << result.error().message() << std::endl; +} +``` + +### Async / Coroutines (C++20) + +```cpp +appwrite::Task> run(appwrite::Client& client) { + appwrite::services::Users users(client); + // Note: Task dispatches to a background thread pool. + auto result = co_await users.listAsync({}); + co_return result; +} +``` + +### Using Query Builder + +```cpp +#include + +auto queries = { + appwrite::Query::equal("status", "active"), + appwrite::Query::between("age", 18, 65), + appwrite::Query::orderDesc("$createdAt"), + appwrite::Query::limit(25), +}; +``` + +### Permissions + +```cpp +#include + +std::vector permissions = { + appwrite::Permission::read(appwrite::Role::any()), + appwrite::Permission::write(appwrite::Role::user("userId")), +}; +``` + +### Realtime Subscriptions + +```cpp +#include + +appwrite::services::Realtime realtime(client); + +auto sub = realtime.subscribe({"collections.movies.documents"}, [](auto const& event) { + std::cout << "Event: " << event.event << std::endl; + std::cout << "Data: " << event.data.dump() << std::endl; +}); + +// Clean up: +sub.unsubscribe(); +``` + +### File Uploads + +```cpp +#include + +appwrite::services::Storage storage(client); + +auto result = storage.createFile( + "bucket-id", + appwrite::Id::unique(), + appwrite::InputFile::fromPath("/path/to/file.png"), + {}, // permissions + [](appwrite::InputFile::Progress p) { + std::cout << "Progress: " << p.progress << "%" << std::endl; + } +); +``` + +## 🧪 Building & Testing + +```bash +# Build with tests enabled +cmake -S . -B build -DAPPWRITE_BUILD_TESTS=ON +cmake --build build + +# Run unit tests (GoogleTest) +ctest --test-dir build --output-on-failure + +# Run integration test against mock server +./build/integration_test +``` + +## 📄 License + +This SDK is released under the [{{ sdk.licenseName }}](LICENSE). diff --git a/templates/cpp/examples/basic_usage.cpp.twig b/templates/cpp/examples/basic_usage.cpp.twig new file mode 100644 index 0000000000..3c33b659dc --- /dev/null +++ b/templates/cpp/examples/basic_usage.cpp.twig @@ -0,0 +1,104 @@ +/** + * Basic usage example for {{ spec.title }} C++ SDK + * + * Build with: + * cmake -S . -B build && cmake --build build + * ./build/basic_usage + */ +#include +#include + +int main() { + // Initialize the client + appwrite::Client client; + client + .setEndpoint("{{ spec.endpoint }}") // Your API Endpoint + .setProject("5df5acd0d48c2") // Your project ID + .setKey("919c2d18fb5d4...a2ae413da83346ad2"); // Your secret API key + + std::cout << "🚀 {{ spec.title }} C++ SDK Example\n"; + std::cout << "Connected to: " << client.getEndpoint() << "\n"; + + // Initialize services + appwrite::services::Users users(client); + + // Create a new user + std::cout << "\n📝 Creating a new user...\n"; + auto result = users.create( + appwrite::Id::unique(), + "walter.obrien@example.com", + "+1234567890", + "password123", + "Walter O'Brien" + ); + + if (result) { + std::cout << "✅ User created successfully!\n"; + std::cout << "User: " << result->toJson().dump(2) << "\n"; + } else { + std::cout << "❌ Error " << result.error().code() + << ": " << result.error().message() << "\n"; + } + + // List users with queries + std::cout << "\n📋 Listing users...\n"; + auto listResult = users.list( + { appwrite::Query::limit(10) } + ); + + if (listResult) { + std::cout << "✅ Found " << listResult->toJson()["total"] << " users\n"; + } else { + std::cout << "❌ Error " << listResult.error().code() + << ": " << listResult.error().message() << "\n"; + } + +{% for service in spec.services %} +{% if service.name == 'databases' %} + // Databases + std::cout << "\n🗄️ Working with databases...\n"; + appwrite::services::Databases databases(client); + auto docsResult = databases.listDocuments( + "your-database-id", + "your-collection-id", + { + appwrite::Query::limit(10), + appwrite::Query::orderDesc("$createdAt") + } + ); + if (docsResult) { + std::cout << "✅ Found " << docsResult->toJson()["total"] << " documents\n"; + } else { + std::cout << "❌ " << docsResult.error().message() << "\n"; + } +{% endif %} +{% endfor %} + +{% for service in spec.services %} +{% if service.name == 'storage' %} + // Storage — upload a file + std::cout << "\n📁 Uploading a file...\n"; + appwrite::services::Storage storage(client); + auto fileResult = storage.createFile( + "your-bucket-id", + appwrite::Id::unique(), + appwrite::InputFile::fromPath("path/to/your/file.png") + ); + if (fileResult) { + std::cout << "✅ File uploaded: " << fileResult->toJson()["name"] << "\n"; + } else { + std::cout << "❌ " << fileResult.error().message() << "\n"; + } +{% endif %} +{% endfor %} + + // Query builder examples + std::cout << "\n🔍 Query builder examples:\n"; + std::cout << " equal: " << appwrite::Query::equal("status", "active") << "\n"; + std::cout << " between: " << appwrite::Query::between("age", 18, 65) << "\n"; + std::cout << " select: " << appwrite::Query::select({"name", "email"}) << "\n"; + std::cout << " limit: " << appwrite::Query::limit(25) << "\n"; + + std::cout << "\n🎉 Example complete!\n"; + return 0; +} diff --git a/templates/cpp/include/appwrite.hpp.twig b/templates/cpp/include/appwrite.hpp.twig new file mode 100644 index 0000000000..61a315e14b --- /dev/null +++ b/templates/cpp/include/appwrite.hpp.twig @@ -0,0 +1,16 @@ +{% autoescape false %} +#pragma once + +/** + * Appwrite C++ SDK — single-header entry point. + * Include this file to use the full SDK. + * + * #include + * using namespace appwrite; + */ +#include "base.hpp" +#include "core.hpp" +#include "models.hpp" +#include "services.hpp" +#include "enums/enums.hpp" +{% endautoescape %} diff --git a/templates/cpp/include/base.hpp.twig b/templates/cpp/include/base.hpp.twig new file mode 100644 index 0000000000..5cc6d071e3 --- /dev/null +++ b/templates/cpp/include/base.hpp.twig @@ -0,0 +1,289 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace nlohmann { + template + struct adl_serializer> { + static void to_json(json& j, const std::optional& opt) { + if (opt == std::nullopt) j = nullptr; + else j = *opt; + } + + static void from_json(const json& j, std::optional& opt) { + if (j.is_null()) opt = std::nullopt; + else opt = j.template get(); + } + }; +} + +namespace appwrite { + +/** + * @brief Base exception for all Appwrite SDK errors. + */ +class AppwriteException : public std::exception { +public: + explicit AppwriteException(std::string message, int code = 0, + std::string response = "") + : message_(std::move(message)), code_(code), response_(std::move(response)) {} + + virtual ~AppwriteException() = default; + + [[nodiscard]] virtual std::shared_ptr clone() const { + return std::make_shared(*this); + } + + [[nodiscard]] const char* what() const noexcept override { return message_.c_str(); } + [[nodiscard]] int code() const noexcept { return code_; } + [[nodiscard]] const std::string& message() const noexcept { return message_; } + [[nodiscard]] const std::string& response() const noexcept { return response_; } + +protected: + std::string message_; + int code_; + std::string response_; +}; + +class NetworkException final : public AppwriteException { +public: + explicit NetworkException(std::string message) + : AppwriteException(std::move(message), 0) {} + + [[nodiscard]] std::shared_ptr clone() const override { + return std::make_shared(*this); + } +}; + +class ServerException final : public AppwriteException { +public: + ServerException(std::string message, int code, + std::string type = "", std::string response = "") + : AppwriteException(std::move(message), code, std::move(response)) + , type_(std::move(type)) {} + + [[nodiscard]] std::shared_ptr clone() const override { + return std::make_shared(*this); + } + + [[nodiscard]] const std::string& type() const noexcept { return type_; } + +private: + std::string type_; +}; + +class DeserializationException final : public AppwriteException { +public: + explicit DeserializationException(std::string message, + std::string raw_response = "") + : AppwriteException(std::move(message), -1, std::move(raw_response)) {} + + [[nodiscard]] std::shared_ptr clone() const override { + return std::make_shared(*this); + } +}; + +using Exception = AppwriteException; + +/** + * @brief Result class to represent either a success value or an Exception. + */ +template +class Result { +public: + static Result Ok(T value) { return Result(std::move(value)); } + static Result Err(std::exception_ptr eptr) { return Result(std::move(eptr)); } + static Result Err(const AppwriteException& error) { + try { throw error; } + catch (...) { return Result(std::current_exception()); } + } + + [[nodiscard]] bool isOk() const { return std::holds_alternative(data_); } + [[nodiscard]] bool has_value() const { return isOk(); } + [[nodiscard]] bool isErr() const { return !isOk(); } + explicit operator bool() const { return isOk(); } + + const T* operator->() const { return &value(); } + T* operator->() { return &value(); } + const T& operator*() const { return value(); } + T& operator*() { return value(); } + + const T& value() const { + if (isErr()) std::rethrow_exception(std::get(data_)); + return std::get(data_); + } + + T& value() { + if (isErr()) std::rethrow_exception(std::get(data_)); + return std::get(data_); + } + + T value_or(T defaultValue) const { + if (isErr()) return defaultValue; + return std::get(data_); + } + + std::shared_ptr error() const { + if (isOk()) throw AppwriteException("Result is Ok, no error available"); + try { std::rethrow_exception(std::get(data_)); } + catch (const AppwriteException& e) { return e.clone(); } + throw AppwriteException("Unknown error"); + } + +private: + explicit Result(T value) : data_(std::move(value)) {} + explicit Result(std::exception_ptr eptr) : data_(std::move(eptr)) {} + std::variant data_; +}; + +/** + * @brief Result specialization for void return types. + * @note To inspect error details, call value() inside a try-catch block. + */ +template <> +class Result { +public: + static Result Ok() { return Result(); } + static Result Err(std::exception_ptr eptr) { return Result(std::move(eptr)); } + static Result Err(const AppwriteException& error) { + try { throw error; } + catch (...) { return Result(std::current_exception()); } + } + + [[nodiscard]] bool isOk() const { return !eptr_.has_value(); } + [[nodiscard]] bool isErr() const { return eptr_.has_value(); } + void value() const { if (isErr()) std::rethrow_exception(*eptr_); } + + explicit operator bool() const { return isOk(); } + void operator*() const { value(); } + +private: + Result() : eptr_(std::nullopt) {} + explicit Result(std::exception_ptr eptr) : eptr_(std::move(eptr)) {} + std::optional eptr_; +}; + +/** + * @brief Lightweight move-only coroutine task. + */ +template +struct Task { + struct promise_type { + Task get_return_object() { return Task{std::coroutine_handle::from_promise(*this)}; } + std::suspend_always initial_suspend() noexcept { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void unhandled_exception() { result = std::current_exception(); } + template + void return_value(V&& value) { result = std::variant(std::forward(value)); } + std::optional> result; + }; + + explicit Task(std::coroutine_handle h) : handle(h) {} + ~Task() { if (handle) handle.destroy(); } + Task(Task&& other) noexcept : handle(std::exchange(other.handle, nullptr)) {} + T get() { + if (handle && !handle.done()) handle.resume(); + if (!handle.promise().result) throw AppwriteException("Coroutine did not return a value"); + if (handle.promise().result->index() == 1) std::rethrow_exception(std::get<1>(*handle.promise().result)); + return std::move(std::get<0>(*handle.promise().result)); + } + + auto operator co_await() noexcept { + struct Awaiter { + Task task_; + bool await_ready() const noexcept { return task_.handle.done(); } + void await_suspend(std::coroutine_handle<> h) noexcept { + task_.handle.resume(); + h.resume(); + } + T await_resume() { + auto& res = *task_.handle.promise().result; + if (res.index() == 1) std::rethrow_exception(std::get<1>(res)); + return std::move(std::get<0>(res)); + } + }; + // Note: Task is move-only. After co_await, the original Task handle is null. + return Awaiter{std::move(*this)}; + } + + std::coroutine_handle handle; +}; + +template<> +struct Task { + struct promise_type { + Task get_return_object() { return Task{std::coroutine_handle::from_promise(*this)}; } + std::suspend_always initial_suspend() noexcept { return {}; } + std::suspend_always final_suspend() noexcept { return {}; } + void unhandled_exception() { exception = std::current_exception(); } + void return_void() noexcept {} + std::exception_ptr exception; + }; + explicit Task(std::coroutine_handle h) : handle(h) {} + ~Task() { if (handle) handle.destroy(); } + Task(Task&& other) noexcept : handle(std::exchange(other.handle, nullptr)) {} + void get() { + if (handle && !handle.done()) handle.resume(); + if (handle.promise().exception) std::rethrow_exception(handle.promise().exception); + } + + auto operator co_await() noexcept { + struct Awaiter { + Task task_; + bool await_ready() const noexcept { return task_.handle.done(); } + void await_suspend(std::coroutine_handle<> h) noexcept { + task_.handle.resume(); + h.resume(); + } + void await_resume() { + if (task_.handle.promise().exception) std::rethrow_exception(task_.handle.promise().exception); + } + }; + // Note: Task is move-only. After co_await, the original Task handle is null. + return Awaiter{std::move(*this)}; + } + + std::coroutine_handle handle; +}; + +/** + * @brief Represents a binary response from the API. + */ +class BinaryResponse { +public: + BinaryResponse() = default; + explicit BinaryResponse(std::vector data) : data_(std::move(data)) {} + [[nodiscard]] std::span span() const { return {data_.data(), data_.size()}; } + [[nodiscard]] const std::vector& data() const { return data_; } + [[nodiscard]] size_t size() const { return data_.size(); } + [[nodiscard]] bool empty() const { return data_.empty(); } +private: + std::vector data_; +}; + + + +/** + * @brief Interface for a Realtime Socket Backend. + */ +class SocketBackend { +public: + virtual ~SocketBackend() = default; + virtual void connect(const std::string& endpoint, const std::string& project) = 0; + virtual void close() = 0; + virtual void subscribe(const std::vector& channels) = 0; + virtual void onMessage(std::function callback) = 0; + virtual void onError(std::function callback) = 0; +}; + +} // namespace appwrite diff --git a/templates/cpp/include/client.hpp.twig b/templates/cpp/include/client.hpp.twig new file mode 100644 index 0000000000..f1e90d904e --- /dev/null +++ b/templates/cpp/include/client.hpp.twig @@ -0,0 +1,585 @@ +{% autoescape false %} +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "base.hpp" +#include "core.hpp" + +namespace appwrite { + +/** + * @brief ThreadPoolAwaiter for yielding coroutines. + */ +struct ThreadPoolAwaiter { + std::function)> enq; + bool await_ready() const noexcept { return false; } + void await_suspend(std::coroutine_handle<> h) { enq([h] { h.resume(); }); } + void await_resume() const noexcept {} +}; + +/** + * @brief ThreadPool for asynchronous Appwrite SDK operations. + */ +class ThreadPool { +public: + explicit ThreadPool(size_t threads = 0) { + if (threads == 0) { + threads = std::max(8, std::thread::hardware_concurrency() * 2); + } + for (size_t i = 0; i < threads; ++i) { + workers_.emplace_back([this] { + while (true) { + std::function t; + { + std::unique_lock lock(mutex_); + cv_tasks_.wait(lock, [this] { return stop.load(std::memory_order_acquire) || !tasks_.empty(); }); + if (stop.load(std::memory_order_acquire) && tasks_.empty()) return; + t = std::move(tasks_.front()); + tasks_.pop(); + } + cv_space_.notify_one(); + try { t(); } catch (...) {} + } + }); + } + } + + ~ThreadPool() { + stop.store(true, std::memory_order_release); + cv_tasks_.notify_all(); + cv_space_.notify_all(); + for (auto& w : workers_) w.join(); + } + + void enqueue(std::function t) { + { + std::unique_lock lock(mutex_); + cv_space_.wait(lock, [this] { return stop.load(std::memory_order_acquire) || tasks_.size() < 1024; }); + if (stop.load(std::memory_order_acquire)) return; + tasks_.push(std::move(t)); + } + cv_tasks_.notify_one(); + } + + auto operator co_await() noexcept { + return ThreadPoolAwaiter{[this](auto f) { enqueue(std::move(f)); }}; + } + +private: + std::vector workers_; + std::queue> tasks_; + std::mutex mutex_; + std::condition_variable cv_tasks_, cv_space_; + std::atomic stop{false}; +}; + +/** + * @brief The primary entry point for all Appwrite API operations. + */ +class Client { +public: + using ProgressCallback = std::function; + + struct RetryPolicy { + int maxRetries = 3; + std::chrono::milliseconds retryDelay{500}; + }; + + struct Config { + std::string endpoint = "https://cloud.appwrite.io/v1"; + std::unordered_map headers = { +{% for key, header in spec.global.defaultHeaders %} + {"{{ key }}", "{{ header }}"}, +{% endfor %} + {"x-sdk-name", "{{ sdk.name }}"}, + {"x-sdk-platform", "{{ sdk.platform }}"}, + {"x-sdk-language", "{{ language.name | lower | replace({'+': 'p'}) }}"}, + {"x-sdk-version", "{{ sdk.version }}"}, + }; + bool selfSigned = false; + size_t chunkSize = 5 * 1024 * 1024; + std::chrono::milliseconds timeout{10000}; + RetryPolicy retryOptions; + }; + + using ConfigPtr = std::shared_ptr; + + Client() : pool(std::make_shared()) {} + + Client(const Client&) = delete; + Client& operator=(const Client&) = delete; + + Client& setEndpoint(std::string endpoint) { + if (endpoint.find("http://") != 0 && endpoint.find("https://") != 0) { + throw AppwriteException("Invalid endpoint URL: " + endpoint); + } + auto next = *get_cfg(); + next.endpoint = std::move(endpoint); + set_cfg(std::move(next)); + return *this; + } + + [[nodiscard]] std::string getEndpoint() const { return get_cfg()->endpoint; } + [[nodiscard]] const std::unordered_map& getHeaders() const { return get_cfg()->headers; } + + Client& setProject(std::string projectId) { return addHeader("x-appwrite-project", std::move(projectId)); } + Client& setKey(std::string key) { return addHeader("x-appwrite-key", std::move(key)); } + Client& setJWT(std::string jwt) { return addHeader("x-appwrite-jwt", std::move(jwt)); } + Client& setSelfSigned(bool status) { + auto next = *get_cfg(); + next.selfSigned = status; + set_cfg(std::move(next)); + return *this; + } + + Client& addHeader(std::string k, std::string v) { + auto next = *get_cfg(); + next.headers[std::move(k)] = std::move(v); + set_cfg(std::move(next)); + return *this; + } + + Client& setTimeout(std::chrono::milliseconds timeout) { + auto next = *get_cfg(); + next.timeout = timeout; + set_cfg(std::move(next)); + return *this; + } + + // Realtime support + using SocketFactory = std::function()>; + Client& setSocketFactory(SocketFactory factory) { + socketFactory_ = std::move(factory); + return *this; + } + + [[nodiscard]] std::shared_ptr createSocket() const { + if (!socketFactory_) throw AppwriteException("Socket factory not set. Use client.setSocketFactory()."); + return socketFactory_(); + } + + [[nodiscard]] std::string getRealtimeEndpoint() const { + auto endpoint = get_cfg()->endpoint; + if (endpoint.find("https://") == 0) endpoint.replace(0, 8, "wss://"); + else if (endpoint.find("http://") == 0) endpoint.replace(0, 7, "ws://"); + return endpoint + "/realtime"; + } + + [[nodiscard]] std::string getProject() const { + auto const c = get_cfg(); + if (c->headers.contains("x-appwrite-project")) return c->headers.at("x-appwrite-project"); + return ""; + } + + // Async Requests — dispatch synchronous calls onto the thread pool. + // The returned Task is a fire-and-forget future; call .get() to block + // until the result is ready, or co_await it from another coroutine. + + Task> callVoidAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return callVoid(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + template + Task> callAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return call(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + Task> callLocationAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return callLocation(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + Task> callBytesAsync(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), + h=std::move(h), pms=std::move(pms), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return callBytes(std::move(m), std::move(p), std::move(h), std::move(pms)); + }); + } + + template + Task> fileUploadAsync(std::string m, std::string p, std::string fk, + InputFile file, std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + ProgressCallback cb = nullptr, + std::stop_token token = {}) const { + return dispatchAsync>([this, m=std::move(m), p=std::move(p), fk=std::move(fk), + file=std::move(file), h=std::move(h), pms=std::move(pms), + cb=std::move(cb), token]() mutable { + if (token.stop_requested()) return Result::Err(AppwriteException("Cancelled")); + return fileUpload(std::move(m), std::move(p), std::move(fk), std::move(file), + std::move(h), std::move(pms), std::move(cb), token); + }); + } + + // Main send logic with retries and hardened session management + template + Result call(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, false); + verify(r); + auto j = r.text.empty() ? nlohmann::json::object() : nlohmann::json::parse(r.text); + if constexpr (std::is_same_v) { + return Result::Ok(j); + } else { + return Result::Ok(T::fromJson(j)); + } + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(DeserializationException(e.what()))); + } + } + + Result callVoid(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, false); + verify(r); + return Result::Ok(); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(DeserializationException(e.what()))); + } + } + + Result callLocation(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, true); // true = no redirect + if (r.status_code == 0) throw NetworkException(r.error.message); + if (r.status_code >= 400) { + std::string msg = "Server Error"; + std::string type = ""; + try { + auto j = nlohmann::json::parse(r.text); + if (j.contains("message")) msg = j["message"]; + if (j.contains("type")) type = j["type"]; + } catch (...) {} + throw ServerException(msg, r.status_code, std::move(type), r.text); + } + if (r.status_code >= 300 && r.status_code < 400 && r.header.contains("Location")) { + return Result::Ok(r.header["Location"]); + } + return Result::Ok(r.text); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + + Result callBytes(std::string m, std::string p, + std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object()) const { + try { + auto const c = get_cfg(); + auto r = send(*c, m, p, h, pms, false); + verify(r); + std::vector data; + if (!r.text.empty()) { + data.assign(r.text.begin(), r.text.end()); + } + return Result::Ok(BinaryResponse(std::move(data))); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + + template + Result fileUpload(std::string m, std::string p, std::string fk, + InputFile file, std::unordered_map h = {}, + nlohmann::json pms = nlohmann::json::object(), + ProgressCallback cb = nullptr, + std::stop_token token = {}) const { + try { + auto const c = get_cfg(); + if (file.size() <= c->chunkSize) { + std::string data = file.readChunk(0, file.size()); + cpr::Session s; + init(s, *c, m, p, h, pms, false, true); + + cpr::Multipart multipart = prepareMultipart(pms); + multipart.parts.emplace_back(std::move(fk), cpr::Buffer{data.begin(), data.end(), file.filename()}); + + s.SetMultipart(multipart); + auto resp = runSession(s, m); + verify(resp); + + if (cb) { + cb(InputFile::Progress{ + .id = 0, + .progress = 100.0, + .sizeUploaded = file.size(), + .chunksTotal = 1, + .chunksUploaded = 1 + }); + } + + auto j = nlohmann::json::parse(resp.text); + if constexpr (std::is_same_v) return Result::Ok(j); + else return Result::Ok(T::fromJson(j)); + } + return upload_chunks(c, std::move(m), std::move(p), std::move(h), std::move(pms), std::move(fk), std::move(file), std::move(cb), token); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + +private: + mutable std::shared_ptr cfg_{std::make_shared()}; + mutable std::mutex cfg_mutex_; + + ConfigPtr get_cfg() const { + std::lock_guard lock(cfg_mutex_); + return cfg_; + } + void set_cfg(Config next) { + std::lock_guard lock(cfg_mutex_); + cfg_ = std::make_shared(std::move(next)); + } + + static cpr::Response send(const Config& c, std::string_view m, std::string_view p, const auto& h, const auto& pms, bool no_redir = false) { + int attempt = 0; + while (true) { + cpr::Session s; + init(s, c, m, p, h, pms, no_redir); + cpr::Response r = runSession(s, m); + if (r.status_code == 0) { + if (attempt < c.retryOptions.maxRetries) { + attempt++; + std::this_thread::sleep_for(c.retryOptions.retryDelay); + continue; + } + } + return r; + } + } + + static void init(cpr::Session& s, const Config& c, std::string_view m, std::string_view p, const auto& h, const auto& pms, bool no_redir, bool is_multipart = false) { + s.SetUrl(cpr::Url{c.endpoint + (p[0] == '/' ? "" : "/") + std::string(p)}); + s.SetVerifySsl(!c.selfSigned); + s.SetTimeout(c.timeout); + if (no_redir) s.SetRedirect(cpr::Redirect{0, false, false, cpr::PostRedirectFlags::POST_ALL}); + + cpr::Header heads; + for (auto const& [k, v] : c.headers) heads[k] = v; + for (auto const& [k, v] : h) heads[k] = v; + if (m != "GET" && !pms.empty() && !is_multipart) heads["content-type"] = "application/json"; + s.SetHeader(heads); + + if (m == "GET") { + cpr::Parameters params; + for (auto const& [k, v] : pms.items()) { + if (v.is_array()) { + for (auto const& item : v) { + if (item.is_string()) { + params.Add(cpr::Parameter(k + "[]", item.template get())); + } else { + params.Add(cpr::Parameter(k + "[]", item.dump())); + } + } + } else if (v.is_string()) { + params.Add(cpr::Parameter(k, v.template get())); + } else { + params.Add(cpr::Parameter(k, v.dump())); + } + } + s.SetParameters(params); + } else if (!pms.empty() && !is_multipart) { + s.SetBody(cpr::Body{pms.dump()}); + } + } + + static cpr::Response runSession(cpr::Session& s, std::string_view m) { + if (m == "GET") return s.Get(); + if (m == "POST") return s.Post(); + if (m == "PUT") return s.Put(); + if (m == "PATCH") return s.Patch(); + if (m == "DELETE") return s.Delete(); + throw AppwriteException("Bad method: " + std::string(m)); + } + + static cpr::Multipart prepareMultipart(const nlohmann::json& pms) { + cpr::Multipart multipart{}; + for (auto const& [key, val] : pms.items()) { + if (val.is_string()) { + multipart.parts.emplace_back(key, val.template get()); + } else if (val.is_array()) { + for (auto const& item : val) { + if (item.is_string()) { + multipart.parts.emplace_back(key + "[]", item.template get()); + } else { + multipart.parts.emplace_back(key + "[]", item.dump()); + } + } + } else { + multipart.parts.emplace_back(key, val.dump()); + } + } + return multipart; + } + + static void verify(const cpr::Response& r) { + if (r.status_code == 0) throw NetworkException(r.error.message); + if (r.status_code >= 400) { + std::string msg = r.text; // fallback: raw body (e.g. text/plain responses) + std::string type = ""; + try { + auto j = nlohmann::json::parse(r.text); + if (j.contains("message")) msg = j["message"]; + if (j.contains("type")) type = j["type"]; + } catch (...) {} + throw ServerException(msg, r.status_code, std::move(type), r.text); + } + } + + template + Result upload_chunks(ConfigPtr c, std::string m, std::string p, + const std::unordered_map& h, + const nlohmann::json& pms, const std::string& fk, + const InputFile& file, const ProgressCallback& cb, + std::stop_token token = {}) const { + try { + size_t size = file.size(), chunk_size = c->chunkSize, off = 0; + nlohmann::json last; + size_t chunksTotal = (size + chunk_size - 1) / chunk_size; + size_t chunksUploaded = 0; + std::string fileId; + + while (off < size) { + if (token.stop_requested()) throw AppwriteException("Cancelled"); + size_t end = std::min(off + chunk_size, size); + std::string chunk = file.readChunk(off, end - off); + + auto cur_h = h; + if (!fileId.empty()) cur_h["x-appwrite-id"] = fileId; + cur_h["Content-Range"] = "bytes " + std::to_string(off) + "-" + std::to_string(end - 1) + "/" + std::to_string(size); + + cpr::Session s; + init(s, *c, m, p, cur_h, pms, false, true); + + cpr::Multipart multipart = prepareMultipart(pms); + multipart.parts.emplace_back(fk, cpr::Buffer{chunk.begin(), chunk.end(), file.filename()}); + + s.SetMultipart(multipart); + auto resp = runSession(s, m); + verify(resp); + + last = nlohmann::json::parse(resp.text); + if (fileId.empty() && last.contains("$id")) fileId = last["$id"].get(); + off = end; + chunksUploaded++; + + if (cb) { + cb(InputFile::Progress{ + .id = 0, + .progress = (double)off / (double)size * 100.0, + .sizeUploaded = off, + .chunksTotal = chunksTotal, + .chunksUploaded = chunksUploaded + }); + } + } + + if constexpr (std::is_same_v) return Result::Ok(last); + else return Result::Ok(T::fromJson(last)); + } catch (const AppwriteException&) { + return Result::Err(std::current_exception()); + } catch (const std::exception& e) { + return Result::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + } + + std::shared_ptr pool; + SocketFactory socketFactory_; + + // Dispatches a synchronous callable onto the thread pool and returns a + // Task. The Task uses std::future internally, so calling .get() or + // co_await blocks the calling thread until the HTTP response arrives. + // True non-blocking I/O would require an event-loop runtime (Asio, libuv) + // which is out of scope for this SDK. The thread-pool model still provides + // concurrency — multiple async calls proceed in parallel on separate threads. + template + Task dispatchAsync(F func) const { + auto promise = std::make_shared>(); + auto future = promise->get_future(); + pool->enqueue([promise = std::move(promise), func = std::move(func)]() mutable { + try { promise->set_value(func()); } + catch (...) { promise->set_exception(std::current_exception()); } + }); + return makeResolvedTask(std::move(future)); + } + + // Builds a Task that wraps a std::future. Task::get() blocks until the + // future is ready, keeping the interface identical to a coroutine Task. + // Note: T must be a Result specialization for T::Err to be valid. + template + static Task makeResolvedTask(std::future fut) { + // Use a shared_ptr so the future survives until Task::get() is called. + auto shared = std::make_shared>(std::move(fut)); + return [](std::shared_ptr> f) -> Task { + try { + co_return f->get(); + } catch (const AppwriteException&) { + co_return T::Err(std::current_exception()); + } catch (const std::exception& e) { + co_return T::Err(std::make_exception_ptr(AppwriteException(e.what()))); + } + }(std::move(shared)); + } +}; + +} // namespace appwrite +{% endautoescape %} diff --git a/templates/cpp/include/core.hpp.twig b/templates/cpp/include/core.hpp.twig new file mode 100644 index 0000000000..59d20136c7 --- /dev/null +++ b/templates/cpp/include/core.hpp.twig @@ -0,0 +1,404 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace appwrite { + +namespace internal { + +static std::string quote(std::string_view s) { + std::string out = "\""; + for (char c : s) { + if (c == '"') out += "\\\""; + else if (c == '\\') out += "\\\\"; + else if (c == '\n') out += "\\n"; + else out += c; + } + return out + "\""; +} + +static std::string int_str(int64_t v) { return std::to_string(v); } + +static std::string dbl_str(double v) { + char buf[32]; + auto [ptr, ec] = std::to_chars(buf, buf + sizeof(buf), v); + return ec == std::errc{} ? std::string(buf, ptr) : "0"; +} + +static std::string point(double lat, double lon) { + return "[" + dbl_str(lat) + "," + dbl_str(lon) + "]"; +} + +static std::string join(const std::vector& parts) { + std::string out; + for (size_t i = 0; i < parts.size(); ++i) { + if (i) out += ','; + out += parts[i]; + } + return out; +} + +static std::vector quote_all(const std::vector& v) { + std::vector out; + out.reserve(v.size()); + for (auto const& s : v) out.push_back(quote(s)); + return out; +} + +static std::string build(std::string_view method, std::string_view attribute, const std::vector& values, bool force_values = false) { + std::string s = "{\"method\":\"" + std::string(method) + "\""; + if (!attribute.empty()) s += ",\"attribute\":" + quote(attribute); + if (!values.empty() || force_values) { + s += ",\"values\":[" + join(values) + "]"; + } + return s + "}"; +} + +} // namespace internal + +/** + * @brief Strong ID type for Appwrite resources. + */ +class Id { +public: + Id() = default; + Id(std::string value) : value_(std::move(value)) {} + Id(std::string_view value) : value_(value) {} + Id(const char* value) : value_(value) {} + + static Id custom(std::string id) { return Id(std::move(id)); } + static Id unique() { + static constexpr std::string_view hex = "0123456789abcdef"; + static std::mt19937 rng{std::random_device{}()}; + static std::uniform_int_distribution dist{0, 15}; + static std::mutex m; + std::string id(20, '0'); + std::lock_guard lock(m); + for (char& c : id) c = hex[dist(rng)]; + return Id(id); + } + + [[nodiscard]] const std::string& str() const { return value_; } + operator const std::string&() const { return value_; } + [[nodiscard]] bool operator==(const Id& other) const { return value_ == other.value_; } + [[nodiscard]] bool operator!=(const Id& other) const { return value_ != other.value_; } + +private: + std::string value_; +}; + +using ID = Id; + +class Role { +public: + static std::string any() { return "any"; } + static std::string guests() { return "guests"; } + static std::string users(const std::string& status = "") { return status.empty() ? "users" : "users/" + status; } + static std::string user(const std::string& id, const std::string& status = "") { return status.empty() ? "user:" + id : "user:" + id + "/" + status; } + static std::string team(const std::string& id, const std::string& role = "") { return role.empty() ? "team:" + id : "team:" + id + "/" + role; } + static std::string member(const std::string& id) { return "member:" + id; } + static std::string label(const std::string& name) { return "label:" + name; } +}; + +class Permission { +public: + static std::string read(const std::string& role) { return "read(\"" + role + "\")"; } + static std::string write(const std::string& role) { return "write(\"" + role + "\")"; } + static std::string create(const std::string& role) { return "create(\"" + role + "\")"; } + static std::string update(const std::string& role) { return "update(\"" + role + "\")"; } + static std::string delete_(const std::string& role) { return "delete(\"" + role + "\")"; } +}; + +/** + * @brief Fluent builder for Appwrite query filters. + */ +class Query { +public: + [[nodiscard]] static std::string equal(std::string_view attribute, std::string_view value) { return internal::build("equal", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, const char* value) { return internal::build("equal", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, int64_t value) { return internal::build("equal", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, int value) { return equal(attribute, (int64_t)value); } + [[nodiscard]] static std::string equal(std::string_view attribute, double value) { return internal::build("equal", attribute, {internal::dbl_str(value)}); } + [[nodiscard]] static std::string equal(std::string_view attribute, bool value) { return internal::build("equal", attribute, {value ? "true" : "false"}); } + [[nodiscard]] static std::string equal(std::string_view attribute, const std::vector& values) { return internal::build("equal", attribute, internal::quote_all(values)); } + + [[nodiscard]] static std::string notEqual(std::string_view attribute, std::string_view value) { return internal::build("notEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, const char* value) { return internal::build("notEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, int64_t value) { return internal::build("notEqual", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, int value) { return notEqual(attribute, (int64_t)value); } + [[nodiscard]] static std::string notEqual(std::string_view attribute, double value) { return internal::build("notEqual", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string lessThan(std::string_view attribute, std::string_view value) { return internal::build("lessThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, const char* value) { return internal::build("lessThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, int64_t value) { return internal::build("lessThan", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, int value) { return lessThan(attribute, (int64_t)value); } + [[nodiscard]] static std::string lessThan(std::string_view attribute, double value) { return internal::build("lessThan", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, std::string_view value) { return internal::build("lessThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, const char* value) { return internal::build("lessThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, int64_t value) { return internal::build("lessThanEqual", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, int value) { return lessThanEqual(attribute, (int64_t)value); } + [[nodiscard]] static std::string lessThanEqual(std::string_view attribute, double value) { return internal::build("lessThanEqual", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string greaterThan(std::string_view attribute, std::string_view value) { return internal::build("greaterThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, const char* value) { return internal::build("greaterThan", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, int64_t value) { return internal::build("greaterThan", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, int value) { return greaterThan(attribute, (int64_t)value); } + [[nodiscard]] static std::string greaterThan(std::string_view attribute, double value) { return internal::build("greaterThan", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, std::string_view value) { return internal::build("greaterThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, const char* value) { return internal::build("greaterThanEqual", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, int64_t value) { return internal::build("greaterThanEqual", attribute, {internal::int_str(value)}); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, int value) { return greaterThanEqual(attribute, (int64_t)value); } + [[nodiscard]] static std::string greaterThanEqual(std::string_view attribute, double value) { return internal::build("greaterThanEqual", attribute, {internal::dbl_str(value)}); } + + [[nodiscard]] static std::string search(std::string_view attribute, std::string_view value) { return internal::build("search", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string search(std::string_view attribute, const char* value) { return internal::build("search", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notSearch(std::string_view attribute, std::string_view value) { return internal::build("notSearch", attribute, {internal::quote(value)}); } + [[nodiscard]] static std::string notSearch(std::string_view attribute, const char* value) { return internal::build("notSearch", attribute, {internal::quote(value)}); } + + static std::string contains(std::string_view attribute, std::string_view value) { return internal::build("contains", attribute, {internal::quote(value)}); } + static std::string contains(std::string_view attribute, const char* value) { return internal::build("contains", attribute, {internal::quote(value)}); } + static std::string contains(std::string_view attribute, const std::vector& values) { return internal::build("contains", attribute, internal::quote_all(values)); } + static std::string containsAny(std::string_view attribute, const std::vector& values) { return internal::build("containsAny", attribute, internal::quote_all(values)); } + static std::string containsAll(std::string_view attribute, const std::vector& values) { return internal::build("containsAll", attribute, internal::quote_all(values)); } + static std::string notContains(std::string_view attribute, std::string_view value) { return internal::build("notContains", attribute, {internal::quote(value)}); } + static std::string notContains(std::string_view attribute, const char* value) { return internal::build("notContains", attribute, {internal::quote(value)}); } + static std::string notContains(std::string_view attribute, const std::vector& values) { return internal::build("notContains", attribute, internal::quote_all(values)); } + + static std::string between(std::string_view attribute, int64_t start, int64_t end) { return internal::build("between", attribute, {internal::int_str(start), internal::int_str(end)}); } + static std::string between(std::string_view attribute, int start, int end) { return between(attribute, (int64_t)start, (int64_t)end); } + static std::string between(std::string_view attribute, double start, double end) { return internal::build("between", attribute, {internal::dbl_str(start), internal::dbl_str(end)}); } + static std::string between(std::string_view attribute, std::string_view start, std::string_view end) { return internal::build("between", attribute, {internal::quote(start), internal::quote(end)}); } + static std::string between(std::string_view attribute, const char* start, const char* end) { return internal::build("between", attribute, {internal::quote(start), internal::quote(end)}); } + + static std::string notBetween(std::string_view attribute, int64_t start, int64_t end) { return internal::build("notBetween", attribute, {internal::int_str(start), internal::int_str(end)}); } + static std::string notBetween(std::string_view attribute, int start, int end) { return notBetween(attribute, (int64_t)start, (int64_t)end); } + static std::string notBetween(std::string_view attribute, double start, double end) { return internal::build("notBetween", attribute, {internal::dbl_str(start), internal::dbl_str(end)}); } + static std::string notBetween(std::string_view attribute, std::string_view start, std::string_view end) { return internal::build("notBetween", attribute, {internal::quote(start), internal::quote(end)}); } + static std::string notBetween(std::string_view attribute, const char* start, const char* end) { return internal::build("notBetween", attribute, {internal::quote(start), internal::quote(end)}); } + + static std::string startsWith(std::string_view attribute, std::string_view value) { return internal::build("startsWith", attribute, {internal::quote(value)}); } + static std::string startsWith(std::string_view attribute, const char* value) { return internal::build("startsWith", attribute, {internal::quote(value)}); } + static std::string notStartsWith(std::string_view attribute, std::string_view value) { return internal::build("notStartsWith", attribute, {internal::quote(value)}); } + static std::string notStartsWith(std::string_view attribute, const char* value) { return internal::build("notStartsWith", attribute, {internal::quote(value)}); } + + static std::string endsWith(std::string_view attribute, std::string_view value) { return internal::build("endsWith", attribute, {internal::quote(value)}); } + static std::string endsWith(std::string_view attribute, const char* value) { return internal::build("endsWith", attribute, {internal::quote(value)}); } + static std::string notEndsWith(std::string_view attribute, std::string_view value) { return internal::build("notEndsWith", attribute, {internal::quote(value)}); } + static std::string notEndsWith(std::string_view attribute, const char* value) { return internal::build("notEndsWith", attribute, {internal::quote(value)}); } + + static std::string regex(std::string_view attribute, std::string_view value) { return internal::build("regex", attribute, {internal::quote(value)}); } + static std::string regex(std::string_view attribute, const char* value) { return internal::build("regex", attribute, {internal::quote(value)}); } + + static std::string elemMatch(std::string_view attribute, const std::vector& queries) { + return internal::build("elemMatch", attribute, queries); + } + + [[nodiscard]] static std::string isNull(std::string_view attribute) { + return "{\"method\":\"isNull\",\"attribute\":" + internal::quote(attribute) + "}"; + } + [[nodiscard]] static std::string isNotNull(std::string_view attribute) { + return "{\"method\":\"isNotNull\",\"attribute\":" + internal::quote(attribute) + "}"; + } + + static std::string exists(const std::vector& attrs) { + return internal::build("exists", "", internal::quote_all(attrs)); + } + + static std::string notExists(const std::vector& attrs) { + return internal::build("notExists", "", internal::quote_all(attrs)); + } + + [[nodiscard]] static std::string limit(int64_t limit) { + return "{\"method\":\"limit\",\"values\":[" + std::to_string(limit) + "]}"; + } + [[nodiscard]] static std::string limit(int n) { return limit((int64_t)n); } + + [[nodiscard]] static std::string offset(int64_t offset) { + return "{\"method\":\"offset\",\"values\":[" + std::to_string(offset) + "]}"; + } + [[nodiscard]] static std::string offset(int n) { return offset((int64_t)n); } + + [[nodiscard]] static std::string cursorAfter(std::string_view documentId) { return internal::build("cursorAfter", "", {internal::quote(documentId)}); } + [[nodiscard]] static std::string cursorAfter(const char* documentId) { return internal::build("cursorAfter", "", {internal::quote(documentId)}); } + [[nodiscard]] static std::string cursorBefore(std::string_view documentId) { return internal::build("cursorBefore", "", {internal::quote(documentId)}); } + [[nodiscard]] static std::string cursorBefore(const char* documentId) { return internal::build("cursorBefore", "", {internal::quote(documentId)}); } + + [[nodiscard]] static std::string select(const std::vector& attributes) { + return internal::build("select", "", internal::quote_all(attributes)); + } + + [[nodiscard]] static std::string orderAsc(std::string_view attribute) { + return "{\"method\":\"orderAsc\",\"attribute\":" + internal::quote(attribute) + "}"; + } + [[nodiscard]] static std::string orderDesc(std::string_view attribute) { + return "{\"method\":\"orderDesc\",\"attribute\":" + internal::quote(attribute) + "}"; + } + static std::string orderRandom() { return "{\"method\":\"orderRandom\"}"; } + + // Geospatial queries - EXACT structures to match Base.php + static std::string distanceEqual(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceEqual", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string distanceEqual(std::string_view attribute, double lat1, double lon1, double lat2, double lon2, double distance) { + // values:[[[[p1],[p2]],distance,true]] — points nested inside an extra array + return internal::build("distanceEqual", attribute, { + "[[" + internal::point(lat1, lon1) + "," + internal::point(lat2, lon2) + "]," + + internal::dbl_str(distance) + ",true]" + }); + } + static std::string distanceNotEqual(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceNotEqual", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string distanceLessThan(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceLessThan", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string distanceGreaterThan(std::string_view attribute, double lat, double lon, double distance) { + return internal::build("distanceGreaterThan", attribute, {"[" + internal::point(lat, lon) + "," + internal::dbl_str(distance) + ",true]"}); + } + static std::string intersects(std::string_view attribute, double lat, double lon) { + return internal::build("intersects", attribute, {internal::point(lat, lon)}); + } + static std::string notIntersects(std::string_view attribute, double lat, double lon) { + return internal::build("notIntersects", attribute, {internal::point(lat, lon)}); + } + static std::string crosses(std::string_view attribute, double lat, double lon) { + return internal::build("crosses", attribute, {internal::point(lat, lon)}); + } + static std::string notCrosses(std::string_view attribute, double lat, double lon) { + return internal::build("notCrosses", attribute, {internal::point(lat, lon)}); + } + static std::string overlaps(std::string_view attribute, double lat, double lon) { + return internal::build("overlaps", attribute, {internal::point(lat, lon)}); + } + static std::string notOverlaps(std::string_view attribute, double lat, double lon) { + return internal::build("notOverlaps", attribute, {internal::point(lat, lon)}); + } + static std::string touches(std::string_view attribute, double lat, double lon) { + return internal::build("touches", attribute, {internal::point(lat, lon)}); + } + static std::string notTouches(std::string_view attribute, double lat, double lon) { + return internal::build("notTouches", attribute, {internal::point(lat, lon)}); + } + + [[nodiscard]] static std::string or_(const std::vector& queries) { + return internal::build("or", "", queries); + } + [[nodiscard]] static std::string and_(const std::vector& queries) { + return internal::build("and", "", queries); + } +}; + +/** + * @brief Database field update operators. + */ +class Operator { +public: + static std::string increment(double value = 1.0) { return internal::build("increment", "", {internal::dbl_str(value)}); } + static std::string increment(double value, double max) { return internal::build("increment", "", {internal::dbl_str(value), internal::dbl_str(max)}); } + static std::string decrement(double value = 1.0) { return internal::build("decrement", "", {internal::dbl_str(value)}); } + static std::string decrement(double value, double min) { return internal::build("decrement", "", {internal::dbl_str(value), internal::dbl_str(min)}); } + static std::string multiply(double value) { return internal::build("multiply", "", {internal::dbl_str(value)}); } + static std::string multiply(double value, double max) { return internal::build("multiply", "", {internal::dbl_str(value), internal::dbl_str(max)}); } + static std::string divide(double value) { return internal::build("divide", "", {internal::dbl_str(value)}); } + static std::string divide(double value, double min) { return internal::build("divide", "", {internal::dbl_str(value), internal::dbl_str(min)}); } + static std::string modulo(double value) { return internal::build("modulo", "", {internal::dbl_str(value)}); } + static std::string power(double value) { return internal::build("power", "", {internal::dbl_str(value)}); } + static std::string power(double value, double max) { return internal::build("power", "", {internal::dbl_str(value), internal::dbl_str(max)}); } + + static std::string arrayAppend(const std::string& value) { return internal::build("arrayAppend", "", {internal::quote(value)}); } + static std::string arrayAppend(const std::vector& values) { return internal::build("arrayAppend", "", internal::quote_all(values)); } + static std::string arrayPrepend(const std::string& value) { return internal::build("arrayPrepend", "", {internal::quote(value)}); } + static std::string arrayPrepend(const std::vector& values) { return internal::build("arrayPrepend", "", internal::quote_all(values)); } + static std::string arrayInsert(int index, const std::string& value) { + return internal::build("arrayInsert", "", {std::to_string(index), internal::quote(value)}); + } + static std::string arrayRemove(const std::string& value) { return internal::build("arrayRemove", "", {internal::quote(value)}); } + static std::string arrayUnique() { return internal::build("arrayUnique", "", {}, true); } + static std::string arrayIntersect(const std::vector& values) { return internal::build("arrayIntersect", "", internal::quote_all(values)); } + static std::string arrayDiff(const std::vector& values) { return internal::build("arrayDiff", "", internal::quote_all(values)); } + static std::string arrayFilter(const std::string& method, const std::string& param) { return internal::build("arrayFilter", "", {internal::quote(method), internal::quote(param)}); } + + static std::string stringConcat(const std::string& value) { return internal::build("stringConcat", "", {internal::quote(value)}); } + static std::string stringReplace(const std::string& search, const std::string& replace) { + return internal::build("stringReplace", "", {internal::quote(search), internal::quote(replace)}); + } + + static std::string toggle() { return internal::build("toggle", "", {}, true); } + + static std::string dateAddDays(int days) { return internal::build("dateAddDays", "", {std::to_string(days)}); } + static std::string dateSubDays(int days) { return internal::build("dateSubDays", "", {std::to_string(days)}); } + static std::string dateSetNow() { return internal::build("dateSetNow", "", {}, true); } +}; + +/** + * @brief Wrapper for files to be uploaded to the Appwrite API. + */ +class InputFile { +public: + struct Progress { + size_t id; + double progress; + size_t sizeUploaded; + size_t chunksTotal; + size_t chunksUploaded; + }; + + [[nodiscard]] static InputFile fromPath(std::string path) { + std::ifstream file(path, std::ios::binary | std::ios::ate); + if (!file) throw std::runtime_error("Could not open file: " + path); + size_t size = file.tellg(); + std::string filename = std::filesystem::path(path).filename().string(); + return InputFile(std::move(path), std::move(filename), size); + } + + [[nodiscard]] const std::string& path() const { return path_; } + [[nodiscard]] const std::string& filename() const { return filename_; } + [[nodiscard]] size_t size() const { return size_; } + + [[nodiscard]] std::string readChunk(size_t offset, size_t size) const { + std::ifstream file(path_, std::ios::binary); + if (!file) throw std::runtime_error("Could not open file: " + path_); + + file.seekg(offset); + std::string buffer; + buffer.resize(size); + file.read(buffer.data(), size); + buffer.resize(file.gcount()); + return buffer; + } + + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); + j["$inputFile"]["path"] = path_; + j["$inputFile"]["filename"] = filename_; + j["$inputFile"]["size"] = size_; + return j; + } + +private: + InputFile(std::string path, std::string filename, size_t size) + : path_(std::move(path)), filename_(std::move(filename)), size_(size) {} + std::string path_; + std::string filename_; + size_t size_; +}; + +} // namespace appwrite diff --git a/templates/cpp/include/enums/enums.hpp.twig b/templates/cpp/include/enums/enums.hpp.twig new file mode 100755 index 0000000000..0e5c48dc60 --- /dev/null +++ b/templates/cpp/include/enums/enums.hpp.twig @@ -0,0 +1,51 @@ +// Enums umbrella header for the Appwrite C++ SDK +// Auto-generated — do not edit manually +#pragma once + +#include +#include +#include + +namespace appwrite { +namespace enums { + +{% for enum in spec.allEnums %} +{% if enum.description %}/// {{ enum.description }} +{% endif %} +enum class {{ enum.name | casePascal }} { +{% for value in enum.enum %} +{% set key = enum.keys is not empty and enum.keys[loop.index0] is defined and enum.keys[loop.index0] is not empty ? enum.keys[loop.index0] : value %} + {{ key | caseUpperSnakeCase }}{% if not loop.last %},{% endif %} + +{% endfor %} +}; + +inline std::string toString({{ enum.name | casePascal }} value) { + switch (value) { +{% for value in enum.enum %} +{% set key = enum.keys is not empty and enum.keys[loop.index0] is defined and enum.keys[loop.index0] is not empty ? enum.keys[loop.index0] : value %} + case {{ enum.name | casePascal }} :: {{ key | caseUpperSnakeCase }}: return "{{ value }}"; +{% endfor %} + default: throw std::invalid_argument("Unknown {{ enum.name | casePascal }} enum value"); + } +} + +inline {{ enum.name | casePascal }} {{ enum.name | caseCamel }}FromString(const std::string& s) { +{% for value in enum.enum %} +{% set key = enum.keys is not empty and enum.keys[loop.index0] is defined and enum.keys[loop.index0] is not empty ? enum.keys[loop.index0] : value %} + if (s == "{{ value }}") return {{ enum.name | casePascal }}::{{ key | caseUpperSnakeCase }}; +{% endfor %} + throw std::invalid_argument("Unknown {{ enum.name | casePascal }} value: " + s); +} + +inline void from_json(const nlohmann::json& j, {{ enum.name | casePascal }}& v) { + v = {{ enum.name | caseCamel }}FromString(j.get()); +} + +inline void to_json(nlohmann::json& j, const {{ enum.name | casePascal }}& v) { + j = toString(v); +} + +{% endfor %} +} // namespace enums +} // namespace appwrite diff --git a/templates/cpp/include/models.hpp.twig b/templates/cpp/include/models.hpp.twig new file mode 100644 index 0000000000..e3d42af211 --- /dev/null +++ b/templates/cpp/include/models.hpp.twig @@ -0,0 +1,125 @@ +{% autoescape false %} +#pragma once + +#include +#include +#include +#include +#include "base.hpp" +#include "enums/enums.hpp" + +namespace appwrite { +namespace models { + +{% set allModels = spec.definitions | merge(spec.requestModels) %} +// Forward declarations — required because some structs reference types defined later +{% for definition in allModels | topoSort %} +struct {{ definition.name | casePascal }}; +{% endfor %} + +{% for definition in allModels | topoSort %} +/** + * @brief {{ definition.description }} + */ +{% if definition.properties is empty %} +struct {{ definition.name | casePascal }} { + nlohmann::json data = nlohmann::json::object(); + + /** @brief Deserialize from JSON */ + static {{ definition.name | casePascal }} fromJson(const nlohmann::json& j) { + {{ definition.name | casePascal }} obj; + obj.data = j; + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + return data; + } +}; +{% else %} +struct {{ definition.name | casePascal }} { +{% for property in definition.properties %} + /** @brief {{ property.description }} */ + {{ property | propertyType(spec) }} {{ property.name | caseCamel | escapeKeyword }}{% if not property.required %} = std::nullopt{% endif %}; +{% endfor %} + + /** @brief Deserialize from JSON */ + static {{ definition.name | casePascal }} fromJson(const nlohmann::json& j) { + {{ definition.name | casePascal }} obj{}; // value-init: zeroes bools, ints, enums +{% for property in definition.properties %} + if (j.contains("{{ property.name }}")) { + if (j["{{ property.name }}"].is_null()) { +{% if property.required %} + throw appwrite::DeserializationException("Required field '{{ property.name }}' is null"); +{% else %} + obj.{{ property.name | caseCamel | escapeKeyword }} = std::nullopt; +{% endif %} + } else { +{% if property.sub_schema %} + {% if property.type == 'array' %} + {% if not property.required %} + obj.{{ property.name | caseCamel | escapeKeyword }} = std::vector<{{ property.sub_schema | casePascal }}>{}; + {% endif %} + for (auto& item : j["{{ property.name }}"]) { + {% if not property.required %} + obj.{{ property.name | caseCamel | escapeKeyword }}->push_back({{ property.sub_schema | casePascal }}::fromJson(item)); + {% else %} + obj.{{ property.name | caseCamel | escapeKeyword }}.push_back({{ property.sub_schema | casePascal }}::fromJson(item)); + {% endif %} + } + {% else %} + obj.{{ property.name | caseCamel | escapeKeyword }} = {{ property.sub_schema | casePascal }}::fromJson(j["{{ property.name }}"]); + {% endif %} +{% else %} + obj.{{ property.name | caseCamel | escapeKeyword }} = j["{{ property.name }}"].get<{{ property | propertyType(spec) }}>(); +{% endif %} + } + } +{% endfor %} + return obj; + } + + /** @brief Serialize to JSON */ + [[nodiscard]] nlohmann::json toJson() const { + nlohmann::json j = nlohmann::json::object(); +{% for property in definition.properties %} +{% if not property.required %} + if (this->{{ property.name | caseCamel | escapeKeyword }}.has_value()) { +{% else %} + { +{% endif %} +{% set val = property.required ? "this->" ~ property.name | caseCamel | escapeKeyword : "this->" ~ property.name | caseCamel | escapeKeyword ~ ".value()" %} +{% if property.sub_schema %} + {% if property.type == 'array' %} + nlohmann::json arr = nlohmann::json::array(); + for (auto& item : this->{{ property.name | caseCamel | escapeKeyword }}{% if not property.required %}.value(){% endif %}) arr.push_back(item.toJson()); + j["{{ property.name }}"] = arr; + {% else %} + j["{{ property.name }}"] = {{ val }}.toJson(); + {% endif %} +{% elseif property | enumName %} + j["{{ property.name }}"] = appwrite::enums::toString({{ val }}); +{% else %} + j["{{ property.name }}"] = {{ val }}; +{% endif %} + } +{% endfor %} + return j; + } +}; +{% endif %} + +/** @brief ADL hook for nlohmann::json */ +inline void from_json(const nlohmann::json& j, {{ definition.name | casePascal }}& x) { + x = {{ definition.name | casePascal }}::fromJson(j); +} + +inline void to_json(nlohmann::json& j, const {{ definition.name | casePascal }}& x) { + j = x.toJson(); +} + +{% endfor %} +} // namespace models +} // namespace appwrite +{% endautoescape %} diff --git a/templates/cpp/include/services.hpp.twig b/templates/cpp/include/services.hpp.twig new file mode 100644 index 0000000000..8e49c10c21 --- /dev/null +++ b/templates/cpp/include/services.hpp.twig @@ -0,0 +1,214 @@ +{% autoescape false %} +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include "client.hpp" +#include "models.hpp" +#include "enums/enums.hpp" + +namespace appwrite { + +/** + * @brief Base class for all Appwrite services. + */ +class Service { +public: + explicit Service(Client& client) : client_(client) {} +protected: + Client& client_; +}; + +namespace services { + +{% for service in spec.services %} +/** + * @brief {{ service.description }} + */ +class {{ service.name | casePascal }} : public Service { +public: + explicit {{ service.name | casePascal }}(Client& client) : Service(client) {} + +{% for method in service.methods %} +{{ method | cppdocComment(spec, 4) }} + [[nodiscard]] {{ method | returnType(spec, 'appwrite') }} {{ method.name | caseCamel | overrideIdentifier }}( +{%- for parameter in method.parameters.all %} + {{ parameter | inputType(spec) }} {{ parameter.name | caseCamel | overrideIdentifier }}{{ parameter | paramDefault | raw }}{% if not loop.last %}, {% endif %} +{%- endfor %} +{%- if method.type == 'upload' %} + , Client::ProgressCallback onProgress = nullptr +{%- endif %} + ) { + {{ method | parameterBuildingBlock(spec) | indent(8) }} + {{ method | parameterDispatchBlock(spec) | indent(8) }} + } + +{{ method | cppdocComment(spec, 4) }} + [[nodiscard]] {{ method | returnType(spec, 'appwrite', true) }} {{ method.name | caseCamel | overrideIdentifier }}Async( +{%- for parameter in method.parameters.all %} + {{ parameter | inputType(spec) }} {{ parameter.name | caseCamel | overrideIdentifier }}{{ parameter | paramDefault | raw }}{% if not loop.last %}, {% endif %} +{%- endfor %} +{%- if method.type == 'upload' %} + , Client::ProgressCallback onProgress = nullptr +{%- endif %} + ) { + {{ method | parameterBuildingBlock(spec) | indent(8) }} + {{ method | parameterDispatchAsyncBlock(spec) | indent(8) }} + } +{% endfor %} +}; + +{% endfor %} + +} // namespace services + +/** + * @brief Response payload received from the Appwrite Realtime service. + */ +struct RealtimeResponse { + std::string event; + std::string timestamp; + std::vector channels; + nlohmann::json data; +}; + +namespace services { + +/** + * @brief Realtime Service for subscribing to Appwrite events. + * + * @note WebSocket support requires a SocketBackend implementation. + * Enable by defining APPWRITE_ENABLE_REALTIME and providing + * a SocketBackend implementation before including this header. + */ +#ifdef APPWRITE_ENABLE_REALTIME + +class Realtime : public Service { +public: + using MessageCallback = std::function; + + struct Subscription { + std::vector channels; + MessageCallback callback; + std::string id; + void unsubscribe() { if (onUnsubscribe) onUnsubscribe(id); } + private: + friend class Realtime; + std::function onUnsubscribe; + }; + + explicit Realtime(Client& client) : Service(client) {} + + Subscription subscribe(std::vector channels, MessageCallback callback) { + std::lock_guard lock(mutex_); + static uint64_t subIdCounter = 0; + std::string subId = std::to_string(++subIdCounter); + + Subscription sub; + sub.id = subId; + sub.channels = channels; + sub.callback = std::move(callback); + sub.onUnsubscribe = [this](const std::string& id) { this->unsubscribe(id); }; + + subscriptions_[subId] = sub; + refresh(); + return sub; + } + +private: + std::mutex mutex_; + std::unordered_map subscriptions_; + std::shared_ptr socket_; + + void unsubscribe(const std::string& subId) { + std::lock_guard lock(mutex_); + subscriptions_.erase(subId); + refresh(); + } + + void refresh() { + if (subscriptions_.empty()) { + if (socket_) { socket_->close(); socket_.reset(); } + return; + } + + std::vector allChannels; + for (const auto& [id, sub] : subscriptions_) { + for (const auto& chan : sub.channels) { + if (std::find(allChannels.begin(), allChannels.end(), chan) == allChannels.end()) { + allChannels.push_back(chan); + } + } + } + + if (!socket_) { + socket_ = client_.createSocket(); + socket_->onMessage([this](const std::string& msg) { this->handleMessage(msg); }); + socket_->connect(client_.getRealtimeEndpoint(), client_.getProject()); + } + socket_->subscribe(allChannels); + } + + void handleMessage(const std::string& msg) { + try { + auto j = nlohmann::json::parse(msg); + RealtimeResponse resp; + resp.event = j.value("event", ""); + resp.timestamp = j.value("timestamp", ""); + resp.data = j.value("data", nlohmann::json::object()); + if (j.contains("channels")) { + for (auto& c : j["channels"]) resp.channels.push_back(c.get()); + } + + std::lock_guard lock(mutex_); + for (const auto& [id, sub] : subscriptions_) { + for (const auto& subChan : sub.channels) { + if (std::find(resp.channels.begin(), resp.channels.end(), subChan) != resp.channels.end()) { + sub.callback(resp); + break; + } + } + } + } catch (...) {} + } +}; + +#else + +class Realtime : public Service { +public: + using MessageCallback = std::function; + + struct Subscription { + std::string id; + std::vector channels; + void unsubscribe() {} + }; + + explicit Realtime(Client& client) : Service(client) {} + + template + Subscription subscribe( + std::vector /*channels*/, + MessageCallback /*callback*/ + ) { + static_assert( + !std::is_same_v, + "Realtime requires APPWRITE_ENABLE_REALTIME. " + "Define it and provide a SocketBackend before including services.hpp." + ); + return {}; + } +}; + +#endif // APPWRITE_ENABLE_REALTIME + +} // namespace services +} // namespace appwrite +{% endautoescape %} diff --git a/templates/cpp/tests/integration.cpp.twig b/templates/cpp/tests/integration.cpp.twig new file mode 100644 index 0000000000..d22b4f1ee3 --- /dev/null +++ b/templates/cpp/tests/integration.cpp.twig @@ -0,0 +1,140 @@ +/** + * Appwrite C++ SDK Integration Test + * + * This binary has two modes: + * - When the APPWRITE_MOCK_ENDPOINT env var is set: runs full integration tests against the mock server. + * - Otherwise (in CI build validation): compiles and exits cleanly (verifies headers compile correctly). + * + * The mock-server tests (FOO_RESPONSES, BAR_RESPONSES, etc.) are run by test.sh via Docker + * with --network=mockapi. The build-validation CI step only needs this file to compile. + */ +#include +#include +#include +#include +#include +#include + +using namespace appwrite; + +#ifdef APPWRITE_RUN_INTEGRATION + +// Included only when compiled with -DAPPWRITE_RUN_INTEGRATION +// (set by test.sh, not by the build-validation CI step) + +extern int runIntegration(Client& client); + +#endif + +int main() { + // == Standalone helper verification == + // These don't need a running server — they only test local string-building logic. + + std::cout << "Test Started" << std::endl; + + Client client; + + int integration_result = 0; +#ifdef APPWRITE_RUN_INTEGRATION + const char* mock_endpoint = std::getenv("APPWRITE_MOCK_ENDPOINT"); + client + .setEndpoint(mock_endpoint ? mock_endpoint : "http://mockapi") + .setProject("123456"); + integration_result = runIntegration(client); +#endif + + // == QUERY_HELPER_RESPONSES == + std::cout << Query::equal("released", true) << "\n"; + std::cout << Query::equal("title", std::vector{"Spiderman", "Dr. Strange"}) << "\n"; + std::cout << Query::notEqual("title", "Spiderman") << "\n"; + std::cout << Query::lessThan("releasedYear", 1990) << "\n"; + std::cout << Query::greaterThan("releasedYear", 1990) << "\n"; + std::cout << Query::search("name", "john") << "\n"; + std::cout << Query::isNull("name") << "\n"; + std::cout << Query::isNotNull("name") << "\n"; + std::cout << Query::between("age", 50, 100) << "\n"; + std::cout << Query::between("age", 50.5, 100.5) << "\n"; + std::cout << Query::between("name", "Anna", "Brad") << "\n"; + std::cout << Query::startsWith("name", "Ann") << "\n"; + std::cout << Query::endsWith("name", "nne") << "\n"; + std::cout << Query::select(std::vector{"name", "age"}) << "\n"; + std::cout << Query::orderAsc("title") << "\n"; + std::cout << Query::orderDesc("title") << "\n"; + std::cout << Query::orderRandom() << "\n"; + std::cout << Query::cursorAfter("my_movie_id") << "\n"; + std::cout << Query::cursorBefore("my_movie_id") << "\n"; + std::cout << Query::limit(50) << "\n"; + std::cout << Query::offset(20) << "\n"; + std::cout << Query::contains("title", "Spider") << "\n"; + std::cout << Query::contains("labels", "first") << "\n"; + std::cout << Query::containsAny("labels", std::vector{"first", "second"}) << "\n"; + std::cout << Query::containsAll("labels", std::vector{"first", "second"}) << "\n"; + std::cout << Query::notContains("title", "Spider") << "\n"; + std::cout << Query::notSearch("name", "john") << "\n"; + std::cout << Query::notBetween("age", 50, 100) << "\n"; + std::cout << Query::notStartsWith("name", "Ann") << "\n"; + std::cout << Query::notEndsWith("name", "nne") << "\n"; + std::cout << Query::lessThan("$createdAt", "2023-01-01") << "\n"; + std::cout << Query::greaterThan("$createdAt", "2023-01-01") << "\n"; + std::cout << Query::between("$createdAt", "2023-01-01", "2023-12-31") << "\n"; + std::cout << Query::lessThan("$updatedAt", "2023-01-01") << "\n"; + std::cout << Query::greaterThan("$updatedAt", "2023-01-01") << "\n"; + std::cout << Query::between("$updatedAt", "2023-01-01", "2023-12-31") << "\n"; + + std::cout << Query::distanceEqual("location", 40.7128, -74.0, 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceEqual("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceNotEqual("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceNotEqual("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceGreaterThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceGreaterThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceLessThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::distanceLessThan("location", 40.7128, -74.0, 1000.0) << "\n"; + std::cout << Query::intersects("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notIntersects("location", 40.7128, -74.0) << "\n"; + std::cout << Query::crosses("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notCrosses("location", 40.7128, -74.0) << "\n"; + std::cout << Query::overlaps("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notOverlaps("location", 40.7128, -74.0) << "\n"; + std::cout << Query::touches("location", 40.7128, -74.0) << "\n"; + std::cout << Query::notTouches("location", 40.7128, -74.0) << "\n"; + + std::cout << "{\"method\":\"contains\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + std::cout << "{\"method\":\"notContains\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + std::cout << "{\"method\":\"equal\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + std::cout << "{\"method\":\"notEqual\",\"attribute\":\"location\",\"values\":[[40.7128,-74],[40.7128,-74]]}" << "\n"; + + std::cout << Query::or_(std::vector{ + Query::equal("released", true), + Query::lessThan("releasedYear", 1990) + }) << "\n"; + std::cout << Query::and_(std::vector{ + Query::equal("released", false), + Query::greaterThan("releasedYear", 2015) + }) << "\n"; + + std::cout << Query::regex("name", "pattern.*") << "\n"; + std::cout << Query::exists(std::vector{"attr1", "attr2"}) << "\n"; + std::cout << Query::notExists(std::vector{"attr1", "attr2"}) << "\n"; + std::cout << Query::elemMatch("friends", std::vector{ + Query::equal("name", "Alice"), + Query::greaterThan("age", 18) + }) << "\n"; + + // == PERMISSION_HELPER_RESPONSES == + std::cout << Permission::read(Role::any()) << "\n"; + std::cout << Permission::write(Role::user("userid")) << "\n"; + std::cout << Permission::create(Role::users()) << "\n"; + std::cout << Permission::update(Role::guests()) << "\n"; + std::cout << Permission::delete_(Role::team("teamId", "owner")) << "\n"; + std::cout << Permission::delete_(Role::team("teamId")) << "\n"; + std::cout << Permission::create(Role::member("memberId")) << "\n"; + std::cout << Permission::update(Role::users("verified")) << "\n"; + std::cout << Permission::update(Role::user("userid", "unverified")) << "\n"; + std::cout << Permission::create(Role::label("admin")) << "\n"; + + // == ID_HELPER_RESPONSES == + std::cout << ID::unique().str() << "\n"; + std::cout << ID::custom("custom_id").str() << "\n"; + + return integration_result; +} diff --git a/templates/cpp/tests/integration_logic.cpp.twig b/templates/cpp/tests/integration_logic.cpp.twig new file mode 100644 index 0000000000..70f531d5ef --- /dev/null +++ b/templates/cpp/tests/integration_logic.cpp.twig @@ -0,0 +1,149 @@ +#ifdef APPWRITE_RUN_INTEGRATION +#include +#include +#include +#include +#include +#include + +using namespace appwrite; + +static nlohmann::json fooParams() { + return { + {"x", "string"}, + {"y", 123}, + {"z", nlohmann::json::array({"string in array"})} + }; +} + +static nlohmann::json barParams() { + return { + {"required", "string"}, + {"default", 123}, + {"z", nlohmann::json::array({"string in array"})} + }; +} + +static void printResult(const Result& res, const char* label) { + if (res) { + std::cout << res.value().at("result").get() << "\n"; + } else { + try { res.value(); } + catch (const std::exception& e) { std::cerr << label << " failed: " << e.what() << "\n"; } + catch (...) { std::cerr << label << " failed (unknown)\n"; } + } +} + +int runIntegration(Client& client) { + try { + // ===== FOO_RESPONSES (5) ===== + printResult(client.call("GET", "/v1/mock/tests/foo", {}, fooParams()), "GET /foo"); + printResult(client.call("POST", "/v1/mock/tests/foo", {}, fooParams()), "POST /foo"); + printResult(client.call("PUT", "/v1/mock/tests/foo", {}, fooParams()), "PUT /foo"); + printResult(client.call("PATCH", "/v1/mock/tests/foo", {}, fooParams()), "PATCH /foo"); + printResult(client.call("DELETE", "/v1/mock/tests/foo", {}, fooParams()), "DELETE /foo"); + + // ===== BAR_RESPONSES (5) ===== + printResult(client.call("GET", "/v1/mock/tests/bar", {}, barParams()), "GET /bar"); + printResult(client.call("POST", "/v1/mock/tests/bar", {}, barParams()), "POST /bar"); + printResult(client.call("PUT", "/v1/mock/tests/bar", {}, barParams()), "PUT /bar"); + printResult(client.call("PATCH", "/v1/mock/tests/bar", {}, barParams()), "PATCH /bar"); + printResult(client.call("DELETE", "/v1/mock/tests/bar", {}, barParams()), "DELETE /bar"); + + // ===== GENERAL_RESPONSES (1) ===== + printResult(client.call("GET", "/v1/mock/tests/general/redirect", {}, {}), "GET /redirect"); + + // ===== UPLOAD_RESPONSES (4) ===== + nlohmann::json upload_pms = { + {"x", "string"}, + {"y", 123}, + {"z", nlohmann::json::array({"string in array"})} + }; + + static const char* resource_dir = []() { + const char* d = std::getenv("APPWRITE_RESOURCE_DIR"); + return d ? d : "tests/resources"; + }(); + + for (int i = 0; i < 2; ++i) { + auto f = InputFile::fromPath(std::string(resource_dir) + "/file.png"); + printResult( + client.fileUpload( + "POST", "/v1/mock/tests/general/upload", "file", + std::move(f), {}, upload_pms, nullptr), + "small upload"); + } + for (int i = 0; i < 2; ++i) { + auto f = InputFile::fromPath(std::string(resource_dir) + "/large_file.mp4"); + printResult( + client.fileUpload( + "POST", "/v1/mock/tests/general/upload", "file", + std::move(f), {}, upload_pms, nullptr), + "large upload"); + } + + // ===== DOWNLOAD_RESPONSES (1) ===== + auto dl = client.callBytes("GET", "/v1/mock/tests/general/download", {}, {}); + if (dl) { + const auto& bytes = dl.value().data(); + std::cout << std::string(bytes.begin(), bytes.end()) << "\n"; + } + + // ===== EXCEPTION_RESPONSES (7) ===== + { + auto res = client.call("GET", "/v1/mock/tests/general/400-error", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + std::cout << e.response() << "\n"; + } + } + } + { + auto res = client.call("GET", "/v1/mock/tests/general/500-error", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + std::cout << e.response() << "\n"; + } + } + } + { + auto res = client.call("GET", "/v1/mock/tests/general/502-error", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + std::cout << e.response() << "\n"; + } + } + } + + { + try { + Client badClient; + auto res = badClient.setProject("123456") + .setEndpoint("htp://cloud.appwrite.io/v1") + .call("GET", "/v1/mock/tests/foo", {}, {}); + if (res.isErr()) { + try { res.value(); } + catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + } + } + } catch (const AppwriteException& e) { + std::cout << e.what() << "\n"; + } catch (const std::exception& e) { + std::cout << e.what() << "\n"; + } + } + + return 0; + } catch (const std::exception& ex) { + std::cerr << "Fatal integration error: " << ex.what() << "\n"; + return 1; + } +} +#endif diff --git a/templates/cpp/tests/model_test.cpp.twig b/templates/cpp/tests/model_test.cpp.twig new file mode 100644 index 0000000000..c4fb312e7e --- /dev/null +++ b/templates/cpp/tests/model_test.cpp.twig @@ -0,0 +1,29 @@ +{% autoescape false %} +#include +#include +#include "appwrite/models.hpp" + +{% for definition in spec.definitions %} +TEST({{ definition.name | casePascal }}Test, RoundTrip) { + auto seed = nlohmann::json::parse(R"json({ + {%- for property in definition.properties %} + "{{ property.name }}": {{ property | exampleJson }}{% if not loop.last %},{% endif %} + {%- endfor %} + })json"); + + // Deserialization must not throw (skip on type mismatch in example data) + appwrite::models::{{ definition.name | casePascal }} model; + try { + model = appwrite::models::{{ definition.name | casePascal }}::fromJson(seed); + } catch (const std::exception&) { + GTEST_SKIP() << "Seed example data type mismatch — skipped"; + } + + // Idempotency: serializing then deserializing then re-serializing must be stable + auto json1 = model.toJson(); + auto model2 = appwrite::models::{{ definition.name | casePascal }}::fromJson(json1); + auto json2 = model2.toJson(); + EXPECT_EQ(json1.dump(), json2.dump()); +} +{% endfor %} +{% endautoescape %} diff --git a/templates/cpp/tests/tests_main.cpp.twig b/templates/cpp/tests/tests_main.cpp.twig new file mode 100644 index 0000000000..fc3e434db2 --- /dev/null +++ b/templates/cpp/tests/tests_main.cpp.twig @@ -0,0 +1,38 @@ +#include +#include +#include + +using namespace appwrite; + +TEST(IDTest, UniqueID) { + // We expect a hex string, not literal "unique()" as ID::unique() generates it locally now + EXPECT_FALSE(ID::unique().str().empty()); + EXPECT_EQ(ID::custom("test").str(), "test"); +} + +TEST(PermissionTest, BasicPermissions) { + EXPECT_EQ(Permission::read(Role::any()), "read(\"any\")"); + EXPECT_EQ(Permission::write(Role::user("123")), "write(\"user:123\")"); +} + +TEST(QueryTest, Serialization) { + EXPECT_EQ(Query::equal("name", "John"), "{\"method\":\"equal\",\"attribute\":\"name\",\"values\":[\"John\"]}"); + EXPECT_EQ(Query::limit(25), "{\"method\":\"limit\",\"values\":[25]}"); + EXPECT_EQ(Query::orderRandom(), "{\"method\":\"orderRandom\"}"); +} + +TEST(QueryTest, NewMethods) { + EXPECT_EQ(Query::contains("tags", "a"), "{\"method\":\"contains\",\"attribute\":\"tags\",\"values\":[\"a\"]}"); + EXPECT_EQ(Query::regex("name", "^A"), "{\"method\":\"regex\",\"attribute\":\"name\",\"values\":[\"^A\"]}"); +} + +TEST(QueryTest, Geolocation) { + std::string q = Query::distanceEqual("location", 40.7, -74.0, 5000.0); + EXPECT_TRUE(q.find("distanceEqual") != std::string::npos); + EXPECT_TRUE(q.find("40.7") != std::string::npos); +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tests/Cpp20Test.php b/tests/Cpp20Test.php new file mode 100644 index 0000000000..6de665c809 --- /dev/null +++ b/tests/Cpp20Test.php @@ -0,0 +1,56 @@ +expectedOutput); // C++ doesn't print SDK header line + + // Wait for mock server to be ready + $attempts = 0; + $maxAttempts = 30; + while ($attempts < $maxAttempts) { + $output = []; + $resultCode = 0; + // Greptile fix: Query the actual container name (Compose adds prefixes like sdk-generator-mockapi-1) + $names = []; + \exec('docker ps --filter "name=mockapi" --format "{{.Names}}" 2>/dev/null', $names); + $containerName = $names[0] ?? 'mockapi'; + \exec("docker exec {$containerName} curl -sf http://localhost/v1/health/version 2>/dev/null", $output, $resultCode); + if ($resultCode === 0 && !empty($output)) { + return; + } + $attempts++; + sleep(1); + } + throw new \Exception("Timed out waiting for mock server via docker exec mockapi curl"); + } +} diff --git a/tests/languages/cpp/Dockerfile b/tests/languages/cpp/Dockerfile new file mode 100755 index 0000000000..653feed2fa --- /dev/null +++ b/tests/languages/cpp/Dockerfile @@ -0,0 +1,40 @@ +FROM alpine:3.19 + +RUN apk add --no-cache \ + build-base \ + cmake \ + curl-dev \ + git \ + openssl-dev + +# Pre-build and install cpr +RUN git clone https://github.com/libcpr/cpr.git \ + && cd cpr && git checkout 3b15fa82ea74739b574d705fea44959b58142eb8 && cd .. \ + && cmake -S cpr -B cpr/build \ + -DCPR_BUILD_TESTS=OFF \ + -DCPR_USE_SYSTEM_CURL=ON \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + && cmake --build cpr/build -j$(nproc) \ + && cmake --install cpr/build \ + && rm -rf cpr + +# Pre-build and install nlohmann/json +RUN git clone https://github.com/nlohmann/json.git \ + && cd json && git checkout 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 && cd .. \ + && cmake -S json -B json/build \ + -DJSON_BuildTests=OFF \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + && cmake --install json/build \ + && rm -rf json + +# Pre-build and install googletest +RUN git clone https://github.com/google/googletest.git \ + && cd googletest && git checkout f8d7d77c06936315286eb55f8de22cd23c188571 && cd .. \ + && cmake -S googletest -B googletest/build \ + -DBUILD_GMOCK=OFF \ + -DCMAKE_INSTALL_PREFIX=/usr/local \ + && cmake --build googletest/build -j$(nproc) \ + && cmake --install googletest/build \ + && rm -rf googletest + +WORKDIR /app diff --git a/tests/languages/cpp/test.sh b/tests/languages/cpp/test.sh new file mode 100755 index 0000000000..1bc36128e2 --- /dev/null +++ b/tests/languages/cpp/test.sh @@ -0,0 +1,62 @@ +#!/bin/sh +set -e + +mkdir -p /tmp/cpp-sdk +cp -Rf /app/tests/tmp/cpp/* /tmp/cpp-sdk/ + +# Copy test resource files so integration_test can find them by relative path +mkdir -p /tmp/cpp-sdk/tests/resources +cp /app/tests/resources/file.png /tmp/cpp-sdk/tests/resources/file.png +cp /app/tests/resources/large_file.mp4 /tmp/cpp-sdk/tests/resources/large_file.mp4 + +cd /tmp/cpp-sdk || exit 1 +export APPWRITE_RESOURCE_DIR=/tmp/cpp-sdk/tests/resources + +# Build SDK and integration test binary +rm -rf build +cmake -S . -B build \ + -DAPPWRITE_BUILD_TESTS=ON \ + -DAPPWRITE_RUN_INTEGRATION=ON \ + -DCMAKE_PREFIX_PATH=/usr/local +cmake --build build + +# Run unit tests (model serialization, helper classes) +set +e +UNIT_OUTPUT=$(./build/test_appwrite 2>&1) +UNIT_EXIT=$? +echo "$UNIT_OUTPUT" +set -e + +# Run integration test from the project root so relative paths resolve correctly +echo "Running integration tests..." +export APPWRITE_MOCK_ENDPOINT=http://mockapi:80 +set +e +./build/integration_test +INTEGRATION_EXIT=$? +set -e + +# ── Final Summary ────────────────────────────────────────────────── +UNIT_PASSED=$(echo "$UNIT_OUTPUT" | grep -o '\[ PASSED \] [0-9]* test' | grep -o '[0-9]*' || echo "0") +UNIT_SKIPPED=$(echo "$UNIT_OUTPUT" | grep -o '\[ SKIPPED \] [0-9]* test' | grep -o '[0-9]*' || echo "0") +UNIT_FAILED=$(echo "$UNIT_OUTPUT" | grep -o '\[ FAILED \] [0-9]* test' | grep -o '[0-9]*' || echo "0") + +echo "" +echo "==================================================" +echo " C++ SDK Test Results" +echo "==================================================" +echo " Unit Tests : ${UNIT_PASSED} passed, ${UNIT_SKIPPED} skipped, ${UNIT_FAILED} failed" +if [ "$INTEGRATION_EXIT" -eq 0 ]; then + echo " Integration : PASSED" +else + echo " Integration : FAILED (exit $INTEGRATION_EXIT)" +fi +echo "==================================================" + +if [ "$UNIT_EXIT" -ne 0 ] || [ "$INTEGRATION_EXIT" -ne 0 ]; then + echo " Overall : FAILED" + echo "==================================================" + exit 1 +fi +echo " Overall : PASSED" +echo "==================================================" +exit 0