diff --git a/CHANGES.md b/CHANGES.md index bc903e4b31..74b46b7edc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,266 +1,654 @@ +# Version 1.8.0 + +## What's Changed + +### Notable changes + +* Do not allow full range in [#9847](https://github.com/appwrite/appwrite/pull/9847) +* Expose internal id as a part of auto increment id in [#9713](https://github.com/appwrite/appwrite/pull/9713) +* Expose sequence in [#9870](https://github.com/appwrite/appwrite/pull/9870) +* Add flutter 3.32 and dart 3.8 runtimes in [#9914](https://github.com/appwrite/appwrite/pull/9914) +* Shorten commit url and branch url in [#9919](https://github.com/appwrite/appwrite/pull/9919) +* Remove powered by from error pages in [#9927](https://github.com/appwrite/appwrite/pull/9927) +* Enable resource limits on GIF previews in [#9940](https://github.com/appwrite/appwrite/pull/9940) +* Only run maintenance task for projects accessed in last 24 hours in [#9989](https://github.com/appwrite/appwrite/pull/9989) +* Add increment + decrement routes in [#9986](https://github.com/appwrite/appwrite/pull/9986) +* Only run maintenance task for projects accessed in last 30 days in [#9995](https://github.com/appwrite/appwrite/pull/9995) +* Update appwrite-assistant image version to 0.8.3 in [#10003](https://github.com/appwrite/appwrite/pull/10003) +* Update emails to use button in [#9590](https://github.com/appwrite/appwrite/pull/9590) +* Create commit & branch url for first git deployment when site is linked to repo in [#9969](https://github.com/appwrite/appwrite/pull/9969) +* Handle React Native schemes in [#9650](https://github.com/appwrite/appwrite/pull/9650) +* Handle origin validation for web extensions in [#10107](https://github.com/appwrite/appwrite/pull/10107) +* Preview text for emails in [#10198](https://github.com/appwrite/appwrite/pull/10198) +* Create email target when using email OTP registration in [#10224](https://github.com/appwrite/appwrite/pull/10224) +* Add CSV imports in [#10231](https://github.com/appwrite/appwrite/pull/10231) +* Add support for svg favicons in [#10255](https://github.com/appwrite/appwrite/pull/10255) +* Realtime support for bulk api in [#10096](https://github.com/appwrite/appwrite/pull/10096) +* Skip redundant subqueries in users list route in [#10297](https://github.com/appwrite/appwrite/pull/10297) +* Add native sign in with Apple function template in [#10286](https://github.com/appwrite/appwrite/pull/10286) +* Add support for HEAD requests in [#10304](https://github.com/appwrite/appwrite/pull/10304) +* Update invite email copy in [#10309](https://github.com/appwrite/appwrite/pull/10309) +* Increase dynamic API key expiration in [#10328](https://github.com/appwrite/appwrite/pull/10328) +* Add TablesDB service in [#10333](https://github.com/appwrite/appwrite/pull/10333) +* Add execution.deploymentId to response model in [#10357](https://github.com/appwrite/appwrite/pull/10357) +* Switch Union China Pay to just Union Pay in [#10372](https://github.com/appwrite/appwrite/pull/10372) and [#10382](https://github.com/appwrite/appwrite/pull/10382) +* Add execution id and log id to response headers in [#10379](https://github.com/appwrite/appwrite/pull/10379) +* Add executionId and client IP to function headers in [#9147](https://github.com/appwrite/appwrite/pull/9147) +* Allow HEAD requests in function executions in [#10385](https://github.com/appwrite/appwrite/pull/10385) +* Add support for select queries when listing deployments in [#10380](https://github.com/appwrite/appwrite/pull/10380) +* Add spatial type attributes in [#10356](https://github.com/appwrite/appwrite/pull/10356) and [#10443](https://github.com/appwrite/appwrite/pull/10443) +* Add realtime support for bulk upserts in [#10425](https://github.com/appwrite/appwrite/pull/10425) +* Add previewUrl to vcs comment from vcs controller in [#10396](https://github.com/appwrite/appwrite/pull/10396) +* Rename verification SDK methods to be more specific in [#10606](https://github.com/appwrite/appwrite/pull/10606) +* Add project name in email subject in [#10609](https://github.com/appwrite/appwrite/pull/10609) +* Throw error when email is not available for account verification in [#10533](https://github.com/appwrite/appwrite/pull/10533) +* Add support for transactions in [#10023](https://github.com/appwrite/appwrite/pull/10023) and [#10624](https://github.com/appwrite/appwrite/pull/10624) +* Use bcc only emails for smtp in [#10644](https://github.com/appwrite/appwrite/pull/10644) + +### Fixes + +* Fix rules on active deployment in [#9902](https://github.com/appwrite/appwrite/pull/9902) +* Fix for upserts with differing optional parameter sets in [#9928](https://github.com/appwrite/appwrite/pull/9928) +* Fix teams deletion in [#9888](https://github.com/appwrite/appwrite/pull/9888) +* Fix deletion logic in [#9938](https://github.com/appwrite/appwrite/pull/9938) +* Update database for upsert fix in [#9941](https://github.com/appwrite/appwrite/pull/9941) +* Fix expire format in account recovery, verification, phone and mfa in [#9600](https://github.com/appwrite/appwrite/pull/9600) +* Fix github comments and deployment creation on branch deletion in [#9949](https://github.com/appwrite/appwrite/pull/9949) +* Fix cache issues with proxy for deployment download in [#9971](https://github.com/appwrite/appwrite/pull/9971) +* Redirect rule parent resource in [#9982](https://github.com/appwrite/appwrite/pull/9982) +* Fix usage queues in [#9946](https://github.com/appwrite/appwrite/pull/9946) +* Transfer control for the migration in [#9997](https://github.com/appwrite/appwrite/pull/9997) +* Prevent 'Attribute "factors" must be an array' error in [#10004](https://github.com/appwrite/appwrite/pull/10004) +* Fix all vcs urls missing region in [#9998](https://github.com/appwrite/appwrite/pull/9998) +* Add readable error for csv imports in [#9947](https://github.com/appwrite/appwrite/pull/9947) +* Fix missing screenshot logs in [#10024](https://github.com/appwrite/appwrite/pull/10024) +* Update executor to fix s3 endpoint bug in [#10036](https://github.com/appwrite/appwrite/pull/10036) +* Fix build duration calculation in [#10053](https://github.com/appwrite/appwrite/pull/10053) +* Fix logs order in [#10052](https://github.com/appwrite/appwrite/pull/10052) +* Fix platform check for Sites with automatic rule in [#10043](https://github.com/appwrite/appwrite/pull/10043) +* Increase cache ttl to ensure hits in [#10079](https://github.com/appwrite/appwrite/pull/10079) +* Fix connect to existing repo flow in [#10034](https://github.com/appwrite/appwrite/pull/10034) +* Fix migrations path and type in [#10090](https://github.com/appwrite/appwrite/pull/10090) +* Fix JWT authentication database selection for admin mode in [#10098](https://github.com/appwrite/appwrite/pull/10098) +* Use _APP_CONSOLE_DOMAIN, if not found, then use _APP_DOMAIN in [#9999](https://github.com/appwrite/appwrite/pull/9999) +* Fix file tokens not working on file-security in [#10120](https://github.com/appwrite/appwrite/pull/10120) +* Fix build activation race condition in [#9952](https://github.com/appwrite/appwrite/pull/9952) +* Changed the default permission param of upsert document in [#10129](https://github.com/appwrite/appwrite/pull/10129) +* Fix success validation in oauth2 redirect in [#10130](https://github.com/appwrite/appwrite/pull/10130) +* Update OAuth2 redirect URLs in [#10119](https://github.com/appwrite/appwrite/pull/10119) +* Fix specs with new env vars in [#10135](https://github.com/appwrite/appwrite/pull/10135) +* Skip deployment when commit is created by us in [#10187](https://github.com/appwrite/appwrite/pull/10187) +* Use direct source for file-preview when empty in [#10181](https://github.com/appwrite/appwrite/pull/10181) +* Better error message for invalid function scheduled time in [#10201](https://github.com/appwrite/appwrite/pull/10201) +* Add defaultBranch in getRepository response in [#10190](https://github.com/appwrite/appwrite/pull/10190) +* Filter sequence to int because any models skip rule checks in [#10221](https://github.com/appwrite/appwrite/pull/10221) +* Fix 500 errors on robots and humans txt files in [#10248](https://github.com/appwrite/appwrite/pull/10248) +* Fix atomic number ops with limit 0 in [#10264](https://github.com/appwrite/appwrite/pull/10264) +* Update build command for flutter in [#10288](https://github.com/appwrite/appwrite/pull/10288) +* Add a fallback locale in [#10307](https://github.com/appwrite/appwrite/pull/10307) +* Fix variables sharing across resources in [#10308](https://github.com/appwrite/appwrite/pull/10308) +* Fix uncaught invalid arg in [#10318](https://github.com/appwrite/appwrite/pull/10318) +* Add missing upsert event in [#10317](https://github.com/appwrite/appwrite/pull/10317) +* Improve font reliability in [#10332](https://github.com/appwrite/appwrite/pull/10332) +* Truncate logs in function worker in [#9773](https://github.com/appwrite/appwrite/pull/9773) +* Fix event template configuration issues in [#10350](https://github.com/appwrite/appwrite/pull/10350) +* Fix users events & missed publisher logic for Functions in [#10348](https://github.com/appwrite/appwrite/pull/10348) +* Fix incorrect file token expiry in [#10329](https://github.com/appwrite/appwrite/pull/10329) +* Fix upserting that makes no change in [#10363](https://github.com/appwrite/appwrite/pull/10363) and [#10364](https://github.com/appwrite/appwrite/pull/10364) +* Fix domain validator in [#10374](https://github.com/appwrite/appwrite/pull/10374) +* Apply sequence integer casting and attribute cleanup fixes to Row model, TablesDB tests, and document processing in [#10383](https://github.com/appwrite/appwrite/pull/10383) +* Fix domain validator in [#10386](https://github.com/appwrite/appwrite/pull/10386) +* Fix sequence removal in [#10388](https://github.com/appwrite/appwrite/pull/10388) +* Fix TablesDB scopes in [#10387](https://github.com/appwrite/appwrite/pull/10387) +* Fix request filter in [#10389](https://github.com/appwrite/appwrite/pull/10389) +* Fix nested filter selects in [#10393](https://github.com/appwrite/appwrite/pull/10393) +* Fix readonly attr stripping on write in [#10405](https://github.com/appwrite/appwrite/pull/10405) +* Replace %s with mustache placeholder in [#10392](https://github.com/appwrite/appwrite/pull/10392) +* Support array headers for set-cookie in [#10427](https://github.com/appwrite/appwrite/pull/10427) +* Fix put prefs structure validation in [#10436](https://github.com/appwrite/appwrite/pull/10436) +* Fix oauth identity check in [#10460](https://github.com/appwrite/appwrite/pull/10460) +* Fix check in [#10489](https://github.com/appwrite/appwrite/pull/10489) +* Fix database usage metrics in [#10483](https://github.com/appwrite/appwrite/pull/10483) +* Throw appropriate 400s from request filters in [#10502](https://github.com/appwrite/appwrite/pull/10502) +* Catch query exception on bucket/file list in [#10505](https://github.com/appwrite/appwrite/pull/10505) +* Use outputDirectory attribute from deployment in [#10571](https://github.com/appwrite/appwrite/pull/10571) +* Fix buildOutput attribute name in deployment check in [#10572](https://github.com/appwrite/appwrite/pull/10572) +* Update database for nested selection fix in [#10577](https://github.com/appwrite/appwrite/pull/10577) +* Auto-allow sites domain for OAuth in [#10503](https://github.com/appwrite/appwrite/pull/10503) +* Handle OIDC well-known endpoint errors in [#10589](https://github.com/appwrite/appwrite/pull/10589) +* Correct invalid template links in Create temporary deployment endpoint in [#10581](https://github.com/appwrite/appwrite/pull/10581) +* Update broken create table links in TablesDB docs in [#10592](https://github.com/appwrite/appwrite/pull/10592) +* Fix cross API compatibility in [#10626](https://github.com/appwrite/appwrite/pull/10626) +* Fix code 0 from databases on realtime in [#10631](https://github.com/appwrite/appwrite/pull/10631) +* Throw duplicate error when function id already exists in [#10618](https://github.com/appwrite/appwrite/pull/10618) + +### Miscellaneous + +* Fix task coroutine hooks in [#9850](https://github.com/appwrite/appwrite/pull/9850) +* Feat sync encrypt updates in [#9871](https://github.com/appwrite/appwrite/pull/9871) +* Revert "Feat sync encrypt updates" in [#9877](https://github.com/appwrite/appwrite/pull/9877) +* Add builds worker group in [#9872](https://github.com/appwrite/appwrite/pull/9872) +* Revert encrypted attribute changes in [#9898](https://github.com/appwrite/appwrite/pull/9898) +* Update sdk generator and sdks in [#9849](https://github.com/appwrite/appwrite/pull/9849) +* Release cli in [#9900](https://github.com/appwrite/appwrite/pull/9900) +* Improve how rules are fetched in [#9915](https://github.com/appwrite/appwrite/pull/9915) +* Sync 1.6 in [#9920](https://github.com/appwrite/appwrite/pull/9920) +* Update messaging library in [#9764](https://github.com/appwrite/appwrite/pull/9764) +* Disable TCP hook on stats resources in [#9932](https://github.com/appwrite/appwrite/pull/9932) +* Remove JSON index on roles due to MySQL bug in [#9924](https://github.com/appwrite/appwrite/pull/9924) +* Update queue in [#9936](https://github.com/appwrite/appwrite/pull/9936) +* Fix flaky account tests in [#9954](https://github.com/appwrite/appwrite/pull/9954) +* Fix flaky messaging test in [#9957](https://github.com/appwrite/appwrite/pull/9957) +* Make usage tests robust in [#9956](https://github.com/appwrite/appwrite/pull/9956) +* Increase deployment timeouts in tests in [#9955](https://github.com/appwrite/appwrite/pull/9955) +* Graceful shutdown on SIGTERM in [#9890](https://github.com/appwrite/appwrite/pull/9890) +* Bring back telemetry for storage in [#9903](https://github.com/appwrite/appwrite/pull/9903) +* Update version to 1.7.4 and add experimental warnings in [#9959](https://github.com/appwrite/appwrite/pull/9959) +* Return queue pre-fetch results in [#9731](https://github.com/appwrite/appwrite/pull/9731) +* Update SDK versions in [#9987](https://github.com/appwrite/appwrite/pull/9987) +* Restore unique filename for health check #9842 in [#9993](https://github.com/appwrite/appwrite/pull/9993) +* Add after build hook in [#9996](https://github.com/appwrite/appwrite/pull/9996) +* Remove endpoint selector in [#10000](https://github.com/appwrite/appwrite/pull/10000) +* Use static code instead of astro in tests in [#9966](https://github.com/appwrite/appwrite/pull/9966) +* Add ref param to vcs list contents in [#9991](https://github.com/appwrite/appwrite/pull/9991) +* Update coderabbit config file in [#10005](https://github.com/appwrite/appwrite/pull/10005) +* TAR support in [#10016](https://github.com/appwrite/appwrite/pull/10016) +* Update delete project scope in [#10017](https://github.com/appwrite/appwrite/pull/10017) +* Lazy-load relationships in [#9669](https://github.com/appwrite/appwrite/pull/9669) +* Revert "Feat: Lazy-load relationships" in [#10018](https://github.com/appwrite/appwrite/pull/10018) +* Revert "Update delete project scope" in [#10022](https://github.com/appwrite/appwrite/pull/10022) +* 1.8.x in [#9985](https://github.com/appwrite/appwrite/pull/9985) +* Update cli version and add bulk operation warnings in [#10007](https://github.com/appwrite/appwrite/pull/10007) +* Update Appwrite description to include Sites, add MCP to products list in [#9867](https://github.com/appwrite/appwrite/pull/9867) +* Update README.md in [#10026](https://github.com/appwrite/appwrite/pull/10026) +* Fix duplication of platforms in swagger specs in [#10008](https://github.com/appwrite/appwrite/pull/10008) +* Update react native sdk and changelog in [#10025](https://github.com/appwrite/appwrite/pull/10025) +* Update delete project signature in [#10028](https://github.com/appwrite/appwrite/pull/10028) +* Fix Golang SDK examples for docs in [#10001](https://github.com/appwrite/appwrite/pull/10001) +* Revert "worker: Graceful shutdown on SIGTERM" in [#10035](https://github.com/appwrite/appwrite/pull/10035) +* Fix benchmark CI in [#10055](https://github.com/appwrite/appwrite/pull/10055) +* Use ->action(...)) instead of ->callback([$this, 'action']); in [#9967](https://github.com/appwrite/appwrite/pull/9967) +* Override project via custom domains log in [#10011](https://github.com/appwrite/appwrite/pull/10011) +* Add database worker job logging in [#10056](https://github.com/appwrite/appwrite/pull/10056) +* Add runtimeEntrypoint param in [#10062](https://github.com/appwrite/appwrite/pull/10062) +* Add missing injections in [#10061](https://github.com/appwrite/appwrite/pull/10061) +* Replace Console loop with Swoole Timer for stats resource m… in [#10054](https://github.com/appwrite/appwrite/pull/10054) +* Update README.md in [#10063](https://github.com/appwrite/appwrite/pull/10063) +* Fix parameter order in action function for robots.txt route in [#10067](https://github.com/appwrite/appwrite/pull/10067) +* Preview endpoint logging in [#10068](https://github.com/appwrite/appwrite/pull/10068) +* Fix flakyness of account tests in [#10066](https://github.com/appwrite/appwrite/pull/10066) +* Update cli to 8.1.0 and add changelog in [#10070](https://github.com/appwrite/appwrite/pull/10070) +* Update composer.json and composer.lock to include appwrite-lab… in [#10051](https://github.com/appwrite/appwrite/pull/10051) +* Fix tests, for `Cloud` in [#10085](https://github.com/appwrite/appwrite/pull/10085) +* Update README.md in [#10084](https://github.com/appwrite/appwrite/pull/10084) +* Revert "chore: update composer.json and composer.lock to include appwrite-lab…" in [#10086](https://github.com/appwrite/appwrite/pull/10086) +* Update README to add Bulk API link in [#10095](https://github.com/appwrite/appwrite/pull/10095) +* Add redis publisher to schedule base if available in [#10099](https://github.com/appwrite/appwrite/pull/10099) +* Fix site template test in [#10104](https://github.com/appwrite/appwrite/pull/10104) +* Update nodejs 17.1.0 in [#10088](https://github.com/appwrite/appwrite/pull/10088) +* Update README.md to add Upsert announcement in [#10112](https://github.com/appwrite/appwrite/pull/10112) +* Reduce delete batch size in [#10128](https://github.com/appwrite/appwrite/pull/10128) +* Update README.md in [#10134](https://github.com/appwrite/appwrite/pull/10134) +* Speed up tests in [#10127](https://github.com/appwrite/appwrite/pull/10127) +* Update cli to 8.2.0 in [#10136](https://github.com/appwrite/appwrite/pull/10136) +* Prevent injected $user from being shadowed in [#10150](https://github.com/appwrite/appwrite/pull/10150) +* Update react native to 0.10.1 and dotnet to 0.14.0 in [#10138](https://github.com/appwrite/appwrite/pull/10138) +* Update README.md in [#10153](https://github.com/appwrite/appwrite/pull/10153) +* Update cli 8.2.1 in [#10155](https://github.com/appwrite/appwrite/pull/10155) +* Fix build usage specification in [#10157](https://github.com/appwrite/appwrite/pull/10157) +* Handle redirect validator in specs + GraphQL type mapper in [#10158](https://github.com/appwrite/appwrite/pull/10158) +* Update dart 16.1.0, flutter 17.0.2 and cli 8.2.2 in [#10161](https://github.com/appwrite/appwrite/pull/10161) +* Improve invalid scheme error in origin check in [#10164](https://github.com/appwrite/appwrite/pull/10164) +* 1.7.x in [#9897](https://github.com/appwrite/appwrite/pull/9897) +* Added the cases of null permissions in the upsert route and update th… in [#10179](https://github.com/appwrite/appwrite/pull/10179) +* Fix 1.7.x specs in [#10197](https://github.com/appwrite/appwrite/pull/10197) +* Suppress git-action exception in deployment worker in [#10199](https://github.com/appwrite/appwrite/pull/10199) +* Stats-usage on redis in [#10156](https://github.com/appwrite/appwrite/pull/10156) +* Fix templates on `1.7.x`. in [#10203](https://github.com/appwrite/appwrite/pull/10203) +* Change preview & body for MFA email in [#10205](https://github.com/appwrite/appwrite/pull/10205) +* Add docs for nestedType, encode, from and toMap in [#10204](https://github.com/appwrite/appwrite/pull/10204) +* Update sdks 1.7.x in [#10202](https://github.com/appwrite/appwrite/pull/10202) +* Update migration release in [#10222](https://github.com/appwrite/appwrite/pull/10222) +* Remove sequence on incoming docs in [#10228](https://github.com/appwrite/appwrite/pull/10228) +* Filter certificates renewal task in maintenance by region in [#10227](https://github.com/appwrite/appwrite/pull/10227) +* Move changelog to sdks platforms array in [#10233](https://github.com/appwrite/appwrite/pull/10233) +* Update changelog and sdk gen in [#10247](https://github.com/appwrite/appwrite/pull/10247) +* Telemetry for cache hits and misses in [#10240](https://github.com/appwrite/appwrite/pull/10240) +* Add model examples + additonal examples to specs in [#10249](https://github.com/appwrite/appwrite/pull/10249) +* Update favicons endpoint to fallback to ico instead of throwing error in [#10260](https://github.com/appwrite/appwrite/pull/10260) +* Update README.md in [#10259](https://github.com/appwrite/appwrite/pull/10259) +* Check CAA record before issuing certificate in [#10258](https://github.com/appwrite/appwrite/pull/10258) +* Revert "Check CAA record before issuing certificate" in [#10263](https://github.com/appwrite/appwrite/pull/10263) +* Test var id attribute in [#10243](https://github.com/appwrite/appwrite/pull/10243) +* Add type attribute to the database creation flow in [#10266](https://github.com/appwrite/appwrite/pull/10266) +* Add CAA validator in [#10267](https://github.com/appwrite/appwrite/pull/10267) +* Update database type to grids and legacy in [#10273](https://github.com/appwrite/appwrite/pull/10273) +* Update README.md in [#10272](https://github.com/appwrite/appwrite/pull/10272) +* Upgrade composer for utopia migration in [#10274](https://github.com/appwrite/appwrite/pull/10274) +* Update SDK generator and sdks in [#10271](https://github.com/appwrite/appwrite/pull/10271) +* Fix wrong resource path for audits in [#10279](https://github.com/appwrite/appwrite/pull/10279) +* Update `grid` on resource events in [#10282](https://github.com/appwrite/appwrite/pull/10282) +* Add readonly param to sequence, databaseId and collectionId in [#10278](https://github.com/appwrite/appwrite/pull/10278) +* Update migrations in [#10283](https://github.com/appwrite/appwrite/pull/10283) +* Add placeholder detection in [#10284](https://github.com/appwrite/appwrite/pull/10284) +* Update docker base to 0.10.3 in [#10285](https://github.com/appwrite/appwrite/pull/10285) +* Make check for adding warning header stricter in [#10293](https://github.com/appwrite/appwrite/pull/10293) +* Fix databases worker cache clearing bug in [#10294](https://github.com/appwrite/appwrite/pull/10294) +* Reapply Redis functions queue in [#10299](https://github.com/appwrite/appwrite/pull/10299) +* Add new database query type tests in [#10296](https://github.com/appwrite/appwrite/pull/10296) +* Update package in [#10312](https://github.com/appwrite/appwrite/pull/10312) +* Update required attributes in [#10311](https://github.com/appwrite/appwrite/pull/10311) +* Remove experiment warnings from bulk methods in [#10310](https://github.com/appwrite/appwrite/pull/10310) +* Update README.md in [#10313](https://github.com/appwrite/appwrite/pull/10313) +* Added internal file param to handle upload to internal bucket in [#10321](https://github.com/appwrite/appwrite/pull/10321) +* Remove temp logging in [#10302](https://github.com/appwrite/appwrite/pull/10302) +* Improve sites test for stability in [#10331](https://github.com/appwrite/appwrite/pull/10331) +* Database lib bump to 0.71.15 in [#10336](https://github.com/appwrite/appwrite/pull/10336) +* Clarify userId param in endpoints that create accounts in [#10117](https://github.com/appwrite/appwrite/pull/10117) +* Upgrade HTTP in [#10338](https://github.com/appwrite/appwrite/pull/10338) +* Remove unnessessary external dependnecies in [#10343](https://github.com/appwrite/appwrite/pull/10343) +* Sync main into 1.7.x in [#10347](https://github.com/appwrite/appwrite/pull/10347) +* Fix TablesDB casing in [#10346](https://github.com/appwrite/appwrite/pull/10346) +* Add cookies test in [#10352](https://github.com/appwrite/appwrite/pull/10352) +* Update token tests with jwt decode in [#10354](https://github.com/appwrite/appwrite/pull/10354) +* Utilize assets server for fonts in [#10358](https://github.com/appwrite/appwrite/pull/10358) +* Sync main into 1.7.x in [#10359](https://github.com/appwrite/appwrite/pull/10359) +* Bump 1.7.x in [#10365](https://github.com/appwrite/appwrite/pull/10365) +* Fix queue health in [#10369](https://github.com/appwrite/appwrite/pull/10369) +* Allow publisher messaging override in scheduler in [#10370](https://github.com/appwrite/appwrite/pull/10370) +* Add replacewith and deprecated since to account methods in [#10377](https://github.com/appwrite/appwrite/pull/10377) +* Update README.md in [#10376](https://github.com/appwrite/appwrite/pull/10376) +* Update CLI in [#10390](https://github.com/appwrite/appwrite/pull/10390) +* Update default method in description in [#10391](https://github.com/appwrite/appwrite/pull/10391) +* Rename namespace from tables-db to tablesdb in specs in [#10395](https://github.com/appwrite/appwrite/pull/10395) +* Update tables group in specs in [#10394](https://github.com/appwrite/appwrite/pull/10394) +* Update description for upsert methods in [#10397](https://github.com/appwrite/appwrite/pull/10397) +* Update README.md in [#10401](https://github.com/appwrite/appwrite/pull/10401) +* Added handling of database resources after migration in [#10400](https://github.com/appwrite/appwrite/pull/10400) +* Revert "Added handling of database resources after migration" in [#10406](https://github.com/appwrite/appwrite/pull/10406) +* Remove sdk deprecation warnings in [#10408](https://github.com/appwrite/appwrite/pull/10408) +* Mark Row response model's param with readonly in [#10409](https://github.com/appwrite/appwrite/pull/10409) +* Update exception thrown when svg sanitization fails in [#10416](https://github.com/appwrite/appwrite/pull/10416) +* Fix allow null params in [#10417](https://github.com/appwrite/appwrite/pull/10417) +* Allow running tests with specific response format in [#10418](https://github.com/appwrite/appwrite/pull/10418) +* Make webhooks publisher overridable in [#10419](https://github.com/appwrite/appwrite/pull/10419) +* Check audits logs in [#10414](https://github.com/appwrite/appwrite/pull/10414) +* Remove direct publisher calls in [#10420](https://github.com/appwrite/appwrite/pull/10420) +* removed spatial type response and will be using the json type for the… in [#10433](https://github.com/appwrite/appwrite/pull/10433) +* Add tests for new time helpers in [#10437](https://github.com/appwrite/appwrite/pull/10437) +* Move projects.list() to module in [#10441](https://github.com/appwrite/appwrite/pull/10441) +* Update cli to 9.1.0 in [#10442](https://github.com/appwrite/appwrite/pull/10442) +* Add requestBody param examples in specs in [#10431](https://github.com/appwrite/appwrite/pull/10431) +* Fix mysql tests in [#10445](https://github.com/appwrite/appwrite/pull/10445) +* Upgrade platform lib to have older queue lib in [#10447](https://github.com/appwrite/appwrite/pull/10447) +* Fix router compression in [#10452](https://github.com/appwrite/appwrite/pull/10452) +* Upgrade http lib for backwards compatible default param in [#10455](https://github.com/appwrite/appwrite/pull/10455) +* Update examples in [#10444](https://github.com/appwrite/appwrite/pull/10444) +* Automatic pr creation in sdk release script in [#10457](https://github.com/appwrite/appwrite/pull/10457) +* Remove avatars command from cli in [#10454](https://github.com/appwrite/appwrite/pull/10454) +* Remove deno from platforms array in [#10453](https://github.com/appwrite/appwrite/pull/10453) +* Spatial type attributes sdk updates in [#10463](https://github.com/appwrite/appwrite/pull/10463) +* Stats resources try catch in [#10469](https://github.com/appwrite/appwrite/pull/10469) +* Move proxy endpoints to modules in [#10470](https://github.com/appwrite/appwrite/pull/10470) +* Add certificate validation override in [#10471](https://github.com/appwrite/appwrite/pull/10471) +* Generate SDKs in [#10475](https://github.com/appwrite/appwrite/pull/10475) +* Spatial test tablesdb updates in [#10473](https://github.com/appwrite/appwrite/pull/10473) +* Add colors to certificate logs in [#10438](https://github.com/appwrite/appwrite/pull/10438) +* appwrite db bump in [#10479](https://github.com/appwrite/appwrite/pull/10479) +* Bump database in [#10480](https://github.com/appwrite/appwrite/pull/10480) +* Health db queues in [#10482](https://github.com/appwrite/appwrite/pull/10482) +* Attempt small size for website dependency in [#10485](https://github.com/appwrite/appwrite/pull/10485) +* Worker stop in [#10498](https://github.com/appwrite/appwrite/pull/10498) +* Update database in [#10506](https://github.com/appwrite/appwrite/pull/10506) +* Stats resources and usage sorting by unique field in [#10472](https://github.com/appwrite/appwrite/pull/10472) +* Add spatial column validation during required mode and tests for exis… in [#10509](https://github.com/appwrite/appwrite/pull/10509) +* Sub query variables order by in [#10513](https://github.com/appwrite/appwrite/pull/10513) +* Update README.md in [#10514](https://github.com/appwrite/appwrite/pull/10514) +* bump database 1.5.0 in [#10515](https://github.com/appwrite/appwrite/pull/10515) +* Don't remove required attributes in [#10516](https://github.com/appwrite/appwrite/pull/10516) +* Catch query exception on bulk update/delete in [#10517](https://github.com/appwrite/appwrite/pull/10517) +* Update cli to 10.0.0 in [#10511](https://github.com/appwrite/appwrite/pull/10511) +* Add type_enum support and update docs in [#10496](https://github.com/appwrite/appwrite/pull/10496) +* Improve code readability for schedules in [#10522](https://github.com/appwrite/appwrite/pull/10522) +* Include response model enum names in [#10538](https://github.com/appwrite/appwrite/pull/10538) +* SDK releases in [#10539](https://github.com/appwrite/appwrite/pull/10539) +* Fix health status enum in [#10540](https://github.com/appwrite/appwrite/pull/10540) +* Update afterbuild fn in [#10541](https://github.com/appwrite/appwrite/pull/10541) +* Update afterbuild to also pass adapter in [#10545](https://github.com/appwrite/appwrite/pull/10545) +* Update `z-index` to be the highest in [#9874](https://github.com/appwrite/appwrite/pull/9874) +* Update framework lib to 0.33.28 in [#10551](https://github.com/appwrite/appwrite/pull/10551) +* Fix enum typing for platform in specs in [#10553](https://github.com/appwrite/appwrite/pull/10553) +* Add enums for database type and column status in [#10561](https://github.com/appwrite/appwrite/pull/10561) +* Fix activities in [#10586](https://github.com/appwrite/appwrite/pull/10586) +* Fix logs truncation tests in [#10585](https://github.com/appwrite/appwrite/pull/10585) +* Remove related data in realtime payload in [#10590](https://github.com/appwrite/appwrite/pull/10590) +* Update composer dependencies in [#10601](https://github.com/appwrite/appwrite/pull/10601) +* Update sdks add response models in [#10554](https://github.com/appwrite/appwrite/pull/10554) +* Sanitize 5xx errors on realtime in [#10598](https://github.com/appwrite/appwrite/pull/10598) +* Update database in [#10596](https://github.com/appwrite/appwrite/pull/10596) +* Add both collection and table id in the realtime in [#10608](https://github.com/appwrite/appwrite/pull/10608) +* Chore bump db in [#10611](https://github.com/appwrite/appwrite/pull/10611) +* Branded email for Console auth flows in [#10501](https://github.com/appwrite/appwrite/pull/10501) +* Add minor releases for all SDKs - deprecate createVerification, add createEmailVerification in [#10614](https://github.com/appwrite/appwrite/pull/10614) +* Add automatic releases in [#10615](https://github.com/appwrite/appwrite/pull/10615) +* Feat txn sdks in [#10621](https://github.com/appwrite/appwrite/pull/10621) +* Prevent empty releases in sdk release script in [#10627](https://github.com/appwrite/appwrite/pull/10627) +* Update domains lib to 0.8.2 in [#10629](https://github.com/appwrite/appwrite/pull/10629) +* Fix txn API scope backwards compat in [#10640](https://github.com/appwrite/appwrite/pull/10640) +* Fix block schedules in [#10620](https://github.com/appwrite/appwrite/pull/10620) +* Update .NET SDK to 0.21.2 and improve release detection in [#10641](https://github.com/appwrite/appwrite/pull/10641) +* Make methods protected for extending in [#10617](https://github.com/appwrite/appwrite/pull/10617) + +# Version 1.7.4 + +## What's Changed + +### Notable changes + +* Update console image to version 6.0.13 in [#9891](https://github.com/appwrite/appwrite/pull/9891) + +### Fixes + +* Fix createDeployment chunk upload in [#9886](https://github.com/appwrite/appwrite/pull/9886) + +### Miscellaneous + +* Update version from 1.7.3 to 1.7.4 in [#9893](https://github.com/appwrite/appwrite/pull/9893) + +# Version 1.7.3 + +## What's Changed + +### Notable changes + +* Allow unlimited deployment size in [#9866](https://github.com/appwrite/appwrite/pull/9866) +* Bump console to version 6.0.11 in [#9881](https://github.com/appwrite/appwrite/pull/9881) + +### Fixes + +* Send deploymentResourceType in rules verification in [#9859](https://github.com/appwrite/appwrite/pull/9859) +* Fix CNAME validation in [#9861](https://github.com/appwrite/appwrite/pull/9861) +* Fix bucket not included in path in [#9864](https://github.com/appwrite/appwrite/pull/9864) +* Fix URL for view logs in github comment in [#9875](https://github.com/appwrite/appwrite/pull/9875) +* Set owner and region while migrating rules in [#9856](https://github.com/appwrite/appwrite/pull/9856) +* Remove _APP_DEFAULT_REGION because it is not a valid env var in [#9883](https://github.com/appwrite/appwrite/pull/9883) + +### Miscellaneous + +* Only load error page for development mode in [#9860](https://github.com/appwrite/appwrite/pull/9860) +* Make max deployment and build size configurable in [#9863](https://github.com/appwrite/appwrite/pull/9863) +* Update flutter_web_auth_2 docs to match 4.x in [#9858](https://github.com/appwrite/appwrite/pull/9858) +* Use unique filename for health check in [#9842](https://github.com/appwrite/appwrite/pull/9842) +* Added encrypt property in the attribute string response model in [#9868](https://github.com/appwrite/appwrite/pull/9868) +* Add sequence in [#9865](https://github.com/appwrite/appwrite/pull/9865) +* Add builds worker group in [#9873](https://github.com/appwrite/appwrite/pull/9873) +* updated errro for the string encryption in [#9878](https://github.com/appwrite/appwrite/pull/9878) +* Revert "Add sequence" in [#9879](https://github.com/appwrite/appwrite/pull/9879) +* Prepare 1.7.3 release in [#9882](https://github.com/appwrite/appwrite/pull/9882) + # Version 1.6.2 ## What's Changed ### Notable changes -* Delete git folder to reduce build size in [9076](https://github.com/appwrite/appwrite/pull/9076) -* Upgrade assistant in [9100](https://github.com/appwrite/appwrite/pull/9100) -* Use redis adapter for abuse in [9121](https://github.com/appwrite/appwrite/pull/9121) -* Set base specification CPUs to 0.5 again in [9146](https://github.com/appwrite/appwrite/pull/9146) -* Add new push message parameters in [9060](https://github.com/appwrite/appwrite/pull/9060) -* Update audits to include user type in [9211](https://github.com/appwrite/appwrite/pull/9211) -* Enable HEIC in [9251](https://github.com/appwrite/appwrite/pull/9251) -* Added teamName to membership redirect url in [9269](https://github.com/appwrite/appwrite/pull/9269) -* Add support endpoint url for S3 in [9303](https://github.com/appwrite/appwrite/pull/9303) -* Added RuPay Credit Card Icon in Avatars Service in [5046](https://github.com/appwrite/appwrite/pull/5046) -* Add figma oauth provider in [9623](https://github.com/appwrite/appwrite/pull/9623) -* Update console to version 5.2.58 in [9637](https://github.com/appwrite/appwrite/pull/9637) +* Delete git folder to reduce build size in [#9076](https://github.com/appwrite/appwrite/pull/9076) +* Upgrade assistant in [#9100](https://github.com/appwrite/appwrite/pull/9100) +* Use redis adapter for abuse in [#9121](https://github.com/appwrite/appwrite/pull/9121) +* Set base specification CPUs to 0.5 again in [#9146](https://github.com/appwrite/appwrite/pull/9146) +* Add new push message parameters in [#9060](https://github.com/appwrite/appwrite/pull/9060) +* Update audits to include user type in [#9211](https://github.com/appwrite/appwrite/pull/9211) +* Enable HEIC in [#9251](https://github.com/appwrite/appwrite/pull/9251) +* Added teamName to membership redirect url in [#9269](https://github.com/appwrite/appwrite/pull/9269) +* Add support endpoint url for S3 in [#9303](https://github.com/appwrite/appwrite/pull/9303) +* Added RuPay Credit Card Icon in Avatars Service in [#5046](https://github.com/appwrite/appwrite/pull/5046) +* Add figma oauth provider in [#9623](https://github.com/appwrite/appwrite/pull/9623) +* Update console to version 5.2.58 in [#9637](https://github.com/appwrite/appwrite/pull/9637) ### Fixes -* Remove failed attribute in [9032](https://github.com/appwrite/appwrite/pull/9032) -* Fix delete notFound attribute in [9038](https://github.com/appwrite/appwrite/pull/9038) -* 🇮🇸 Added missing Icelandic translations for email strings. in [4848](https://github.com/appwrite/appwrite/pull/4848) -* fix doc comment for filter method in [5769](https://github.com/appwrite/appwrite/pull/5769) -* Delete attribute No throwing Exception on not found in [9157](https://github.com/appwrite/appwrite/pull/9157) -* Fix VCS identity collision in [9138](https://github.com/appwrite/appwrite/pull/9138) -* Fix disabling of email-otp when user wants to in [9200](https://github.com/appwrite/appwrite/pull/9200) -* Ensure user can delete session in [9209](https://github.com/appwrite/appwrite/pull/9209) -* Fix resend invitation in [9218](https://github.com/appwrite/appwrite/pull/9218) -* Fix phone number parsing exception handling in [9246](https://github.com/appwrite/appwrite/pull/9246) -* Fix amazon oauth in [9253](https://github.com/appwrite/appwrite/pull/9253) -* Fix slack oauth scopes, and updated to v2 in [9228](https://github.com/appwrite/appwrite/pull/9228) -* Fix forwarded user agent in [9271](https://github.com/appwrite/appwrite/pull/9271) -* Fix WEBP File Preview Rendering Issue in [9321](https://github.com/appwrite/appwrite/pull/9321) -* Fix build memory specifications in [9360](https://github.com/appwrite/appwrite/pull/9360) -* Fix Self Hosting functions by adding missed config in [9373](https://github.com/appwrite/appwrite/pull/9373) -* Fix resend team invite if already accepted in [9348](https://github.com/appwrite/appwrite/pull/9348) -* Fix null errors on team invite in [9391](https://github.com/appwrite/appwrite/pull/9391) -* Fix email (smtp) to multiple recipients in [9243](https://github.com/appwrite/appwrite/pull/9243) -* Fix stats timing by using receivedAt date when available in [9428](https://github.com/appwrite/appwrite/pull/9428) -* Make min/max params optional for attribute update in [9387](https://github.com/appwrite/appwrite/pull/9387) -* Fix blocking of phone sessions when disabled on console in [9447](https://github.com/appwrite/appwrite/pull/9447) -* Fix logging config in [9467](https://github.com/appwrite/appwrite/pull/9467) -* Update audit timestamp origin in [9481](https://github.com/appwrite/appwrite/pull/9481) -* Fix certificates in deletes worker in [9466](https://github.com/appwrite/appwrite/pull/9466) -* Fix console audits delete in [9547](https://github.com/appwrite/appwrite/pull/9547) -* Fix migrations in [9633](https://github.com/appwrite/appwrite/pull/9633) -* Ensure all 4xx errors in OAuth redirect lead to the failure URL in [9679](https://github.com/appwrite/appwrite/pull/9679) -* Treat 0 as unlimited for CPUs and memory in [9638](https://github.com/appwrite/appwrite/pull/9638) -* Add contextual dispatch logic to fix high CPU usage in [9687](https://github.com/appwrite/appwrite/pull/9687) +* Remove failed attribute in [#9032](https://github.com/appwrite/appwrite/pull/9032) +* Fix delete notFound attribute in [#9038](https://github.com/appwrite/appwrite/pull/9038) +* 🇮🇸 Added missing Icelandic translations for email strings. in [#4848](https://github.com/appwrite/appwrite/pull/4848) +* fix doc comment for filter method in [#5769](https://github.com/appwrite/appwrite/pull/5769) +* Delete attribute No throwing Exception on not found in [#9157](https://github.com/appwrite/appwrite/pull/9157) +* Fix VCS identity collision in [#9138](https://github.com/appwrite/appwrite/pull/9138) +* Fix disabling of email-otp when user wants to in [#9200](https://github.com/appwrite/appwrite/pull/9200) +* Ensure user can delete session in [#9209](https://github.com/appwrite/appwrite/pull/9209) +* Fix resend invitation in [#9218](https://github.com/appwrite/appwrite/pull/9218) +* Fix phone number parsing exception handling in [#9246](https://github.com/appwrite/appwrite/pull/9246) +* Fix amazon oauth in [#9253](https://github.com/appwrite/appwrite/pull/9253) +* Fix slack oauth scopes, and updated to v2 in [#9228](https://github.com/appwrite/appwrite/pull/9228) +* Fix forwarded user agent in [#9271](https://github.com/appwrite/appwrite/pull/9271) +* Fix WEBP File Preview Rendering Issue in [#9321](https://github.com/appwrite/appwrite/pull/9321) +* Fix build memory specifications in [#9360](https://github.com/appwrite/appwrite/pull/9360) +* Fix Self Hosting functions by adding missed config in [#9373](https://github.com/appwrite/appwrite/pull/9373) +* Fix resend team invite if already accepted in [#9348](https://github.com/appwrite/appwrite/pull/9348) +* Fix null errors on team invite in [#9391](https://github.com/appwrite/appwrite/pull/9391) +* Fix email (smtp) to multiple recipients in [#9243](https://github.com/appwrite/appwrite/pull/9243) +* Fix stats timing by using receivedAt date when available in [#9428](https://github.com/appwrite/appwrite/pull/9428) +* Make min/max params optional for attribute update in [#9387](https://github.com/appwrite/appwrite/pull/9387) +* Fix blocking of phone sessions when disabled on console in [#9447](https://github.com/appwrite/appwrite/pull/9447) +* Fix logging config in [#9467](https://github.com/appwrite/appwrite/pull/9467) +* Update audit timestamp origin in [#9481](https://github.com/appwrite/appwrite/pull/9481) +* Fix certificates in deletes worker in [#9466](https://github.com/appwrite/appwrite/pull/9466) +* Fix console audits delete in [#9547](https://github.com/appwrite/appwrite/pull/9547) +* Fix migrations in [#9633](https://github.com/appwrite/appwrite/pull/9633) +* Ensure all 4xx errors in OAuth redirect lead to the failure URL in [#9679](https://github.com/appwrite/appwrite/pull/9679) +* Treat 0 as unlimited for CPUs and memory in [#9638](https://github.com/appwrite/appwrite/pull/9638) +* Add contextual dispatch logic to fix high CPU usage in [#9687](https://github.com/appwrite/appwrite/pull/9687) ### Miscellaneous -* Merge 1.6.x into feat-custom-cf-hostnames in [8904](https://github.com/appwrite/appwrite/pull/8904) -* Improve compression param checks in [8922](https://github.com/appwrite/appwrite/pull/8922) -* upgrade utopia storage in [8930](https://github.com/appwrite/appwrite/pull/8930) -* Feat migration in [8797](https://github.com/appwrite/appwrite/pull/8797) -* feat fix web routes in [8962](https://github.com/appwrite/appwrite/pull/8962) -* Fix no pool access in [9027](https://github.com/appwrite/appwrite/pull/9027) -* feat: use environment variable to check rules format in [9039](https://github.com/appwrite/appwrite/pull/9039) -* Update storage.php in [9037](https://github.com/appwrite/appwrite/pull/9037) -* Upgrade db 0.53.200 in [9050](https://github.com/appwrite/appwrite/pull/9050) -* Chore: upgrade utopia storage in [9066](https://github.com/appwrite/appwrite/pull/9066) -* Update usage-dump payload in [9085](https://github.com/appwrite/appwrite/pull/9085) -* GitHub Workflows security hardening in [3728](https://github.com/appwrite/appwrite/pull/3728) -* Update add-oauth2-provider.md in [4313](https://github.com/appwrite/appwrite/pull/4313) -* update readme-cn some doc in [5278](https://github.com/appwrite/appwrite/pull/5278) -* Add accessibility features in [7042](https://github.com/appwrite/appwrite/pull/7042) -* Add Appwrite Cloud to read me. in [5445](https://github.com/appwrite/appwrite/pull/5445) -* Migration throw error in [9092](https://github.com/appwrite/appwrite/pull/9092) -* Fix usage payload bug in [9097](https://github.com/appwrite/appwrite/pull/9097) -* chore: replace occurrences of dbForConsole to dbForPlatform in [9096](https://github.com/appwrite/appwrite/pull/9096) -* fix(realtime): decrement connectionCounter only if connection is known in [9055](https://github.com/appwrite/appwrite/pull/9055) -* payload bug fix in [9098](https://github.com/appwrite/appwrite/pull/9098) -* Fix usage payload bug in [9099](https://github.com/appwrite/appwrite/pull/9099) -* Usage payload debug in [9101](https://github.com/appwrite/appwrite/pull/9101) -* Usage payload debug in [9103](https://github.com/appwrite/appwrite/pull/9103) -* Usage payload debug in [9104](https://github.com/appwrite/appwrite/pull/9104) -* Feat: createFunction abuse labels in [9102](https://github.com/appwrite/appwrite/pull/9102) -* Docs-create-document in [9105](https://github.com/appwrite/appwrite/pull/9105) -* Docs: Create document and unknown attribute error messages. in [5427](https://github.com/appwrite/appwrite/pull/5427) -* Fix: update project accessed at from router and schedulers in [9109](https://github.com/appwrite/appwrite/pull/9109) -* chore: initial commit in [9111](https://github.com/appwrite/appwrite/pull/9111) -* chore: optimise webhooks payload in [9115](https://github.com/appwrite/appwrite/pull/9115) -* Revert "chore: initial commit" in [9117](https://github.com/appwrite/appwrite/pull/9117) -* chore: fix attribute name in [9118](https://github.com/appwrite/appwrite/pull/9118) -* Migrate to redis abuse in [9124](https://github.com/appwrite/appwrite/pull/9124) -* Added webhooks usage stats in [9125](https://github.com/appwrite/appwrite/pull/9125) -* chore remove abuse cleanup in [9137](https://github.com/appwrite/appwrite/pull/9137) -* fix: remove abuse delete trigger in [9139](https://github.com/appwrite/appwrite/pull/9139) -* Remove firebase OAuth API endpoints in [9144](https://github.com/appwrite/appwrite/pull/9144) -* chore: release client sdks in [9112](https://github.com/appwrite/appwrite/pull/9112) -* Update general.php in [9155](https://github.com/appwrite/appwrite/pull/9155) -* feat(swoole): allow configuration override of available cpus in [9177](https://github.com/appwrite/appwrite/pull/9177) -* Usage databases api read writes addition in [9142](https://github.com/appwrite/appwrite/pull/9142) -* Fix dead connections in [9190](https://github.com/appwrite/appwrite/pull/9190) -* Add hostname to audits in [9165](https://github.com/appwrite/appwrite/pull/9165) -* chore: shifted authphone usage tracking to api calls in [9191](https://github.com/appwrite/appwrite/pull/9191) -* Revert "Fix dead connections" in [9201](https://github.com/appwrite/appwrite/pull/9201) -* Add assertEventually to messaging provider logs test in [9192](https://github.com/appwrite/appwrite/pull/9192) -* feat project sms usage in [9198](https://github.com/appwrite/appwrite/pull/9198) -* chore: add audit labels to project resources in [9056](https://github.com/appwrite/appwrite/pull/9056) -* fix sms usage in [9207](https://github.com/appwrite/appwrite/pull/9207) -* Update database in [9202](https://github.com/appwrite/appwrite/pull/9202) -* Fix dead connections in [9213](https://github.com/appwrite/appwrite/pull/9213) -* Revert "Fix dead connections" in [9214](https://github.com/appwrite/appwrite/pull/9214) -* Add logs db init for consistency in [9163](https://github.com/appwrite/appwrite/pull/9163) -* Split the collection definitions in [9153](https://github.com/appwrite/appwrite/pull/9153) -* Log path with populated parameters in [9220](https://github.com/appwrite/appwrite/pull/9220) -* Add missing scope on function template in [9208](https://github.com/appwrite/appwrite/pull/9208) -* Add relatedCollection default in [9225](https://github.com/appwrite/appwrite/pull/9225) -* fix: function usage in [9235](https://github.com/appwrite/appwrite/pull/9235) -* feat: optimise events payloads in [9232](https://github.com/appwrite/appwrite/pull/9232) -* Optimise webhook events in [9168](https://github.com/appwrite/appwrite/pull/9168) -* fix: maintenance job missing type in [9238](https://github.com/appwrite/appwrite/pull/9238) -* Update Fetch to 0.3.0 in [9245](https://github.com/appwrite/appwrite/pull/9245) -* Fix maintenance job in [9247](https://github.com/appwrite/appwrite/pull/9247) -* chore: add missing case for executions in [9248](https://github.com/appwrite/appwrite/pull/9248) -* Add index dependency exception in [9226](https://github.com/appwrite/appwrite/pull/9226) -* chore: fix benchmarking test when made from fork in [9233](https://github.com/appwrite/appwrite/pull/9233) -* Update SDK Generator versions in [9188](https://github.com/appwrite/appwrite/pull/9188) -* chore: skipped job instead of throwing error in [9250](https://github.com/appwrite/appwrite/pull/9250) -* Implement new SDK Class on 1.6.x in [9237](https://github.com/appwrite/appwrite/pull/9237) -* Delete collection before Appwrite's attributes in [9256](https://github.com/appwrite/appwrite/pull/9256) -* Feat batch usage dump in [9255](https://github.com/appwrite/appwrite/pull/9255) -* Fix cloud tests in [9261](https://github.com/appwrite/appwrite/pull/9261) -* Usage: Databases reads writes in [9260](https://github.com/appwrite/appwrite/pull/9260) -* Update: Latest sdk specs in [9274](https://github.com/appwrite/appwrite/pull/9274) -* Revert "Feat batch usage dump" in [9276](https://github.com/appwrite/appwrite/pull/9276) -* feat: add fast2SMS adapter in [9263](https://github.com/appwrite/appwrite/pull/9263) -* Update Sdk Generator dependency in [9280](https://github.com/appwrite/appwrite/pull/9280) -* Transformed at addition in [9281](https://github.com/appwrite/appwrite/pull/9281) -* Docs: clarify update endpoints only work on draft messages in [9236](https://github.com/appwrite/appwrite/pull/9236) -* Update sdk generator dependency in [9282](https://github.com/appwrite/appwrite/pull/9282) -* Revert "Transformed at addition" in [9284](https://github.com/appwrite/appwrite/pull/9284) -* replaced init for cloud link in [9285](https://github.com/appwrite/appwrite/pull/9285) -* Add transformed at in [9289](https://github.com/appwrite/appwrite/pull/9289) -* Make migrations use Dynamic keys for destination in [9291](https://github.com/appwrite/appwrite/pull/9291) -* Make sessions limit tests assert eventually in [9298](https://github.com/appwrite/appwrite/pull/9298) -* Chore update database in [9306](https://github.com/appwrite/appwrite/pull/9306) -* feat: add AMQP queues in [9287](https://github.com/appwrite/appwrite/pull/9287) -* fix(test): use assertEventually instead of while(true) in [9308](https://github.com/appwrite/appwrite/pull/9308) -* fix(certificate worker): events are published without queue name in [9309](https://github.com/appwrite/appwrite/pull/9309) -* chore: update utopia-php/queue to 0.8.1 in [9311](https://github.com/appwrite/appwrite/pull/9311) -* chore: update utopia-php/queue to 0.8.2 in [9312](https://github.com/appwrite/appwrite/pull/9312) -* fix(schedule-tasks): revert back to direct pool usage in [9313](https://github.com/appwrite/appwrite/pull/9313) -* feat: custom app schemes in [9262](https://github.com/appwrite/appwrite/pull/9262) -* Revert "feat: custom app schemes" in [9319](https://github.com/appwrite/appwrite/pull/9319) -* Restore "feat: custom app schemes"" in [9320](https://github.com/appwrite/appwrite/pull/9320) -* Revert "Restore "feat: custom app schemes""" in [9323](https://github.com/appwrite/appwrite/pull/9323) -* chore: update dependencies in [9330](https://github.com/appwrite/appwrite/pull/9330) -* Feat: logs DB in [9272](https://github.com/appwrite/appwrite/pull/9272) -* Catch invalid index in [9329](https://github.com/appwrite/appwrite/pull/9329) -* Fix: missing call for image transformations counting in [9342](https://github.com/appwrite/appwrite/pull/9342) -* Fix drop abuse on shared table project delete in [9346](https://github.com/appwrite/appwrite/pull/9346) -* Only run all table mode tests on db update in [9338](https://github.com/appwrite/appwrite/pull/9338) -* Fix: missing periodic metric in [9350](https://github.com/appwrite/appwrite/pull/9350) -* feat(builds): check if function is blocked before building in [9332](https://github.com/appwrite/appwrite/pull/9332) -* feat: batch create audit logs in [9347](https://github.com/appwrite/appwrite/pull/9347) -* Chore: Update migrations in [9355](https://github.com/appwrite/appwrite/pull/9355) -* Fix: metric time was not being written to DB in [9354](https://github.com/appwrite/appwrite/pull/9354) -* Fix patch index validation in [9356](https://github.com/appwrite/appwrite/pull/9356) -* Fix image trnasformation metrics in [9370](https://github.com/appwrite/appwrite/pull/9370) -* Use batch delete in worker in [9375](https://github.com/appwrite/appwrite/pull/9375) -* Fix Model Platform is missing response key: store in [9361](https://github.com/appwrite/appwrite/pull/9361) -* Feat key segmented usage in [9336](https://github.com/appwrite/appwrite/pull/9336) -* Feat messaging metrics in [9353](https://github.com/appwrite/appwrite/pull/9353) -* Fix removed audits for shared v2 in [9388](https://github.com/appwrite/appwrite/pull/9388) -* chore: bump utopia-php/image to 0.8.0 in [9390](https://github.com/appwrite/appwrite/pull/9390) -* Fix outdated CLI commands in documentation in [9122](https://github.com/appwrite/appwrite/pull/9122) -* disable logs display in [9398](https://github.com/appwrite/appwrite/pull/9398) -* Log batches per project in [9403](https://github.com/appwrite/appwrite/pull/9403) -* Batch per project in [9410](https://github.com/appwrite/appwrite/pull/9410) -* Fix: stats resources only queue projects accessed in last 3 hours in [9411](https://github.com/appwrite/appwrite/pull/9411) -* Track options requests in [9397](https://github.com/appwrite/appwrite/pull/9397) -* chore: bump docker-base in [9406](https://github.com/appwrite/appwrite/pull/9406) -* refactor: migrate Realtime::send calls to queueForRealtime in [9325](https://github.com/appwrite/appwrite/pull/9325) -* Revert "Fix: stats resources only queue projects accessed in last 3 hours" in [9424](https://github.com/appwrite/appwrite/pull/9424) -* Remove usage and usage dump in favor of stats-usage and stats-usage-dump in [9339](https://github.com/appwrite/appwrite/pull/9339) -* Fix: disable dual writing in [9429](https://github.com/appwrite/appwrite/pull/9429) -* Disable transformedAt update for console users in [9425](https://github.com/appwrite/appwrite/pull/9425) -* chore: add image transformation stats to usage endpoint in [9393](https://github.com/appwrite/appwrite/pull/9393) -* chore: added timeout to deployment builds in tests in [9426](https://github.com/appwrite/appwrite/pull/9426) -* fix: model for image transformations in usage project in [9442](https://github.com/appwrite/appwrite/pull/9442) -* Feat: calculate database storage in stats-resources in [9443](https://github.com/appwrite/appwrite/pull/9443) -* Activities batch writes in [9438](https://github.com/appwrite/appwrite/pull/9438) -* chore: bump cache 0.12.x in [9412](https://github.com/appwrite/appwrite/pull/9412) -* chore: queue console project for maintenance delete in [9479](https://github.com/appwrite/appwrite/pull/9479) -* chore: added logsdb for deletes worker in [9462](https://github.com/appwrite/appwrite/pull/9462) -* Feat: calculate and log time taken for each project in [9491](https://github.com/appwrite/appwrite/pull/9491) -* chore: update initializing dbForLogs in [9494](https://github.com/appwrite/appwrite/pull/9494) -* Feat bulk audit delete in [9487](https://github.com/appwrite/appwrite/pull/9487) -* Prepare 1.6.2 release in [9499](https://github.com/appwrite/appwrite/pull/9499) -* Regenerate specs in [9497](https://github.com/appwrite/appwrite/pull/9497) -* Regenerate examples in [9498](https://github.com/appwrite/appwrite/pull/9498) -* chore: bump sdk in [9414](https://github.com/appwrite/appwrite/pull/9414) -* update queue to 0.9.* in [9505](https://github.com/appwrite/appwrite/pull/9505) -* Feat improve delete queries in [9507](https://github.com/appwrite/appwrite/pull/9507) -* Feat: Add rule attributes in [9508](https://github.com/appwrite/appwrite/pull/9508) -* Sync main into 1.6.x in [9496](https://github.com/appwrite/appwrite/pull/9496) -* Bump console to version 5.2.53 in [9495](https://github.com/appwrite/appwrite/pull/9495) -* Prepare 1.6.1 release in [9294](https://github.com/appwrite/appwrite/pull/9294) -* Improve delete ordering in [9512](https://github.com/appwrite/appwrite/pull/9512) -* Cleanups in [9511](https://github.com/appwrite/appwrite/pull/9511) -* Feat dynamic regions in [9408](https://github.com/appwrite/appwrite/pull/9408) -* Feat env vars to system lib in [9515](https://github.com/appwrite/appwrite/pull/9515) -* Feat: domains count in [9514](https://github.com/appwrite/appwrite/pull/9514) -* Migration read from db in [9529](https://github.com/appwrite/appwrite/pull/9529) -* feat: add pool telemetry in [9530](https://github.com/appwrite/appwrite/pull/9530) -* Disable PDO persistence since we manage our own pool in [9526](https://github.com/appwrite/appwrite/pull/9526) -* chore: set min operations to 1 for reads and writes in [9536](https://github.com/appwrite/appwrite/pull/9536) -* Remove default region in [9430](https://github.com/appwrite/appwrite/pull/9430) -* Use cursor pagination with bigger limit for maintenance project loop in [9546](https://github.com/appwrite/appwrite/pull/9546) -* chore: stop tests on failure in [9525](https://github.com/appwrite/appwrite/pull/9525) -* chore: only update total count for privileged users in [9554](https://github.com/appwrite/appwrite/pull/9554) -* refactor: initialization of audit retention in [9563](https://github.com/appwrite/appwrite/pull/9563) -* Delete worker queries fixes in [9523](https://github.com/appwrite/appwrite/pull/9523) -* Bump database 0.62.x in [9568](https://github.com/appwrite/appwrite/pull/9568) -* Fix: schedules region filtering in [9577](https://github.com/appwrite/appwrite/pull/9577) -* Deletes worker fix selects for pagination in [9578](https://github.com/appwrite/appwrite/pull/9578) -* Add $permissions for delete documents selects in [9579](https://github.com/appwrite/appwrite/pull/9579) -* chore(audits): return queue pre-fetch results in [9533](https://github.com/appwrite/appwrite/pull/9533) -* Revert "chore(audits): return queue pre-fetch results" in [9586](https://github.com/appwrite/appwrite/pull/9586) -* Feat multi tenant insert in [9573](https://github.com/appwrite/appwrite/pull/9573) -* Add order by for cursor in [9588](https://github.com/appwrite/appwrite/pull/9588) -* Feat update fetch in [9592](https://github.com/appwrite/appwrite/pull/9592) -* Fix tenant casting in [9598](https://github.com/appwrite/appwrite/pull/9598) -* Feat update ws in [9602](https://github.com/appwrite/appwrite/pull/9602) -* Update database in [9603](https://github.com/appwrite/appwrite/pull/9603) -* Fix: image transformation cache in [9608](https://github.com/appwrite/appwrite/pull/9608) -* Remove audit payload in [9610](https://github.com/appwrite/appwrite/pull/9610) -* Sample rate from DSN in [9559](https://github.com/appwrite/appwrite/pull/9559) -* Restrict role change for sole org owner in [9615](https://github.com/appwrite/appwrite/pull/9615) -* chore: update php image to 0.8.1 in [9616](https://github.com/appwrite/appwrite/pull/9616) -* feat: refactor executor setup in [9420](https://github.com/appwrite/appwrite/pull/9420) -* chore: update gitpod.yml config in [9561](https://github.com/appwrite/appwrite/pull/9561) -* chore: update dependencies in [9625](https://github.com/appwrite/appwrite/pull/9625) -* Update migrations lib in [9628](https://github.com/appwrite/appwrite/pull/9628) -* feat: cache telemetry in [9624](https://github.com/appwrite/appwrite/pull/9624) -* Bump console to version 5.2.56 in [9631](https://github.com/appwrite/appwrite/pull/9631) -* Multi region support in [8667](https://github.com/appwrite/appwrite/pull/8667) -* Revert "Multi region support" in [9632](https://github.com/appwrite/appwrite/pull/9632) -* Revert "Revert "Multi region support"" in [9636](https://github.com/appwrite/appwrite/pull/9636) -* Fix tasks in [9644](https://github.com/appwrite/appwrite/pull/9644) -* chore: updated the migration version to 8.6 in [9646](https://github.com/appwrite/appwrite/pull/9646) -* Fix: merge the working of StatsUsage and StatsUsageDump in [9585](https://github.com/appwrite/appwrite/pull/9585) -* Update database in [9643](https://github.com/appwrite/appwrite/pull/9643) -* chore: fix error logging for CLI tasks in [9651](https://github.com/appwrite/appwrite/pull/9651) -* fix: usage test assertion in [9653](https://github.com/appwrite/appwrite/pull/9653) -* Fix keys in [9656](https://github.com/appwrite/appwrite/pull/9656) -* Feat: multi tenant dual writing in [9583](https://github.com/appwrite/appwrite/pull/9583) -* Fix/throwing 400 for null order attributes in [9657](https://github.com/appwrite/appwrite/pull/9657) -* feat: sdk group attribute in [9596](https://github.com/appwrite/appwrite/pull/9596) -* Add configurable function and build size in [9648](https://github.com/appwrite/appwrite/pull/9648) -* feat: update API endpoint in the code examples in [8933](https://github.com/appwrite/appwrite/pull/8933) -* chore: abstract token secret hiding to response model in [9574](https://github.com/appwrite/appwrite/pull/9574) -* chore: update sdks in [9655](https://github.com/appwrite/appwrite/pull/9655) -* feat: allow non-critical events to ignore exceptions when enqueuing the event in [9680](https://github.com/appwrite/appwrite/pull/9680) -* Revert "Add configurable function and build size" in [9681](https://github.com/appwrite/appwrite/pull/9681) -* core: introduce endpoint.docs in specs in [9685](https://github.com/appwrite/appwrite/pull/9685) -* fix: remove content-type header from get request specs in [9666](https://github.com/appwrite/appwrite/pull/9666) -* chore: update flutter sdk in [9691](https://github.com/appwrite/appwrite/pull/9691) +* Merge 1.6.x into feat-custom-cf-hostnames in [#8904](https://github.com/appwrite/appwrite/pull/8904) +* Improve compression param checks in [#8922](https://github.com/appwrite/appwrite/pull/8922) +* upgrade utopia storage in [#8930](https://github.com/appwrite/appwrite/pull/8930) +* Feat migration in [#8797](https://github.com/appwrite/appwrite/pull/8797) +* feat fix web routes in [#8962](https://github.com/appwrite/appwrite/pull/8962) +* Fix no pool access in [#9027](https://github.com/appwrite/appwrite/pull/9027) +* feat: use environment variable to check rules format in [#9039](https://github.com/appwrite/appwrite/pull/9039) +* Update storage.php in [#9037](https://github.com/appwrite/appwrite/pull/9037) +* Upgrade db 0.53.200 in [#9050](https://github.com/appwrite/appwrite/pull/9050) +* Chore: upgrade utopia storage in [#9066](https://github.com/appwrite/appwrite/pull/9066) +* Update usage-dump payload in [#9085](https://github.com/appwrite/appwrite/pull/9085) +* GitHub Workflows security hardening in [#3728](https://github.com/appwrite/appwrite/pull/3728) +* Update add-oauth2-provider.md in [#4313](https://github.com/appwrite/appwrite/pull/4313) +* update readme-cn some doc in [#5278](https://github.com/appwrite/appwrite/pull/5278) +* Add accessibility features in [#7042](https://github.com/appwrite/appwrite/pull/7042) +* Add Appwrite Cloud to read me. in [#5445](https://github.com/appwrite/appwrite/pull/5445) +* Migration throw error in [#9092](https://github.com/appwrite/appwrite/pull/9092) +* Fix usage payload bug in [#9097](https://github.com/appwrite/appwrite/pull/9097) +* chore: replace occurrences of dbForConsole to dbForPlatform in [#9096](https://github.com/appwrite/appwrite/pull/9096) +* fix(realtime): decrement connectionCounter only if connection is known in [#9055](https://github.com/appwrite/appwrite/pull/9055) +* payload bug fix in [#9098](https://github.com/appwrite/appwrite/pull/9098) +* Fix usage payload bug in [#9099](https://github.com/appwrite/appwrite/pull/9099) +* Usage payload debug in [#9101](https://github.com/appwrite/appwrite/pull/9101) +* Usage payload debug in [#9103](https://github.com/appwrite/appwrite/pull/9103) +* Usage payload debug in [#9104](https://github.com/appwrite/appwrite/pull/9104) +* Feat: createFunction abuse labels in [#9102](https://github.com/appwrite/appwrite/pull/9102) +* Docs-create-document in [#9105](https://github.com/appwrite/appwrite/pull/9105) +* Docs: Create document and unknown attribute error messages. in [#5427](https://github.com/appwrite/appwrite/pull/5427) +* Fix: update project accessed at from router and schedulers in [#9109](https://github.com/appwrite/appwrite/pull/9109) +* chore: initial commit in [#9111](https://github.com/appwrite/appwrite/pull/9111) +* chore: optimise webhooks payload in [#9115](https://github.com/appwrite/appwrite/pull/9115) +* Revert "chore: initial commit" in [#9117](https://github.com/appwrite/appwrite/pull/9117) +* chore: fix attribute name in [#9118](https://github.com/appwrite/appwrite/pull/9118) +* Migrate to redis abuse in [#9124](https://github.com/appwrite/appwrite/pull/9124) +* Added webhooks usage stats in [#9125](https://github.com/appwrite/appwrite/pull/9125) +* chore remove abuse cleanup in [#9137](https://github.com/appwrite/appwrite/pull/9137) +* fix: remove abuse delete trigger in [#9139](https://github.com/appwrite/appwrite/pull/9139) +* Remove firebase OAuth API endpoints in [#9144](https://github.com/appwrite/appwrite/pull/9144) +* chore: release client sdks in [#9112](https://github.com/appwrite/appwrite/pull/9112) +* Update general.php in [#9155](https://github.com/appwrite/appwrite/pull/9155) +* feat(swoole): allow configuration override of available cpus in [#9177](https://github.com/appwrite/appwrite/pull/9177) +* Usage databases api read writes addition in [#9142](https://github.com/appwrite/appwrite/pull/9142) +* Fix dead connections in [#9190](https://github.com/appwrite/appwrite/pull/9190) +* Add hostname to audits in [#9165](https://github.com/appwrite/appwrite/pull/9165) +* chore: shifted authphone usage tracking to api calls in [#9191](https://github.com/appwrite/appwrite/pull/9191) +* Revert "Fix dead connections" in [#9201](https://github.com/appwrite/appwrite/pull/9201) +* Add assertEventually to messaging provider logs test in [#9192](https://github.com/appwrite/appwrite/pull/9192) +* feat project sms usage in [#9198](https://github.com/appwrite/appwrite/pull/9198) +* chore: add audit labels to project resources in [#9056](https://github.com/appwrite/appwrite/pull/9056) +* fix sms usage in [#9207](https://github.com/appwrite/appwrite/pull/9207) +* Update database in [#9202](https://github.com/appwrite/appwrite/pull/9202) +* Fix dead connections in [#9213](https://github.com/appwrite/appwrite/pull/9213) +* Revert "Fix dead connections" in [#9214](https://github.com/appwrite/appwrite/pull/9214) +* Add logs db init for consistency in [#9163](https://github.com/appwrite/appwrite/pull/9163) +* Split the collection definitions in [#9153](https://github.com/appwrite/appwrite/pull/9153) +* Log path with populated parameters in [#9220](https://github.com/appwrite/appwrite/pull/9220) +* Add missing scope on function template in [#9208](https://github.com/appwrite/appwrite/pull/9208) +* Add relatedCollection default in [#9225](https://github.com/appwrite/appwrite/pull/9225) +* fix: function usage in [#9235](https://github.com/appwrite/appwrite/pull/9235) +* feat: optimise events payloads in [#9232](https://github.com/appwrite/appwrite/pull/9232) +* Optimise webhook events in [#9168](https://github.com/appwrite/appwrite/pull/9168) +* fix: maintenance job missing type in [#9238](https://github.com/appwrite/appwrite/pull/9238) +* Update Fetch to 0.3.0 in [#9245](https://github.com/appwrite/appwrite/pull/9245) +* Fix maintenance job in [#9247](https://github.com/appwrite/appwrite/pull/9247) +* chore: add missing case for executions in [#9248](https://github.com/appwrite/appwrite/pull/9248) +* Add index dependency exception in [#9226](https://github.com/appwrite/appwrite/pull/9226) +* chore: fix benchmarking test when made from fork in [#9233](https://github.com/appwrite/appwrite/pull/9233) +* Update SDK Generator versions in [#9188](https://github.com/appwrite/appwrite/pull/9188) +* chore: skipped job instead of throwing error in [#9250](https://github.com/appwrite/appwrite/pull/9250) +* Implement new SDK Class on 1.6.x in [#9237](https://github.com/appwrite/appwrite/pull/9237) +* Delete collection before Appwrite's attributes in [#9256](https://github.com/appwrite/appwrite/pull/9256) +* Feat batch usage dump in [#9255](https://github.com/appwrite/appwrite/pull/9255) +* Fix cloud tests in [#9261](https://github.com/appwrite/appwrite/pull/9261) +* Usage: Databases reads writes in [#9260](https://github.com/appwrite/appwrite/pull/9260) +* Update: Latest sdk specs in [#9274](https://github.com/appwrite/appwrite/pull/9274) +* Revert "Feat batch usage dump" in [#9276](https://github.com/appwrite/appwrite/pull/9276) +* feat: add fast2SMS adapter in [#9263](https://github.com/appwrite/appwrite/pull/9263) +* Update Sdk Generator dependency in [#9280](https://github.com/appwrite/appwrite/pull/9280) +* Transformed at addition in [#9281](https://github.com/appwrite/appwrite/pull/9281) +* Docs: clarify update endpoints only work on draft messages in [#9236](https://github.com/appwrite/appwrite/pull/9236) +* Update sdk generator dependency in [#9282](https://github.com/appwrite/appwrite/pull/9282) +* Revert "Transformed at addition" in [#9284](https://github.com/appwrite/appwrite/pull/9284) +* replaced init for cloud link in [#9285](https://github.com/appwrite/appwrite/pull/9285) +* Add transformed at in [#9289](https://github.com/appwrite/appwrite/pull/9289) +* Make migrations use Dynamic keys for destination in [#9291](https://github.com/appwrite/appwrite/pull/9291) +* Make sessions limit tests assert eventually in [#9298](https://github.com/appwrite/appwrite/pull/9298) +* Chore update database in [#9306](https://github.com/appwrite/appwrite/pull/9306) +* feat: add AMQP queues in [#9287](https://github.com/appwrite/appwrite/pull/9287) +* fix(test): use assertEventually instead of while(true) in [#9308](https://github.com/appwrite/appwrite/pull/9308) +* fix(certificate worker): events are published without queue name in [#9309](https://github.com/appwrite/appwrite/pull/9309) +* chore: update utopia-php/queue to 0.8.1 in [#9311](https://github.com/appwrite/appwrite/pull/9311) +* chore: update utopia-php/queue to 0.8.2 in [#9312](https://github.com/appwrite/appwrite/pull/9312) +* fix(schedule-tasks): revert back to direct pool usage in [#9313](https://github.com/appwrite/appwrite/pull/9313) +* feat: custom app schemes in [#9262](https://github.com/appwrite/appwrite/pull/9262) +* Revert "feat: custom app schemes" in [#9319](https://github.com/appwrite/appwrite/pull/9319) +* Restore "feat: custom app schemes"" in [#9320](https://github.com/appwrite/appwrite/pull/9320) +* Revert "Restore "feat: custom app schemes""" in [#9323](https://github.com/appwrite/appwrite/pull/9323) +* chore: update dependencies in [#9330](https://github.com/appwrite/appwrite/pull/9330) +* Feat: logs DB in [#9272](https://github.com/appwrite/appwrite/pull/9272) +* Catch invalid index in [#9329](https://github.com/appwrite/appwrite/pull/9329) +* Fix: missing call for image transformations counting in [#9342](https://github.com/appwrite/appwrite/pull/9342) +* Fix drop abuse on shared table project delete in [#9346](https://github.com/appwrite/appwrite/pull/9346) +* Only run all table mode tests on db update in [#9338](https://github.com/appwrite/appwrite/pull/9338) +* Fix: missing periodic metric in [#9350](https://github.com/appwrite/appwrite/pull/9350) +* feat(builds): check if function is blocked before building in [#9332](https://github.com/appwrite/appwrite/pull/9332) +* feat: batch create audit logs in [#9347](https://github.com/appwrite/appwrite/pull/9347) +* Chore: Update migrations in [#9355](https://github.com/appwrite/appwrite/pull/9355) +* Fix: metric time was not being written to DB in [#9354](https://github.com/appwrite/appwrite/pull/9354) +* Fix patch index validation in [#9356](https://github.com/appwrite/appwrite/pull/9356) +* Fix image trnasformation metrics in [#9370](https://github.com/appwrite/appwrite/pull/9370) +* Use batch delete in worker in [#9375](https://github.com/appwrite/appwrite/pull/9375) +* Fix Model Platform is missing response key: store in [#9361](https://github.com/appwrite/appwrite/pull/9361) +* Feat key segmented usage in [#9336](https://github.com/appwrite/appwrite/pull/9336) +* Feat messaging metrics in [#9353](https://github.com/appwrite/appwrite/pull/9353) +* Fix removed audits for shared v2 in [#9388](https://github.com/appwrite/appwrite/pull/9388) +* chore: bump utopia-php/image to 0.8.0 in [#9390](https://github.com/appwrite/appwrite/pull/9390) +* Fix outdated CLI commands in documentation in [#9122](https://github.com/appwrite/appwrite/pull/9122) +* disable logs display in [#9398](https://github.com/appwrite/appwrite/pull/9398) +* Log batches per project in [#9403](https://github.com/appwrite/appwrite/pull/9403) +* Batch per project in [#9410](https://github.com/appwrite/appwrite/pull/9410) +* Fix: stats resources only queue projects accessed in last 3 hours in [#9411](https://github.com/appwrite/appwrite/pull/9411) +* Track options requests in [#9397](https://github.com/appwrite/appwrite/pull/9397) +* chore: bump docker-base in [#9406](https://github.com/appwrite/appwrite/pull/9406) +* refactor: migrate Realtime::send calls to queueForRealtime in [#9325](https://github.com/appwrite/appwrite/pull/9325) +* Revert "Fix: stats resources only queue projects accessed in last 3 hours" in [#9424](https://github.com/appwrite/appwrite/pull/9424) +* Remove usage and usage dump in favor of stats-usage and stats-usage-dump in [#9339](https://github.com/appwrite/appwrite/pull/9339) +* Fix: disable dual writing in [#9429](https://github.com/appwrite/appwrite/pull/9429) +* Disable transformedAt update for console users in [#9425](https://github.com/appwrite/appwrite/pull/9425) +* chore: add image transformation stats to usage endpoint in [#9393](https://github.com/appwrite/appwrite/pull/9393) +* chore: added timeout to deployment builds in tests in [#9426](https://github.com/appwrite/appwrite/pull/9426) +* fix: model for image transformations in usage project in [#9442](https://github.com/appwrite/appwrite/pull/9442) +* Feat: calculate database storage in stats-resources in [#9443](https://github.com/appwrite/appwrite/pull/9443) +* Activities batch writes in [#9438](https://github.com/appwrite/appwrite/pull/9438) +* chore: bump cache 0.12.x in [#9412](https://github.com/appwrite/appwrite/pull/9412) +* chore: queue console project for maintenance delete in [#9479](https://github.com/appwrite/appwrite/pull/9479) +* chore: added logsdb for deletes worker in [#9462](https://github.com/appwrite/appwrite/pull/9462) +* Feat: calculate and log time taken for each project in [#9491](https://github.com/appwrite/appwrite/pull/9491) +* chore: update initializing dbForLogs in [#9494](https://github.com/appwrite/appwrite/pull/9494) +* Feat bulk audit delete in [#9487](https://github.com/appwrite/appwrite/pull/9487) +* Prepare 1.6.2 release in [#9499](https://github.com/appwrite/appwrite/pull/9499) +* Regenerate specs in [#9497](https://github.com/appwrite/appwrite/pull/9497) +* Regenerate examples in [#9498](https://github.com/appwrite/appwrite/pull/9498) +* chore: bump sdk in [#9414](https://github.com/appwrite/appwrite/pull/9414) +* update queue to 0.9.* in [#9505](https://github.com/appwrite/appwrite/pull/9505) +* Feat improve delete queries in [#9507](https://github.com/appwrite/appwrite/pull/9507) +* Feat: Add rule attributes in [#9508](https://github.com/appwrite/appwrite/pull/9508) +* Sync main into 1.6.x in [#9496](https://github.com/appwrite/appwrite/pull/9496) +* Bump console to version 5.2.53 in [#9495](https://github.com/appwrite/appwrite/pull/9495) +* Prepare 1.6.1 release in [#9294](https://github.com/appwrite/appwrite/pull/9294) +* Improve delete ordering in [#9512](https://github.com/appwrite/appwrite/pull/9512) +* Cleanups in [#9511](https://github.com/appwrite/appwrite/pull/9511) +* Feat dynamic regions in [#9408](https://github.com/appwrite/appwrite/pull/9408) +* Feat env vars to system lib in [#9515](https://github.com/appwrite/appwrite/pull/9515) +* Feat: domains count in [#9514](https://github.com/appwrite/appwrite/pull/9514) +* Migration read from db in [#9529](https://github.com/appwrite/appwrite/pull/9529) +* feat: add pool telemetry in [#9530](https://github.com/appwrite/appwrite/pull/9530) +* Disable PDO persistence since we manage our own pool in [#9526](https://github.com/appwrite/appwrite/pull/9526) +* chore: set min operations to 1 for reads and writes in [#9536](https://github.com/appwrite/appwrite/pull/9536) +* Remove default region in [#9430](https://github.com/appwrite/appwrite/pull/9430) +* Use cursor pagination with bigger limit for maintenance project loop in [#9546](https://github.com/appwrite/appwrite/pull/9546) +* chore: stop tests on failure in [#9525](https://github.com/appwrite/appwrite/pull/9525) +* chore: only update total count for privileged users in [#9554](https://github.com/appwrite/appwrite/pull/9554) +* refactor: initialization of audit retention in [#9563](https://github.com/appwrite/appwrite/pull/9563) +* Delete worker queries fixes in [#9523](https://github.com/appwrite/appwrite/pull/9523) +* Bump database 0.62.x in [#9568](https://github.com/appwrite/appwrite/pull/9568) +* Fix: schedules region filtering in [#9577](https://github.com/appwrite/appwrite/pull/9577) +* Deletes worker fix selects for pagination in [#9578](https://github.com/appwrite/appwrite/pull/9578) +* Add $permissions for delete documents selects in [#9579](https://github.com/appwrite/appwrite/pull/9579) +* chore(audits): return queue pre-fetch results in [#9533](https://github.com/appwrite/appwrite/pull/9533) +* Revert "chore(audits): return queue pre-fetch results" in [#9586](https://github.com/appwrite/appwrite/pull/9586) +* Feat multi tenant insert in [#9573](https://github.com/appwrite/appwrite/pull/9573) +* Add order by for cursor in [#9588](https://github.com/appwrite/appwrite/pull/9588) +* Feat update fetch in [#9592](https://github.com/appwrite/appwrite/pull/9592) +* Fix tenant casting in [#9598](https://github.com/appwrite/appwrite/pull/9598) +* Feat update ws in [#9602](https://github.com/appwrite/appwrite/pull/9602) +* Update database in [#9603](https://github.com/appwrite/appwrite/pull/9603) +* Fix: image transformation cache in [#9608](https://github.com/appwrite/appwrite/pull/9608) +* Remove audit payload in [#9610](https://github.com/appwrite/appwrite/pull/9610) +* Sample rate from DSN in [#9559](https://github.com/appwrite/appwrite/pull/9559) +* Restrict role change for sole org owner in [#9615](https://github.com/appwrite/appwrite/pull/9615) +* chore: update php image to 0.8.1 in [#9616](https://github.com/appwrite/appwrite/pull/9616) +* feat: refactor executor setup in [#9420](https://github.com/appwrite/appwrite/pull/9420) +* chore: update gitpod.yml config in [#9561](https://github.com/appwrite/appwrite/pull/9561) +* chore: update dependencies in [#9625](https://github.com/appwrite/appwrite/pull/9625) +* Update migrations lib in [#9628](https://github.com/appwrite/appwrite/pull/9628) +* feat: cache telemetry in [#9624](https://github.com/appwrite/appwrite/pull/9624) +* Bump console to version 5.2.56 in [#9631](https://github.com/appwrite/appwrite/pull/9631) +* Multi region support in [#8667](https://github.com/appwrite/appwrite/pull/8667) +* Revert "Multi region support" in [#9632](https://github.com/appwrite/appwrite/pull/9632) +* Revert "Revert "Multi region support"" in [#9636](https://github.com/appwrite/appwrite/pull/9636) +* Fix tasks in [#9644](https://github.com/appwrite/appwrite/pull/9644) +* chore: updated the migration version to 8.6 in [#9646](https://github.com/appwrite/appwrite/pull/9646) +* Fix: merge the working of StatsUsage and StatsUsageDump in [#9585](https://github.com/appwrite/appwrite/pull/9585) +* Update database in [#9643](https://github.com/appwrite/appwrite/pull/9643) +* chore: fix error logging for CLI tasks in [#9651](https://github.com/appwrite/appwrite/pull/9651) +* fix: usage test assertion in [#9653](https://github.com/appwrite/appwrite/pull/9653) +* Fix keys in [#9656](https://github.com/appwrite/appwrite/pull/9656) +* Feat: multi tenant dual writing in [#9583](https://github.com/appwrite/appwrite/pull/9583) +* Fix/throwing 400 for null order attributes in [#9657](https://github.com/appwrite/appwrite/pull/9657) +* feat: sdk group attribute in [#9596](https://github.com/appwrite/appwrite/pull/9596) +* Add configurable function and build size in [#9648](https://github.com/appwrite/appwrite/pull/9648) +* feat: update API endpoint in the code examples in [#8933](https://github.com/appwrite/appwrite/pull/8933) +* chore: abstract token secret hiding to response model in [#9574](https://github.com/appwrite/appwrite/pull/9574) +* chore: update sdks in [#9655](https://github.com/appwrite/appwrite/pull/9655) +* feat: allow non-critical events to ignore exceptions when enqueuing the event in [#9680](https://github.com/appwrite/appwrite/pull/9680) +* Revert "Add configurable function and build size" in [#9681](https://github.com/appwrite/appwrite/pull/9681) +* core: introduce endpoint.docs in specs in [#9685](https://github.com/appwrite/appwrite/pull/9685) +* fix: remove content-type header from get request specs in [#9666](https://github.com/appwrite/appwrite/pull/9666) +* chore: update flutter sdk in [#9691](https://github.com/appwrite/appwrite/pull/9691) # Version 1.6.1 diff --git a/README.md b/README.md index 9cd5808e33..1f24d5c5f2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> We just announced Timestamp Overrides for Appwrite Databases - [Learn more](https://appwrite.io/blog/post/announcing-timestamp-overrides) +> We just announced Transactions API for Appwrite Databases - [Learn more](https://appwrite.io/blog/post/announcing-transactions-api) > Appwrite Cloud is now Generally Available - [Learn more](https://appwrite.io/cloud-ga) diff --git a/app/cli.php b/app/cli.php index 0f98cf3458..71b6464cb9 100644 --- a/app/cli.php +++ b/app/cli.php @@ -103,6 +103,11 @@ CLI::setResource('console', function () { return new Document(Config::getParam('console')); }, []); +CLI::setResource( + 'isResourceBlocked', + fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false +); + CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) { $databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index 7fc82b7441..bf0cee3527 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -2521,4 +2521,128 @@ return [ ], ], ], + + 'transactions' => [ + '$collection' => ID::custom(Database::METADATA), + '$id' => ID::custom('transactions'), + 'name' => 'Transactions', + 'attributes' => [ + [ + '$id' => ID::custom('status'), + 'type' => Database::VAR_STRING, + 'size' => 16, // pending | committing | committed | failed + 'signed' => true, + 'required' => false, + 'default' => 'pending', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('operations'), + 'type' => Database::VAR_INTEGER, + 'size' => 0, + 'signed' => false, + 'required' => true, + 'default' => 0, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('expiresAt'), + 'type' => Database::VAR_DATETIME, + 'size' => 0, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + ], + 'indexes' => [ + [ + '$id' => ID::custom('_key_expiresAt'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['expiresAt'], + 'lengths' => [], + 'orders' => [Database::ORDER_DESC], + ], + ], + ], + + 'transactionLogs' => [ + '$collection' => ID::custom(Database::METADATA), + '$id' => ID::custom('transactionLogs'), + 'name' => 'Transaction Logs', + 'attributes' => [ + [ + '$id' => ID::custom('transactionInternalId'), + 'type' => Database::VAR_STRING, + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('databaseInternalId'), + 'type' => Database::VAR_STRING, + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('collectionInternalId'), + 'type' => Database::VAR_STRING, + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('documentId'), + 'type' => Database::VAR_STRING, + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('action'), + 'type' => Database::VAR_STRING, + 'size' => 32, // create | update | upsert | increment | decrement | delete | bulkCreate | bulkUpdate | bulkUpsert | bulkDelete + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('data'), + 'type' => Database::VAR_STRING, + 'size' => 5_000_000, // Allow large payloads for bulk operations + 'signed' => false, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => ['json'], + ], + ], + 'indexes' => [ + [ + '$id' => ID::custom('_key_transaction'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['transactionInternalId'], + 'lengths' => [], + 'orders' => [], + ], + ], + ], ]; diff --git a/app/config/console.php b/app/config/console.php index faacecaa08..f8f68a8039 100644 --- a/app/config/console.php +++ b/app/config/console.php @@ -49,6 +49,7 @@ $console = [ 'githubSecret' => System::getEnv('_APP_CONSOLE_GITHUB_SECRET', ''), 'githubAppid' => System::getEnv('_APP_CONSOLE_GITHUB_APP_ID', '') ], + 'smtpBaseTemplate' => APP_BRANDED_EMAIL_BASE_TEMPLATE, ]; return $console; diff --git a/app/config/errors.php b/app/config/errors.php index 156af5db8f..2e18f05797 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -211,6 +211,11 @@ return [ 'description' => 'User with the requested ID could not be found.', 'code' => 404, ], + Exception::USER_EMAIL_NOT_FOUND => [ + 'name' => Exception::USER_EMAIL_NOT_FOUND, + 'description' => 'User email could not be found.', + 'code' => 400, + ], Exception::USER_EMAIL_ALREADY_EXISTS => [ 'name' => Exception::USER_EMAIL_ALREADY_EXISTS, 'description' => 'A user with the same email already exists in the current project.', @@ -312,11 +317,21 @@ return [ 'description' => 'OAuth2 provider returned some error.', 'code' => 424, ], + Exception::USER_EMAIL_NOT_VERIFIED => [ + 'name' => Exception::USER_EMAIL_NOT_VERIFIED, + 'description' => 'User email is not verified', + 'code' => 400, + ], Exception::USER_EMAIL_ALREADY_VERIFIED => [ 'name' => Exception::USER_EMAIL_ALREADY_VERIFIED, 'description' => 'User email is already verified', 'code' => 409, ], + Exception::USER_PHONE_NOT_VERIFIED => [ + 'name' => Exception::USER_PHONE_NOT_VERIFIED, + 'description' => 'User phone is not verified', + 'code' => 400, + ], Exception::USER_PHONE_ALREADY_VERIFIED => [ 'name' => Exception::USER_PHONE_ALREADY_VERIFIED, 'description' => 'User phone is already verified', @@ -563,6 +578,11 @@ return [ 'description' => 'The requested runtime is either inactive or unsupported. Please check the value of the _APP_FUNCTIONS_RUNTIMES environment variable.', 'code' => 404, ], + Exception::FUNCTION_ALREADY_EXISTS => [ + 'name' => Exception::FUNCTION_ALREADY_EXISTS, + 'description' => 'Function with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.', + 'code' => 409, + ], Exception::FUNCTION_ENTRYPOINT_MISSING => [ 'name' => Exception::FUNCTION_ENTRYPOINT_MISSING, 'description' => 'Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".', @@ -966,6 +986,48 @@ return [ 'code' => 409, ], + /** Transactions */ + Exception::TRANSACTION_NOT_FOUND => [ + 'name' => Exception::TRANSACTION_NOT_FOUND, + 'description' => 'Transaction with the requested ID could not be found.', + 'code' => 404, + ], + Exception::TRANSACTION_ALREADY_EXISTS => [ + 'name' => Exception::TRANSACTION_ALREADY_EXISTS, + 'description' => 'Transaction with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.', + 'code' => 409, + ], + Exception::TRANSACTION_INVALID => [ + 'name' => Exception::TRANSACTION_INVALID, + 'description' => 'The transaction is invalid. Please check the transaction state and try again.', + 'code' => 400, + ], + Exception::TRANSACTION_FAILED => [ + 'name' => Exception::TRANSACTION_FAILED, + 'description' => 'The transaction has errored. Please check the transaction data and try again.', + 'code' => 400, + ], + Exception::TRANSACTION_EXPIRED => [ + 'name' => Exception::TRANSACTION_EXPIRED, + 'description' => 'The transaction has expired. Please create a new transaction and try again.', + 'code' => 410, + ], + Exception::TRANSACTION_CONFLICT => [ + 'name' => Exception::TRANSACTION_CONFLICT, + 'description' => 'The transaction has a conflict. Please resolve the conflict and try again.', + 'code' => 409, + ], + Exception::TRANSACTION_LIMIT_EXCEEDED => [ + 'name' => Exception::TRANSACTION_LIMIT_EXCEEDED, + 'description' => 'The maximum number of operations per transaction has been exceeded.', + 'code' => 400, + ], + Exception::TRANSACTION_NOT_READY => [ + 'name' => Exception::TRANSACTION_NOT_READY, + 'description' => 'The transaction is not ready yet. Please try again later.', + 'code' => 400, + ], + /** Project Errors */ Exception::PROJECT_NOT_FOUND => [ 'name' => Exception::PROJECT_NOT_FOUND, diff --git a/app/config/locale/templates/email-base-styled.tpl b/app/config/locale/templates/email-base-styled.tpl index 16036e792c..37ca630d43 100644 --- a/app/config/locale/templates/email-base-styled.tpl +++ b/app/config/locale/templates/email-base-styled.tpl @@ -131,6 +131,14 @@ .social-icon > img { margin: auto; } + p.security-phrase:not(:empty) { + opacity: 0.7; + margin: 0; + padding: 0; + margin-top: 32px; + padding-top: 32px; + border-top: 1px solid #e8e9f0; + } @@ -147,6 +155,7 @@ Appwrite logo @@ -155,12 +164,12 @@
-

{{subject}}

+

{{heading}}

- +
{{body}} diff --git a/app/config/locale/templates/email-base.tpl b/app/config/locale/templates/email-base.tpl index 8c94c3f63e..de632d7838 100644 --- a/app/config/locale/templates/email-base.tpl +++ b/app/config/locale/templates/email-base.tpl @@ -44,6 +44,21 @@ color: currentColor; word-break: break-all; } + a.button { + box-sizing: border-box; + display: inline-block; + text-align: center; + text-decoration: none; + padding: 9px 14px; + color: #ffffff; + background-color: #2D2D31; + border: 1px solid #414146; + border-radius: 8px; + } + a.button:hover, + a.button:focus { + opacity: 0.8; + } table { width: 100%; border-spacing: 0 !important; @@ -94,10 +109,15 @@ h* { font-family: 'Poppins', sans-serif; } - p { margin-bottom: 10px; } + p.security-phrase:not(:empty) { + opacity: 0.7; + margin-top: 32px; + padding-top: 32px; + border-top: 1px solid #e8e9f0; + } diff --git a/app/config/locale/templates/email-inner-base.tpl b/app/config/locale/templates/email-inner-base.tpl index 677f70ce7d..4b68f224db 100644 --- a/app/config/locale/templates/email-inner-base.tpl +++ b/app/config/locale/templates/email-inner-base.tpl @@ -1,6 +1,6 @@

{{hello}}

{{body}}

-

{{buttonText}}

+

{{buttonText}}

{{footer}}

{{thanks}} diff --git a/app/config/locale/templates/email-magic-url.tpl b/app/config/locale/templates/email-magic-url.tpl index 21988c5bc1..618993e0e9 100644 --- a/app/config/locale/templates/email-magic-url.tpl +++ b/app/config/locale/templates/email-magic-url.tpl @@ -5,7 +5,7 @@
- {{buttonText}} + {{buttonText}}
diff --git a/app/config/locale/templates/email-mfa-challenge.tpl b/app/config/locale/templates/email-mfa-challenge.tpl index 3e55227055..a828e3d299 100644 --- a/app/config/locale/templates/email-mfa-challenge.tpl +++ b/app/config/locale/templates/email-mfa-challenge.tpl @@ -5,7 +5,7 @@
-

{{otp}}

+

{{otp}}

diff --git a/app/config/locale/templates/email-otp.tpl b/app/config/locale/templates/email-otp.tpl index 84802c1603..cfcdb8f7af 100644 --- a/app/config/locale/templates/email-otp.tpl +++ b/app/config/locale/templates/email-otp.tpl @@ -5,7 +5,7 @@
-

{{otp}}

+

{{otp}}

@@ -15,6 +15,4 @@

{{thanks}}

{{signature}}

-
- -

{{securityPhrase}}

\ No newline at end of file +

{{securityPhrase}}

\ No newline at end of file diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json index e2ee20b2d7..c18c7350c3 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -3,8 +3,9 @@ "settings.locale": "en", "settings.direction": "ltr", "emails.sender": "{{project}} Team", - "emails.verification.subject": "Account Verification", + "emails.verification.subject": "Account Verification for {{project}}", "emails.verification.preview": "Verify your email to activate your {{project}} account.", + "emails.verification.heading": "Verify your email to start using {{project}}", "emails.verification.hello": "Hello {{user}},", "emails.verification.body": "Follow this link to verify your email address to your {{b}}{{project}}{{/b}} account.", "emails.verification.footer": "If you didn’t ask to verify this address, you can ignore this message.", @@ -33,6 +34,7 @@ "emails.sessionAlert.signature": "{{project}} team", "emails.otpSession.subject": "OTP for {{project}} Login", "emails.otpSession.preview": "Use OTP {{otp}} to sign in to {{project}}. Expires in 15 minutes.", + "emails.otpSession.heading": "Login with OTP to use {{project}}", "emails.otpSession.hello": "Hello {{user}},", "emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{b}}{{project}}{{/b}} account. This code will expire in 15 minutes.", "emails.otpSession.clientInfo": "This sign in was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.", @@ -41,12 +43,13 @@ "emails.otpSession.signature": "{{project}} team", "emails.mfaChallenge.subject": "Verification Code for {{project}}", "emails.mfaChallenge.preview": "Use code {{otp}} for two-step verification in {{project}}. Expires in 15 minutes.", + "emails.mfaChallenge.heading": "Complete two-step verification to use {{project}}", "emails.mfaChallenge.hello": "Hello {{user}},", "emails.mfaChallenge.description": "Enter the following code to confirm your two-step verification in {{b}}{{project}}{{/b}}. This code will expire in 15 minutes.", "emails.mfaChallenge.clientInfo": "This verification code was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the verification code, you can safely ignore this email.", "emails.mfaChallenge.thanks": "Thanks,", "emails.mfaChallenge.signature": "{{project}} team", - "emails.recovery.subject": "Password Reset", + "emails.recovery.subject": "Password Reset for {{project}}", "emails.recovery.preview": "Reset your {{project}} password using the link.", "emails.recovery.hello": "Hello {{user}},", "emails.recovery.body": "Follow this link to reset your {{b}}{{project}}{{/b}} password.", diff --git a/app/config/platforms.php b/app/config/platforms.php index 7aec82d1cf..3b675b174c 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -11,7 +11,7 @@ return [ [ 'key' => 'web', 'name' => 'Web', - 'version' => '20.0.0', + 'version' => '21.2.1', 'url' => 'https://github.com/appwrite/sdk-for-web', 'package' => 'https://www.npmjs.com/package/appwrite', 'enabled' => true, @@ -60,7 +60,7 @@ return [ [ 'key' => 'flutter', 'name' => 'Flutter', - 'version' => '19.0.0', + 'version' => '20.2.1', 'url' => 'https://github.com/appwrite/sdk-for-flutter', 'package' => 'https://pub.dev/packages/appwrite', 'enabled' => true, @@ -79,7 +79,7 @@ return [ [ 'key' => 'apple', 'name' => 'Apple', - 'version' => '12.0.0', + 'version' => '13.3.0', 'url' => 'https://github.com/appwrite/sdk-for-apple', 'package' => 'https://github.com/appwrite/sdk-for-apple', 'enabled' => true, @@ -116,7 +116,7 @@ return [ [ 'key' => 'android', 'name' => 'Android', - 'version' => '10.0.0', + 'version' => '11.2.1', 'url' => 'https://github.com/appwrite/sdk-for-android', 'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-android', 'enabled' => true, @@ -139,7 +139,7 @@ return [ [ 'key' => 'react-native', 'name' => 'React Native', - 'version' => '0.13.0', + 'version' => '0.17.1', 'url' => 'https://github.com/appwrite/sdk-for-react-native', 'package' => 'https://npmjs.com/package/react-native-appwrite', 'enabled' => true, @@ -207,7 +207,7 @@ return [ [ 'key' => 'web', 'name' => 'Console', - 'version' => '0.1.0', + 'version' => '0.1.1', 'url' => '', 'package' => '', 'enabled' => true, @@ -226,7 +226,7 @@ return [ [ 'key' => 'cli', 'name' => 'Command Line', - 'version' => '10.0.0', + 'version' => '10.2.2', 'url' => 'https://github.com/appwrite/sdk-for-cli', 'package' => 'https://www.npmjs.com/package/appwrite-cli', 'enabled' => true, @@ -262,7 +262,7 @@ return [ [ 'key' => 'nodejs', 'name' => 'Node.js', - 'version' => '19.0.0', + 'version' => '20.2.1', 'url' => 'https://github.com/appwrite/sdk-for-node', 'package' => 'https://www.npmjs.com/package/node-appwrite', 'enabled' => true, @@ -281,7 +281,7 @@ return [ [ 'key' => 'php', 'name' => 'PHP', - 'version' => '17.0.0', + 'version' => '17.4.1', 'url' => 'https://github.com/appwrite/sdk-for-php', 'package' => 'https://packagist.org/packages/appwrite/appwrite', 'enabled' => true, @@ -300,7 +300,7 @@ return [ [ 'key' => 'python', 'name' => 'Python', - 'version' => '13.0.0', + 'version' => '13.4.1', 'url' => 'https://github.com/appwrite/sdk-for-python', 'package' => 'https://pypi.org/project/appwrite/', 'enabled' => true, @@ -319,7 +319,7 @@ return [ [ 'key' => 'ruby', 'name' => 'Ruby', - 'version' => '18.0.0', + 'version' => '19.2.1', 'url' => 'https://github.com/appwrite/sdk-for-ruby', 'package' => 'https://rubygems.org/gems/appwrite', 'enabled' => true, @@ -338,7 +338,7 @@ return [ [ 'key' => 'go', 'name' => 'Go', - 'version' => '0.11.0', + 'version' => 'v0.13.1', 'url' => 'https://github.com/appwrite/sdk-for-go', 'package' => 'https://github.com/appwrite/sdk-for-go', 'enabled' => true, @@ -357,7 +357,7 @@ return [ [ 'key' => 'dotnet', 'name' => '.NET', - 'version' => '0.17.0', + 'version' => '0.21.2', 'url' => 'https://github.com/appwrite/sdk-for-dotnet', 'package' => 'https://www.nuget.org/packages/Appwrite', 'enabled' => true, @@ -376,7 +376,7 @@ return [ [ 'key' => 'dart', 'name' => 'Dart', - 'version' => '18.0.0', + 'version' => '19.2.1', 'url' => 'https://github.com/appwrite/sdk-for-dart', 'package' => 'https://pub.dev/packages/dart_appwrite', 'enabled' => true, @@ -395,7 +395,7 @@ return [ [ 'key' => 'kotlin', 'name' => 'Kotlin', - 'version' => '11.0.0', + 'version' => '12.2.1', 'url' => 'https://github.com/appwrite/sdk-for-kotlin', 'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin', 'enabled' => true, @@ -418,7 +418,7 @@ return [ [ 'key' => 'swift', 'name' => 'Swift', - 'version' => '12.0.0', + 'version' => '13.2.2', 'url' => 'https://github.com/appwrite/sdk-for-swift', 'package' => 'https://github.com/appwrite/sdk-for-swift', 'enabled' => true, diff --git a/app/config/roles.php b/app/config/roles.php index 4b06e0a6c1..0f0945a2b4 100644 --- a/app/config/roles.php +++ b/app/config/roles.php @@ -28,7 +28,7 @@ $member = [ 'subscribers.write', 'subscribers.read', 'assistant.read', - 'rules.read' + 'rules.read', ]; $admins = [ diff --git a/app/config/specs/open-api3-1.8.x-client.json b/app/config/specs/open-api3-1.8.x-client.json index d57b9f83b2..b6a6a1afe3 100644 --- a/app/config/specs/open-api3-1.8.x-client.json +++ b/app/config/specs/open-api3-1.8.x-client.json @@ -3464,10 +3464,10 @@ } } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "tags": [ "account" ], @@ -3486,12 +3486,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3502,6 +3502,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3535,7 +3585,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "tags": [ "account" ], @@ -3554,12 +3604,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3570,6 +3620,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3608,7 +3712,7 @@ } } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4806,6 +4910,424 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents": { "get": { "summary": "List documents", @@ -4893,6 +5415,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -4951,7 +5483,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5037,6 +5570,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5142,6 +5680,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -5200,7 +5748,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5283,6 +5832,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -5396,6 +5950,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5480,7 +6039,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/decrement": { @@ -5594,6 +6169,11 @@ "type": "number", "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5713,6 +6293,11 @@ "type": "number", "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5745,7 +6330,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -5820,7 +6405,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -5896,9 +6481,9 @@ "x-enum-keys": [] }, "headers": { - "type": "string", + "type": "object", "description": "HTTP headers of execution. Defaults to empty.", - "x-example": null + "x-example": "{}" }, "scheduledAt": { "type": "string", @@ -5936,7 +6521,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -7467,6 +8052,424 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows": { "get": { "summary": "List rows", @@ -7491,7 +8494,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -7533,7 +8536,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "schema": { "type": "string", @@ -7553,6 +8556,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -7562,7 +8575,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7579,7 +8592,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -7610,7 +8623,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7624,7 +8638,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" } ], @@ -7652,7 +8666,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "schema": { "type": "string", @@ -7692,6 +8706,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -7724,7 +8743,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -7766,7 +8785,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -7796,6 +8815,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -7805,7 +8834,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7822,7 +8851,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -7853,7 +8882,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7866,7 +8896,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -7931,6 +8961,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -7961,7 +8996,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -8040,6 +9075,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -8063,7 +9103,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -8105,7 +9145,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -8123,7 +9163,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows\/{rowId}\/{column}\/decrement": { @@ -8150,7 +9206,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -8236,6 +9292,11 @@ "type": "number", "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -8268,7 +9329,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -8354,6 +9415,11 @@ "type": "number", "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9935,6 +11001,34 @@ "localeCodes": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "$ref": "#\/components\/schemas\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "row": { "description": "Row", "type": "object", @@ -11850,6 +12944,59 @@ "recoveryCode": true } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/open-api3-1.8.x-console.json b/app/config/specs/open-api3-1.8.x-console.json index 1dd58c3261..c086fe03d0 100644 --- a/app/config/specs/open-api3-1.8.x-console.json +++ b/app/config/specs/open-api3-1.8.x-console.json @@ -3473,10 +3473,10 @@ } } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "tags": [ "account" ], @@ -3495,12 +3495,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3511,6 +3511,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3543,7 +3593,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "tags": [ "account" ], @@ -3562,12 +3612,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3578,6 +3628,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3615,7 +3719,7 @@ } } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4888,7 +4992,7 @@ "x-appwrite": { "method": "getResource", "group": null, - "weight": 496, + "weight": 508, "cookies": false, "type": "", "demo": "console\/get-resource.md", @@ -5205,6 +5309,424 @@ } } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/databases\/usage": { "get": { "summary": "Get databases usage stats", @@ -9460,6 +9982,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -9518,7 +10050,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9549,7 +10082,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9634,6 +10168,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9693,7 +10232,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9759,6 +10299,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -9860,6 +10405,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9953,6 +10503,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10058,6 +10613,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -10116,7 +10681,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -10199,6 +10765,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -10312,6 +10883,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10396,7 +10972,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/logs": { @@ -10607,6 +11199,11 @@ "type": "number", "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10726,6 +11323,11 @@ "type": "number", "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10960,7 +11562,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -11540,7 +12142,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -11613,7 +12215,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -11846,7 +12448,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -11895,7 +12497,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -11945,7 +12547,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 466, + "weight": 478, "cookies": false, "type": "", "demo": "functions\/list-templates.md", @@ -12045,7 +12647,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 465, + "weight": 477, "cookies": false, "type": "", "demo": "functions\/get-template.md", @@ -12105,7 +12707,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 459, + "weight": 471, "cookies": false, "type": "", "demo": "functions\/list-usage.md", @@ -12177,7 +12779,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -12236,7 +12838,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -12466,7 +13068,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -12527,7 +13129,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -12607,7 +13209,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -12690,7 +13292,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -12786,7 +13388,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -12854,7 +13456,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -12871,11 +13473,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12974,7 +13576,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -13071,7 +13673,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -13133,7 +13735,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -13197,7 +13799,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -13287,7 +13889,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -13358,7 +13960,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -13433,7 +14035,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -13509,9 +14111,9 @@ "x-enum-keys": [] }, "headers": { - "type": "string", + "type": "object", "description": "HTTP headers of execution. Defaults to empty.", - "x-example": null + "x-example": "{}" }, "scheduledAt": { "type": "string", @@ -13549,7 +14151,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -13614,7 +14216,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -13685,7 +14287,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 458, + "weight": 470, "cookies": false, "type": "", "demo": "functions\/get-usage.md", @@ -13767,7 +14369,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -13826,7 +14428,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -13917,7 +14519,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -13986,7 +14588,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -14077,7 +14679,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -16411,7 +17013,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -16592,7 +17194,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -21190,7 +21792,7 @@ "resourceId": { "type": "string", "description": "Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "internalFile": { "type": "boolean", @@ -22433,7 +23035,7 @@ "x-appwrite": { "method": "list", "group": "projects", - "weight": 436, + "weight": 448, "cookies": false, "type": "", "demo": "projects\/list.md", @@ -24068,7 +24670,7 @@ "x-appwrite": { "method": "listDevKeys", "group": "devKeys", - "weight": 434, + "weight": 446, "cookies": false, "type": "", "demo": "projects\/list-dev-keys.md", @@ -24106,7 +24708,10 @@ "description": "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: accessedAt, expire", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -24136,7 +24741,7 @@ "x-appwrite": { "method": "createDevKey", "group": "devKeys", - "weight": 431, + "weight": 443, "cookies": false, "type": "", "demo": "projects\/create-dev-key.md", @@ -24221,7 +24826,7 @@ "x-appwrite": { "method": "getDevKey", "group": "devKeys", - "weight": 433, + "weight": 445, "cookies": false, "type": "", "demo": "projects\/get-dev-key.md", @@ -24289,7 +24894,7 @@ "x-appwrite": { "method": "updateDevKey", "group": "devKeys", - "weight": 432, + "weight": 444, "cookies": false, "type": "", "demo": "projects\/update-dev-key.md", @@ -24375,7 +24980,7 @@ "x-appwrite": { "method": "deleteDevKey", "group": "devKeys", - "weight": 435, + "weight": 447, "cookies": false, "type": "", "demo": "projects\/delete-dev-key.md", @@ -25153,7 +25758,7 @@ "properties": { "type": { "type": "string", - "description": "Platform type.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "x-example": "web", "enum": [ "web", @@ -28209,7 +28814,7 @@ "x-appwrite": { "method": "listRules", "group": null, - "weight": 502, + "weight": 514, "cookies": false, "type": "", "demo": "proxy\/list-rules.md", @@ -28283,7 +28888,7 @@ "x-appwrite": { "method": "createAPIRule", "group": null, - "weight": 497, + "weight": 509, "cookies": false, "type": "", "demo": "proxy\/create-api-rule.md", @@ -28350,7 +28955,7 @@ "x-appwrite": { "method": "createFunctionRule", "group": null, - "weight": 499, + "weight": 511, "cookies": false, "type": "", "demo": "proxy\/create-function-rule.md", @@ -28428,7 +29033,7 @@ "x-appwrite": { "method": "createRedirectRule", "group": null, - "weight": 500, + "weight": 512, "cookies": false, "type": "", "demo": "proxy\/create-redirect-rule.md", @@ -28541,7 +29146,7 @@ "x-appwrite": { "method": "createSiteRule", "group": null, - "weight": 498, + "weight": 510, "cookies": false, "type": "", "demo": "proxy\/create-site-rule.md", @@ -28619,7 +29224,7 @@ "x-appwrite": { "method": "getRule", "group": null, - "weight": 501, + "weight": 513, "cookies": false, "type": "", "demo": "proxy\/get-rule.md", @@ -28670,7 +29275,7 @@ "x-appwrite": { "method": "deleteRule", "group": null, - "weight": 503, + "weight": 515, "cookies": false, "type": "", "demo": "proxy\/delete-rule.md", @@ -28730,7 +29335,7 @@ "x-appwrite": { "method": "updateRuleVerification", "group": null, - "weight": 504, + "weight": 516, "cookies": false, "type": "", "demo": "proxy\/update-rule-verification.md", @@ -28790,7 +29395,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -28819,7 +29424,10 @@ "description": "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, framework, deploymentId, buildCommand, installCommand, outputDirectory, installationId", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -28860,7 +29468,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -29109,7 +29717,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -29158,7 +29766,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -29208,7 +29816,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 491, + "weight": 503, "cookies": false, "type": "", "demo": "sites\/list-templates.md", @@ -29308,7 +29916,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 492, + "weight": 504, "cookies": false, "type": "", "demo": "sites\/get-template.md", @@ -29368,7 +29976,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 493, + "weight": 505, "cookies": false, "type": "", "demo": "sites\/list-usage.md", @@ -29440,7 +30048,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -29499,7 +30107,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -29744,7 +30352,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -29805,7 +30413,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -29885,7 +30493,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -29968,7 +30576,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -30069,7 +30677,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -30132,7 +30740,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -30149,11 +30757,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -30252,7 +30860,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -30350,7 +30958,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -30412,7 +31020,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -30476,7 +31084,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -30566,7 +31174,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -30637,7 +31245,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -30676,7 +31284,10 @@ "description": "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", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -30708,7 +31319,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -30770,7 +31381,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -30841,7 +31452,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 494, + "weight": 506, "cookies": false, "type": "", "demo": "sites\/get-usage.md", @@ -30923,7 +31534,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -30982,7 +31593,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -31073,7 +31684,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -31142,7 +31753,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -31233,7 +31844,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -32705,7 +33316,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -32778,7 +33389,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -32833,6 +33444,424 @@ } } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/tablesdb\/usage": { "get": { "summary": "Get TablesDB usage stats", @@ -32857,7 +33886,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 378, + "weight": 384, "cookies": false, "type": "", "demo": "tablesdb\/list-usage.md", @@ -32954,7 +33983,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -33013,7 +34042,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -33089,7 +34118,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -33150,7 +34179,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -33219,7 +34248,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -33236,7 +34265,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -33343,7 +34372,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -33415,7 +34444,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -33517,7 +34546,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -33591,7 +34620,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -33678,7 +34707,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -33717,7 +34746,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -33787,7 +34816,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -33826,7 +34855,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -33901,7 +34930,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -34010,7 +35039,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -34124,7 +35153,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -34233,7 +35262,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -34347,7 +35376,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -34465,7 +35494,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -34588,7 +35617,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -34707,7 +35736,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -34831,7 +35860,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -34950,7 +35979,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -35074,7 +36103,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -35183,7 +36212,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -35297,7 +36326,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -35336,7 +36365,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35409,7 +36438,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -35448,7 +36477,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35529,7 +36558,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -35568,7 +36597,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35641,7 +36670,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -35680,7 +36709,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35761,7 +36790,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -35800,7 +36829,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35873,7 +36902,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -35912,7 +36941,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35993,7 +37022,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -36127,7 +37156,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -36166,7 +37195,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -36247,7 +37276,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -36286,7 +37315,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -36366,7 +37395,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -36475,7 +37504,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -36620,7 +37649,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -36694,7 +37723,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -36777,7 +37806,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -36888,7 +37917,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -36927,7 +37956,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -36973,7 +38002,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -37012,7 +38041,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37105,7 +38134,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -37144,7 +38173,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37179,7 +38208,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -37218,7 +38247,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37262,7 +38291,7 @@ "x-appwrite": { "method": "listTableLogs", "group": "tables", - "weight": 384, + "weight": 390, "cookies": false, "type": "", "demo": "tablesdb\/list-table-logs.md", @@ -37348,7 +38377,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -37390,7 +38419,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "schema": { "type": "string", @@ -37410,6 +38439,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -37419,7 +38458,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -37436,7 +38475,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -37467,7 +38506,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -37481,7 +38521,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -37494,7 +38534,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37507,7 +38548,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -37535,7 +38576,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "schema": { "type": "string", @@ -37575,6 +38616,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -37588,7 +38634,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -37605,7 +38651,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -37633,7 +38679,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37646,7 +38693,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -37695,6 +38742,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -37728,7 +38780,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -37795,6 +38847,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -37825,7 +38882,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -37865,7 +38922,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37887,6 +38944,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -37919,7 +38981,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -37961,7 +39023,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37991,6 +39053,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -38000,7 +39072,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -38017,7 +39089,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -38048,7 +39120,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -38061,7 +39134,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -38126,6 +39199,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38156,7 +39234,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -38235,6 +39313,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38258,7 +39341,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -38300,7 +39383,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -38318,7 +39401,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows\/{rowId}\/logs": { @@ -38345,7 +39444,7 @@ "x-appwrite": { "method": "listRowLogs", "group": "logs", - "weight": 428, + "weight": 434, "cookies": false, "type": "", "demo": "tablesdb\/list-row-logs.md", @@ -38441,7 +39540,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -38527,6 +39626,11 @@ "type": "number", "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38559,7 +39663,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -38645,6 +39749,11 @@ "type": "number", "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38677,7 +39786,7 @@ "x-appwrite": { "method": "getTableUsage", "group": null, - "weight": 385, + "weight": 391, "cookies": false, "type": "", "demo": "tablesdb\/get-table-usage.md", @@ -38772,7 +39881,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 377, + "weight": 383, "cookies": false, "type": "", "demo": "tablesdb\/get-usage.md", @@ -39984,7 +41093,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -40034,7 +41143,10 @@ "description": "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: expire", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -40064,7 +41176,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -40153,7 +41265,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -40213,7 +41325,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -40283,7 +41395,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -46107,6 +47219,34 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "$ref": "#\/components\/schemas\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "migrationList": { "description": "Migrations List", "type": "object", @@ -46223,7 +47363,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -46468,7 +47612,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46563,7 +47708,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46660,7 +47806,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46757,7 +47904,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46837,7 +47985,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46924,7 +48073,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47021,7 +48171,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47108,7 +48259,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47195,7 +48347,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47282,7 +48435,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47397,7 +48551,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47483,7 +48638,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47581,7 +48737,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47897,7 +49054,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -47985,7 +49150,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48075,7 +49248,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48165,7 +49346,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48238,7 +49427,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48318,7 +49515,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48408,7 +49613,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48488,7 +49701,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48568,7 +49789,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48648,7 +49877,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48756,7 +49993,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48835,7 +50080,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48926,7 +50179,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -53427,16 +54688,24 @@ }, "type": { "type": "string", - "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, ios, android, and unity.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "x-example": "web", "enum": [ "web", "flutter-web", "flutter-ios", "flutter-android", - "ios", + "flutter-linux", + "flutter-macos", + "flutter-windows", + "apple-ios", + "apple-macos", + "apple-watchos", + "apple-tvos", "android", - "unity" + "unity", + "react-native-ios", + "react-native-android" ] }, "key": { @@ -53796,7 +55065,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -56535,7 +57805,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -56649,6 +57926,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/open-api3-1.8.x-server.json b/app/config/specs/open-api3-1.8.x-server.json index b437d56bfc..49adaeeefa 100644 --- a/app/config/specs/open-api3-1.8.x-server.json +++ b/app/config/specs/open-api3-1.8.x-server.json @@ -3161,10 +3161,10 @@ } } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "tags": [ "account" ], @@ -3183,12 +3183,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3199,6 +3199,58 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3233,7 +3285,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "tags": [ "account" ], @@ -3252,12 +3304,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3268,6 +3320,62 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3307,7 +3415,7 @@ } } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4743,6 +4851,436 @@ } } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/databases\/{databaseId}": { "get": { "summary": "Get database", @@ -8938,6 +9476,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -8997,7 +9545,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9029,7 +9578,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9116,6 +9666,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9176,7 +9731,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9243,6 +9799,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -9345,6 +9906,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9439,6 +10005,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9546,6 +10117,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -9605,7 +10186,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9690,6 +10272,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -9805,6 +10392,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9891,7 +10483,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/decrement": { @@ -10007,6 +10615,11 @@ "type": "number", "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10128,6 +10741,11 @@ "type": "number", "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10364,7 +10982,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -10542,7 +11160,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -10616,7 +11234,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -10850,7 +11468,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -10900,7 +11518,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -10951,7 +11569,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -11011,7 +11629,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -11242,7 +11860,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -11304,7 +11922,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -11385,7 +12003,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -11469,7 +12087,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -11566,7 +12184,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -11635,7 +12253,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -11652,11 +12270,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11756,7 +12374,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -11854,7 +12472,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -11917,7 +12535,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -11982,7 +12600,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -12073,7 +12691,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -12145,7 +12763,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -12222,7 +12840,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -12300,9 +12918,9 @@ "x-enum-keys": [] }, "headers": { - "type": "string", + "type": "object", "description": "HTTP headers of execution. Defaults to empty.", - "x-example": null + "x-example": "{}" }, "scheduledAt": { "type": "string", @@ -12340,7 +12958,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -12407,7 +13025,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -12479,7 +13097,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -12539,7 +13157,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -12631,7 +13249,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -12701,7 +13319,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -12793,7 +13411,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -15174,7 +15792,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -15356,7 +15974,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -19717,7 +20335,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -19747,7 +20365,10 @@ "description": "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, framework, deploymentId, buildCommand, installCommand, outputDirectory, installationId", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -19788,7 +20409,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -20038,7 +20659,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -20088,7 +20709,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -20139,7 +20760,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -20199,7 +20820,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -20445,7 +21066,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -20507,7 +21128,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -20588,7 +21209,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -20672,7 +21293,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -20774,7 +21395,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -20838,7 +21459,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -20855,11 +21476,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -20959,7 +21580,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -21058,7 +21679,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -21121,7 +21742,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -21186,7 +21807,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -21277,7 +21898,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -21349,7 +21970,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -21389,7 +22010,10 @@ "description": "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", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -21421,7 +22045,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -21484,7 +22108,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -21556,7 +22180,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -21616,7 +22240,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -21708,7 +22332,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -21778,7 +22402,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -21870,7 +22494,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -23210,7 +23834,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -23284,7 +23908,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -23340,6 +23964,436 @@ } } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/tablesdb\/{databaseId}": { "get": { "summary": "Get database", @@ -23364,7 +24418,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -23424,7 +24478,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -23501,7 +24555,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -23563,7 +24617,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -23633,7 +24687,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -23650,7 +24704,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -23758,7 +24812,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -23831,7 +24885,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -23934,7 +24988,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -24009,7 +25063,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -24097,7 +25151,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -24137,7 +25191,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -24207,7 +25261,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -24247,7 +25301,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -24322,7 +25376,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -24432,7 +25486,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -24547,7 +25601,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -24657,7 +25711,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -24772,7 +25826,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -24891,7 +25945,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -25015,7 +26069,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -25135,7 +26189,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -25260,7 +26314,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -25380,7 +26434,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -25505,7 +26559,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -25615,7 +26669,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -25730,7 +26784,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -25770,7 +26824,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -25843,7 +26897,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -25883,7 +26937,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -25964,7 +27018,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -26004,7 +27058,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26077,7 +27131,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -26117,7 +27171,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26198,7 +27252,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -26238,7 +27292,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26311,7 +27365,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -26351,7 +27405,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26432,7 +27486,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -26567,7 +27621,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -26607,7 +27661,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26688,7 +27742,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -26728,7 +27782,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26808,7 +27862,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -26918,7 +27972,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -27064,7 +28118,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -27139,7 +28193,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -27223,7 +28277,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -27335,7 +28389,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -27375,7 +28429,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27421,7 +28475,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -27461,7 +28515,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27554,7 +28608,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -27594,7 +28648,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27629,7 +28683,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -27669,7 +28723,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27713,7 +28767,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -27757,7 +28811,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "schema": { "type": "string", @@ -27777,6 +28831,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -27786,7 +28850,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -27803,7 +28867,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -27835,7 +28899,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -27849,7 +28914,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -27863,7 +28928,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -27876,7 +28942,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -27906,7 +28972,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "schema": { "type": "string", @@ -27946,6 +29012,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -27959,7 +29030,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -27976,7 +29047,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -28005,7 +29076,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -28018,7 +29090,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -28068,6 +29140,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -28101,7 +29178,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -28169,6 +29246,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28199,7 +29281,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -28240,7 +29322,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -28262,6 +29344,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28294,7 +29381,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -28338,7 +29425,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -28368,6 +29455,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -28377,7 +29474,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -28394,7 +29491,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -28426,7 +29523,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -28439,7 +29537,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -28506,6 +29604,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28536,7 +29639,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -28617,6 +29720,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28640,7 +29748,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -28684,7 +29792,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -28702,7 +29810,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows\/{rowId}\/{column}\/decrement": { @@ -28729,7 +29853,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -28817,6 +29941,11 @@ "type": "number", "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28849,7 +29978,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -28937,6 +30066,11 @@ "type": "number", "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -30024,7 +31158,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -30075,7 +31209,10 @@ "description": "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: expire", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -30105,7 +31242,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -30195,7 +31332,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -30256,7 +31393,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -30327,7 +31464,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -35033,6 +36170,34 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "$ref": "#\/components\/schemas\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "specificationList": { "description": "Specifications List", "type": "object", @@ -35093,7 +36258,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -35338,7 +36507,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35433,7 +36603,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35530,7 +36701,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35627,7 +36799,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35707,7 +36880,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35794,7 +36968,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35891,7 +37066,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35978,7 +37154,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36065,7 +37242,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36152,7 +37330,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36267,7 +37446,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36353,7 +37533,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36451,7 +37632,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36767,7 +37949,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36855,7 +38045,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36945,7 +38143,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37035,7 +38241,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37108,7 +38322,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37188,7 +38410,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37278,7 +38508,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37358,7 +38596,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37438,7 +38684,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37518,7 +38772,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37626,7 +38888,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37705,7 +38975,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37796,7 +39074,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -40984,7 +42270,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -41449,7 +42736,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -41563,6 +42857,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/open-api3-latest-client.json b/app/config/specs/open-api3-latest-client.json index d57b9f83b2..b6a6a1afe3 100644 --- a/app/config/specs/open-api3-latest-client.json +++ b/app/config/specs/open-api3-latest-client.json @@ -3464,10 +3464,10 @@ } } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "tags": [ "account" ], @@ -3486,12 +3486,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3502,6 +3502,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3535,7 +3585,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "tags": [ "account" ], @@ -3554,12 +3604,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3570,6 +3620,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3608,7 +3712,7 @@ } } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4806,6 +4910,424 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents": { "get": { "summary": "List documents", @@ -4893,6 +5415,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -4951,7 +5483,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5037,6 +5570,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5142,6 +5680,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -5200,7 +5748,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5283,6 +5832,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -5396,6 +5950,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5480,7 +6039,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/decrement": { @@ -5594,6 +6169,11 @@ "type": "number", "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5713,6 +6293,11 @@ "type": "number", "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -5745,7 +6330,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -5820,7 +6405,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -5896,9 +6481,9 @@ "x-enum-keys": [] }, "headers": { - "type": "string", + "type": "object", "description": "HTTP headers of execution. Defaults to empty.", - "x-example": null + "x-example": "{}" }, "scheduledAt": { "type": "string", @@ -5936,7 +6521,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -7467,6 +8052,424 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows": { "get": { "summary": "List rows", @@ -7491,7 +8494,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -7533,7 +8536,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "schema": { "type": "string", @@ -7553,6 +8556,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -7562,7 +8575,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7579,7 +8592,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -7610,7 +8623,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7624,7 +8638,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" } ], @@ -7652,7 +8666,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "schema": { "type": "string", @@ -7692,6 +8706,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -7724,7 +8743,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -7766,7 +8785,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -7796,6 +8815,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -7805,7 +8834,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7822,7 +8851,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -7853,7 +8882,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7866,7 +8896,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -7931,6 +8961,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -7961,7 +8996,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -8040,6 +9075,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -8063,7 +9103,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -8105,7 +9145,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -8123,7 +9163,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows\/{rowId}\/{column}\/decrement": { @@ -8150,7 +9206,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -8236,6 +9292,11 @@ "type": "number", "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -8268,7 +9329,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -8354,6 +9415,11 @@ "type": "number", "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9935,6 +11001,34 @@ "localeCodes": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "$ref": "#\/components\/schemas\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "row": { "description": "Row", "type": "object", @@ -11850,6 +12944,59 @@ "recoveryCode": true } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 1dd58c3261..c086fe03d0 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -3473,10 +3473,10 @@ } } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "tags": [ "account" ], @@ -3495,12 +3495,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3511,6 +3511,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3543,7 +3593,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "tags": [ "account" ], @@ -3562,12 +3612,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3578,6 +3628,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3615,7 +3719,7 @@ } } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4888,7 +4992,7 @@ "x-appwrite": { "method": "getResource", "group": null, - "weight": 496, + "weight": 508, "cookies": false, "type": "", "demo": "console\/get-resource.md", @@ -5205,6 +5309,424 @@ } } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/databases\/usage": { "get": { "summary": "Get databases usage stats", @@ -9460,6 +9982,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -9518,7 +10050,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9549,7 +10082,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9634,6 +10168,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9693,7 +10232,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9759,6 +10299,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -9860,6 +10405,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9953,6 +10503,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10058,6 +10613,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -10116,7 +10681,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -10199,6 +10765,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -10312,6 +10883,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10396,7 +10972,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/logs": { @@ -10607,6 +11199,11 @@ "type": "number", "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10726,6 +11323,11 @@ "type": "number", "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10960,7 +11562,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -11540,7 +12142,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -11613,7 +12215,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -11846,7 +12448,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -11895,7 +12497,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -11945,7 +12547,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 466, + "weight": 478, "cookies": false, "type": "", "demo": "functions\/list-templates.md", @@ -12045,7 +12647,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 465, + "weight": 477, "cookies": false, "type": "", "demo": "functions\/get-template.md", @@ -12105,7 +12707,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 459, + "weight": 471, "cookies": false, "type": "", "demo": "functions\/list-usage.md", @@ -12177,7 +12779,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -12236,7 +12838,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -12466,7 +13068,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -12527,7 +13129,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -12607,7 +13209,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -12690,7 +13292,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -12786,7 +13388,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -12854,7 +13456,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -12871,11 +13473,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12974,7 +13576,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -13071,7 +13673,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -13133,7 +13735,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -13197,7 +13799,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -13287,7 +13889,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -13358,7 +13960,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -13433,7 +14035,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -13509,9 +14111,9 @@ "x-enum-keys": [] }, "headers": { - "type": "string", + "type": "object", "description": "HTTP headers of execution. Defaults to empty.", - "x-example": null + "x-example": "{}" }, "scheduledAt": { "type": "string", @@ -13549,7 +14151,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -13614,7 +14216,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -13685,7 +14287,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 458, + "weight": 470, "cookies": false, "type": "", "demo": "functions\/get-usage.md", @@ -13767,7 +14369,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -13826,7 +14428,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -13917,7 +14519,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -13986,7 +14588,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -14077,7 +14679,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -16411,7 +17013,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -16592,7 +17194,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -21190,7 +21792,7 @@ "resourceId": { "type": "string", "description": "Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "internalFile": { "type": "boolean", @@ -22433,7 +23035,7 @@ "x-appwrite": { "method": "list", "group": "projects", - "weight": 436, + "weight": 448, "cookies": false, "type": "", "demo": "projects\/list.md", @@ -24068,7 +24670,7 @@ "x-appwrite": { "method": "listDevKeys", "group": "devKeys", - "weight": 434, + "weight": 446, "cookies": false, "type": "", "demo": "projects\/list-dev-keys.md", @@ -24106,7 +24708,10 @@ "description": "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: accessedAt, expire", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -24136,7 +24741,7 @@ "x-appwrite": { "method": "createDevKey", "group": "devKeys", - "weight": 431, + "weight": 443, "cookies": false, "type": "", "demo": "projects\/create-dev-key.md", @@ -24221,7 +24826,7 @@ "x-appwrite": { "method": "getDevKey", "group": "devKeys", - "weight": 433, + "weight": 445, "cookies": false, "type": "", "demo": "projects\/get-dev-key.md", @@ -24289,7 +24894,7 @@ "x-appwrite": { "method": "updateDevKey", "group": "devKeys", - "weight": 432, + "weight": 444, "cookies": false, "type": "", "demo": "projects\/update-dev-key.md", @@ -24375,7 +24980,7 @@ "x-appwrite": { "method": "deleteDevKey", "group": "devKeys", - "weight": 435, + "weight": 447, "cookies": false, "type": "", "demo": "projects\/delete-dev-key.md", @@ -25153,7 +25758,7 @@ "properties": { "type": { "type": "string", - "description": "Platform type.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "x-example": "web", "enum": [ "web", @@ -28209,7 +28814,7 @@ "x-appwrite": { "method": "listRules", "group": null, - "weight": 502, + "weight": 514, "cookies": false, "type": "", "demo": "proxy\/list-rules.md", @@ -28283,7 +28888,7 @@ "x-appwrite": { "method": "createAPIRule", "group": null, - "weight": 497, + "weight": 509, "cookies": false, "type": "", "demo": "proxy\/create-api-rule.md", @@ -28350,7 +28955,7 @@ "x-appwrite": { "method": "createFunctionRule", "group": null, - "weight": 499, + "weight": 511, "cookies": false, "type": "", "demo": "proxy\/create-function-rule.md", @@ -28428,7 +29033,7 @@ "x-appwrite": { "method": "createRedirectRule", "group": null, - "weight": 500, + "weight": 512, "cookies": false, "type": "", "demo": "proxy\/create-redirect-rule.md", @@ -28541,7 +29146,7 @@ "x-appwrite": { "method": "createSiteRule", "group": null, - "weight": 498, + "weight": 510, "cookies": false, "type": "", "demo": "proxy\/create-site-rule.md", @@ -28619,7 +29224,7 @@ "x-appwrite": { "method": "getRule", "group": null, - "weight": 501, + "weight": 513, "cookies": false, "type": "", "demo": "proxy\/get-rule.md", @@ -28670,7 +29275,7 @@ "x-appwrite": { "method": "deleteRule", "group": null, - "weight": 503, + "weight": 515, "cookies": false, "type": "", "demo": "proxy\/delete-rule.md", @@ -28730,7 +29335,7 @@ "x-appwrite": { "method": "updateRuleVerification", "group": null, - "weight": 504, + "weight": 516, "cookies": false, "type": "", "demo": "proxy\/update-rule-verification.md", @@ -28790,7 +29395,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -28819,7 +29424,10 @@ "description": "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, framework, deploymentId, buildCommand, installCommand, outputDirectory, installationId", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -28860,7 +29468,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -29109,7 +29717,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -29158,7 +29766,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -29208,7 +29816,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 491, + "weight": 503, "cookies": false, "type": "", "demo": "sites\/list-templates.md", @@ -29308,7 +29916,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 492, + "weight": 504, "cookies": false, "type": "", "demo": "sites\/get-template.md", @@ -29368,7 +29976,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 493, + "weight": 505, "cookies": false, "type": "", "demo": "sites\/list-usage.md", @@ -29440,7 +30048,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -29499,7 +30107,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -29744,7 +30352,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -29805,7 +30413,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -29885,7 +30493,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -29968,7 +30576,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -30069,7 +30677,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -30132,7 +30740,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -30149,11 +30757,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -30252,7 +30860,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -30350,7 +30958,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -30412,7 +31020,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -30476,7 +31084,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -30566,7 +31174,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -30637,7 +31245,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -30676,7 +31284,10 @@ "description": "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", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -30708,7 +31319,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -30770,7 +31381,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -30841,7 +31452,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 494, + "weight": 506, "cookies": false, "type": "", "demo": "sites\/get-usage.md", @@ -30923,7 +31534,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -30982,7 +31593,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -31073,7 +31684,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -31142,7 +31753,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -31233,7 +31844,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -32705,7 +33316,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -32778,7 +33389,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -32833,6 +33444,424 @@ } } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/tablesdb\/usage": { "get": { "summary": "Get TablesDB usage stats", @@ -32857,7 +33886,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 378, + "weight": 384, "cookies": false, "type": "", "demo": "tablesdb\/list-usage.md", @@ -32954,7 +33983,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -33013,7 +34042,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -33089,7 +34118,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -33150,7 +34179,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -33219,7 +34248,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -33236,7 +34265,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -33343,7 +34372,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -33415,7 +34444,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -33517,7 +34546,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -33591,7 +34620,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -33678,7 +34707,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -33717,7 +34746,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -33787,7 +34816,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -33826,7 +34855,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -33901,7 +34930,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -34010,7 +35039,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -34124,7 +35153,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -34233,7 +35262,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -34347,7 +35376,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -34465,7 +35494,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -34588,7 +35617,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -34707,7 +35736,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -34831,7 +35860,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -34950,7 +35979,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -35074,7 +36103,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -35183,7 +36212,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -35297,7 +36326,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -35336,7 +36365,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35409,7 +36438,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -35448,7 +36477,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35529,7 +36558,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -35568,7 +36597,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35641,7 +36670,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -35680,7 +36709,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35761,7 +36790,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -35800,7 +36829,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35873,7 +36902,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -35912,7 +36941,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -35993,7 +37022,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -36127,7 +37156,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -36166,7 +37195,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -36247,7 +37276,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -36286,7 +37315,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -36366,7 +37395,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -36475,7 +37504,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -36620,7 +37649,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -36694,7 +37723,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -36777,7 +37806,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -36888,7 +37917,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -36927,7 +37956,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -36973,7 +38002,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -37012,7 +38041,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37105,7 +38134,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -37144,7 +38173,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37179,7 +38208,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -37218,7 +38247,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37262,7 +38291,7 @@ "x-appwrite": { "method": "listTableLogs", "group": "tables", - "weight": 384, + "weight": 390, "cookies": false, "type": "", "demo": "tablesdb\/list-table-logs.md", @@ -37348,7 +38377,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -37390,7 +38419,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "schema": { "type": "string", @@ -37410,6 +38439,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -37419,7 +38458,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -37436,7 +38475,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -37467,7 +38506,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -37481,7 +38521,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -37494,7 +38534,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37507,7 +38548,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -37535,7 +38576,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "schema": { "type": "string", @@ -37575,6 +38616,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -37588,7 +38634,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -37605,7 +38651,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -37633,7 +38679,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37646,7 +38693,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -37695,6 +38742,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -37728,7 +38780,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -37795,6 +38847,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -37825,7 +38882,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -37865,7 +38922,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37887,6 +38944,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -37919,7 +38981,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -37961,7 +39023,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -37991,6 +39053,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -38000,7 +39072,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -38017,7 +39089,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -38048,7 +39120,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -38061,7 +39134,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -38126,6 +39199,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38156,7 +39234,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -38235,6 +39313,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38258,7 +39341,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -38300,7 +39383,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -38318,7 +39401,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows\/{rowId}\/logs": { @@ -38345,7 +39444,7 @@ "x-appwrite": { "method": "listRowLogs", "group": "logs", - "weight": 428, + "weight": 434, "cookies": false, "type": "", "demo": "tablesdb\/list-row-logs.md", @@ -38441,7 +39540,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -38527,6 +39626,11 @@ "type": "number", "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38559,7 +39663,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -38645,6 +39749,11 @@ "type": "number", "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -38677,7 +39786,7 @@ "x-appwrite": { "method": "getTableUsage", "group": null, - "weight": 385, + "weight": 391, "cookies": false, "type": "", "demo": "tablesdb\/get-table-usage.md", @@ -38772,7 +39881,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 377, + "weight": 383, "cookies": false, "type": "", "demo": "tablesdb\/get-usage.md", @@ -39984,7 +41093,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -40034,7 +41143,10 @@ "description": "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: expire", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -40064,7 +41176,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -40153,7 +41265,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -40213,7 +41325,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -40283,7 +41395,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -46107,6 +47219,34 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "$ref": "#\/components\/schemas\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "migrationList": { "description": "Migrations List", "type": "object", @@ -46223,7 +47363,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -46468,7 +47612,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46563,7 +47708,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46660,7 +47806,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46757,7 +47904,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46837,7 +47985,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46924,7 +48073,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47021,7 +48171,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47108,7 +48259,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47195,7 +48347,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47282,7 +48435,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47397,7 +48551,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47483,7 +48638,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47581,7 +48737,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47897,7 +49054,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -47985,7 +49150,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48075,7 +49248,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48165,7 +49346,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48238,7 +49427,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48318,7 +49515,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48408,7 +49613,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48488,7 +49701,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48568,7 +49789,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48648,7 +49877,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48756,7 +49993,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48835,7 +50080,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48926,7 +50179,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -53427,16 +54688,24 @@ }, "type": { "type": "string", - "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, ios, android, and unity.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "x-example": "web", "enum": [ "web", "flutter-web", "flutter-ios", "flutter-android", - "ios", + "flutter-linux", + "flutter-macos", + "flutter-windows", + "apple-ios", + "apple-macos", + "apple-watchos", + "apple-tvos", "android", - "unity" + "unity", + "react-native-ios", + "react-native-android" ] }, "key": { @@ -53796,7 +55065,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -56535,7 +57805,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -56649,6 +57926,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index b437d56bfc..49adaeeefa 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -3161,10 +3161,10 @@ } } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "tags": [ "account" ], @@ -3183,12 +3183,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3199,6 +3199,58 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3233,7 +3285,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "tags": [ "account" ], @@ -3252,12 +3304,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3268,6 +3320,62 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/components\/schemas\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3307,7 +3415,7 @@ } } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4743,6 +4851,436 @@ } } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/databases\/{databaseId}": { "get": { "summary": "Get database", @@ -8938,6 +9476,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -8997,7 +9545,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9029,7 +9578,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9116,6 +9666,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9176,7 +9731,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9243,6 +9799,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -9345,6 +9906,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9439,6 +10005,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9546,6 +10117,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -9605,7 +10186,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9690,6 +10272,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -9805,6 +10392,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -9891,7 +10483,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/decrement": { @@ -10007,6 +10615,11 @@ "type": "number", "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10128,6 +10741,11 @@ "type": "number", "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -10364,7 +10982,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -10542,7 +11160,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -10616,7 +11234,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -10850,7 +11468,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -10900,7 +11518,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -10951,7 +11569,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -11011,7 +11629,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -11242,7 +11860,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -11304,7 +11922,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -11385,7 +12003,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -11469,7 +12087,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -11566,7 +12184,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -11635,7 +12253,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -11652,11 +12270,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11756,7 +12374,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -11854,7 +12472,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -11917,7 +12535,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -11982,7 +12600,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -12073,7 +12691,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -12145,7 +12763,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -12222,7 +12840,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -12300,9 +12918,9 @@ "x-enum-keys": [] }, "headers": { - "type": "string", + "type": "object", "description": "HTTP headers of execution. Defaults to empty.", - "x-example": null + "x-example": "{}" }, "scheduledAt": { "type": "string", @@ -12340,7 +12958,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -12407,7 +13025,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -12479,7 +13097,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -12539,7 +13157,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -12631,7 +13249,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -12701,7 +13319,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -12793,7 +13411,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -15174,7 +15792,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -15356,7 +15974,7 @@ "image": { "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -19717,7 +20335,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -19747,7 +20365,10 @@ "description": "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, framework, deploymentId, buildCommand, installCommand, outputDirectory, installationId", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -19788,7 +20409,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -20038,7 +20659,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -20088,7 +20709,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -20139,7 +20760,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -20199,7 +20820,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -20445,7 +21066,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -20507,7 +21128,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -20588,7 +21209,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -20672,7 +21293,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -20774,7 +21395,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -20838,7 +21459,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -20855,11 +21476,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -20959,7 +21580,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -21058,7 +21679,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -21121,7 +21742,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -21186,7 +21807,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -21277,7 +21898,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -21349,7 +21970,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -21389,7 +22010,10 @@ "description": "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", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -21421,7 +22045,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -21484,7 +22108,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -21556,7 +22180,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -21616,7 +22240,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -21708,7 +22332,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -21778,7 +22402,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -21870,7 +22494,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -23210,7 +23834,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -23284,7 +23908,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -23340,6 +23964,436 @@ } } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transactionList" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "x-example": 60 + } + } + } + } + } + } + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "x-example": false + } + } + } + } + } + } + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "content": { + "application\/json": { + "schema": { + "$ref": "#\/components\/schemas\/transaction" + } + } + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client", + "server" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "path" + } + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + } + } + } + }, "\/tablesdb\/{databaseId}": { "get": { "summary": "Get database", @@ -23364,7 +24418,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -23424,7 +24478,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -23501,7 +24555,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -23563,7 +24617,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -23633,7 +24687,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -23650,7 +24704,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -23758,7 +24812,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -23831,7 +24885,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -23934,7 +24988,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -24009,7 +25063,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -24097,7 +25151,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -24137,7 +25191,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -24207,7 +25261,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -24247,7 +25301,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -24322,7 +25376,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -24432,7 +25486,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -24547,7 +25601,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -24657,7 +25711,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -24772,7 +25826,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -24891,7 +25945,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -25015,7 +26069,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -25135,7 +26189,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -25260,7 +26314,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -25380,7 +26434,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -25505,7 +26559,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -25615,7 +26669,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -25730,7 +26784,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -25770,7 +26824,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -25843,7 +26897,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -25883,7 +26937,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -25964,7 +27018,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -26004,7 +27058,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26077,7 +27131,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -26117,7 +27171,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26198,7 +27252,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -26238,7 +27292,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26311,7 +27365,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -26351,7 +27405,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26432,7 +27486,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -26567,7 +27621,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -26607,7 +27661,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26688,7 +27742,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -26728,7 +27782,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -26808,7 +27862,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -26918,7 +27972,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -27064,7 +28118,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -27139,7 +28193,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -27223,7 +28277,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -27335,7 +28389,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -27375,7 +28429,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27421,7 +28475,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -27461,7 +28515,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27554,7 +28608,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -27594,7 +28648,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27629,7 +28683,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -27669,7 +28723,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -27713,7 +28767,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -27757,7 +28811,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "schema": { "type": "string", @@ -27777,6 +28831,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -27786,7 +28850,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -27803,7 +28867,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -27835,7 +28899,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -27849,7 +28914,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -27863,7 +28928,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -27876,7 +28942,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -27906,7 +28972,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "schema": { "type": "string", @@ -27946,6 +29012,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -27959,7 +29030,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -27976,7 +29047,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -28005,7 +29076,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -28018,7 +29090,7 @@ "model": "#\/components\/schemas\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -28068,6 +29140,11 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } }, "required": [ @@ -28101,7 +29178,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -28169,6 +29246,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28199,7 +29281,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -28240,7 +29322,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -28262,6 +29344,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28294,7 +29381,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -28338,7 +29425,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -28368,6 +29455,16 @@ "default": [] }, "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "schema": { + "type": "string", + "x-example": "" + }, + "in": "query" } ] }, @@ -28377,7 +29474,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -28394,7 +29491,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -28426,7 +29523,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -28439,7 +29537,7 @@ "model": "#\/components\/schemas\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -28506,6 +29604,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28536,7 +29639,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -28617,6 +29720,11 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28640,7 +29748,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -28684,7 +29792,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "schema": { "type": "string", @@ -28702,7 +29810,23 @@ }, "in": "path" } - ] + ], + "requestBody": { + "content": { + "application\/json": { + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" + } + } + } + } + } + } } }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows\/{rowId}\/{column}\/decrement": { @@ -28729,7 +29853,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -28817,6 +29941,11 @@ "type": "number", "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -28849,7 +29978,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -28937,6 +30066,11 @@ "type": "number", "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "x-example": "" } } } @@ -30024,7 +31158,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -30075,7 +31209,10 @@ "description": "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: expire", "required": false, "schema": { - "type": "string", + "type": "array", + "items": { + "type": "string" + }, "default": [] }, "in": "query" @@ -30105,7 +31242,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -30195,7 +31332,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -30256,7 +31393,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -30327,7 +31464,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -35033,6 +36170,34 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "$ref": "#\/components\/schemas\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "specificationList": { "description": "Specifications List", "type": "object", @@ -35093,7 +36258,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -35338,7 +36507,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35433,7 +36603,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35530,7 +36701,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35627,7 +36799,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35707,7 +36880,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35794,7 +36968,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35891,7 +37066,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35978,7 +37154,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36065,7 +37242,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36152,7 +37330,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36267,7 +37446,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36353,7 +37533,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36451,7 +37632,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36767,7 +37949,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36855,7 +38045,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36945,7 +38143,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37035,7 +38241,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37108,7 +38322,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37188,7 +38410,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37278,7 +38508,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37358,7 +38596,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37438,7 +38684,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37518,7 +38772,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37626,7 +38888,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37705,7 +38975,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37796,7 +39074,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -40984,7 +42270,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -41449,7 +42736,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -41563,6 +42857,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/swagger2-1.8.x-client.json b/app/config/specs/swagger2-1.8.x-client.json index c2628533d0..89fc5e7e5c 100644 --- a/app/config/specs/swagger2-1.8.x-client.json +++ b/app/config/specs/swagger2-1.8.x-client.json @@ -3599,10 +3599,10 @@ ] } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "consumes": [ "application\/json" ], @@ -3623,12 +3623,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3639,6 +3639,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3673,7 +3723,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "consumes": [ "application\/json" ], @@ -3694,12 +3744,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3710,6 +3760,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3750,7 +3854,7 @@ ] } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4948,6 +5052,419 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents": { "get": { "summary": "List documents", @@ -5029,6 +5546,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -5088,7 +5613,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5173,6 +5699,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5269,6 +5801,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -5328,7 +5868,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5406,6 +5947,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -5514,6 +6061,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5593,6 +6146,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -5702,6 +6270,12 @@ "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5814,6 +6388,12 @@ "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5845,7 +6425,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -5918,7 +6498,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -6035,7 +6615,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -7549,6 +8129,419 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows": { "get": { "summary": "List rows", @@ -7573,7 +8566,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -7612,7 +8605,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "type": "string", "x-example": "", @@ -7629,6 +8622,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -7644,7 +8645,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7657,7 +8658,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -7687,7 +8688,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7701,7 +8703,7 @@ "model": "#\/definitions\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" } ], @@ -7727,7 +8729,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "type": "string", "x-example": "", @@ -7768,6 +8770,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -7799,7 +8807,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -7838,7 +8846,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -7863,6 +8871,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -7878,7 +8894,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7891,7 +8907,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -7921,7 +8937,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7934,7 +8951,7 @@ "model": "#\/definitions\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -7994,6 +9011,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -8025,7 +9048,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -8098,6 +9121,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -8124,7 +9153,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -8163,7 +9192,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -8176,6 +9205,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -8206,7 +9250,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -8284,6 +9328,12 @@ "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -8317,7 +9367,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -8395,6 +9445,12 @@ "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9931,6 +10987,35 @@ "localeCodes": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "type": "object", + "$ref": "#\/definitions\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "row": { "description": "Row", "type": "object", @@ -11851,6 +12936,59 @@ "recoveryCode": true } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/swagger2-1.8.x-console.json b/app/config/specs/swagger2-1.8.x-console.json index 0f91a5433d..098f138b30 100644 --- a/app/config/specs/swagger2-1.8.x-console.json +++ b/app/config/specs/swagger2-1.8.x-console.json @@ -3618,10 +3618,10 @@ ] } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "consumes": [ "application\/json" ], @@ -3642,12 +3642,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3658,6 +3658,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3691,7 +3741,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "consumes": [ "application\/json" ], @@ -3712,12 +3762,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3728,6 +3778,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3767,7 +3871,7 @@ ] } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -5052,7 +5156,7 @@ "x-appwrite": { "method": "getResource", "group": null, - "weight": 496, + "weight": 508, "cookies": false, "type": "", "demo": "console\/get-resource.md", @@ -5367,6 +5471,419 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/databases\/usage": { "get": { "summary": "Get databases usage stats", @@ -9525,6 +10042,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -9584,7 +10109,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9615,7 +10141,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9699,6 +10226,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9759,7 +10292,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9821,6 +10355,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -9920,6 +10460,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10010,6 +10556,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10106,6 +10658,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -10165,7 +10725,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -10243,6 +10804,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -10351,6 +10918,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10430,6 +11003,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -10629,6 +11217,12 @@ "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10741,6 +11335,12 @@ "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10974,7 +11574,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -11524,7 +12124,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -11596,7 +12196,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -11847,7 +12447,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -11896,7 +12496,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -11946,7 +12546,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 466, + "weight": 478, "cookies": false, "type": "", "demo": "functions\/list-templates.md", @@ -12040,7 +12640,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 465, + "weight": 477, "cookies": false, "type": "", "demo": "functions\/get-template.md", @@ -12098,7 +12698,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 459, + "weight": 471, "cookies": false, "type": "", "demo": "functions\/list-usage.md", @@ -12168,7 +12768,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -12227,7 +12827,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -12474,7 +13074,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -12535,7 +13135,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -12612,7 +13212,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -12692,7 +13292,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -12784,7 +13384,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -12856,7 +13456,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -12869,11 +13469,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12975,7 +13575,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -13071,7 +13671,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -13133,7 +13733,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -13200,7 +13800,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -13285,7 +13885,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -13352,7 +13952,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -13425,7 +14025,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -13542,7 +14142,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -13606,7 +14206,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -13673,7 +14273,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 458, + "weight": 470, "cookies": false, "type": "", "demo": "functions\/get-usage.md", @@ -13751,7 +14351,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -13810,7 +14410,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -13900,7 +14500,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -13967,7 +14567,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -14059,7 +14659,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -16423,7 +17023,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": "", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -16620,7 +17220,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": null, - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -21355,7 +21955,7 @@ "type": "string", "description": "Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.", "default": null, - "x-example": "[ID1:ID2]" + "x-example": "" }, "internalFile": { "type": "boolean", @@ -22590,7 +23190,7 @@ "x-appwrite": { "method": "list", "group": "projects", - "weight": 436, + "weight": 448, "cookies": false, "type": "", "demo": "projects\/list.md", @@ -24233,7 +24833,7 @@ "x-appwrite": { "method": "listDevKeys", "group": "devKeys", - "weight": 434, + "weight": 446, "cookies": false, "type": "", "demo": "projects\/list-dev-keys.md", @@ -24303,7 +24903,7 @@ "x-appwrite": { "method": "createDevKey", "group": "devKeys", - "weight": 431, + "weight": 443, "cookies": false, "type": "", "demo": "projects\/create-dev-key.md", @@ -24386,7 +24986,7 @@ "x-appwrite": { "method": "getDevKey", "group": "devKeys", - "weight": 433, + "weight": 445, "cookies": false, "type": "", "demo": "projects\/get-dev-key.md", @@ -24452,7 +25052,7 @@ "x-appwrite": { "method": "updateDevKey", "group": "devKeys", - "weight": 432, + "weight": 444, "cookies": false, "type": "", "demo": "projects\/update-dev-key.md", @@ -24538,7 +25138,7 @@ "x-appwrite": { "method": "deleteDevKey", "group": "devKeys", - "weight": 435, + "weight": 447, "cookies": false, "type": "", "demo": "projects\/delete-dev-key.md", @@ -25305,7 +25905,7 @@ "properties": { "type": { "type": "string", - "description": "Platform type.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "default": null, "x-example": "web", "enum": [ @@ -28351,7 +28951,7 @@ "x-appwrite": { "method": "listRules", "group": null, - "weight": 502, + "weight": 514, "cookies": false, "type": "", "demo": "proxy\/list-rules.md", @@ -28424,7 +29024,7 @@ "x-appwrite": { "method": "createAPIRule", "group": null, - "weight": 497, + "weight": 509, "cookies": false, "type": "", "demo": "proxy\/create-api-rule.md", @@ -28494,7 +29094,7 @@ "x-appwrite": { "method": "createFunctionRule", "group": null, - "weight": 499, + "weight": 511, "cookies": false, "type": "", "demo": "proxy\/create-function-rule.md", @@ -28577,7 +29177,7 @@ "x-appwrite": { "method": "createRedirectRule", "group": null, - "weight": 500, + "weight": 512, "cookies": false, "type": "", "demo": "proxy\/create-redirect-rule.md", @@ -28697,7 +29297,7 @@ "x-appwrite": { "method": "createSiteRule", "group": null, - "weight": 498, + "weight": 510, "cookies": false, "type": "", "demo": "proxy\/create-site-rule.md", @@ -28778,7 +29378,7 @@ "x-appwrite": { "method": "getRule", "group": null, - "weight": 501, + "weight": 513, "cookies": false, "type": "", "demo": "proxy\/get-rule.md", @@ -28831,7 +29431,7 @@ "x-appwrite": { "method": "deleteRule", "group": null, - "weight": 503, + "weight": 515, "cookies": false, "type": "", "demo": "proxy\/delete-rule.md", @@ -28891,7 +29491,7 @@ "x-appwrite": { "method": "updateRuleVerification", "group": null, - "weight": 504, + "weight": 516, "cookies": false, "type": "", "demo": "proxy\/update-rule-verification.md", @@ -28949,7 +29549,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -29021,7 +29621,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -29288,7 +29888,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -29337,7 +29937,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -29387,7 +29987,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 491, + "weight": 503, "cookies": false, "type": "", "demo": "sites\/list-templates.md", @@ -29481,7 +30081,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 492, + "weight": 504, "cookies": false, "type": "", "demo": "sites\/get-template.md", @@ -29539,7 +30139,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 493, + "weight": 505, "cookies": false, "type": "", "demo": "sites\/list-usage.md", @@ -29609,7 +30209,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -29668,7 +30268,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -29930,7 +30530,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -29991,7 +30591,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -30068,7 +30668,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -30148,7 +30748,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -30248,7 +30848,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -30314,7 +30914,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -30327,11 +30927,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -30433,7 +31033,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -30530,7 +31130,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -30592,7 +31192,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -30659,7 +31259,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -30744,7 +31344,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -30811,7 +31411,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -30882,7 +31482,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -30946,7 +31546,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -31013,7 +31613,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 494, + "weight": 506, "cookies": false, "type": "", "demo": "sites\/get-usage.md", @@ -31091,7 +31691,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -31150,7 +31750,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -31240,7 +31840,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -31307,7 +31907,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -31399,7 +31999,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -32833,7 +33433,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -32905,7 +33505,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -32963,6 +33563,419 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/tablesdb\/usage": { "get": { "summary": "Get TablesDB usage stats", @@ -32987,7 +34000,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 378, + "weight": 384, "cookies": false, "type": "", "demo": "tablesdb\/list-usage.md", @@ -33082,7 +34095,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -33141,7 +34154,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -33219,7 +34232,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -33278,7 +34291,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -33348,7 +34361,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -33361,7 +34374,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -33469,7 +34482,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -33539,7 +34552,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -33643,7 +34656,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -33713,7 +34726,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -33797,7 +34810,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -33834,7 +34847,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -33906,7 +34919,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -33943,7 +34956,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -34017,7 +35030,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -34126,7 +35139,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -34237,7 +35250,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -34346,7 +35359,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -34457,7 +35470,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -34576,7 +35589,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -34697,7 +35710,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -34818,7 +35831,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -34941,7 +35954,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -35062,7 +36075,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -35185,7 +36198,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -35294,7 +36307,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -35405,7 +36418,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -35442,7 +36455,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35509,7 +36522,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -35546,7 +36559,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35619,7 +36632,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -35656,7 +36669,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35723,7 +36736,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -35760,7 +36773,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35833,7 +36846,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -35870,7 +36883,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35937,7 +36950,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -35974,7 +36987,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -36047,7 +37060,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -36183,7 +37196,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -36220,7 +37233,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -36305,7 +37318,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -36342,7 +37355,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -36422,7 +37435,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -36531,7 +37544,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -36671,7 +37684,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -36743,7 +37756,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -36822,7 +37835,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -36927,7 +37940,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -36964,7 +37977,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37009,7 +38022,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -37046,7 +38059,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37140,7 +38153,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -37177,7 +38190,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37212,7 +38225,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -37249,7 +38262,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37289,7 +38302,7 @@ "x-appwrite": { "method": "listTableLogs", "group": "tables", - "weight": 384, + "weight": 390, "cookies": false, "type": "", "demo": "tablesdb\/list-table-logs.md", @@ -37370,7 +38383,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -37409,7 +38422,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "type": "string", "x-example": "", @@ -37426,6 +38439,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -37441,7 +38462,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -37454,7 +38475,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -37484,7 +38505,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -37498,7 +38520,7 @@ "model": "#\/definitions\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -37511,7 +38533,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37524,7 +38547,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -37550,7 +38573,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "type": "string", "x-example": "", @@ -37591,6 +38614,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -37609,7 +38638,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -37622,7 +38651,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -37650,7 +38679,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37663,7 +38693,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -37708,6 +38738,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -37742,7 +38778,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -37806,6 +38842,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -37837,7 +38879,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -37875,7 +38917,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37895,6 +38937,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -37926,7 +38974,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -37965,7 +39013,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37990,6 +39038,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -38005,7 +39061,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -38018,7 +39074,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -38048,7 +39104,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -38061,7 +39118,7 @@ "model": "#\/definitions\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -38121,6 +39178,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38152,7 +39215,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -38225,6 +39288,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38251,7 +39320,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -38290,7 +39359,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -38303,6 +39372,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -38331,7 +39415,7 @@ "x-appwrite": { "method": "listRowLogs", "group": "logs", - "weight": 428, + "weight": 434, "cookies": false, "type": "", "demo": "tablesdb\/list-row-logs.md", @@ -38422,7 +39506,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -38500,6 +39584,12 @@ "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38533,7 +39623,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -38611,6 +39701,12 @@ "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38642,7 +39738,7 @@ "x-appwrite": { "method": "getTableUsage", "group": null, - "weight": 385, + "weight": 391, "cookies": false, "type": "", "demo": "tablesdb\/get-table-usage.md", @@ -38731,7 +39827,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 377, + "weight": 383, "cookies": false, "type": "", "demo": "tablesdb\/get-usage.md", @@ -39916,7 +41012,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -39996,7 +41092,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -40080,7 +41176,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -40140,7 +41236,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -40211,7 +41307,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -46040,6 +47136,35 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "type": "object", + "$ref": "#\/definitions\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "migrationList": { "description": "Migrations List", "type": "object", @@ -46159,7 +47284,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -46405,7 +47534,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46500,7 +47630,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46597,7 +47728,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46694,7 +47826,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46774,7 +47907,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46861,7 +47995,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46958,7 +48093,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47045,7 +48181,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47132,7 +48269,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47219,7 +48357,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47334,7 +48473,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47420,7 +48560,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47518,7 +48659,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47835,7 +48977,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -47923,7 +49073,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48013,7 +49171,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48103,7 +49269,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48176,7 +49350,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48256,7 +49438,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48346,7 +49536,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48426,7 +49624,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48506,7 +49712,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48586,7 +49800,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48694,7 +49916,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48773,7 +50003,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48864,7 +50102,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -53383,16 +54629,24 @@ }, "type": { "type": "string", - "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, ios, android, and unity.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "x-example": "web", "enum": [ "web", "flutter-web", "flutter-ios", "flutter-android", - "ios", + "flutter-linux", + "flutter-macos", + "flutter-windows", + "apple-ios", + "apple-macos", + "apple-watchos", + "apple-tvos", "android", - "unity" + "unity", + "react-native-ios", + "react-native-android" ] }, "key": { @@ -53752,7 +55006,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -56584,7 +57839,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -56698,6 +57960,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/swagger2-1.8.x-server.json b/app/config/specs/swagger2-1.8.x-server.json index 679da75e5d..9c8ef73243 100644 --- a/app/config/specs/swagger2-1.8.x-server.json +++ b/app/config/specs/swagger2-1.8.x-server.json @@ -3302,10 +3302,10 @@ ] } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "consumes": [ "application\/json" ], @@ -3326,12 +3326,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3342,6 +3342,58 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3377,7 +3429,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "consumes": [ "application\/json" ], @@ -3398,12 +3450,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3414,6 +3466,62 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3455,7 +3563,7 @@ ] } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4893,6 +5001,431 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/databases\/{databaseId}": { "get": { "summary": "Get database", @@ -8993,6 +9526,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -9053,7 +9594,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9085,7 +9627,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9171,6 +9714,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9232,7 +9781,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9295,6 +9845,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -9395,6 +9951,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9486,6 +10048,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9584,6 +10152,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -9644,7 +10220,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9724,6 +10301,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -9834,6 +10417,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9915,6 +10504,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -10026,6 +10630,12 @@ "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10140,6 +10750,12 @@ "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10375,7 +10991,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -10541,7 +11157,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -10614,7 +11230,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -10866,7 +11482,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -10916,7 +11532,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -10967,7 +11583,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -11027,7 +11643,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -11275,7 +11891,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -11337,7 +11953,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -11415,7 +12031,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -11496,7 +12112,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -11589,7 +12205,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -11662,7 +12278,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -11675,11 +12291,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11782,7 +12398,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -11879,7 +12495,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -11942,7 +12558,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -12010,7 +12626,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -12096,7 +12712,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -12164,7 +12780,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -12239,7 +12855,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -12358,7 +12974,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -12424,7 +13040,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -12492,7 +13108,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -12552,7 +13168,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -12643,7 +13259,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -12711,7 +13327,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -12804,7 +13420,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -15215,7 +15831,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": "", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -15413,7 +16029,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": null, - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -19909,7 +20525,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -19982,7 +20598,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -20250,7 +20866,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -20300,7 +20916,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -20351,7 +20967,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -20411,7 +21027,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -20674,7 +21290,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -20736,7 +21352,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -20814,7 +21430,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -20895,7 +21511,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -20996,7 +21612,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -21063,7 +21679,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -21076,11 +21692,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -21183,7 +21799,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -21281,7 +21897,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -21344,7 +21960,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -21412,7 +22028,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -21498,7 +22114,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -21566,7 +22182,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -21638,7 +22254,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -21703,7 +22319,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -21771,7 +22387,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -21831,7 +22447,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -21922,7 +22538,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -21990,7 +22606,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -22083,7 +22699,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -23391,7 +24007,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -23464,7 +24080,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -23523,6 +24139,431 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/tablesdb\/{databaseId}": { "get": { "summary": "Get database", @@ -23547,7 +24588,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -23607,7 +24648,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -23686,7 +24727,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -23746,7 +24787,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -23817,7 +24858,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -23830,7 +24871,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -23939,7 +24980,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -24010,7 +25051,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -24115,7 +25156,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -24186,7 +25227,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -24271,7 +25312,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -24309,7 +25350,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -24381,7 +25422,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -24419,7 +25460,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -24493,7 +25534,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -24603,7 +25644,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -24715,7 +25756,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -24825,7 +25866,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -24937,7 +25978,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -25057,7 +26098,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -25179,7 +26220,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -25301,7 +26342,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -25425,7 +26466,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -25547,7 +26588,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -25671,7 +26712,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -25781,7 +26822,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -25893,7 +26934,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -25931,7 +26972,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -25998,7 +27039,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -26036,7 +27077,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26109,7 +27150,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -26147,7 +27188,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26214,7 +27255,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -26252,7 +27293,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26325,7 +27366,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -26363,7 +27404,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26430,7 +27471,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -26468,7 +27509,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26541,7 +27582,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -26678,7 +27719,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -26716,7 +27757,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26801,7 +27842,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -26839,7 +27880,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26919,7 +27960,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -27029,7 +28070,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -27170,7 +28211,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -27243,7 +28284,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -27323,7 +28364,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -27429,7 +28470,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -27467,7 +28508,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27512,7 +28553,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -27550,7 +28591,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27644,7 +28685,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -27682,7 +28723,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27717,7 +28758,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -27755,7 +28796,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27795,7 +28836,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -27836,7 +28877,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "type": "string", "x-example": "", @@ -27853,6 +28894,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -27868,7 +28917,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -27881,7 +28930,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -27912,7 +28961,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -27926,7 +28976,7 @@ "model": "#\/definitions\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -27940,7 +28990,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -27953,7 +29004,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -27981,7 +29032,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "type": "string", "x-example": "", @@ -28022,6 +29073,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28040,7 +29097,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -28053,7 +29110,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -28082,7 +29139,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -28095,7 +29153,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -28141,6 +29199,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -28175,7 +29239,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -28240,6 +29304,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28271,7 +29341,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -28310,7 +29380,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -28330,6 +29400,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28361,7 +29437,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -28402,7 +29478,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -28427,6 +29503,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -28442,7 +29526,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -28455,7 +29539,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -28486,7 +29570,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -28499,7 +29584,7 @@ "model": "#\/definitions\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -28561,6 +29646,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28592,7 +29683,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -28667,6 +29758,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28693,7 +29790,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -28734,7 +29831,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -28747,6 +29844,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -28777,7 +29889,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -28857,6 +29969,12 @@ "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28890,7 +30008,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -28970,6 +30088,12 @@ "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -30036,7 +31160,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -30117,7 +31241,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -30202,7 +31326,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -30263,7 +31387,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -30335,7 +31459,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -35059,6 +36183,35 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "type": "object", + "$ref": "#\/definitions\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "specificationList": { "description": "Specifications List", "type": "object", @@ -35120,7 +36273,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -35366,7 +36523,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35461,7 +36619,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35558,7 +36717,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35655,7 +36815,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35735,7 +36896,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35822,7 +36984,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35919,7 +37082,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36006,7 +37170,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36093,7 +37258,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36180,7 +37346,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36295,7 +37462,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36381,7 +37549,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36479,7 +37648,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36796,7 +37966,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36884,7 +38062,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36974,7 +38160,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37064,7 +38258,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37137,7 +38339,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37217,7 +38427,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37307,7 +38525,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37387,7 +38613,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37467,7 +38701,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37547,7 +38789,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37655,7 +38905,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37734,7 +38992,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37825,7 +39091,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -41021,7 +42295,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -41488,7 +42763,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -41602,6 +42884,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/swagger2-latest-client.json b/app/config/specs/swagger2-latest-client.json index c2628533d0..89fc5e7e5c 100644 --- a/app/config/specs/swagger2-latest-client.json +++ b/app/config/specs/swagger2-latest-client.json @@ -3599,10 +3599,10 @@ ] } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "consumes": [ "application\/json" ], @@ -3623,12 +3623,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3639,6 +3639,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3673,7 +3723,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "consumes": [ "application\/json" ], @@ -3694,12 +3744,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3710,6 +3760,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3750,7 +3854,7 @@ ] } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4948,6 +5052,419 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/databases\/{databaseId}\/collections\/{collectionId}\/documents": { "get": { "summary": "List documents", @@ -5029,6 +5546,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -5088,7 +5613,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5173,6 +5699,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5269,6 +5801,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -5328,7 +5868,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -5406,6 +5947,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -5514,6 +6061,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5593,6 +6146,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -5702,6 +6270,12 @@ "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5814,6 +6388,12 @@ "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -5845,7 +6425,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -5918,7 +6498,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -6035,7 +6615,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -7549,6 +8129,419 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/tablesdb\/{databaseId}\/tables\/{tableId}\/rows": { "get": { "summary": "List rows", @@ -7573,7 +8566,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -7612,7 +8605,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "type": "string", "x-example": "", @@ -7629,6 +8622,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -7644,7 +8645,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7657,7 +8658,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -7687,7 +8688,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7701,7 +8703,7 @@ "model": "#\/definitions\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" } ], @@ -7727,7 +8729,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "type": "string", "x-example": "", @@ -7768,6 +8770,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -7799,7 +8807,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -7838,7 +8846,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -7863,6 +8871,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -7878,7 +8894,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -7891,7 +8907,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -7921,7 +8937,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -7934,7 +8951,7 @@ "model": "#\/definitions\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -7994,6 +9011,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -8025,7 +9048,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -8098,6 +9121,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -8124,7 +9153,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -8163,7 +9192,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -8176,6 +9205,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -8206,7 +9250,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -8284,6 +9328,12 @@ "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -8317,7 +9367,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -8395,6 +9445,12 @@ "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9931,6 +10987,35 @@ "localeCodes": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "type": "object", + "$ref": "#\/definitions\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "row": { "description": "Row", "type": "object", @@ -11851,6 +12936,59 @@ "recoveryCode": true } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 0f91a5433d..098f138b30 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -3618,10 +3618,10 @@ ] } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "consumes": [ "application\/json" ], @@ -3642,12 +3642,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3658,6 +3658,56 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3691,7 +3741,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "consumes": [ "application\/json" ], @@ -3712,12 +3762,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3728,6 +3778,60 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [] } @@ -3767,7 +3871,7 @@ ] } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -5052,7 +5156,7 @@ "x-appwrite": { "method": "getResource", "group": null, - "weight": 496, + "weight": 508, "cookies": false, "type": "", "demo": "console\/get-resource.md", @@ -5367,6 +5471,419 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/databases\/usage": { "get": { "summary": "Get databases usage stats", @@ -9525,6 +10042,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -9584,7 +10109,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9615,7 +10141,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9699,6 +10226,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9759,7 +10292,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9821,6 +10355,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -9920,6 +10460,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10010,6 +10556,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10106,6 +10658,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -10165,7 +10725,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -10243,6 +10804,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -10351,6 +10918,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10430,6 +11003,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -10629,6 +11217,12 @@ "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10741,6 +11335,12 @@ "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10974,7 +11574,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -11524,7 +12124,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -11596,7 +12196,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -11847,7 +12447,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -11896,7 +12496,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -11946,7 +12546,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 466, + "weight": 478, "cookies": false, "type": "", "demo": "functions\/list-templates.md", @@ -12040,7 +12640,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 465, + "weight": 477, "cookies": false, "type": "", "demo": "functions\/get-template.md", @@ -12098,7 +12698,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 459, + "weight": 471, "cookies": false, "type": "", "demo": "functions\/list-usage.md", @@ -12168,7 +12768,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -12227,7 +12827,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -12474,7 +13074,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -12535,7 +13135,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -12612,7 +13212,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -12692,7 +13292,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -12784,7 +13384,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -12856,7 +13456,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -12869,11 +13469,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -12975,7 +13575,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -13071,7 +13671,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -13133,7 +13733,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -13200,7 +13800,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -13285,7 +13885,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -13352,7 +13952,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -13425,7 +14025,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -13542,7 +14142,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -13606,7 +14206,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -13673,7 +14273,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 458, + "weight": 470, "cookies": false, "type": "", "demo": "functions\/get-usage.md", @@ -13751,7 +14351,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -13810,7 +14410,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -13900,7 +14500,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -13967,7 +14567,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -14059,7 +14659,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -16423,7 +17023,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": "", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -16620,7 +17220,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": null, - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -21355,7 +21955,7 @@ "type": "string", "description": "Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.", "default": null, - "x-example": "[ID1:ID2]" + "x-example": "" }, "internalFile": { "type": "boolean", @@ -22590,7 +23190,7 @@ "x-appwrite": { "method": "list", "group": "projects", - "weight": 436, + "weight": 448, "cookies": false, "type": "", "demo": "projects\/list.md", @@ -24233,7 +24833,7 @@ "x-appwrite": { "method": "listDevKeys", "group": "devKeys", - "weight": 434, + "weight": 446, "cookies": false, "type": "", "demo": "projects\/list-dev-keys.md", @@ -24303,7 +24903,7 @@ "x-appwrite": { "method": "createDevKey", "group": "devKeys", - "weight": 431, + "weight": 443, "cookies": false, "type": "", "demo": "projects\/create-dev-key.md", @@ -24386,7 +24986,7 @@ "x-appwrite": { "method": "getDevKey", "group": "devKeys", - "weight": 433, + "weight": 445, "cookies": false, "type": "", "demo": "projects\/get-dev-key.md", @@ -24452,7 +25052,7 @@ "x-appwrite": { "method": "updateDevKey", "group": "devKeys", - "weight": 432, + "weight": 444, "cookies": false, "type": "", "demo": "projects\/update-dev-key.md", @@ -24538,7 +25138,7 @@ "x-appwrite": { "method": "deleteDevKey", "group": "devKeys", - "weight": 435, + "weight": 447, "cookies": false, "type": "", "demo": "projects\/delete-dev-key.md", @@ -25305,7 +25905,7 @@ "properties": { "type": { "type": "string", - "description": "Platform type.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "default": null, "x-example": "web", "enum": [ @@ -28351,7 +28951,7 @@ "x-appwrite": { "method": "listRules", "group": null, - "weight": 502, + "weight": 514, "cookies": false, "type": "", "demo": "proxy\/list-rules.md", @@ -28424,7 +29024,7 @@ "x-appwrite": { "method": "createAPIRule", "group": null, - "weight": 497, + "weight": 509, "cookies": false, "type": "", "demo": "proxy\/create-api-rule.md", @@ -28494,7 +29094,7 @@ "x-appwrite": { "method": "createFunctionRule", "group": null, - "weight": 499, + "weight": 511, "cookies": false, "type": "", "demo": "proxy\/create-function-rule.md", @@ -28577,7 +29177,7 @@ "x-appwrite": { "method": "createRedirectRule", "group": null, - "weight": 500, + "weight": 512, "cookies": false, "type": "", "demo": "proxy\/create-redirect-rule.md", @@ -28697,7 +29297,7 @@ "x-appwrite": { "method": "createSiteRule", "group": null, - "weight": 498, + "weight": 510, "cookies": false, "type": "", "demo": "proxy\/create-site-rule.md", @@ -28778,7 +29378,7 @@ "x-appwrite": { "method": "getRule", "group": null, - "weight": 501, + "weight": 513, "cookies": false, "type": "", "demo": "proxy\/get-rule.md", @@ -28831,7 +29431,7 @@ "x-appwrite": { "method": "deleteRule", "group": null, - "weight": 503, + "weight": 515, "cookies": false, "type": "", "demo": "proxy\/delete-rule.md", @@ -28891,7 +29491,7 @@ "x-appwrite": { "method": "updateRuleVerification", "group": null, - "weight": 504, + "weight": 516, "cookies": false, "type": "", "demo": "proxy\/update-rule-verification.md", @@ -28949,7 +29549,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -29021,7 +29621,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -29288,7 +29888,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -29337,7 +29937,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -29387,7 +29987,7 @@ "x-appwrite": { "method": "listTemplates", "group": "templates", - "weight": 491, + "weight": 503, "cookies": false, "type": "", "demo": "sites\/list-templates.md", @@ -29481,7 +30081,7 @@ "x-appwrite": { "method": "getTemplate", "group": "templates", - "weight": 492, + "weight": 504, "cookies": false, "type": "", "demo": "sites\/get-template.md", @@ -29539,7 +30139,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 493, + "weight": 505, "cookies": false, "type": "", "demo": "sites\/list-usage.md", @@ -29609,7 +30209,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -29668,7 +30268,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -29930,7 +30530,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -29991,7 +30591,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -30068,7 +30668,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -30148,7 +30748,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -30248,7 +30848,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -30314,7 +30914,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -30327,11 +30927,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -30433,7 +31033,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -30530,7 +31130,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -30592,7 +31192,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -30659,7 +31259,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -30744,7 +31344,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -30811,7 +31411,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -30882,7 +31482,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -30946,7 +31546,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -31013,7 +31613,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 494, + "weight": 506, "cookies": false, "type": "", "demo": "sites\/get-usage.md", @@ -31091,7 +31691,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -31150,7 +31750,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -31240,7 +31840,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -31307,7 +31907,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -31399,7 +31999,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -32833,7 +33433,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -32905,7 +33505,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -32963,6 +33563,419 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/tablesdb\/usage": { "get": { "summary": "Get TablesDB usage stats", @@ -32987,7 +34000,7 @@ "x-appwrite": { "method": "listUsage", "group": null, - "weight": 378, + "weight": 384, "cookies": false, "type": "", "demo": "tablesdb\/list-usage.md", @@ -33082,7 +34095,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -33141,7 +34154,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -33219,7 +34232,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -33278,7 +34291,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -33348,7 +34361,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -33361,7 +34374,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -33469,7 +34482,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -33539,7 +34552,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -33643,7 +34656,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -33713,7 +34726,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -33797,7 +34810,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -33834,7 +34847,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -33906,7 +34919,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -33943,7 +34956,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -34017,7 +35030,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -34126,7 +35139,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -34237,7 +35250,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -34346,7 +35359,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -34457,7 +35470,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -34576,7 +35589,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -34697,7 +35710,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -34818,7 +35831,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -34941,7 +35954,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -35062,7 +36075,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -35185,7 +36198,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -35294,7 +36307,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -35405,7 +36418,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -35442,7 +36455,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35509,7 +36522,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -35546,7 +36559,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35619,7 +36632,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -35656,7 +36669,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35723,7 +36736,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -35760,7 +36773,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35833,7 +36846,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -35870,7 +36883,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -35937,7 +36950,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -35974,7 +36987,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -36047,7 +37060,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -36183,7 +37196,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -36220,7 +37233,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -36305,7 +37318,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -36342,7 +37355,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -36422,7 +37435,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -36531,7 +37544,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -36671,7 +37684,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -36743,7 +37756,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -36822,7 +37835,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -36927,7 +37940,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -36964,7 +37977,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37009,7 +38022,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -37046,7 +38059,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37140,7 +38153,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -37177,7 +38190,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37212,7 +38225,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -37249,7 +38262,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37289,7 +38302,7 @@ "x-appwrite": { "method": "listTableLogs", "group": "tables", - "weight": 384, + "weight": 390, "cookies": false, "type": "", "demo": "tablesdb\/list-table-logs.md", @@ -37370,7 +38383,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -37409,7 +38422,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "type": "string", "x-example": "", @@ -37426,6 +38439,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -37441,7 +38462,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -37454,7 +38475,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -37484,7 +38505,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -37498,7 +38520,7 @@ "model": "#\/definitions\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -37511,7 +38533,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37524,7 +38547,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -37550,7 +38573,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "type": "string", "x-example": "", @@ -37591,6 +38614,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -37609,7 +38638,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -37622,7 +38651,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -37650,7 +38679,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -37663,7 +38693,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -37708,6 +38738,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -37742,7 +38778,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -37806,6 +38842,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -37837,7 +38879,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -37875,7 +38917,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37895,6 +38937,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -37926,7 +38974,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -37965,7 +39013,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -37990,6 +39038,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -38005,7 +39061,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -38018,7 +39074,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -38048,7 +39104,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -38061,7 +39118,7 @@ "model": "#\/definitions\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -38121,6 +39178,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38152,7 +39215,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -38225,6 +39288,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38251,7 +39320,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -38290,7 +39359,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -38303,6 +39372,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -38331,7 +39415,7 @@ "x-appwrite": { "method": "listRowLogs", "group": "logs", - "weight": 428, + "weight": 434, "cookies": false, "type": "", "demo": "tablesdb\/list-row-logs.md", @@ -38422,7 +39506,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -38500,6 +39584,12 @@ "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38533,7 +39623,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -38611,6 +39701,12 @@ "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -38642,7 +39738,7 @@ "x-appwrite": { "method": "getTableUsage", "group": null, - "weight": 385, + "weight": 391, "cookies": false, "type": "", "demo": "tablesdb\/get-table-usage.md", @@ -38731,7 +39827,7 @@ "x-appwrite": { "method": "getUsage", "group": null, - "weight": 377, + "weight": 383, "cookies": false, "type": "", "demo": "tablesdb\/get-usage.md", @@ -39916,7 +41012,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -39996,7 +41092,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -40080,7 +41176,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -40140,7 +41236,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -40211,7 +41307,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -46040,6 +47136,35 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "type": "object", + "$ref": "#\/definitions\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "migrationList": { "description": "Migrations List", "type": "object", @@ -46159,7 +47284,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -46405,7 +47534,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46500,7 +47630,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46597,7 +47728,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46694,7 +47826,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46774,7 +47907,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46861,7 +47995,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -46958,7 +48093,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47045,7 +48181,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47132,7 +48269,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47219,7 +48357,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47334,7 +48473,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47420,7 +48560,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47518,7 +48659,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -47835,7 +48977,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -47923,7 +49073,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48013,7 +49171,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48103,7 +49269,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48176,7 +49350,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48256,7 +49438,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48346,7 +49536,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48426,7 +49624,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48506,7 +49712,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48586,7 +49800,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48694,7 +49916,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48773,7 +50003,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -48864,7 +50102,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -53383,16 +54629,24 @@ }, "type": { "type": "string", - "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, ios, android, and unity.", + "description": "Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.", "x-example": "web", "enum": [ "web", "flutter-web", "flutter-ios", "flutter-android", - "ios", + "flutter-linux", + "flutter-macos", + "flutter-windows", + "apple-ios", + "apple-macos", + "apple-watchos", + "apple-tvos", "android", - "unity" + "unity", + "react-native-ios", + "react-native-android" ] }, "key": { @@ -53752,7 +55006,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -56584,7 +57839,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -56698,6 +57960,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index 679da75e5d..9c8ef73243 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -3302,10 +3302,10 @@ ] } }, - "\/account\/verification": { + "\/account\/verifications\/email": { "post": { "summary": "Create email verification", - "operationId": "accountCreateVerification", + "operationId": "accountCreateEmailVerification", "consumes": [ "application\/json" ], @@ -3326,12 +3326,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "createVerification", + "method": "createEmailVerification", "group": "verification", "weight": 41, "cookies": false, "type": "", - "demo": "account\/create-verification.md", + "demo": "account\/create-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/create-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3342,6 +3342,58 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "createEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-email-verification.md" + }, + { + "name": "createVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "url" + ], + "required": [ + "url" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/token" + } + ], + "description": "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.\n\nPlease 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.\n", + "demo": "account\/create-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.createEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3377,7 +3429,7 @@ }, "put": { "summary": "Update email verification (confirmation)", - "operationId": "accountUpdateVerification", + "operationId": "accountUpdateEmailVerification", "consumes": [ "application\/json" ], @@ -3398,12 +3450,12 @@ }, "deprecated": false, "x-appwrite": { - "method": "updateVerification", + "method": "updateEmailVerification", "group": "verification", "weight": 42, "cookies": false, "type": "", - "demo": "account\/update-verification.md", + "demo": "account\/update-email-verification.md", "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/account\/update-email-verification.md", "rate-limit": 10, "rate-time": 3600, @@ -3414,6 +3466,62 @@ "server" ], "packaging": false, + "methods": [ + { + "name": "updateEmailVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-email-verification.md" + }, + { + "name": "updateVerification", + "namespace": "account", + "desc": "", + "auth": { + "Project": [], + "Session": [] + }, + "parameters": [ + "userId", + "secret" + ], + "required": [ + "userId", + "secret" + ], + "responses": [ + { + "code": 200, + "model": "#\/definitions\/token" + } + ], + "description": "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.", + "demo": "account\/update-verification.md", + "deprecated": { + "since": "1.8.0", + "replaceWith": "account.updateEmailVerification" + } + } + ], "auth": { "Project": [], "Session": [] @@ -3455,7 +3563,7 @@ ] } }, - "\/account\/verification\/phone": { + "\/account\/verifications\/phone": { "post": { "summary": "Create phone verification", "operationId": "accountCreatePhoneVerification", @@ -4893,6 +5001,431 @@ ] } }, + "\/databases\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "databasesListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 376, + "cookies": false, + "type": "", + "demo": "databases\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "databasesCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 372, + "cookies": false, + "type": "", + "demo": "databases\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/databases\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "databasesGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 373, + "cookies": false, + "type": "", + "demo": "databases\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "databasesUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 374, + "cookies": false, + "type": "", + "demo": "databases\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "databasesDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "databases" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 375, + "cookies": false, + "type": "", + "demo": "databases\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/databases\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "databasesCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "databases" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 377, + "cookies": false, + "type": "", + "demo": "databases\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "documents.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"collectionId\": \"\",\n\t \"documentId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/databases\/{databaseId}": { "get": { "summary": "Get database", @@ -8993,6 +9526,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -9053,7 +9594,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9085,7 +9627,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9171,6 +9714,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9232,7 +9781,8 @@ "parameters": [ "databaseId", "collectionId", - "documents" + "documents", + "transactionId" ], "required": [ "databaseId", @@ -9295,6 +9845,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -9395,6 +9951,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9486,6 +10048,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9584,6 +10152,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -9644,7 +10220,8 @@ "collectionId", "documentId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -9724,6 +10301,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -9834,6 +10417,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -9915,6 +10504,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -10026,6 +10630,12 @@ "description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10140,6 +10750,12 @@ "description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -10375,7 +10991,7 @@ "tags": [ "databases" ], - "description": "Get index by ID.", + "description": "Get an index by its unique ID.", "responses": { "200": { "description": "Index", @@ -10541,7 +11157,7 @@ "x-appwrite": { "method": "list", "group": "functions", - "weight": 440, + "weight": 452, "cookies": false, "type": "", "demo": "functions\/list.md", @@ -10614,7 +11230,7 @@ "x-appwrite": { "method": "create", "group": "functions", - "weight": 437, + "weight": 449, "cookies": false, "type": "", "demo": "functions\/create.md", @@ -10866,7 +11482,7 @@ "x-appwrite": { "method": "listRuntimes", "group": "runtimes", - "weight": 442, + "weight": 454, "cookies": false, "type": "", "demo": "functions\/list-runtimes.md", @@ -10916,7 +11532,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "runtimes", - "weight": 443, + "weight": 455, "cookies": false, "type": "", "demo": "functions\/list-specifications.md", @@ -10967,7 +11583,7 @@ "x-appwrite": { "method": "get", "group": "functions", - "weight": 438, + "weight": 450, "cookies": false, "type": "", "demo": "functions\/get.md", @@ -11027,7 +11643,7 @@ "x-appwrite": { "method": "update", "group": "functions", - "weight": 439, + "weight": 451, "cookies": false, "type": "", "demo": "functions\/update.md", @@ -11275,7 +11891,7 @@ "x-appwrite": { "method": "delete", "group": "functions", - "weight": 441, + "weight": 453, "cookies": false, "type": "", "demo": "functions\/delete.md", @@ -11337,7 +11953,7 @@ "x-appwrite": { "method": "updateFunctionDeployment", "group": "functions", - "weight": 446, + "weight": 458, "cookies": false, "type": "", "demo": "functions\/update-function-deployment.md", @@ -11415,7 +12031,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 447, + "weight": 459, "cookies": false, "type": "", "demo": "functions\/list-deployments.md", @@ -11496,7 +12112,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 444, + "weight": 456, "cookies": false, "type": "upload", "demo": "functions\/create-deployment.md", @@ -11589,7 +12205,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 452, + "weight": 464, "cookies": false, "type": "", "demo": "functions\/create-duplicate-deployment.md", @@ -11662,7 +12278,7 @@ "tags": [ "functions" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -11675,11 +12291,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 449, + "weight": 461, "cookies": false, "type": "", "demo": "functions\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/functions#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/functions\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -11782,7 +12398,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 450, + "weight": 462, "cookies": false, "type": "", "demo": "functions\/create-vcs-deployment.md", @@ -11879,7 +12495,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 445, + "weight": 457, "cookies": false, "type": "", "demo": "functions\/get-deployment.md", @@ -11942,7 +12558,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 448, + "weight": 460, "cookies": false, "type": "", "demo": "functions\/delete-deployment.md", @@ -12010,7 +12626,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 451, + "weight": 463, "cookies": false, "type": "location", "demo": "functions\/get-deployment-download.md", @@ -12096,7 +12712,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 453, + "weight": 465, "cookies": false, "type": "", "demo": "functions\/update-deployment-status.md", @@ -12164,7 +12780,7 @@ "x-appwrite": { "method": "listExecutions", "group": "executions", - "weight": 456, + "weight": 468, "cookies": false, "type": "", "demo": "functions\/list-executions.md", @@ -12239,7 +12855,7 @@ "x-appwrite": { "method": "createExecution", "group": "executions", - "weight": 454, + "weight": 466, "cookies": false, "type": "", "demo": "functions\/create-execution.md", @@ -12358,7 +12974,7 @@ "x-appwrite": { "method": "getExecution", "group": "executions", - "weight": 455, + "weight": 467, "cookies": false, "type": "", "demo": "functions\/get-execution.md", @@ -12424,7 +13040,7 @@ "x-appwrite": { "method": "deleteExecution", "group": "executions", - "weight": 457, + "weight": 469, "cookies": false, "type": "", "demo": "functions\/delete-execution.md", @@ -12492,7 +13108,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 462, + "weight": 474, "cookies": false, "type": "", "demo": "functions\/list-variables.md", @@ -12552,7 +13168,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 460, + "weight": 472, "cookies": false, "type": "", "demo": "functions\/create-variable.md", @@ -12643,7 +13259,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 461, + "weight": 473, "cookies": false, "type": "", "demo": "functions\/get-variable.md", @@ -12711,7 +13327,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 463, + "weight": 475, "cookies": false, "type": "", "demo": "functions\/update-variable.md", @@ -12804,7 +13420,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 464, + "weight": 476, "cookies": false, "type": "", "demo": "functions\/delete-variable.md", @@ -15215,7 +15831,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": "", - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -15413,7 +16029,7 @@ "type": "string", "description": "Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as :.", "default": null, - "x-example": "[ID1:ID2]" + "x-example": "" }, "icon": { "type": "string", @@ -19909,7 +20525,7 @@ "x-appwrite": { "method": "list", "group": "sites", - "weight": 469, + "weight": 481, "cookies": false, "type": "", "demo": "sites\/list.md", @@ -19982,7 +20598,7 @@ "x-appwrite": { "method": "create", "group": "sites", - "weight": 467, + "weight": 479, "cookies": false, "type": "", "demo": "sites\/create.md", @@ -20250,7 +20866,7 @@ "x-appwrite": { "method": "listFrameworks", "group": "frameworks", - "weight": 472, + "weight": 484, "cookies": false, "type": "", "demo": "sites\/list-frameworks.md", @@ -20300,7 +20916,7 @@ "x-appwrite": { "method": "listSpecifications", "group": "frameworks", - "weight": 495, + "weight": 507, "cookies": false, "type": "", "demo": "sites\/list-specifications.md", @@ -20351,7 +20967,7 @@ "x-appwrite": { "method": "get", "group": "sites", - "weight": 468, + "weight": 480, "cookies": false, "type": "", "demo": "sites\/get.md", @@ -20411,7 +21027,7 @@ "x-appwrite": { "method": "update", "group": "sites", - "weight": 470, + "weight": 482, "cookies": false, "type": "", "demo": "sites\/update.md", @@ -20674,7 +21290,7 @@ "x-appwrite": { "method": "delete", "group": "sites", - "weight": 471, + "weight": 483, "cookies": false, "type": "", "demo": "sites\/delete.md", @@ -20736,7 +21352,7 @@ "x-appwrite": { "method": "updateSiteDeployment", "group": "sites", - "weight": 478, + "weight": 490, "cookies": false, "type": "", "demo": "sites\/update-site-deployment.md", @@ -20814,7 +21430,7 @@ "x-appwrite": { "method": "listDeployments", "group": "deployments", - "weight": 477, + "weight": 489, "cookies": false, "type": "", "demo": "sites\/list-deployments.md", @@ -20895,7 +21511,7 @@ "x-appwrite": { "method": "createDeployment", "group": "deployments", - "weight": 473, + "weight": 485, "cookies": false, "type": "upload", "demo": "sites\/create-deployment.md", @@ -20996,7 +21612,7 @@ "x-appwrite": { "method": "createDuplicateDeployment", "group": "deployments", - "weight": 481, + "weight": 493, "cookies": false, "type": "", "demo": "sites\/create-duplicate-deployment.md", @@ -21063,7 +21679,7 @@ "tags": [ "sites" ], - "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "description": "Create a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "responses": { "202": { "description": "Deployment", @@ -21076,11 +21692,11 @@ "x-appwrite": { "method": "createTemplateDeployment", "group": "deployments", - "weight": 474, + "weight": 486, "cookies": false, "type": "", "demo": "sites\/create-template-deployment.md", - "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/server\/sites#listTemplates) to find the template details.", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterCreate a deployment based on a template.\n\nUse this endpoint with combination of [listTemplates](https:\/\/appwrite.io\/docs\/products\/sites\/templates) to find the template details.", "rate-limit": 0, "rate-time": 3600, "rate-key": "url:{url},ip:{ip}", @@ -21183,7 +21799,7 @@ "x-appwrite": { "method": "createVcsDeployment", "group": "deployments", - "weight": 475, + "weight": 487, "cookies": false, "type": "", "demo": "sites\/create-vcs-deployment.md", @@ -21281,7 +21897,7 @@ "x-appwrite": { "method": "getDeployment", "group": "deployments", - "weight": 476, + "weight": 488, "cookies": false, "type": "", "demo": "sites\/get-deployment.md", @@ -21344,7 +21960,7 @@ "x-appwrite": { "method": "deleteDeployment", "group": "deployments", - "weight": 479, + "weight": 491, "cookies": false, "type": "", "demo": "sites\/delete-deployment.md", @@ -21412,7 +22028,7 @@ "x-appwrite": { "method": "getDeploymentDownload", "group": "deployments", - "weight": 480, + "weight": 492, "cookies": false, "type": "location", "demo": "sites\/get-deployment-download.md", @@ -21498,7 +22114,7 @@ "x-appwrite": { "method": "updateDeploymentStatus", "group": "deployments", - "weight": 482, + "weight": 494, "cookies": false, "type": "", "demo": "sites\/update-deployment-status.md", @@ -21566,7 +22182,7 @@ "x-appwrite": { "method": "listLogs", "group": "logs", - "weight": 484, + "weight": 496, "cookies": false, "type": "", "demo": "sites\/list-logs.md", @@ -21638,7 +22254,7 @@ "x-appwrite": { "method": "getLog", "group": "logs", - "weight": 483, + "weight": 495, "cookies": false, "type": "", "demo": "sites\/get-log.md", @@ -21703,7 +22319,7 @@ "x-appwrite": { "method": "deleteLog", "group": "logs", - "weight": 485, + "weight": 497, "cookies": false, "type": "", "demo": "sites\/delete-log.md", @@ -21771,7 +22387,7 @@ "x-appwrite": { "method": "listVariables", "group": "variables", - "weight": 488, + "weight": 500, "cookies": false, "type": "", "demo": "sites\/list-variables.md", @@ -21831,7 +22447,7 @@ "x-appwrite": { "method": "createVariable", "group": "variables", - "weight": 486, + "weight": 498, "cookies": false, "type": "", "demo": "sites\/create-variable.md", @@ -21922,7 +22538,7 @@ "x-appwrite": { "method": "getVariable", "group": "variables", - "weight": 487, + "weight": 499, "cookies": false, "type": "", "demo": "sites\/get-variable.md", @@ -21990,7 +22606,7 @@ "x-appwrite": { "method": "updateVariable", "group": "variables", - "weight": 489, + "weight": 501, "cookies": false, "type": "", "demo": "sites\/update-variable.md", @@ -22083,7 +22699,7 @@ "x-appwrite": { "method": "deleteVariable", "group": "variables", - "weight": 490, + "weight": 502, "cookies": false, "type": "", "demo": "sites\/delete-variable.md", @@ -23391,7 +24007,7 @@ "x-appwrite": { "method": "list", "group": "tablesdb", - "weight": 376, + "weight": 382, "cookies": false, "type": "", "demo": "tablesdb\/list.md", @@ -23464,7 +24080,7 @@ "x-appwrite": { "method": "create", "group": "tablesdb", - "weight": 372, + "weight": 378, "cookies": false, "type": "", "demo": "tablesdb\/create.md", @@ -23523,6 +24139,431 @@ ] } }, + "\/tablesdb\/transactions": { + "get": { + "summary": "List transactions", + "operationId": "tablesDBListTransactions", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "List transactions across all databases.", + "responses": { + "200": { + "description": "Transaction List", + "schema": { + "$ref": "#\/definitions\/transactionList" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "listTransactions", + "group": "transactions", + "weight": 441, + "cookies": false, + "type": "", + "demo": "tablesdb\/list-transactions.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/list-transactions.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "queries", + "description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries).", + "required": false, + "type": "array", + "collectionFormat": "multi", + "items": { + "type": "string" + }, + "default": [], + "in": "query" + } + ] + }, + "post": { + "summary": "Create transaction", + "operationId": "tablesDBCreateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create a new transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createTransaction", + "group": "transactions", + "weight": 437, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "ttl": { + "type": "integer", + "description": "Seconds before the transaction expires.", + "default": 300, + "x-example": 60 + } + } + } + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}": { + "get": { + "summary": "Get transaction", + "operationId": "tablesDBGetTransaction", + "consumes": [], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Get a transaction by its unique ID.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "getTransaction", + "group": "transactions", + "weight": 438, + "cookies": false, + "type": "", + "demo": "tablesdb\/get-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/get-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.read", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + }, + "patch": { + "summary": "Update transaction", + "operationId": "tablesDBUpdateTransaction", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Update a transaction, to either commit or roll back its operations.", + "responses": { + "200": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "updateTransaction", + "group": "transactions", + "weight": 439, + "cookies": false, + "type": "", + "demo": "tablesdb\/update-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/update-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "commit": { + "type": "boolean", + "description": "Commit transaction?", + "default": false, + "x-example": false + }, + "rollback": { + "type": "boolean", + "description": "Rollback transaction?", + "default": false, + "x-example": false + } + } + } + } + ] + }, + "delete": { + "summary": "Delete transaction", + "operationId": "tablesDBDeleteTransaction", + "consumes": [ + "application\/json" + ], + "produces": [], + "tags": [ + "tablesDB" + ], + "description": "Delete a transaction by its unique ID.", + "responses": { + "204": { + "description": "No content" + } + }, + "deprecated": false, + "x-appwrite": { + "method": "deleteTransaction", + "group": "transactions", + "weight": 440, + "cookies": false, + "type": "", + "demo": "tablesdb\/delete-transaction.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/delete-transaction.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + } + ] + } + }, + "\/tablesdb\/transactions\/{transactionId}\/operations": { + "post": { + "summary": "Create operations", + "operationId": "tablesDBCreateOperations", + "consumes": [ + "application\/json" + ], + "produces": [ + "application\/json" + ], + "tags": [ + "tablesDB" + ], + "description": "Create multiple operations in a single transaction.", + "responses": { + "201": { + "description": "Transaction", + "schema": { + "$ref": "#\/definitions\/transaction" + } + } + }, + "deprecated": false, + "x-appwrite": { + "method": "createOperations", + "group": "transactions", + "weight": 442, + "cookies": false, + "type": "", + "demo": "tablesdb\/create-operations.md", + "edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/tablesdb\/create-operations.md", + "rate-limit": 0, + "rate-time": 3600, + "rate-key": "url:{url},ip:{ip}", + "scope": "rows.write", + "platforms": [ + "server", + "client" + ], + "packaging": false, + "auth": { + "Project": [], + "Key": [] + } + }, + "security": [ + { + "Project": [], + "Key": [], + "Session": [], + "JWT": [] + } + ], + "parameters": [ + { + "name": "transactionId", + "description": "Transaction ID.", + "required": true, + "type": "string", + "x-example": "", + "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of staged operations.", + "default": [], + "x-example": "[\n\t {\n\t \"action\": \"create\",\n\t \"databaseId\": \"\",\n\t \"tableId\": \"\",\n\t \"rowId\": \"\",\n\t \"data\": {\n\t \"name\": \"Walter O'Brien\"\n\t }\n\t }\n\t]", + "items": { + "type": "object" + } + } + } + } + } + ] + } + }, "\/tablesdb\/{databaseId}": { "get": { "summary": "Get database", @@ -23547,7 +24588,7 @@ "x-appwrite": { "method": "get", "group": "tablesdb", - "weight": 373, + "weight": 379, "cookies": false, "type": "", "demo": "tablesdb\/get.md", @@ -23607,7 +24648,7 @@ "x-appwrite": { "method": "update", "group": "tablesdb", - "weight": 374, + "weight": 380, "cookies": false, "type": "", "demo": "tablesdb\/update.md", @@ -23686,7 +24727,7 @@ "x-appwrite": { "method": "delete", "group": "tablesdb", - "weight": 375, + "weight": 381, "cookies": false, "type": "", "demo": "tablesdb\/delete.md", @@ -23746,7 +24787,7 @@ "x-appwrite": { "method": "listTables", "group": "tables", - "weight": 383, + "weight": 389, "cookies": false, "type": "", "demo": "tablesdb\/list-tables.md", @@ -23817,7 +24858,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Table", @@ -23830,7 +24871,7 @@ "x-appwrite": { "method": "createTable", "group": "tables", - "weight": 379, + "weight": 385, "cookies": false, "type": "", "demo": "tablesdb\/create-table.md", @@ -23939,7 +24980,7 @@ "x-appwrite": { "method": "getTable", "group": "tables", - "weight": 380, + "weight": 386, "cookies": false, "type": "", "demo": "tablesdb\/get-table.md", @@ -24010,7 +25051,7 @@ "x-appwrite": { "method": "updateTable", "group": "tables", - "weight": 381, + "weight": 387, "cookies": false, "type": "", "demo": "tablesdb\/update-table.md", @@ -24115,7 +25156,7 @@ "x-appwrite": { "method": "deleteTable", "group": "tables", - "weight": 382, + "weight": 388, "cookies": false, "type": "", "demo": "tablesdb\/delete-table.md", @@ -24186,7 +25227,7 @@ "x-appwrite": { "method": "listColumns", "group": "columns", - "weight": 388, + "weight": 394, "cookies": false, "type": "", "demo": "tablesdb\/list-columns.md", @@ -24271,7 +25312,7 @@ "x-appwrite": { "method": "createBooleanColumn", "group": "columns", - "weight": 389, + "weight": 395, "cookies": false, "type": "", "demo": "tablesdb\/create-boolean-column.md", @@ -24309,7 +25350,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -24381,7 +25422,7 @@ "x-appwrite": { "method": "updateBooleanColumn", "group": "columns", - "weight": 390, + "weight": 396, "cookies": false, "type": "", "demo": "tablesdb\/update-boolean-column.md", @@ -24419,7 +25460,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -24493,7 +25534,7 @@ "x-appwrite": { "method": "createDatetimeColumn", "group": "columns", - "weight": 391, + "weight": 397, "cookies": false, "type": "", "demo": "tablesdb\/create-datetime-column.md", @@ -24603,7 +25644,7 @@ "x-appwrite": { "method": "updateDatetimeColumn", "group": "columns", - "weight": 392, + "weight": 398, "cookies": false, "type": "", "demo": "tablesdb\/update-datetime-column.md", @@ -24715,7 +25756,7 @@ "x-appwrite": { "method": "createEmailColumn", "group": "columns", - "weight": 393, + "weight": 399, "cookies": false, "type": "", "demo": "tablesdb\/create-email-column.md", @@ -24825,7 +25866,7 @@ "x-appwrite": { "method": "updateEmailColumn", "group": "columns", - "weight": 394, + "weight": 400, "cookies": false, "type": "", "demo": "tablesdb\/update-email-column.md", @@ -24937,7 +25978,7 @@ "x-appwrite": { "method": "createEnumColumn", "group": "columns", - "weight": 395, + "weight": 401, "cookies": false, "type": "", "demo": "tablesdb\/create-enum-column.md", @@ -25057,7 +26098,7 @@ "x-appwrite": { "method": "updateEnumColumn", "group": "columns", - "weight": 396, + "weight": 402, "cookies": false, "type": "", "demo": "tablesdb\/update-enum-column.md", @@ -25179,7 +26220,7 @@ "x-appwrite": { "method": "createFloatColumn", "group": "columns", - "weight": 397, + "weight": 403, "cookies": false, "type": "", "demo": "tablesdb\/create-float-column.md", @@ -25301,7 +26342,7 @@ "x-appwrite": { "method": "updateFloatColumn", "group": "columns", - "weight": 398, + "weight": 404, "cookies": false, "type": "", "demo": "tablesdb\/update-float-column.md", @@ -25425,7 +26466,7 @@ "x-appwrite": { "method": "createIntegerColumn", "group": "columns", - "weight": 399, + "weight": 405, "cookies": false, "type": "", "demo": "tablesdb\/create-integer-column.md", @@ -25547,7 +26588,7 @@ "x-appwrite": { "method": "updateIntegerColumn", "group": "columns", - "weight": 400, + "weight": 406, "cookies": false, "type": "", "demo": "tablesdb\/update-integer-column.md", @@ -25671,7 +26712,7 @@ "x-appwrite": { "method": "createIpColumn", "group": "columns", - "weight": 401, + "weight": 407, "cookies": false, "type": "", "demo": "tablesdb\/create-ip-column.md", @@ -25781,7 +26822,7 @@ "x-appwrite": { "method": "updateIpColumn", "group": "columns", - "weight": 402, + "weight": 408, "cookies": false, "type": "", "demo": "tablesdb\/update-ip-column.md", @@ -25893,7 +26934,7 @@ "x-appwrite": { "method": "createLineColumn", "group": "columns", - "weight": 403, + "weight": 409, "cookies": false, "type": "", "demo": "tablesdb\/create-line-column.md", @@ -25931,7 +26972,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -25998,7 +27039,7 @@ "x-appwrite": { "method": "updateLineColumn", "group": "columns", - "weight": 404, + "weight": 410, "cookies": false, "type": "", "demo": "tablesdb\/update-line-column.md", @@ -26036,7 +27077,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26109,7 +27150,7 @@ "x-appwrite": { "method": "createPointColumn", "group": "columns", - "weight": 405, + "weight": 411, "cookies": false, "type": "", "demo": "tablesdb\/create-point-column.md", @@ -26147,7 +27188,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26214,7 +27255,7 @@ "x-appwrite": { "method": "updatePointColumn", "group": "columns", - "weight": 406, + "weight": 412, "cookies": false, "type": "", "demo": "tablesdb\/update-point-column.md", @@ -26252,7 +27293,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26325,7 +27366,7 @@ "x-appwrite": { "method": "createPolygonColumn", "group": "columns", - "weight": 407, + "weight": 413, "cookies": false, "type": "", "demo": "tablesdb\/create-polygon-column.md", @@ -26363,7 +27404,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26430,7 +27471,7 @@ "x-appwrite": { "method": "updatePolygonColumn", "group": "columns", - "weight": 408, + "weight": 414, "cookies": false, "type": "", "demo": "tablesdb\/update-polygon-column.md", @@ -26468,7 +27509,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26541,7 +27582,7 @@ "x-appwrite": { "method": "createRelationshipColumn", "group": "columns", - "weight": 409, + "weight": 415, "cookies": false, "type": "", "demo": "tablesdb\/create-relationship-column.md", @@ -26678,7 +27719,7 @@ "x-appwrite": { "method": "createStringColumn", "group": "columns", - "weight": 411, + "weight": 417, "cookies": false, "type": "", "demo": "tablesdb\/create-string-column.md", @@ -26716,7 +27757,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26801,7 +27842,7 @@ "x-appwrite": { "method": "updateStringColumn", "group": "columns", - "weight": 412, + "weight": 418, "cookies": false, "type": "", "demo": "tablesdb\/update-string-column.md", @@ -26839,7 +27880,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -26919,7 +27960,7 @@ "x-appwrite": { "method": "createUrlColumn", "group": "columns", - "weight": 413, + "weight": 419, "cookies": false, "type": "", "demo": "tablesdb\/create-url-column.md", @@ -27029,7 +28070,7 @@ "x-appwrite": { "method": "updateUrlColumn", "group": "columns", - "weight": 414, + "weight": 420, "cookies": false, "type": "", "demo": "tablesdb\/update-url-column.md", @@ -27170,7 +28211,7 @@ "x-appwrite": { "method": "getColumn", "group": "columns", - "weight": 386, + "weight": 392, "cookies": false, "type": "", "demo": "tablesdb\/get-column.md", @@ -27243,7 +28284,7 @@ "x-appwrite": { "method": "deleteColumn", "group": "columns", - "weight": 387, + "weight": 393, "cookies": false, "type": "", "demo": "tablesdb\/delete-column.md", @@ -27323,7 +28364,7 @@ "x-appwrite": { "method": "updateRelationshipColumn", "group": "columns", - "weight": 410, + "weight": 416, "cookies": false, "type": "", "demo": "tablesdb\/update-relationship-column.md", @@ -27429,7 +28470,7 @@ "x-appwrite": { "method": "listIndexes", "group": "indexes", - "weight": 418, + "weight": 424, "cookies": false, "type": "", "demo": "tablesdb\/list-indexes.md", @@ -27467,7 +28508,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27512,7 +28553,7 @@ "x-appwrite": { "method": "createIndex", "group": "indexes", - "weight": 415, + "weight": 421, "cookies": false, "type": "", "demo": "tablesdb\/create-index.md", @@ -27550,7 +28591,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27644,7 +28685,7 @@ "x-appwrite": { "method": "getIndex", "group": "indexes", - "weight": 416, + "weight": 422, "cookies": false, "type": "", "demo": "tablesdb\/get-index.md", @@ -27682,7 +28723,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27717,7 +28758,7 @@ "x-appwrite": { "method": "deleteIndex", "group": "indexes", - "weight": 417, + "weight": 423, "cookies": false, "type": "", "demo": "tablesdb\/delete-index.md", @@ -27755,7 +28796,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -27795,7 +28836,7 @@ "x-appwrite": { "method": "listRows", "group": "rows", - "weight": 427, + "weight": 433, "cookies": false, "type": "", "demo": "tablesdb\/list-rows.md", @@ -27836,7 +28877,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the TableDB service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdbdb#tablesdbCreate).", + "description": "Table ID. You can create a new table using the TablesDB service [server integration](https:\/\/appwrite.io\/docs\/products\/databases\/tables#create-table).", "required": true, "type": "string", "x-example": "", @@ -27853,6 +28894,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -27868,7 +28917,7 @@ "tags": [ "tablesDB" ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -27881,7 +28930,7 @@ "x-appwrite": { "method": "createRow", "group": "rows", - "weight": 419, + "weight": 425, "cookies": false, "type": "", "demo": "tablesdb\/create-row.md", @@ -27912,7 +28961,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -27926,7 +28976,7 @@ "model": "#\/definitions\/row" } ], - "description": "Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-row.md" }, { @@ -27940,7 +28990,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -27953,7 +29004,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/create-rows.md" } ], @@ -27981,7 +29032,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.", + "description": "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.", "required": true, "type": "string", "x-example": "", @@ -28022,6 +29073,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28040,7 +29097,7 @@ "tags": [ "tablesDB" ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "responses": { "201": { "description": "Rows List", @@ -28053,7 +29110,7 @@ "x-appwrite": { "method": "upsertRows", "group": "rows", - "weight": 424, + "weight": 430, "cookies": false, "type": "", "demo": "tablesdb\/upsert-rows.md", @@ -28082,7 +29139,8 @@ "parameters": [ "databaseId", "tableId", - "rows" + "rows", + "transactionId" ], "required": [ "databaseId", @@ -28095,7 +29153,7 @@ "model": "#\/definitions\/rowList" } ], - "description": "Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.\n", + "description": "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.\n", "demo": "tablesdb\/upsert-rows.md" } ], @@ -28141,6 +29199,12 @@ "items": { "type": "object" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } }, "required": [ @@ -28175,7 +29239,7 @@ "x-appwrite": { "method": "updateRows", "group": "rows", - "weight": 422, + "weight": 428, "cookies": false, "type": "", "demo": "tablesdb\/update-rows.md", @@ -28240,6 +29304,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28271,7 +29341,7 @@ "x-appwrite": { "method": "deleteRows", "group": "rows", - "weight": 426, + "weight": 432, "cookies": false, "type": "", "demo": "tablesdb\/delete-rows.md", @@ -28310,7 +29380,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -28330,6 +29400,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28361,7 +29437,7 @@ "x-appwrite": { "method": "getRow", "group": "rows", - "weight": 420, + "weight": 426, "cookies": false, "type": "", "demo": "tablesdb\/get-row.md", @@ -28402,7 +29478,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -28427,6 +29503,14 @@ }, "default": [], "in": "query" + }, + { + "name": "transactionId", + "description": "Transaction ID to read uncommitted changes within the transaction.", + "required": false, + "type": "string", + "x-example": "", + "in": "query" } ] }, @@ -28442,7 +29526,7 @@ "tags": [ "tablesDB" ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "responses": { "201": { "description": "Row", @@ -28455,7 +29539,7 @@ "x-appwrite": { "method": "upsertRow", "group": "rows", - "weight": 423, + "weight": 429, "cookies": false, "type": "", "demo": "tablesdb\/upsert-row.md", @@ -28486,7 +29570,8 @@ "tableId", "rowId", "data", - "permissions" + "permissions", + "transactionId" ], "required": [ "databaseId", @@ -28499,7 +29584,7 @@ "model": "#\/definitions\/row" } ], - "description": "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\/server\/tablesdb#tablesDBCreateTable) API or directly from your database console.", + "description": "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.", "demo": "tablesdb\/upsert-row.md" } ], @@ -28561,6 +29646,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28592,7 +29683,7 @@ "x-appwrite": { "method": "updateRow", "group": "rows", - "weight": 421, + "weight": 427, "cookies": false, "type": "", "demo": "tablesdb\/update-row.md", @@ -28667,6 +29758,12 @@ "items": { "type": "string" } + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28693,7 +29790,7 @@ "x-appwrite": { "method": "deleteRow", "group": "rows", - "weight": 425, + "weight": 431, "cookies": false, "type": "", "demo": "tablesdb\/delete-row.md", @@ -28734,7 +29831,7 @@ }, { "name": "tableId", - "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/server\/tablesdb#tablesDBCreate).", + "description": "Table ID. You can create a new table using the Database service [server integration](https:\/\/appwrite.io\/docs\/references\/cloud\/server-dart\/tablesDB#createTable).", "required": true, "type": "string", "x-example": "", @@ -28747,6 +29844,21 @@ "type": "string", "x-example": "", "in": "path" + }, + { + "name": "payload", + "in": "body", + "schema": { + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" + } + } + } } ] } @@ -28777,7 +29889,7 @@ "x-appwrite": { "method": "decrementRowColumn", "group": "rows", - "weight": 430, + "weight": 436, "cookies": false, "type": "", "demo": "tablesdb\/decrement-row-column.md", @@ -28857,6 +29969,12 @@ "description": "Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -28890,7 +30008,7 @@ "x-appwrite": { "method": "incrementRowColumn", "group": "rows", - "weight": 429, + "weight": 435, "cookies": false, "type": "", "demo": "tablesdb\/increment-row-column.md", @@ -28970,6 +30088,12 @@ "description": "Maximum value for the column. If the current value is greater than this value, an error will be thrown.", "default": null, "x-example": null + }, + "transactionId": { + "type": "string", + "description": "Transaction ID for staging the operation.", + "default": null, + "x-example": "" } } } @@ -30036,7 +31160,7 @@ "x-appwrite": { "method": "list", "group": "files", - "weight": 507, + "weight": 519, "cookies": false, "type": "", "demo": "tokens\/list.md", @@ -30117,7 +31241,7 @@ "x-appwrite": { "method": "createFileToken", "group": "files", - "weight": 505, + "weight": 517, "cookies": false, "type": "", "demo": "tokens\/create-file-token.md", @@ -30202,7 +31326,7 @@ "x-appwrite": { "method": "get", "group": "tokens", - "weight": 506, + "weight": 518, "cookies": false, "type": "", "demo": "tokens\/get.md", @@ -30263,7 +31387,7 @@ "x-appwrite": { "method": "update", "group": "tokens", - "weight": 508, + "weight": 520, "cookies": false, "type": "", "demo": "tokens\/update.md", @@ -30335,7 +31459,7 @@ "x-appwrite": { "method": "delete", "group": "tokens", - "weight": 509, + "weight": 521, "cookies": false, "type": "", "demo": "tokens\/delete.md", @@ -35059,6 +36183,35 @@ "targets": "" } }, + "transactionList": { + "description": "Transaction List", + "type": "object", + "properties": { + "total": { + "type": "integer", + "description": "Total number of transactions that matched your query.", + "x-example": 5, + "format": "int32" + }, + "transactions": { + "type": "array", + "description": "List of transactions.", + "items": { + "type": "object", + "$ref": "#\/definitions\/transaction" + }, + "x-example": "" + } + }, + "required": [ + "total", + "transactions" + ], + "example": { + "total": 5, + "transactions": "" + } + }, "specificationList": { "description": "Specifications List", "type": "object", @@ -35120,7 +36273,11 @@ "type": { "type": "string", "description": "Database type.", - "x-example": "legacy" + "x-example": "legacy", + "enum": [ + "legacy", + "tablesdb" + ] } }, "required": [ @@ -35366,7 +36523,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35461,7 +36619,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35558,7 +36717,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35655,7 +36815,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35735,7 +36896,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35822,7 +36984,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -35919,7 +37082,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36006,7 +37170,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36093,7 +37258,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36180,7 +37346,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36295,7 +37462,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36381,7 +37549,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36479,7 +37648,8 @@ "deleting", "stuck", "failed" - ] + ], + "x-enum-name": "AttributeStatus" }, "error": { "type": "string", @@ -36796,7 +37966,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36884,7 +38062,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -36974,7 +38160,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37064,7 +38258,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37137,7 +38339,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37217,7 +38427,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37307,7 +38525,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37387,7 +38613,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37467,7 +38701,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37547,7 +38789,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37655,7 +38905,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37734,7 +38992,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -37825,7 +39091,15 @@ "status": { "type": "string", "description": "Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`", - "x-example": "available" + "x-example": "available", + "enum": [ + "available", + "processing", + "deleting", + "stuck", + "failed" + ], + "x-enum-name": "ColumnStatus" }, "error": { "type": "string", @@ -41021,7 +42295,8 @@ "enum": [ "pass", "fail" - ] + ], + "x-enum-name": "HealthCheckStatus" } }, "required": [ @@ -41488,7 +42763,14 @@ "status": { "type": "string", "description": "Status of delivery.", - "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed." + "x-example": "Message status can be one of the following: draft, processing, scheduled, sent, or failed.", + "enum": [ + "draft", + "processing", + "scheduled", + "sent", + "failed" + ] } }, "required": [ @@ -41602,6 +42884,59 @@ "subscribe": "users" } }, + "transaction": { + "description": "Transaction", + "type": "object", + "properties": { + "$id": { + "type": "string", + "description": "Transaction ID.", + "x-example": "259125845563242502" + }, + "$createdAt": { + "type": "string", + "description": "Transaction creation time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "$updatedAt": { + "type": "string", + "description": "Transaction update date in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + }, + "status": { + "type": "string", + "description": "Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.", + "x-example": "pending" + }, + "operations": { + "type": "integer", + "description": "Number of operations in the transaction.", + "x-example": 5, + "format": "int32" + }, + "expiresAt": { + "type": "string", + "description": "Expiration time in ISO 8601 format.", + "x-example": "2020-10-15T06:38:00.000+00:00" + } + }, + "required": [ + "$id", + "$createdAt", + "$updatedAt", + "status", + "operations", + "expiresAt" + ], + "example": { + "$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" + } + }, "subscriber": { "description": "Subscriber", "type": "object", diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 8aaa5283c4..5563fc6a59 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -58,6 +58,7 @@ use Utopia\Database\Validator\Query\Limit; use Utopia\Database\Validator\Query\Offset; use Utopia\Database\Validator\UID; use Utopia\Locale\Locale; +use Utopia\Storage\Validator\FileName; use Utopia\System\System; use Utopia\Validator\ArrayList; use Utopia\Validator\Assoc; @@ -165,7 +166,8 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, Doc ->setVariables($emailVariables) ->setRecipient($email) ->trigger(); -}; +} +; $createSession = function (string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $queueForEvents, Mail $queueForMails) { @@ -838,7 +840,7 @@ App::patch('/v1/account/sessions/:sessionId') $session ->setAttribute('providerAccessToken', $oauth2->getAccessToken('')) ->setAttribute('providerRefreshToken', $oauth2->getRefreshToken('')) - ->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$oauth2->getAccessTokenExpiry(''))); + ->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int) $oauth2->getAccessTokenExpiry(''))); } // Save changes @@ -982,9 +984,11 @@ App::post('/v1/account/sessions/email') ; if ($project->getAttribute('auths', [])['sessionAlerts'] ?? false) { - if ($dbForProject->count('sessions', [ - Query::equal('userId', [$user->getId()]), - ]) !== 1) { + if ( + $dbForProject->count('sessions', [ + Query::equal('userId', [$user->getId()]), + ]) !== 1 + ) { sendSessionAlert($locale, $user, $project, $session, $queueForMails); } } @@ -1098,7 +1102,7 @@ App::post('/v1/account/sessions/anonymous') Authorization::setRole(Role::user($user->getId())->toString()); - $session = $dbForProject->createDocument('sessions', $session-> setAttribute('$permissions', [ + $session = $dbForProject->createDocument('sessions', $session->setAttribute('$permissions', [ Permission::read(Role::user($user->getId())), Permission::update(Role::user($user->getId())), Permission::delete(Role::user($user->getId())), @@ -1659,13 +1663,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'providerEmail' => $email, 'providerAccessToken' => $accessToken, 'providerRefreshToken' => $refreshToken, - 'providerAccessTokenExpiry' => DateTime::addSeconds(new \DateTime(), (int)$accessTokenExpiry), + 'providerAccessTokenExpiry' => DateTime::addSeconds(new \DateTime(), (int) $accessTokenExpiry), ])); } else { $identity ->setAttribute('providerAccessToken', $accessToken) ->setAttribute('providerRefreshToken', $refreshToken) - ->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$accessTokenExpiry)); + ->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int) $accessTokenExpiry)); $dbForProject->updateDocument('identities', $identity->getId(), $identity); } @@ -1735,7 +1739,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect') 'providerUid' => $oauth2ID, 'providerAccessToken' => $accessToken, 'providerRefreshToken' => $refreshToken, - 'providerAccessTokenExpiry' => DateTime::addSeconds(new \DateTime(), (int)$accessTokenExpiry), + 'providerAccessTokenExpiry' => DateTime::addSeconds(new \DateTime(), (int) $accessTokenExpiry), 'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak 'userAgent' => $request->getUserAgent('UNKNOWN'), 'ip' => $request->getIP(), @@ -2293,7 +2297,17 @@ App::post('/v1/account/tokens/email') $subject = $locale->getText("emails.otpSession.subject"); $preview = $locale->getText("emails.otpSession.preview"); + $heading = $locale->getText("emails.otpSession.heading"); + $customTemplate = $project->getAttribute('templates', [])['email.otpSession-' . $locale->default] ?? []; + $smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base'); + + $validator = new FileName(); + if (!$validator->isValid($smtpBaseTemplate)) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid template path'); + } + + $bodyTemplate = __DIR__ . '/../../config/locale/templates/' . $smtpBaseTemplate . '.tpl'; $detector = new Detector($request->getUserAgent('UNKNOWN')); $agentOs = $detector->getOS(); @@ -2363,6 +2377,7 @@ App::post('/v1/account/tokens/email') } $emailVariables = [ + 'heading' => $heading, 'direction' => $locale->getText('settings.direction'), // {{user}}, {{project}} and {{otp}} are required in the templates 'user' => $user->getAttribute('name'), @@ -2376,10 +2391,23 @@ App::post('/v1/account/tokens/email') 'team' => '', ]; + if ($smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE) { + $emailVariables = array_merge($emailVariables, [ + 'accentColor' => APP_EMAIL_ACCENT_COLOR, + 'logoUrl' => APP_EMAIL_LOGO_URL, + 'twitterUrl' => APP_SOCIAL_TWITTER, + 'discordUrl' => APP_SOCIAL_DISCORD, + 'githubUrl' => APP_SOCIAL_GITHUB_APPWRITE, + 'termsUrl' => APP_EMAIL_TERMS_URL, + 'privacyUrl' => APP_EMAIL_PRIVACY_URL, + ]); + } + $queueForMails ->setSubject($subject) ->setPreview($preview) ->setBody($body) + ->setBodyTemplate($bodyTemplate) ->setVariables($emailVariables) ->setRecipient($email) ->trigger(); @@ -2732,10 +2760,12 @@ App::post('/v1/account/jwts') $response ->setStatusCode(Response::STATUS_CODE_CREATED) - ->dynamic(new Document(['jwt' => $jwt->encode([ - 'userId' => $user->getId(), - 'sessionId' => $current->getId(), - ])]), Response::MODEL_JWT); + ->dynamic(new Document([ + 'jwt' => $jwt->encode([ + 'userId' => $user->getId(), + 'sessionId' => $current->getId(), + ]) + ]), Response::MODEL_JWT); }); App::get('/v1/account/prefs') @@ -3480,12 +3510,12 @@ App::put('/v1/account/recovery') $hooks->trigger('passwordValidator', [$dbForProject, $project, $password, &$user, true]); $profile = $dbForProject->updateDocument('users', $profile->getId(), $profile - ->setAttribute('password', $newPassword) - ->setAttribute('passwordHistory', $history) - ->setAttribute('passwordUpdate', DateTime::now()) - ->setAttribute('hash', Auth::DEFAULT_ALGO) - ->setAttribute('hashOptions', Auth::DEFAULT_ALGO_OPTIONS) - ->setAttribute('emailVerification', true)); + ->setAttribute('password', $newPassword) + ->setAttribute('passwordHistory', $history) + ->setAttribute('passwordUpdate', DateTime::now()) + ->setAttribute('hash', Auth::DEFAULT_ALGO) + ->setAttribute('hashOptions', Auth::DEFAULT_ALGO_OPTIONS) + ->setAttribute('emailVerification', true)); $user->setAttributes($profile->getArrayCopy()); @@ -3506,27 +3536,48 @@ App::put('/v1/account/recovery') $response->dynamic($recoveryDocument, Response::MODEL_TOKEN); }); -App::post('/v1/account/verification') +App::post('/v1/account/verifications/email') + ->alias('/v1/account/verification') ->desc('Create email verification') ->groups(['api', 'account']) ->label('scope', 'account') ->label('event', 'users.[userId].verification.[tokenId].create') ->label('audits.event', 'verification.create') ->label('audits.resource', 'user/{response.userId}') - ->label('sdk', new Method( - namespace: 'account', - group: 'verification', - name: 'createVerification', - description: '/docs/references/account/create-email-verification.md', - auth: [AuthType::SESSION, AuthType::JWT], - responses: [ - new SDKResponse( - code: Response::STATUS_CODE_CREATED, - model: Response::MODEL_TOKEN, - ) - ], - contentType: ContentType::JSON, - )) + ->label('sdk', [ + new Method( + namespace: 'account', + group: 'verification', + name: 'createEmailVerification', + description: '/docs/references/account/create-email-verification.md', + auth: [AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: Response::STATUS_CODE_CREATED, + model: Response::MODEL_TOKEN, + ) + ], + contentType: ContentType::JSON, + ), + new Method( + namespace: 'account', + group: 'verification', + name: 'createVerification', + description: '/docs/references/account/create-email-verification.md', + auth: [AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: Response::STATUS_CODE_CREATED, + model: Response::MODEL_TOKEN, + ) + ], + contentType: ContentType::JSON, + deprecated: new Deprecated( + since: '1.8.0', + replaceWith: 'account.createEmailVerification' + ), + ) + ]) ->label('abuse-limit', 10) ->label('abuse-key', 'url:{url},userId:{userId}') ->param('url', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new 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.', false, ['platforms', 'devKey']) // TODO add built-in confirm page @@ -3544,6 +3595,10 @@ App::post('/v1/account/verification') throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled'); } + if (empty($user->getAttribute('email'))) { + throw new Exception(Exception::USER_EMAIL_NOT_FOUND); + } + $url = htmlentities($url); if ($user->getAttribute('emailVerification')) { throw new Exception(Exception::USER_EMAIL_ALREADY_VERIFIED); @@ -3582,7 +3637,17 @@ App::post('/v1/account/verification') $body = $locale->getText("emails.verification.body"); $preview = $locale->getText("emails.verification.preview"); $subject = $locale->getText("emails.verification.subject"); + $heading = $locale->getText("emails.verification.heading"); + $customTemplate = $project->getAttribute('templates', [])['email.verification-' . $locale->default] ?? []; + $smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base'); + + $validator = new FileName(); + if (!$validator->isValid($smtpBaseTemplate)) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid template path'); + } + + $bodyTemplate = __DIR__ . '/../../config/locale/templates/' . $smtpBaseTemplate . '.tpl'; $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl'); $message @@ -3642,6 +3707,7 @@ App::post('/v1/account/verification') } $emailVariables = [ + 'heading' => $heading, 'direction' => $locale->getText('settings.direction'), // {{user}}, {{redirect}} and {{project}} are required in default and custom templates 'user' => $user->getAttribute('name'), @@ -3651,10 +3717,23 @@ App::post('/v1/account/verification') 'team' => '', ]; + if ($smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE) { + $emailVariables = array_merge($emailVariables, [ + 'accentColor' => APP_EMAIL_ACCENT_COLOR, + 'logoUrl' => APP_EMAIL_LOGO_URL, + 'twitterUrl' => APP_SOCIAL_TWITTER, + 'discordUrl' => APP_SOCIAL_DISCORD, + 'githubUrl' => APP_SOCIAL_GITHUB_APPWRITE, + 'termsUrl' => APP_EMAIL_TERMS_URL, + 'privacyUrl' => APP_EMAIL_PRIVACY_URL, + ]); + } + $queueForMails ->setSubject($subject) ->setPreview($preview) ->setBody($body) + ->setBodyTemplate($bodyTemplate) ->setVariables($emailVariables) ->setRecipient($user->getAttribute('email')) ->setName($user->getAttribute('name') ?? '') @@ -3672,27 +3751,48 @@ App::post('/v1/account/verification') ->dynamic($verification, Response::MODEL_TOKEN); }); -App::put('/v1/account/verification') +App::put('/v1/account/verifications/email') + ->alias('/v1/account/verification') ->desc('Update email verification (confirmation)') ->groups(['api', 'account']) ->label('scope', 'public') ->label('event', 'users.[userId].verification.[tokenId].update') ->label('audits.event', 'verification.update') ->label('audits.resource', 'user/{response.userId}') - ->label('sdk', new Method( - namespace: 'account', - group: 'verification', - name: 'updateVerification', - description: '/docs/references/account/update-email-verification.md', - auth: [AuthType::SESSION, AuthType::JWT], - responses: [ - new SDKResponse( - code: Response::STATUS_CODE_OK, - model: Response::MODEL_TOKEN, - ) - ], - contentType: ContentType::JSON - )) + ->label('sdk', [ + new Method( + namespace: 'account', + group: 'verification', + name: 'updateEmailVerification', + description: '/docs/references/account/update-email-verification.md', + auth: [AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: Response::STATUS_CODE_OK, + model: Response::MODEL_TOKEN, + ) + ], + contentType: ContentType::JSON + ), + new Method( + namespace: 'account', + group: 'verification', + name: 'updateVerification', + description: '/docs/references/account/update-email-verification.md', + auth: [AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: Response::STATUS_CODE_OK, + model: Response::MODEL_TOKEN, + ) + ], + contentType: ContentType::JSON, + deprecated: new Deprecated( + since: '1.8.0', + replaceWith: 'account.updateEmailVerification' + ), + ) + ]) ->label('abuse-limit', 10) ->label('abuse-key', 'url:{url},userId:{param-userId}') ->param('userId', '', new UID(), 'User ID.') @@ -3739,7 +3839,8 @@ App::put('/v1/account/verification') $response->dynamic($verification, Response::MODEL_TOKEN); }); -App::post('/v1/account/verification/phone') +App::post('/v1/account/verifications/phone') + ->alias('/v1/account/verification/phone') ->desc('Create phone verification') ->groups(['api', 'account', 'auth']) ->label('scope', 'account') @@ -3888,7 +3989,8 @@ App::post('/v1/account/verification/phone') ->dynamic($verification, Response::MODEL_TOKEN); }); -App::put('/v1/account/verification/phone') +App::put('/v1/account/verifications/phone') + ->alias('/v1/account/verification/phone') ->desc('Update phone verification (confirmation)') ->groups(['api', 'account']) ->label('scope', 'public') @@ -4660,7 +4762,17 @@ App::post('/v1/account/mfa/challenge') $subject = $locale->getText("emails.mfaChallenge.subject"); $preview = $locale->getText("emails.mfaChallenge.preview"); + $heading = $locale->getText("emails.mfaChallenge.heading"); + $customTemplate = $project->getAttribute('templates', [])['email.mfaChallenge-' . $locale->default] ?? []; + $smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base'); + + $validator = new FileName(); + if (!$validator->isValid($smtpBaseTemplate)) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid template path'); + } + + $bodyTemplate = __DIR__ . '/../../config/locale/templates/' . $smtpBaseTemplate . '.tpl'; $detector = new Detector($request->getUserAgent('UNKNOWN')); $agentOs = $detector->getOS(); @@ -4724,6 +4836,7 @@ App::post('/v1/account/mfa/challenge') } $emailVariables = [ + 'heading' => $heading, 'direction' => $locale->getText('settings.direction'), // {{user}}, {{project}} and {{otp}} are required in the templates 'user' => $user->getAttribute('name'), @@ -4731,13 +4844,26 @@ App::post('/v1/account/mfa/challenge') 'otp' => $code, 'agentDevice' => $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN', 'agentClient' => $agentClient['clientName'] ?? 'UNKNOWN', - 'agentOs' => $agentOs['osName'] ?? 'UNKNOWN' + 'agentOs' => $agentOs['osName'] ?? 'UNKNOWN', ]; + if ($smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE) { + $emailVariables = array_merge($emailVariables, [ + 'accentColor' => APP_EMAIL_ACCENT_COLOR, + 'logoUrl' => APP_EMAIL_LOGO_URL, + 'twitterUrl' => APP_SOCIAL_TWITTER, + 'discordUrl' => APP_SOCIAL_DISCORD, + 'githubUrl' => APP_SOCIAL_GITHUB_APPWRITE, + 'termsUrl' => APP_EMAIL_TERMS_URL, + 'privacyUrl' => APP_EMAIL_PRIVACY_URL, + ]); + } + $queueForMails ->setSubject($subject) ->setPreview($preview) ->setBody($body) + ->setBodyTemplate($bodyTemplate) ->setVariables($emailVariables) ->setRecipient($user->getAttribute('email')) ->trigger(); @@ -4860,8 +4986,8 @@ App::put('/v1/account/mfa/challenge') $dbForProject->updateDocument('sessions', $session->getId(), $session); $queueForEvents - ->setParam('userId', $user->getId()) - ->setParam('sessionId', $session->getId()); + ->setParam('userId', $user->getId()) + ->setParam('sessionId', $session->getId()); $response->dynamic($session, Response::MODEL_SESSION); }); @@ -4924,7 +5050,7 @@ App::post('/v1/account/targets/push') ], 'providerId' => !empty($providerId) ? $providerId : null, 'providerInternalId' => !empty($providerId) ? $provider->getSequence() : null, - 'providerType' => MESSAGE_TYPE_PUSH, + 'providerType' => MESSAGE_TYPE_PUSH, 'userId' => $user->getId(), 'userInternalId' => $user->getSequence(), 'sessionId' => $session->getId(), @@ -5099,8 +5225,8 @@ App::get('/v1/account/identities') $queries[] = Query::equal('userInternalId', [$user->getSequence()]); /** - * Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries - */ + * Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries + */ $cursor = \array_filter($queries, function ($query) { return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]); }); diff --git a/app/controllers/api/console.php b/app/controllers/api/console.php index b0619df3b3..ec68f1050c 100644 --- a/app/controllers/api/console.php +++ b/app/controllers/api/console.php @@ -74,6 +74,7 @@ App::get('/v1/console/variables') // Combine CAA domain with most common flags and tag (no parameters) '_APP_DOMAIN_TARGET_CAA' => '0 issue "' . System::getEnv('_APP_DOMAIN_TARGET_CAA') . '"', '_APP_STORAGE_LIMIT' => +System::getEnv('_APP_STORAGE_LIMIT'), + '_APP_COMPUTE_BUILD_TIMEOUT' => +System::getEnv('_APP_COMPUTE_BUILD_TIMEOUT'), '_APP_COMPUTE_SIZE_LIMIT' => +System::getEnv('_APP_COMPUTE_SIZE_LIMIT'), '_APP_USAGE_STATS' => System::getEnv('_APP_USAGE_STATS'), '_APP_VCS_ENABLED' => $isVcsEnabled, diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index d22c5cb2c2..dbc384f3c4 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -3102,7 +3102,7 @@ App::post('/v1/messaging/messages/email') case MessageStatus::SCHEDULED: $schedule = $dbForPlatform->createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => 'message', + 'resourceType' => SCHEDULE_RESOURCE_TYPE_MESSAGE, 'resourceId' => $message->getId(), 'resourceInternalId' => $message->getSequence(), 'resourceUpdatedAt' => DateTime::now(), @@ -3244,7 +3244,7 @@ App::post('/v1/messaging/messages/sms') case MessageStatus::SCHEDULED: $schedule = $dbForPlatform->createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => 'message', + 'resourceType' => SCHEDULE_RESOURCE_TYPE_MESSAGE, 'resourceId' => $message->getId(), 'resourceInternalId' => $message->getSequence(), 'resourceUpdatedAt' => DateTime::now(), @@ -3462,7 +3462,7 @@ App::post('/v1/messaging/messages/push') case MessageStatus::SCHEDULED: $schedule = $dbForPlatform->createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => 'message', + 'resourceType' => SCHEDULE_RESOURCE_TYPE_MESSAGE, 'resourceId' => $message->getId(), 'resourceInternalId' => $message->getSequence(), 'resourceUpdatedAt' => DateTime::now(), @@ -3863,7 +3863,7 @@ App::patch('/v1/messaging/messages/email/:messageId') if (\is_null($currentScheduledAt) && !\is_null($scheduledAt)) { $schedule = $dbForPlatform->createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => 'message', + 'resourceType' => SCHEDULE_RESOURCE_TYPE_MESSAGE, 'resourceId' => $message->getId(), 'resourceInternalId' => $message->getSequence(), 'resourceUpdatedAt' => DateTime::now(), @@ -4084,7 +4084,7 @@ App::patch('/v1/messaging/messages/sms/:messageId') if (\is_null($currentScheduledAt) && !\is_null($scheduledAt)) { $schedule = $dbForPlatform->createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => 'message', + 'resourceType' => SCHEDULE_RESOURCE_TYPE_MESSAGE, 'resourceId' => $message->getId(), 'resourceInternalId' => $message->getSequence(), 'resourceUpdatedAt' => DateTime::now(), @@ -4258,7 +4258,7 @@ App::patch('/v1/messaging/messages/push/:messageId') if (\is_null($currentScheduledAt) && !\is_null($scheduledAt)) { $schedule = $dbForPlatform->createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => 'message', + 'resourceType' => SCHEDULE_RESOURCE_TYPE_MESSAGE, 'resourceId' => $message->getId(), 'resourceInternalId' => $message->getSequence(), 'resourceUpdatedAt' => DateTime::now(), diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index ea3a00dcb6..80d407322e 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -1756,7 +1756,28 @@ App::post('/v1/projects/:projectId/platforms') ] )) ->param('projectId', '', new UID(), 'Project unique ID.') - ->param('type', null, new WhiteList([Platform::TYPE_WEB, Platform::TYPE_FLUTTER_WEB, Platform::TYPE_FLUTTER_IOS, Platform::TYPE_FLUTTER_ANDROID, Platform::TYPE_FLUTTER_LINUX, Platform::TYPE_FLUTTER_MACOS, Platform::TYPE_FLUTTER_WINDOWS, Platform::TYPE_APPLE_IOS, Platform::TYPE_APPLE_MACOS, Platform::TYPE_APPLE_WATCHOS, Platform::TYPE_APPLE_TVOS, Platform::TYPE_ANDROID, Platform::TYPE_UNITY, Platform::TYPE_REACT_NATIVE_IOS, Platform::TYPE_REACT_NATIVE_ANDROID], true), 'Platform type.') + ->param( + 'type', + null, + new WhiteList([ + Platform::TYPE_WEB, + Platform::TYPE_FLUTTER_WEB, + Platform::TYPE_FLUTTER_IOS, + Platform::TYPE_FLUTTER_ANDROID, + Platform::TYPE_FLUTTER_LINUX, + Platform::TYPE_FLUTTER_MACOS, + Platform::TYPE_FLUTTER_WINDOWS, + Platform::TYPE_APPLE_IOS, + Platform::TYPE_APPLE_MACOS, + Platform::TYPE_APPLE_WATCHOS, + Platform::TYPE_APPLE_TVOS, + Platform::TYPE_ANDROID, + Platform::TYPE_UNITY, + Platform::TYPE_REACT_NATIVE_IOS, + Platform::TYPE_REACT_NATIVE_ANDROID, + ], true), + 'Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.' + ) ->param('name', null, new Text(128), 'Platform name. Max length: 128 chars.') ->param('key', '', new Text(256), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.', true) ->param('store', '', new Text(256), 'App store or Google Play store ID. Max length: 256 chars.', true) diff --git a/app/controllers/general.php b/app/controllers/general.php index 8abca96742..07de95a38f 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -1253,7 +1253,7 @@ App::error() } /** - * If its not a publishable error, track usage stats. Publishable errors are >= 500 or those explicitly marked as publish=true in errors.php + * If not a publishable error, track usage stats. Publishable errors are >= 500 or those explicitly marked as publish=true in errors.php */ if (!$publish && $project->getId() !== 'console') { if (!Auth::isPrivilegedUser(Authorization::getRoles())) { @@ -1355,6 +1355,7 @@ App::error() case 409: // Error allowed publicly case 412: // Error allowed publicly case 416: // Error allowed publicly + case 422: // Error allowed publicly case 429: // Error allowed publicly case 451: // Error allowed publicly case 501: // Error allowed publicly diff --git a/app/init/constants.php b/app/init/constants.php index 6d723e9182..db46303ca8 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -31,6 +31,7 @@ const APP_LIMIT_WRITE_RATE_DEFAULT = 60; // Default maximum write rate per rate const APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT = 60; // Default maximum write rate period in seconds const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return in list API calls const APP_LIMIT_DATABASE_BATCH = 100; // Default maximum batch size for database operations +const APP_LIMIT_DATABASE_TRANSACTION = 100; // Default maximum operations per transaction const APP_KEY_ACCESS = 24 * 60 * 60; // 24 hours const APP_USER_ACCESS = 24 * 60 * 60; // 24 hours const APP_PROJECT_ACCESS = 24 * 60 * 60; // 24 hours @@ -55,6 +56,10 @@ const APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER = 300 * 1000; // 5 minutes const APP_DATABASE_TIMEOUT_MILLISECONDS_TASK = 300 * 1000; // 5 minutes const APP_DATABASE_QUERY_MAX_VALUES = 500; const APP_DATABASE_ENCRYPT_SIZE_MIN = 150; +const APP_DATABASE_TXN_TTL_MIN = 60; // 1 minute +const APP_DATABASE_TXN_TTL_MAX = 3600; // 1 hour +const APP_DATABASE_TXN_TTL_DEFAULT = 300; // 5 minutes +const APP_DATABASE_TXN_MAX_OPERATIONS = 100; // Maximum operations per transaction const APP_STORAGE_UPLOADS = '/storage/uploads'; const APP_STORAGE_SITES = '/storage/sites'; const APP_STORAGE_FUNCTIONS = '/storage/functions'; @@ -86,6 +91,7 @@ const APP_PLATFORM_CONSOLE = 'console'; const APP_VCS_GITHUB_USERNAME = 'Appwrite'; const APP_VCS_GITHUB_EMAIL = 'team@appwrite.io'; const APP_VCS_GITHUB_URL = 'https://github.com/TeamAppwrite'; +const APP_BRANDED_EMAIL_BASE_TEMPLATE = 'email-base-styled'; // Database Reconnect const DATABASE_RECONNECT_SLEEP = 2; @@ -105,8 +111,11 @@ const BUILD_TYPE_RETRY = 'retry'; // Deletion Types const DELETE_TYPE_DATABASES = 'databases'; + const DELETE_TYPE_DOCUMENT = 'document'; const DELETE_TYPE_COLLECTIONS = 'collections'; +const DELETE_TYPE_TRANSACTION = 'transaction'; +const DELETE_TYPE_EXPIRED_TRANSACTIONS = 'expired_transactions'; const DELETE_TYPE_PROJECTS = 'projects'; const DELETE_TYPE_SITES = 'sites'; const DELETE_TYPE_FUNCTIONS = 'functions'; @@ -263,7 +272,6 @@ const METRIC_SITES_ID_INBOUND = 'sites.{siteInternalId}.inbound'; const METRIC_SITES_ID_OUTBOUND = 'sites.{siteInternalId}.outbound'; // Resource types - const RESOURCE_TYPE_PROJECTS = 'projects'; const RESOURCE_TYPE_FUNCTIONS = 'functions'; const RESOURCE_TYPE_SITES = 'sites'; @@ -273,10 +281,15 @@ const RESOURCE_TYPE_PROVIDERS = 'providers'; const RESOURCE_TYPE_TOPICS = 'topics'; const RESOURCE_TYPE_SUBSCRIBERS = 'subscribers'; const RESOURCE_TYPE_MESSAGES = 'messages'; +const RESOURCE_TYPE_EXECUTIONS = 'executions'; // Resource types for Tokens - const TOKENS_RESOURCE_TYPE_FILES = 'files'; const TOKENS_RESOURCE_TYPE_SITES = 'sites'; const TOKENS_RESOURCE_TYPE_FUNCTIONS = 'functions'; const TOKENS_RESOURCE_TYPE_DATABASES = 'databases'; + +// Resource types for Schedules +const SCHEDULE_RESOURCE_TYPE_EXECUTION = 'execution'; +const SCHEDULE_RESOURCE_TYPE_FUNCTION = 'function'; +const SCHEDULE_RESOURCE_TYPE_MESSAGE = 'message'; diff --git a/app/init/resources.php b/app/init/resources.php index e4e8fbef5e..f91d18f698 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -4,6 +4,7 @@ use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; use Appwrite\Auth\Auth; use Appwrite\Auth\Key; +use Appwrite\Databases\TransactionState; use Appwrite\Event\Audit; use Appwrite\Event\Build; use Appwrite\Event\Certificate; @@ -151,7 +152,7 @@ App::setResource('queueForMigrations', function (Publisher $publisher) { App::setResource('queueForStatsResources', function (Publisher $publisher) { return new StatsResources($publisher); }, ['publisher']); -App::setResource('platforms', function (Request $request, Document $console, Document $project) { +App::setResource('platforms', function (Request $request, Document $console, Document $project, Database $dbForPlatform) { $console->setAttribute('platforms', [ // Always allow current host '$collection' => ID::custom('platforms'), 'name' => 'Current Host', @@ -190,11 +191,40 @@ App::setResource('platforms', function (Request $request, Document $console, Doc ], Document::SET_TYPE_APPEND); } + $origin = \parse_url($request->getOrigin(), PHP_URL_HOST); + + if (empty($origin)) { + $origin = \parse_url($request->getReferer(), PHP_URL_HOST); + } + + // Safe if rule with same project ID exists + if (!empty($origin)) { + if (System::getEnv('_APP_RULES_FORMAT') === 'md5') { + $rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($origin ?? ''))); + } else { + $rule = Authorization::skip( + fn () => $dbForPlatform->find('rules', [ + Query::equal('domain', [$origin]), + Query::limit(1) + ]) + )[0] ?? new Document(); + } + + if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getSequence()) { + $project->setAttribute('platforms', [ + '$collection' => ID::custom('platforms'), + 'type' => Platform::TYPE_WEB, + 'name' => $origin, + 'hostname' => $origin, + ], Document::SET_TYPE_APPEND); + } + } + return [ ...$console->getAttribute('platforms', []), ...$project->getAttribute('platforms', []), ]; -}, ['request', 'console', 'project']); +}, ['request', 'console', 'project', 'dbForPlatform']); App::setResource('user', function ($mode, $project, $console, $request, $response, $dbForProject, $dbForPlatform) { /** @var Appwrite\Utopia\Request $request */ @@ -375,7 +405,7 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant((int)$project->getSequence()) + ->setTenant((int) $project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -428,7 +458,7 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant((int)$project->getSequence()) + ->setTenant((int) $project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -458,7 +488,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) { return function (?Document $project = null) use ($pools, $cache, &$database) { if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant((int)$project->getSequence()); + $database->setTenant((int) $project->getSequence()); return $database; } @@ -473,7 +503,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) { // set tenant if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant((int)$project->getSequence()); + $database->setTenant((int) $project->getSequence()); } return $database; @@ -501,7 +531,7 @@ App::setResource('redis', function () { $pass = System::getEnv('_APP_REDIS_PASS', ''); $redis = new \Redis(); - @$redis->pconnect($host, (int)$port); + @$redis->pconnect($host, (int) $port); if ($pass) { $redis->auth($pass); } @@ -714,7 +744,7 @@ App::setResource('schema', function ($utopia, $dbForProject) { // NOTE: `params` and `urls` are not used internally in the `Schema::build` function below! $params = [ 'list' => function (string $databaseId, string $collectionId, array $args) { - return [ 'queries' => $args['queries']]; + return ['queries' => $args['queries']]; }, 'create' => function (string $databaseId, string $collectionId, array $args) { $id = $args['id'] ?? 'unique()'; @@ -963,7 +993,7 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request) { } $accessedAt = $token->getAttribute('accessedAt', 0); - if (empty($accessedAt) || DatabaseDateTime::formatTz(DatabaseDateTime::addSeconds(new \DateTime(), - APP_RESOURCE_TOKEN_ACCESS)) > $accessedAt) { + if (empty($accessedAt) || DatabaseDateTime::formatTz(DatabaseDateTime::addSeconds(new \DateTime(), -APP_RESOURCE_TOKEN_ACCESS)) > $accessedAt) { $token->setAttribute('accessedAt', DatabaseDateTime::now()); Authorization::skip(fn () => $dbForProject->updateDocument('resourceTokens', $token->getId(), $token)); } @@ -1005,24 +1035,6 @@ App::setResource('httpReferrerSafe', function (Request $request, string $httpRef return $referrer; } - // Safe if rule with same project ID exists - if (!empty($origin)) { - if (System::getEnv('_APP_RULES_FORMAT') === 'md5') { - $rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($origin ?? ''))); - } else { - $rule = Authorization::skip( - fn () => $dbForPlatform->find('rules', [ - Query::equal('domain', [$origin]), - Query::limit(1) - ]) - )[0] ?? new Document(); - } - - if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getSequence()) { - return $referrer; - } - } - // Unsafe; Localhost is always safe for ease of local development $origin = 'localhost'; $protocol = \parse_url($request->getOrigin($httpReferrer), PHP_URL_SCHEME); @@ -1030,3 +1042,7 @@ App::setResource('httpReferrerSafe', function (Request $request, string $httpRef $referrer = (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $origin . (!empty($port) ? ':' . $port : ''); return $referrer; }, ['request', 'httpReferrer', 'platforms', 'dbForPlatform', 'project', 'utopia']); + +App::setResource('transactionState', function (Database $dbForProject) { + return new TransactionState($dbForProject); +}, ['dbForProject']); diff --git a/app/realtime.php b/app/realtime.php index bb0d4da78c..e18ab8e10d 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -604,11 +604,18 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $code = 500; } + $message = $th->getMessage(); + + // sanitize 0 && 5xx errors + if (($code === 0 || $code >= 500) && !App::isDevelopment()) { + $message = 'Error: Server Error'; + } + $response = [ 'type' => 'error', 'data' => [ 'code' => $code, - 'message' => $th->getMessage() + 'message' => $message ] ]; @@ -705,11 +712,23 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Message type is not valid.'); } } catch (Throwable $th) { + $code = $th->getCode(); + if (!is_int($code)) { + $code = 500; + } + + $message = $th->getMessage(); + + // sanitize 0 && 5xx errors + if (($code === 0 || $code >= 500) && !App::isDevelopment()) { + $message = 'Error: Server Error'; + } + $response = [ 'type' => 'error', 'data' => [ - 'code' => $th->getCode(), - 'message' => $th->getMessage() + 'code' => $code, + 'message' => $message ] ]; diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index ed4de38d2b..4c98b20b18 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -179,7 +179,7 @@ $image = $this->getParam('image', ''); appwrite-console: <<: *x-logging container_name: appwrite-console - image: /console:7.0.2 + image: /console:7.4.7 restart: unless-stopped networks: - appwrite diff --git a/composer.json b/composer.json index 1dc7288441..de5f296cd3 100644 --- a/composer.json +++ b/composer.json @@ -52,9 +52,9 @@ "utopia-php/cache": "0.13.*", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", - "utopia-php/database": "1.*", + "utopia-php/database": "3.*", "utopia-php/detector": "0.1.*", - "utopia-php/domains": "0.8.*", + "utopia-php/domains": "0.9.*", "utopia-php/dns": "0.3.*", "utopia-php/dsn": "0.2.1", "utopia-php/framework": "0.33.*", @@ -62,7 +62,7 @@ "utopia-php/image": "0.8.*", "utopia-php/locale": "0.8.*", "utopia-php/logger": "0.6.*", - "utopia-php/messaging": "0.18.*", + "utopia-php/messaging": "0.19.*", "utopia-php/migration": "1.*", "utopia-php/orchestration": "0.9.*", "utopia-php/platform": "0.7.*", diff --git a/composer.lock b/composer.lock index 98089f9ed9..62d92e566f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7553e976312b0423cc31544abb91caec", + "content-hash": "b48bd33d40081c107b826f78981e0a54", "packages": [ { "name": "adhocore/jwt", @@ -756,16 +756,16 @@ }, { "name": "google/protobuf", - "version": "v4.32.1", + "version": "v4.33.0", "source": { "type": "git", "url": "https://github.com/protocolbuffers/protobuf-php.git", - "reference": "c4ed1c1f9bbc1e91766e2cd6c0af749324fe87cb" + "reference": "b50269e23204e5ae859a326ec3d90f09efe3047d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/c4ed1c1f9bbc1e91766e2cd6c0af749324fe87cb", - "reference": "c4ed1c1f9bbc1e91766e2cd6c0af749324fe87cb", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/b50269e23204e5ae859a326ec3d90f09efe3047d", + "reference": "b50269e23204e5ae859a326ec3d90f09efe3047d", "shasum": "" }, "require": { @@ -794,9 +794,9 @@ "proto" ], "support": { - "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.32.1" + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.33.0" }, - "time": "2025-09-14T05:14:52+00:00" + "time": "2025-10-15T20:10:28+00:00" }, { "name": "league/csv", @@ -959,6 +959,83 @@ }, "time": "2025-08-20T17:20:16+00:00" }, + { + "name": "mongodb/mongodb", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/mongodb/mongo-php-library.git", + "reference": "f399d24905dd42f97dfe0af9706129743ef247ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/f399d24905dd42f97dfe0af9706129743ef247ac", + "reference": "f399d24905dd42f97dfe0af9706129743ef247ac", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0", + "ext-mongodb": "^2.1", + "php": "^8.1", + "psr/log": "^1.1.4|^2|^3", + "symfony/polyfill-php85": "^1.32" + }, + "replace": { + "mongodb/builder": "*" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0", + "phpunit/phpunit": "^10.5.35", + "rector/rector": "^1.2", + "squizlabs/php_codesniffer": "^3.7", + "vimeo/psalm": "6.5.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "MongoDB\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Andreas Braun", + "email": "andreas.braun@mongodb.com" + }, + { + "name": "Jeremy Mikola", + "email": "jmikola@gmail.com" + }, + { + "name": "Jérôme Tamarelle", + "email": "jerome.tamarelle@mongodb.com" + } + ], + "description": "MongoDB driver library", + "homepage": "https://jira.mongodb.org/browse/PHPLIB", + "keywords": [ + "database", + "driver", + "mongodb", + "persistence" + ], + "support": { + "issues": "https://github.com/mongodb/mongo-php-library/issues", + "source": "https://github.com/mongodb/mongo-php-library/tree/2.1.1" + }, + "time": "2025-08-13T20:50:05+00:00" + }, { "name": "mustangostang/spyc", "version": "0.6.3", @@ -1159,20 +1236,20 @@ }, { "name": "open-telemetry/api", - "version": "1.5.0", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/api.git", - "reference": "7692075f486c14d8cfd37fba98a08a5667f089e5" + "reference": "610b79ad9d6d97e8368bcb6c4d42394fbb87b522" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/7692075f486c14d8cfd37fba98a08a5667f089e5", - "reference": "7692075f486c14d8cfd37fba98a08a5667f089e5", + "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/610b79ad9d6d97e8368bcb6c4d42394fbb87b522", + "reference": "610b79ad9d6d97e8368bcb6c4d42394fbb87b522", "shasum": "" }, "require": { - "open-telemetry/context": "^1.0", + "open-telemetry/context": "^1.4", "php": "^8.1", "psr/log": "^1.1|^2.0|^3.0", "symfony/polyfill-php82": "^1.26" @@ -1188,7 +1265,7 @@ ] }, "branch-alias": { - "dev-main": "1.4.x-dev" + "dev-main": "1.7.x-dev" } }, "autoload": { @@ -1225,20 +1302,20 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2025-08-07T23:07:38+00:00" + "time": "2025-10-02T23:44:28+00:00" }, { "name": "open-telemetry/context", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/context.git", - "reference": "438f71812242db3f196fb4c717c6f92cbc819be6" + "reference": "d4c4470b541ce72000d18c339cfee633e4c8e0cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/context/zipball/438f71812242db3f196fb4c717c6f92cbc819be6", - "reference": "438f71812242db3f196fb4c717c6f92cbc819be6", + "url": "https://api.github.com/repos/opentelemetry-php/context/zipball/d4c4470b541ce72000d18c339cfee633e4c8e0cf", + "reference": "d4c4470b541ce72000d18c339cfee633e4c8e0cf", "shasum": "" }, "require": { @@ -1284,7 +1361,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2025-08-13T01:12:00+00:00" + "time": "2025-09-19T00:05:49+00:00" }, { "name": "open-telemetry/exporter-otlp", @@ -1415,23 +1492,23 @@ }, { "name": "open-telemetry/sdk", - "version": "1.7.1", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/sdk.git", - "reference": "52690d4b37ae4f091af773eef3c238ed2bc0aa06" + "reference": "8986bcbcbea79cb1ba9e91c1d621541ad63d6b3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/52690d4b37ae4f091af773eef3c238ed2bc0aa06", - "reference": "52690d4b37ae4f091af773eef3c238ed2bc0aa06", + "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/8986bcbcbea79cb1ba9e91c1d621541ad63d6b3e", + "reference": "8986bcbcbea79cb1ba9e91c1d621541ad63d6b3e", "shasum": "" }, "require": { "ext-json": "*", "nyholm/psr7-server": "^1.1", - "open-telemetry/api": "^1.4", - "open-telemetry/context": "^1.0", + "open-telemetry/api": "^1.7", + "open-telemetry/context": "^1.4", "open-telemetry/sem-conv": "^1.0", "php": "^8.1", "php-http/discovery": "^1.14", @@ -1465,7 +1542,7 @@ ] }, "branch-alias": { - "dev-main": "1.0.x-dev" + "dev-main": "1.9.x-dev" } }, "autoload": { @@ -1508,7 +1585,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2025-09-05T07:17:06+00:00" + "time": "2025-10-02T23:44:28+00:00" }, { "name": "open-telemetry/sem-conv", @@ -1569,16 +1646,16 @@ }, { "name": "paragonie/constant_time_encoding", - "version": "v2.7.0", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105" + "reference": "e30811f7bc69e4b5b6d5783e712c06c8eabf0226" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/52a0d99e69f56b9ec27ace92ba56897fe6993105", - "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/e30811f7bc69e4b5b6d5783e712c06c8eabf0226", + "reference": "e30811f7bc69e4b5b6d5783e712c06c8eabf0226", "shasum": "" }, "require": { @@ -1632,7 +1709,7 @@ "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2024-05-08T12:18:48+00:00" + "time": "2025-09-24T15:12:37+00:00" }, { "name": "paragonie/random_compat", @@ -1927,16 +2004,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.46", + "version": "3.0.47", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6" + "reference": "9d6ca36a6c2dd434765b1071b2644a1c683b385d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6", - "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/9d6ca36a6c2dd434765b1071b2644a1c683b385d", + "reference": "9d6ca36a6c2dd434765b1071b2644a1c683b385d", "shasum": "" }, "require": { @@ -2017,7 +2094,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.46" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.47" }, "funding": [ { @@ -2033,7 +2110,7 @@ "type": "tidelift" } ], - "time": "2025-06-26T16:29:55+00:00" + "time": "2025-10-06T01:07:24+00:00" }, { "name": "psr/container", @@ -2596,16 +2673,16 @@ }, { "name": "symfony/http-client", - "version": "v7.3.3", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019" + "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019", - "reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019", + "url": "https://api.github.com/repos/symfony/http-client/zipball/4b62871a01c49457cf2a8e560af7ee8a94b87a62", + "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62", "shasum": "" }, "require": { @@ -2672,7 +2749,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.3.3" + "source": "https://github.com/symfony/http-client/tree/v7.3.4" }, "funding": [ { @@ -2692,7 +2769,7 @@ "type": "tidelift" } ], - "time": "2025-08-27T07:45:05+00:00" + "time": "2025-09-11T10:12:26+00:00" }, { "name": "symfony/http-client-contracts", @@ -3017,6 +3094,86 @@ ], "time": "2025-07-08T02:45:35+00:00" }, + { + "name": "symfony/polyfill-php85", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php85.git", + "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php85\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-23T16:12:55+00:00" + }, { "name": "symfony/service-contracts", "version": "v3.6.0", @@ -3293,16 +3450,16 @@ }, { "name": "utopia-php/abuse", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "c5e2232033b507a07f72180dc56d37e1872ee7be" + "reference": "611fa66a97e87c0dbbc133a717d970da7a5ca828" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/c5e2232033b507a07f72180dc56d37e1872ee7be", - "reference": "c5e2232033b507a07f72180dc56d37e1872ee7be", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/611fa66a97e87c0dbbc133a717d970da7a5ca828", + "reference": "611fa66a97e87c0dbbc133a717d970da7a5ca828", "shasum": "" }, "require": { @@ -3310,7 +3467,7 @@ "ext-pdo": "*", "ext-redis": "*", "php": ">=8.0", - "utopia-php/database": "1.*" + "utopia-php/database": "*" }, "require-dev": { "laravel/pint": "1.*", @@ -3338,9 +3495,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/1.0.0" + "source": "https://github.com/utopia-php/abuse/tree/1.0.2" }, - "time": "2025-08-13T09:12:54+00:00" + "time": "2025-10-20T07:18:33+00:00" }, { "name": "utopia-php/analytics", @@ -3390,21 +3547,21 @@ }, { "name": "utopia-php/audit", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "c0ed75f4d068f1f6c2e7149a909490d4214e72bb" + "reference": "8c17065c2473d4ca799f65585ca74eb53e1be211" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/c0ed75f4d068f1f6c2e7149a909490d4214e72bb", - "reference": "c0ed75f4d068f1f6c2e7149a909490d4214e72bb", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/8c17065c2473d4ca799f65585ca74eb53e1be211", + "reference": "8c17065c2473d4ca799f65585ca74eb53e1be211", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/database": "1.*" + "utopia-php/database": "*" }, "require-dev": { "laravel/pint": "1.*", @@ -3431,9 +3588,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/1.0.0" + "source": "https://github.com/utopia-php/audit/tree/1.0.2" }, - "time": "2025-08-13T09:09:00+00:00" + "time": "2025-10-20T07:14:26+00:00" }, { "name": "utopia-php/cache", @@ -3634,30 +3791,80 @@ "time": "2020-10-24T09:49:09+00:00" }, { - "name": "utopia-php/database", - "version": "1.5.0", + "name": "utopia-php/console", + "version": "0.0.1", "source": { "type": "git", - "url": "https://github.com/utopia-php/database.git", - "reference": "24c4519b4ac32aee13af31dddd984db2a3b34980" + "url": "https://github.com/utopia-php/console.git", + "reference": "f77104e4a888fa9cb3e08f32955ec09479ab7a92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/24c4519b4ac32aee13af31dddd984db2a3b34980", - "reference": "24c4519b4ac32aee13af31dddd984db2a3b34980", + "url": "https://api.github.com/repos/utopia-php/console/zipball/f77104e4a888fa9cb3e08f32955ec09479ab7a92", + "reference": "f77104e4a888fa9cb3e08f32955ec09479ab7a92", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "swoole/ide-helper": "4.8.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Console helpers for logging, prompting, and executing commands", + "keywords": [ + "cli", + "console", + "php", + "terminal", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/console/issues", + "source": "https://github.com/utopia-php/console/tree/0.0.1" + }, + "time": "2025-10-20T14:41:36+00:00" + }, + { + "name": "utopia-php/database", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/database.git", + "reference": "b92554e2e7b3b00f0f0acb2b53c6a11e1349b81e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/database/zipball/b92554e2e7b3b00f0f0acb2b53c6a11e1349b81e", + "reference": "b92554e2e7b3b00f0f0acb2b53c6a11e1349b81e", "shasum": "" }, "require": { "ext-mbstring": "*", + "ext-mongodb": "*", "ext-pdo": "*", "php": ">=8.1", "utopia-php/cache": "0.13.*", "utopia-php/framework": "0.33.*", + "utopia-php/mongo": "0.11.*", "utopia-php/pools": "0.8.*" }, "require-dev": { "fakerphp/faker": "1.23.*", - "laravel/pint": "1.*", + "laravel/pint": "*", "pcov/clobber": "2.*", "phpstan/phpstan": "1.*", "phpunit/phpunit": "9.*", @@ -3685,9 +3892,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/1.5.0" + "source": "https://github.com/utopia-php/database/tree/3.0.2" }, - "time": "2025-09-18T14:42:01+00:00" + "time": "2025-10-20T23:58:56+00:00" }, { "name": "utopia-php/detector", @@ -3792,21 +3999,22 @@ }, { "name": "utopia-php/domains", - "version": "0.8.0", + "version": "0.9.1", "source": { "type": "git", "url": "https://github.com/utopia-php/domains.git", - "reference": "650463d2a1525273eb03223c48da9fb1a768bbf7" + "reference": "99b4ec95d5d6b7a5c990a66c56412212d9af37e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/650463d2a1525273eb03223c48da9fb1a768bbf7", - "reference": "650463d2a1525273eb03223c48da9fb1a768bbf7", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/99b4ec95d5d6b7a5c990a66c56412212d9af37e7", + "reference": "99b4ec95d5d6b7a5c990a66c56412212d9af37e7", "shasum": "" }, "require": { "php": ">=8.0", - "utopia-php/framework": "0.33.*" + "utopia-php/cache": "0.13.*", + "utopia-php/validators": "0.0.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -3847,9 +4055,9 @@ ], "support": { "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/0.8.0" + "source": "https://github.com/utopia-php/domains/tree/0.9.1" }, - "time": "2025-05-16T10:03:59+00:00" + "time": "2025-10-21T14:52:27+00:00" }, { "name": "utopia-php/dsn", @@ -3939,16 +4147,16 @@ }, { "name": "utopia-php/framework", - "version": "0.33.27", + "version": "0.33.28", "source": { "type": "git", "url": "https://github.com/utopia-php/http.git", - "reference": "d9d10a895e85c8c7675220347cc6109db9d3bd37" + "reference": "5aaa94d406577b0059ad28c78022606890dc6de0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/http/zipball/d9d10a895e85c8c7675220347cc6109db9d3bd37", - "reference": "d9d10a895e85c8c7675220347cc6109db9d3bd37", + "url": "https://api.github.com/repos/utopia-php/http/zipball/5aaa94d406577b0059ad28c78022606890dc6de0", + "reference": "5aaa94d406577b0059ad28c78022606890dc6de0", "shasum": "" }, "require": { @@ -3980,9 +4188,9 @@ ], "support": { "issues": "https://github.com/utopia-php/http/issues", - "source": "https://github.com/utopia-php/http/tree/0.33.27" + "source": "https://github.com/utopia-php/http/tree/0.33.28" }, - "time": "2025-09-07T18:40:53+00:00" + "time": "2025-09-25T10:44:24+00:00" }, { "name": "utopia-php/image", @@ -4136,16 +4344,16 @@ }, { "name": "utopia-php/messaging", - "version": "0.18.2", + "version": "0.19.0", "source": { "type": "git", "url": "https://github.com/utopia-php/messaging.git", - "reference": "0d364edacf4d4867964c7e17f653031dd39394bf" + "reference": "0b866d54e70c792a3c4f5ca9c12a6d358a31f4b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/0d364edacf4d4867964c7e17f653031dd39394bf", - "reference": "0d364edacf4d4867964c7e17f653031dd39394bf", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/0b866d54e70c792a3c4f5ca9c12a6d358a31f4b8", + "reference": "0b866d54e70c792a3c4f5ca9c12a6d358a31f4b8", "shasum": "" }, "require": { @@ -4181,22 +4389,22 @@ ], "support": { "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.18.2" + "source": "https://github.com/utopia-php/messaging/tree/0.19.0" }, - "time": "2025-07-21T18:27:03+00:00" + "time": "2025-10-14T11:46:49+00:00" }, { "name": "utopia-php/migration", - "version": "1.1.1", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "c42935a6a4ee3701c68d24244e82ecb39e945ec4" + "reference": "b6985b235ab64f07a6b88569e20cf9b2df7d838c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/c42935a6a4ee3701c68d24244e82ecb39e945ec4", - "reference": "c42935a6a4ee3701c68d24244e82ecb39e945ec4", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/b6985b235ab64f07a6b88569e20cf9b2df7d838c", + "reference": "b6985b235ab64f07a6b88569e20cf9b2df7d838c", "shasum": "" }, "require": { @@ -4204,9 +4412,9 @@ "ext-curl": "*", "ext-openssl": "*", "php": ">=8.1", - "utopia-php/database": "1.*", + "utopia-php/console": "0.0.*", + "utopia-php/database": "3.*", "utopia-php/dsn": "0.2.*", - "utopia-php/framework": "0.33.*", "utopia-php/storage": "0.18.*" }, "require-dev": { @@ -4214,7 +4422,6 @@ "laravel/pint": "1.*", "phpstan/phpstan": "1.*", "phpunit/phpunit": "11.*", - "utopia-php/cli": "0.16.*", "vlucas/phpdotenv": "5.*" }, "type": "library", @@ -4237,9 +4444,70 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/1.1.1" + "source": "https://github.com/utopia-php/migration/tree/1.3.1" }, - "time": "2025-09-10T06:17:20+00:00" + "time": "2025-10-21T08:13:54+00:00" + }, + { + "name": "utopia-php/mongo", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/mongo.git", + "reference": "34bc0cda8ea368cde68702a6fffe2c3ac625398e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/mongo/zipball/34bc0cda8ea368cde68702a6fffe2c3ac625398e", + "reference": "34bc0cda8ea368cde68702a6fffe2c3ac625398e", + "shasum": "" + }, + "require": { + "ext-mongodb": "2.1.*", + "mongodb/mongodb": "2.1.*", + "php": ">=8.0", + "ramsey/uuid": "4.9.*" + }, + "require-dev": { + "fakerphp/faker": "1.*", + "laravel/pint": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "9.*", + "swoole/ide-helper": "5.1.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Mongo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Wess", + "email": "wess@appwrite.io" + } + ], + "description": "A simple library to manage Mongo database", + "keywords": [ + "database", + "mongo", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/mongo/issues", + "source": "https://github.com/utopia-php/mongo/tree/0.11.0" + }, + "time": "2025-10-20T11:11:23+00:00" }, { "name": "utopia-php/orchestration", @@ -4566,16 +4834,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.13", + "version": "0.18.14", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "3d8ce53ae042173bf230445e996056c5f65ded22" + "reference": "4f14ec952c6f4006dd0613e55bbf7631814fbc00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/3d8ce53ae042173bf230445e996056c5f65ded22", - "reference": "3d8ce53ae042173bf230445e996056c5f65ded22", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/4f14ec952c6f4006dd0613e55bbf7631814fbc00", + "reference": "4f14ec952c6f4006dd0613e55bbf7631814fbc00", "shasum": "" }, "require": { @@ -4618,9 +4886,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.13" + "source": "https://github.com/utopia-php/storage/tree/0.18.14" }, - "time": "2025-05-26T13:10:35+00:00" + "time": "2025-10-07T10:21:47+00:00" }, { "name": "utopia-php/swoole", @@ -4779,6 +5047,52 @@ }, "time": "2025-03-17T11:57:52+00:00" }, + { + "name": "utopia-php/validators", + "version": "0.0.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/validators.git", + "reference": "894210695c5d35fa248fb65f7fe7237b6ff4fb0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/validators/zipball/894210695c5d35fa248fb65f7fe7237b6ff4fb0b", + "reference": "894210695c5d35fa248fb65f7fe7237b6ff4fb0b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-xdebug": "*", + "laravel/pint": "^1.2", + "phpstan/phpstan": "1.*", + "phpunit/phpunit": "^9.5.25" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A lightweight collection of reusable validators for Utopia projects", + "keywords": [ + "php", + "utopia", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/utopia-php/validators/issues", + "source": "https://github.com/utopia-php/validators/tree/0.0.2" + }, + "time": "2025-10-20T21:52:28+00:00" + }, { "name": "utopia-php/vcs", "version": "0.11.0", @@ -4879,28 +5193,28 @@ }, { "name": "webmozart/assert", - "version": "1.11.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + "reference": "541057574806f942c94662b817a50f63f7345360" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/541057574806f942c94662b817a50f63f7345360", + "reference": "541057574806f942c94662b817a50f63f7345360", "shasum": "" }, "require": { "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", "php": "^7.2 || ^8.0" }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" }, "type": "library", "extra": { @@ -4931,9 +5245,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" + "source": "https://github.com/webmozarts/assert/tree/1.12.0" }, - "time": "2022-06-03T18:03:27+00:00" + "time": "2025-10-20T12:43:39+00:00" }, { "name": "webonyx/graphql-php", @@ -5004,16 +5318,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "1.3.5", + "version": "1.4.7", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "6fda9e58b37c9872c1a2a424e5467de8de1bc567" + "reference": "a61c8be551e10f4970bf46f75a54e4b0385c550d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/6fda9e58b37c9872c1a2a424e5467de8de1bc567", - "reference": "6fda9e58b37c9872c1a2a424e5467de8de1bc567", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/a61c8be551e10f4970bf46f75a54e4b0385c550d", + "reference": "a61c8be551e10f4970bf46f75a54e4b0385c550d", "shasum": "" }, "require": { @@ -5049,9 +5363,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/1.3.5" + "source": "https://github.com/appwrite/sdk-generator/tree/1.4.7" }, - "time": "2025-09-15T04:19:40+00:00" + "time": "2025-10-22T06:03:44+00:00" }, { "name": "doctrine/annotations", @@ -5127,6 +5441,7 @@ "issues": "https://github.com/doctrine/annotations/issues", "source": "https://github.com/doctrine/annotations/tree/2.0.2" }, + "abandoned": true, "time": "2024-09-05T10:17:24+00:00" }, { @@ -5278,16 +5593,16 @@ }, { "name": "laravel/pint", - "version": "v1.25.0", + "version": "v1.25.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "595de38458c6b0ab4cae4bcc769c2e5c5d5b8e96" + "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/595de38458c6b0ab4cae4bcc769c2e5c5d5b8e96", - "reference": "595de38458c6b0ab4cae4bcc769c2e5c5d5b8e96", + "url": "https://api.github.com/repos/laravel/pint/zipball/5016e263f95d97670d71b9a987bd8996ade6d8d9", + "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9", "shasum": "" }, "require": { @@ -5340,7 +5655,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2025-09-17T01:36:44+00:00" + "time": "2025-09-19T02:57:12+00:00" }, { "name": "matthiasmullie/minify", @@ -5527,16 +5842,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.6.1", + "version": "v5.6.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" + "reference": "3a454ca033b9e06b63282ce19562e892747449bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", - "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb", + "reference": "3a454ca033b9e06b63282ce19562e892747449bb", "shasum": "" }, "require": { @@ -5579,9 +5894,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2" }, - "time": "2025-08-13T20:13:15+00:00" + "time": "2025-10-21T19:32:17+00:00" }, { "name": "phar-io/manifest", @@ -6230,16 +6545,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.27", + "version": "9.6.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "0a9aa4440b6a9528cf360071502628d717af3e0a" + "reference": "9ecfec57835a5581bc888ea7e13b51eb55ab9dd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0a9aa4440b6a9528cf360071502628d717af3e0a", - "reference": "0a9aa4440b6a9528cf360071502628d717af3e0a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9ecfec57835a5581bc888ea7e13b51eb55ab9dd3", + "reference": "9ecfec57835a5581bc888ea7e13b51eb55ab9dd3", "shasum": "" }, "require": { @@ -6264,7 +6579,7 @@ "sebastian/comparator": "^4.0.9", "sebastian/diff": "^4.0.6", "sebastian/environment": "^5.1.5", - "sebastian/exporter": "^4.0.6", + "sebastian/exporter": "^4.0.8", "sebastian/global-state": "^5.0.8", "sebastian/object-enumerator": "^4.0.4", "sebastian/resource-operations": "^3.0.4", @@ -6313,7 +6628,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.27" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.29" }, "funding": [ { @@ -6337,7 +6652,7 @@ "type": "tidelift" } ], - "time": "2025-09-14T06:18:03+00:00" + "time": "2025-09-24T06:29:11+00:00" }, { "name": "psr/cache", @@ -6829,16 +7144,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c", + "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c", "shasum": "" }, "require": { @@ -6894,15 +7209,27 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.8" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" } ], - "time": "2024-03-02T06:33:00+00:00" + "time": "2025-09-24T06:03:27+00:00" }, { "name": "sebastian/global-state", @@ -7485,16 +7812,16 @@ }, { "name": "symfony/console", - "version": "v7.3.3", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7" + "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7", - "reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7", + "url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", + "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", "shasum": "" }, "require": { @@ -7559,7 +7886,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.3" + "source": "https://github.com/symfony/console/tree/v7.3.4" }, "funding": [ { @@ -7579,7 +7906,7 @@ "type": "tidelift" } ], - "time": "2025-08-25T06:35:40+00:00" + "time": "2025-09-22T15:31:00+00:00" }, { "name": "symfony/filesystem", @@ -8122,16 +8449,16 @@ }, { "name": "symfony/process", - "version": "v7.3.3", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "32241012d521e2e8a9d713adb0812bb773b907f1" + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/32241012d521e2e8a9d713adb0812bb773b907f1", - "reference": "32241012d521e2e8a9d713adb0812bb773b907f1", + "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b", + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b", "shasum": "" }, "require": { @@ -8163,7 +8490,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.3.3" + "source": "https://github.com/symfony/process/tree/v7.3.4" }, "funding": [ { @@ -8183,20 +8510,20 @@ "type": "tidelift" } ], - "time": "2025-08-18T09:42:54+00:00" + "time": "2025-09-11T10:12:26+00:00" }, { "name": "symfony/string", - "version": "v7.3.3", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c" + "reference": "f96476035142921000338bad71e5247fbc138872" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", - "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", + "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", + "reference": "f96476035142921000338bad71e5247fbc138872", "shasum": "" }, "require": { @@ -8211,7 +8538,6 @@ }, "require-dev": { "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", "symfony/http-client": "^6.4|^7.0", "symfony/intl": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3.0", @@ -8254,7 +8580,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.3.3" + "source": "https://github.com/symfony/string/tree/v7.3.4" }, "funding": [ { @@ -8274,7 +8600,7 @@ "type": "tidelift" } ], - "time": "2025-08-25T06:35:40+00:00" + "time": "2025-09-11T14:36:48+00:00" }, { "name": "textalk/websocket", @@ -8506,7 +8832,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/docker-compose.yml b/docker-compose.yml index da6362b4c4..b72f12a116 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -219,7 +219,7 @@ services: appwrite-console: <<: *x-logging container_name: appwrite-console - image: appwrite/console:7.0.2 + image: appwrite/console:7.4.7 restart: unless-stopped networks: - appwrite diff --git a/docs/examples/1.8.x/client-android/java/account/create-email-verification.md b/docs/examples/1.8.x/client-android/java/account/create-email-verification.md new file mode 100644 index 0000000000..dfbf059d45 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/account/create-email-verification.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Account account = new Account(client); + +account.createEmailVerification( + "https://example.com", // url + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/account/update-email-verification.md b/docs/examples/1.8.x/client-android/java/account/update-email-verification.md new file mode 100644 index 0000000000..9d157c8e92 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/account/update-email-verification.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Account account = new Account(client); + +account.updateEmailVerification( + "", // userId + "", // secret + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/databases/create-document.md b/docs/examples/1.8.x/client-android/java/databases/create-document.md index bd0b57ac4c..694d99a089 100644 --- a/docs/examples/1.8.x/client-android/java/databases/create-document.md +++ b/docs/examples/1.8.x/client-android/java/databases/create-document.md @@ -20,6 +20,7 @@ databases.createDocument( "isAdmin" to false ), // data listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/databases/create-operations.md b/docs/examples/1.8.x/client-android/java/databases/create-operations.md new file mode 100644 index 0000000000..def58af773 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/databases/create-operations.md @@ -0,0 +1,33 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Databases databases = new Databases(client); + +databases.createOperations( + "", // transactionId + listOf( + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ), // operations (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/databases/create-transaction.md b/docs/examples/1.8.x/client-android/java/databases/create-transaction.md new file mode 100644 index 0000000000..871d1907f6 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/databases/create-transaction.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Databases databases = new Databases(client); + +databases.createTransaction( + 60, // ttl (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-android/java/databases/decrement-document-attribute.md index de6a4ab48d..8669494532 100644 --- a/docs/examples/1.8.x/client-android/java/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-android/java/databases/decrement-document-attribute.md @@ -15,6 +15,7 @@ databases.decrementDocumentAttribute( "", // attribute 0, // value (optional) 0, // min (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/databases/delete-document.md b/docs/examples/1.8.x/client-android/java/databases/delete-document.md index 5288e53bed..2795670807 100644 --- a/docs/examples/1.8.x/client-android/java/databases/delete-document.md +++ b/docs/examples/1.8.x/client-android/java/databases/delete-document.md @@ -12,6 +12,7 @@ databases.deleteDocument( "", // databaseId "", // collectionId "", // documentId + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/databases/delete-transaction.md b/docs/examples/1.8.x/client-android/java/databases/delete-transaction.md new file mode 100644 index 0000000000..ac1121e9b9 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/databases/delete-transaction.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Databases databases = new Databases(client); + +databases.deleteTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/databases/get-document.md b/docs/examples/1.8.x/client-android/java/databases/get-document.md index e7ae2079ed..92d6b5ed23 100644 --- a/docs/examples/1.8.x/client-android/java/databases/get-document.md +++ b/docs/examples/1.8.x/client-android/java/databases/get-document.md @@ -13,6 +13,7 @@ databases.getDocument( "", // collectionId "", // documentId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/databases/get-transaction.md b/docs/examples/1.8.x/client-android/java/databases/get-transaction.md new file mode 100644 index 0000000000..5dee850305 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/databases/get-transaction.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Databases databases = new Databases(client); + +databases.getTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-android/java/databases/increment-document-attribute.md index 94ffa9d749..5928b455c6 100644 --- a/docs/examples/1.8.x/client-android/java/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-android/java/databases/increment-document-attribute.md @@ -15,6 +15,7 @@ databases.incrementDocumentAttribute( "", // attribute 0, // value (optional) 0, // max (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/databases/list-documents.md b/docs/examples/1.8.x/client-android/java/databases/list-documents.md index 606d67705d..7b2ba23453 100644 --- a/docs/examples/1.8.x/client-android/java/databases/list-documents.md +++ b/docs/examples/1.8.x/client-android/java/databases/list-documents.md @@ -12,6 +12,7 @@ databases.listDocuments( "", // databaseId "", // collectionId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/databases/list-transactions.md b/docs/examples/1.8.x/client-android/java/databases/list-transactions.md new file mode 100644 index 0000000000..39f58f3490 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/databases/list-transactions.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Databases databases = new Databases(client); + +databases.listTransactions( + listOf(), // queries (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/databases/update-document.md b/docs/examples/1.8.x/client-android/java/databases/update-document.md index baa827cdf5..a6103e44d1 100644 --- a/docs/examples/1.8.x/client-android/java/databases/update-document.md +++ b/docs/examples/1.8.x/client-android/java/databases/update-document.md @@ -14,6 +14,7 @@ databases.updateDocument( "", // documentId mapOf( "a" to "b" ), // data (optional) listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/databases/update-transaction.md b/docs/examples/1.8.x/client-android/java/databases/update-transaction.md new file mode 100644 index 0000000000..c5f586fce3 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/databases/update-transaction.md @@ -0,0 +1,24 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +Databases databases = new Databases(client); + +databases.updateTransaction( + "", // transactionId + false, // commit (optional) + false, // rollback (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/databases/upsert-document.md b/docs/examples/1.8.x/client-android/java/databases/upsert-document.md index 868576b982..52be46ebe6 100644 --- a/docs/examples/1.8.x/client-android/java/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-android/java/databases/upsert-document.md @@ -14,6 +14,7 @@ databases.upsertDocument( "", // documentId mapOf( "a" to "b" ), // data listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/create-operations.md b/docs/examples/1.8.x/client-android/java/tablesdb/create-operations.md new file mode 100644 index 0000000000..7ca288c2ae --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/tablesdb/create-operations.md @@ -0,0 +1,33 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.createOperations( + "", // transactionId + listOf( + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ), // operations (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/create-row.md b/docs/examples/1.8.x/client-android/java/tablesdb/create-row.md index 8273573ddd..92a9058401 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/create-row.md @@ -20,6 +20,7 @@ tablesDB.createRow( "isAdmin" to false ), // data listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-android/java/tablesdb/create-transaction.md new file mode 100644 index 0000000000..c232c56991 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/tablesdb/create-transaction.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.createTransaction( + 60, // ttl (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-android/java/tablesdb/decrement-row-column.md index 73f2128a8f..2252564e73 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/decrement-row-column.md @@ -15,6 +15,7 @@ tablesDB.decrementRowColumn( "", // column 0, // value (optional) 0, // min (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/delete-row.md b/docs/examples/1.8.x/client-android/java/tablesdb/delete-row.md index d4c351bc32..6680100499 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/delete-row.md @@ -12,6 +12,7 @@ tablesDB.deleteRow( "", // databaseId "", // tableId "", // rowId + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-android/java/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..18cb2357d3 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/tablesdb/delete-transaction.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.deleteTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/get-row.md b/docs/examples/1.8.x/client-android/java/tablesdb/get-row.md index 191fc896e9..45efc6b061 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/get-row.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/get-row.md @@ -13,6 +13,7 @@ tablesDB.getRow( "", // tableId "", // rowId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-android/java/tablesdb/get-transaction.md new file mode 100644 index 0000000000..fb51916264 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/tablesdb/get-transaction.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.getTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-android/java/tablesdb/increment-row-column.md index dc2120ea07..a1194a67a5 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/increment-row-column.md @@ -15,6 +15,7 @@ tablesDB.incrementRowColumn( "", // column 0, // value (optional) 0, // max (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/list-rows.md b/docs/examples/1.8.x/client-android/java/tablesdb/list-rows.md index dc50574f1e..21f0005b2d 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/list-rows.md @@ -12,6 +12,7 @@ tablesDB.listRows( "", // databaseId "", // tableId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-android/java/tablesdb/list-transactions.md new file mode 100644 index 0000000000..c37ccf1931 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/tablesdb/list-transactions.md @@ -0,0 +1,22 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.listTransactions( + listOf(), // queries (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/update-row.md b/docs/examples/1.8.x/client-android/java/tablesdb/update-row.md index 0f1fabc91e..cea7baaa16 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/update-row.md @@ -14,6 +14,7 @@ tablesDB.updateRow( "", // rowId mapOf( "a" to "b" ), // data (optional) listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-android/java/tablesdb/update-transaction.md new file mode 100644 index 0000000000..804b5d5023 --- /dev/null +++ b/docs/examples/1.8.x/client-android/java/tablesdb/update-transaction.md @@ -0,0 +1,24 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject(""); // Your project ID + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.updateTransaction( + "", // transactionId + false, // commit (optional) + false, // rollback (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Log.d("Appwrite", result.toString()); + }) +); + diff --git a/docs/examples/1.8.x/client-android/java/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-android/java/tablesdb/upsert-row.md index 22c0e94b44..9d6323fffa 100644 --- a/docs/examples/1.8.x/client-android/java/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-android/java/tablesdb/upsert-row.md @@ -14,6 +14,7 @@ tablesDB.upsertRow( "", // rowId mapOf( "a" to "b" ), // data (optional) listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/client-android/kotlin/account/create-email-verification.md b/docs/examples/1.8.x/client-android/kotlin/account/create-email-verification.md new file mode 100644 index 0000000000..dc87901eaf --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/account/create-email-verification.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val account = Account(client) + +val result = account.createEmailVerification( + url = "https://example.com", +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/account/update-email-verification.md b/docs/examples/1.8.x/client-android/kotlin/account/update-email-verification.md new file mode 100644 index 0000000000..9fb21d2d7c --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/account/update-email-verification.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val account = Account(client) + +val result = account.updateEmailVerification( + userId = "", + secret = "", +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/create-document.md b/docs/examples/1.8.x/client-android/kotlin/databases/create-document.md index 7f0aaf81f4..7d4b04d13a 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/create-document.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/create-document.md @@ -20,4 +20,5 @@ val result = databases.createDocument( "isAdmin" to false ), permissions = listOf("read("any")"), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/create-operations.md b/docs/examples/1.8.x/client-android/kotlin/databases/create-operations.md new file mode 100644 index 0000000000..62c93351e7 --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/databases/create-operations.md @@ -0,0 +1,24 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val databases = Databases(client) + +val result = databases.createOperations( + transactionId = "", + operations = listOf( + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ), // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/create-transaction.md b/docs/examples/1.8.x/client-android/kotlin/databases/create-transaction.md new file mode 100644 index 0000000000..3b953c3bda --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/databases/create-transaction.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val databases = Databases(client) + +val result = databases.createTransaction( + ttl = 60, // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-android/kotlin/databases/decrement-document-attribute.md index c500fa8687..84a4a0edea 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/decrement-document-attribute.md @@ -15,4 +15,5 @@ val result = databases.decrementDocumentAttribute( attribute = "", value = 0, // (optional) min = 0, // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/delete-document.md b/docs/examples/1.8.x/client-android/kotlin/databases/delete-document.md index 052bf97f89..242655ec1f 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/delete-document.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/delete-document.md @@ -12,4 +12,5 @@ val result = databases.deleteDocument( databaseId = "", collectionId = "", documentId = "", + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/delete-transaction.md b/docs/examples/1.8.x/client-android/kotlin/databases/delete-transaction.md new file mode 100644 index 0000000000..bbce98c661 --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/databases/delete-transaction.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val databases = Databases(client) + +val result = databases.deleteTransaction( + transactionId = "", +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/get-document.md b/docs/examples/1.8.x/client-android/kotlin/databases/get-document.md index 157af2b562..f21b6f34f0 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/get-document.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/get-document.md @@ -13,4 +13,5 @@ val result = databases.getDocument( collectionId = "", documentId = "", queries = listOf(), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/get-transaction.md b/docs/examples/1.8.x/client-android/kotlin/databases/get-transaction.md new file mode 100644 index 0000000000..0a1fda69df --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/databases/get-transaction.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val databases = Databases(client) + +val result = databases.getTransaction( + transactionId = "", +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-android/kotlin/databases/increment-document-attribute.md index 0ae6b02d3d..ca32cfcb5c 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/increment-document-attribute.md @@ -15,4 +15,5 @@ val result = databases.incrementDocumentAttribute( attribute = "", value = 0, // (optional) max = 0, // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/list-documents.md b/docs/examples/1.8.x/client-android/kotlin/databases/list-documents.md index 1cc785fab1..a2b6e0e0b6 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/list-documents.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/list-documents.md @@ -12,4 +12,5 @@ val result = databases.listDocuments( databaseId = "", collectionId = "", queries = listOf(), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/list-transactions.md b/docs/examples/1.8.x/client-android/kotlin/databases/list-transactions.md new file mode 100644 index 0000000000..da5cd4ba7a --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/databases/list-transactions.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val databases = Databases(client) + +val result = databases.listTransactions( + queries = listOf(), // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/update-document.md b/docs/examples/1.8.x/client-android/kotlin/databases/update-document.md index d61fdea5b1..2cacce6f95 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/update-document.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/update-document.md @@ -14,4 +14,5 @@ val result = databases.updateDocument( documentId = "", data = mapOf( "a" to "b" ), // (optional) permissions = listOf("read("any")"), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/update-transaction.md b/docs/examples/1.8.x/client-android/kotlin/databases/update-transaction.md new file mode 100644 index 0000000000..c9d6a852ce --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/databases/update-transaction.md @@ -0,0 +1,15 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val databases = Databases(client) + +val result = databases.updateTransaction( + transactionId = "", + commit = false, // (optional) + rollback = false, // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/databases/upsert-document.md b/docs/examples/1.8.x/client-android/kotlin/databases/upsert-document.md index a31dfc8797..e5ac4375e8 100644 --- a/docs/examples/1.8.x/client-android/kotlin/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-android/kotlin/databases/upsert-document.md @@ -14,4 +14,5 @@ val result = databases.upsertDocument( documentId = "", data = mapOf( "a" to "b" ), permissions = listOf("read("any")"), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-operations.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-operations.md new file mode 100644 index 0000000000..3073a00bca --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-operations.md @@ -0,0 +1,24 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val tablesDB = TablesDB(client) + +val result = tablesDB.createOperations( + transactionId = "", + operations = listOf( + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ), // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-row.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-row.md index eb44cc48d6..f5850b23be 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-row.md @@ -20,4 +20,5 @@ val result = tablesDB.createRow( "isAdmin" to false ), permissions = listOf("read("any")"), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-transaction.md new file mode 100644 index 0000000000..b011fa051f --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/create-transaction.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val tablesDB = TablesDB(client) + +val result = tablesDB.createTransaction( + ttl = 60, // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/decrement-row-column.md index 645e9f4a66..1a8964078e 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/decrement-row-column.md @@ -15,4 +15,5 @@ val result = tablesDB.decrementRowColumn( column = "", value = 0, // (optional) min = 0, // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/delete-row.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/delete-row.md index 3fcd409295..6912afa10a 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/delete-row.md @@ -12,4 +12,5 @@ val result = tablesDB.deleteRow( databaseId = "", tableId = "", rowId = "", + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..92c0074acc --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/delete-transaction.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val tablesDB = TablesDB(client) + +val result = tablesDB.deleteTransaction( + transactionId = "", +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/get-row.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/get-row.md index b754cba915..adea429759 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/get-row.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/get-row.md @@ -13,4 +13,5 @@ val result = tablesDB.getRow( tableId = "", rowId = "", queries = listOf(), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/get-transaction.md new file mode 100644 index 0000000000..38b7c33e83 --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/get-transaction.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val tablesDB = TablesDB(client) + +val result = tablesDB.getTransaction( + transactionId = "", +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/increment-row-column.md index 230408abac..1b679e181b 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/increment-row-column.md @@ -15,4 +15,5 @@ val result = tablesDB.incrementRowColumn( column = "", value = 0, // (optional) max = 0, // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/list-rows.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/list-rows.md index 05d9ca33b3..6d2a4b8b40 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/list-rows.md @@ -12,4 +12,5 @@ val result = tablesDB.listRows( databaseId = "", tableId = "", queries = listOf(), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/list-transactions.md new file mode 100644 index 0000000000..b7764c719f --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/list-transactions.md @@ -0,0 +1,13 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val tablesDB = TablesDB(client) + +val result = tablesDB.listTransactions( + queries = listOf(), // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/update-row.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/update-row.md index f99f8f275e..a17f231418 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/update-row.md @@ -14,4 +14,5 @@ val result = tablesDB.updateRow( rowId = "", data = mapOf( "a" to "b" ), // (optional) permissions = listOf("read("any")"), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/update-transaction.md new file mode 100644 index 0000000000..791649ff09 --- /dev/null +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/update-transaction.md @@ -0,0 +1,15 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +val tablesDB = TablesDB(client) + +val result = tablesDB.updateTransaction( + transactionId = "", + commit = false, // (optional) + rollback = false, // (optional) +) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-android/kotlin/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-android/kotlin/tablesdb/upsert-row.md index d82406a7f8..074fa339cb 100644 --- a/docs/examples/1.8.x/client-android/kotlin/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-android/kotlin/tablesdb/upsert-row.md @@ -14,4 +14,5 @@ val result = tablesDB.upsertRow( rowId = "", data = mapOf( "a" to "b" ), // (optional) permissions = listOf("read("any")"), // (optional) + transactionId = "", // (optional) ) \ No newline at end of file diff --git a/docs/examples/1.8.x/client-apple/examples/account/create-email-verification.md b/docs/examples/1.8.x/client-apple/examples/account/create-email-verification.md new file mode 100644 index 0000000000..378558ecd6 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/account/create-email-verification.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let account = Account(client) + +let token = try await account.createEmailVerification( + url: "https://example.com" +) + diff --git a/docs/examples/1.8.x/client-apple/examples/account/update-email-verification.md b/docs/examples/1.8.x/client-apple/examples/account/update-email-verification.md new file mode 100644 index 0000000000..77ef28eb49 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/account/update-email-verification.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let account = Account(client) + +let token = try await account.updateEmailVerification( + userId: "", + secret: "" +) + diff --git a/docs/examples/1.8.x/client-apple/examples/databases/create-document.md b/docs/examples/1.8.x/client-apple/examples/databases/create-document.md index c044eee17a..d7fa796ed1 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/create-document.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/create-document.md @@ -17,6 +17,7 @@ let document = try await databases.createDocument( "age": 30, "isAdmin": false ], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/databases/create-operations.md b/docs/examples/1.8.x/client-apple/examples/databases/create-operations.md new file mode 100644 index 0000000000..7c22de38ca --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/databases/create-operations.md @@ -0,0 +1,23 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let databases = Databases(client) + +let transaction = try await databases.createOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/databases/create-transaction.md b/docs/examples/1.8.x/client-apple/examples/databases/create-transaction.md new file mode 100644 index 0000000000..4319907a65 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/databases/create-transaction.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let databases = Databases(client) + +let transaction = try await databases.createTransaction( + ttl: 60 // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-apple/examples/databases/decrement-document-attribute.md index 8ef2637bf2..714d7baabb 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/decrement-document-attribute.md @@ -12,6 +12,7 @@ let document = try await databases.decrementDocumentAttribute( documentId: "", attribute: "", value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/databases/delete-document.md b/docs/examples/1.8.x/client-apple/examples/databases/delete-document.md index 301203dc7f..4d8f5074ea 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/delete-document.md @@ -9,6 +9,7 @@ let databases = Databases(client) let result = try await databases.deleteDocument( databaseId: "", collectionId: "", - documentId: "" + documentId: "", + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/databases/delete-transaction.md b/docs/examples/1.8.x/client-apple/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..134d72df9c --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/databases/delete-transaction.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let databases = Databases(client) + +let result = try await databases.deleteTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/client-apple/examples/databases/get-document.md b/docs/examples/1.8.x/client-apple/examples/databases/get-document.md index 6e4dc55c6d..89c89a3868 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/get-document.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/get-document.md @@ -10,6 +10,7 @@ let document = try await databases.getDocument( databaseId: "", collectionId: "", documentId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/databases/get-transaction.md b/docs/examples/1.8.x/client-apple/examples/databases/get-transaction.md new file mode 100644 index 0000000000..6274ff8d15 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/databases/get-transaction.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let databases = Databases(client) + +let transaction = try await databases.getTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/client-apple/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-apple/examples/databases/increment-document-attribute.md index f64b2cd76c..9c771a7490 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/increment-document-attribute.md @@ -12,6 +12,7 @@ let document = try await databases.incrementDocumentAttribute( documentId: "", attribute: "", value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/databases/list-documents.md b/docs/examples/1.8.x/client-apple/examples/databases/list-documents.md index 0d624f3a92..528d9992a4 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/list-documents.md @@ -9,6 +9,7 @@ let databases = Databases(client) let documentList = try await databases.listDocuments( databaseId: "", collectionId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/databases/list-transactions.md b/docs/examples/1.8.x/client-apple/examples/databases/list-transactions.md new file mode 100644 index 0000000000..3f889c213c --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/databases/list-transactions.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let databases = Databases(client) + +let transactionList = try await databases.listTransactions( + queries: [] // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/databases/update-document.md b/docs/examples/1.8.x/client-apple/examples/databases/update-document.md index af224c8e09..d626d7d3c0 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/update-document.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/update-document.md @@ -11,6 +11,7 @@ let document = try await databases.updateDocument( collectionId: "", documentId: "", data: [:], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/databases/update-transaction.md b/docs/examples/1.8.x/client-apple/examples/databases/update-transaction.md new file mode 100644 index 0000000000..96705d019f --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/databases/update-transaction.md @@ -0,0 +1,14 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let databases = Databases(client) + +let transaction = try await databases.updateTransaction( + transactionId: "", + commit: false, // optional + rollback: false // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/databases/upsert-document.md b/docs/examples/1.8.x/client-apple/examples/databases/upsert-document.md index 3e1bf83a66..8e2a4a09e9 100644 --- a/docs/examples/1.8.x/client-apple/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-apple/examples/databases/upsert-document.md @@ -11,6 +11,7 @@ let document = try await databases.upsertDocument( collectionId: "", documentId: "", data: [:], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..c4032cc02c --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/create-operations.md @@ -0,0 +1,23 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.createOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/create-row.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/create-row.md index 2ee601340f..4d66980bb5 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/create-row.md @@ -17,6 +17,7 @@ let row = try await tablesDB.createRow( "age": 30, "isAdmin": false ], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..366aa5b663 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/create-transaction.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.createTransaction( + ttl: 60 // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/decrement-row-column.md index ab8ac5b0b8..8a41d43362 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/decrement-row-column.md @@ -12,6 +12,7 @@ let row = try await tablesDB.decrementRowColumn( rowId: "", column: "", value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/delete-row.md index b527acaed9..6ddd1c5fc2 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/delete-row.md @@ -9,6 +9,7 @@ let tablesDB = TablesDB(client) let result = try await tablesDB.deleteRow( databaseId: "", tableId: "", - rowId: "" + rowId: "", + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..12cf45fa2c --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/delete-transaction.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let tablesDB = TablesDB(client) + +let result = try await tablesDB.deleteTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/get-row.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/get-row.md index bc2e2c6b55..7a3aa40806 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/get-row.md @@ -10,6 +10,7 @@ let row = try await tablesDB.getRow( databaseId: "", tableId: "", rowId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..fe3cbf78b2 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/get-transaction.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.getTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/increment-row-column.md index 550d6685af..29b346e27d 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/increment-row-column.md @@ -12,6 +12,7 @@ let row = try await tablesDB.incrementRowColumn( rowId: "", column: "", value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/list-rows.md index 94853c24a0..dee2ab9e81 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/list-rows.md @@ -9,6 +9,7 @@ let tablesDB = TablesDB(client) let rowList = try await tablesDB.listRows( databaseId: "", tableId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..b7edd2d1a0 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/list-transactions.md @@ -0,0 +1,12 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let tablesDB = TablesDB(client) + +let transactionList = try await tablesDB.listTransactions( + queries: [] // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/update-row.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/update-row.md index 87a8f27313..cd5591db80 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/update-row.md @@ -11,6 +11,7 @@ let row = try await tablesDB.updateRow( tableId: "", rowId: "", data: [:], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..2c0e6a7a37 --- /dev/null +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/update-transaction.md @@ -0,0 +1,14 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.updateTransaction( + transactionId: "", + commit: false, // optional + rollback: false // optional +) + diff --git a/docs/examples/1.8.x/client-apple/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-apple/examples/tablesdb/upsert-row.md index ed95da7b62..955935adef 100644 --- a/docs/examples/1.8.x/client-apple/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-apple/examples/tablesdb/upsert-row.md @@ -11,6 +11,7 @@ let row = try await tablesDB.upsertRow( tableId: "", rowId: "", data: [:], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/client-flutter/examples/account/create-email-verification.md b/docs/examples/1.8.x/client-flutter/examples/account/create-email-verification.md new file mode 100644 index 0000000000..823ea2f216 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/account/create-email-verification.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Account account = Account(client); + +Token result = await account.createEmailVerification( + url: 'https://example.com', +); diff --git a/docs/examples/1.8.x/client-flutter/examples/account/update-email-verification.md b/docs/examples/1.8.x/client-flutter/examples/account/update-email-verification.md new file mode 100644 index 0000000000..927aadf184 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/account/update-email-verification.md @@ -0,0 +1,12 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Account account = Account(client); + +Token result = await account.updateEmailVerification( + userId: '', + secret: '', +); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/create-document.md b/docs/examples/1.8.x/client-flutter/examples/databases/create-document.md index 3becbcf1fc..0acbe689dc 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/create-document.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/create-document.md @@ -18,4 +18,5 @@ Document result = await databases.createDocument( "isAdmin": false }, permissions: ["read("any")"], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/create-operations.md b/docs/examples/1.8.x/client-flutter/examples/databases/create-operations.md new file mode 100644 index 0000000000..2dec7ff7c8 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/databases/create-operations.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Databases databases = Databases(client); + +Transaction result = await databases.createOperations( + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ], // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/create-transaction.md b/docs/examples/1.8.x/client-flutter/examples/databases/create-transaction.md new file mode 100644 index 0000000000..3d7ddc3efa --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/databases/create-transaction.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Databases databases = Databases(client); + +Transaction result = await databases.createTransaction( + ttl: 60, // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-flutter/examples/databases/decrement-document-attribute.md index ec0d9ee300..dad45bc836 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/decrement-document-attribute.md @@ -13,4 +13,5 @@ Document result = await databases.decrementDocumentAttribute( attribute: '', value: 0, // optional min: 0, // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/delete-document.md b/docs/examples/1.8.x/client-flutter/examples/databases/delete-document.md index 3354917c20..bd101370a6 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/delete-document.md @@ -10,4 +10,5 @@ await databases.deleteDocument( databaseId: '', collectionId: '', documentId: '', + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/delete-transaction.md b/docs/examples/1.8.x/client-flutter/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..333dd1d3a1 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/databases/delete-transaction.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Databases databases = Databases(client); + +await databases.deleteTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/get-document.md b/docs/examples/1.8.x/client-flutter/examples/databases/get-document.md index f85c1f9b5a..9dcf2cf119 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/get-document.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/get-document.md @@ -11,4 +11,5 @@ Document result = await databases.getDocument( collectionId: '', documentId: '', queries: [], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/get-transaction.md b/docs/examples/1.8.x/client-flutter/examples/databases/get-transaction.md new file mode 100644 index 0000000000..153b0f3856 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/databases/get-transaction.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Databases databases = Databases(client); + +Transaction result = await databases.getTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-flutter/examples/databases/increment-document-attribute.md index 78f5b0cb6f..855fd8f51e 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/increment-document-attribute.md @@ -13,4 +13,5 @@ Document result = await databases.incrementDocumentAttribute( attribute: '', value: 0, // optional max: 0, // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/list-documents.md b/docs/examples/1.8.x/client-flutter/examples/databases/list-documents.md index 31fec1f522..b53120cb4e 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/list-documents.md @@ -10,4 +10,5 @@ DocumentList result = await databases.listDocuments( databaseId: '', collectionId: '', queries: [], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/list-transactions.md b/docs/examples/1.8.x/client-flutter/examples/databases/list-transactions.md new file mode 100644 index 0000000000..467a1ced84 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/databases/list-transactions.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Databases databases = Databases(client); + +TransactionList result = await databases.listTransactions( + queries: [], // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/update-document.md b/docs/examples/1.8.x/client-flutter/examples/databases/update-document.md index 1f444d875a..44ade30c3a 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/update-document.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/update-document.md @@ -12,4 +12,5 @@ Document result = await databases.updateDocument( documentId: '', data: {}, // optional permissions: ["read("any")"], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/update-transaction.md b/docs/examples/1.8.x/client-flutter/examples/databases/update-transaction.md new file mode 100644 index 0000000000..a51f9d05d6 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/databases/update-transaction.md @@ -0,0 +1,13 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Databases databases = Databases(client); + +Transaction result = await databases.updateTransaction( + transactionId: '', + commit: false, // optional + rollback: false, // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/databases/upsert-document.md b/docs/examples/1.8.x/client-flutter/examples/databases/upsert-document.md index 398a99cb1d..10117ac78d 100644 --- a/docs/examples/1.8.x/client-flutter/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-flutter/examples/databases/upsert-document.md @@ -12,4 +12,5 @@ Document result = await databases.upsertDocument( documentId: '', data: {}, permissions: ["read("any")"], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..631aefe603 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-operations.md @@ -0,0 +1,22 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.createOperations( + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ], // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-row.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-row.md index 038bb2bac6..345f0c239a 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-row.md @@ -18,4 +18,5 @@ Row result = await tablesDB.createRow( "isAdmin": false }, permissions: ["read("any")"], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..0ad0eb5223 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/create-transaction.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.createTransaction( + ttl: 60, // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/decrement-row-column.md index 4f3b4bdb61..65f67513f4 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/decrement-row-column.md @@ -13,4 +13,5 @@ Row result = await tablesDB.decrementRowColumn( column: '', value: 0, // optional min: 0, // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/delete-row.md index cc902fa198..b8ea1d2656 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/delete-row.md @@ -10,4 +10,5 @@ await tablesDB.deleteRow( databaseId: '', tableId: '', rowId: '', + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..2d27c6afda --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/delete-transaction.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +TablesDB tablesDB = TablesDB(client); + +await tablesDB.deleteTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/get-row.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/get-row.md index 29e6eaab93..eb75da5073 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/get-row.md @@ -11,4 +11,5 @@ Row result = await tablesDB.getRow( tableId: '', rowId: '', queries: [], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..000e230227 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/get-transaction.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.getTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/increment-row-column.md index e05dc76753..91cd0ce351 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/increment-row-column.md @@ -13,4 +13,5 @@ Row result = await tablesDB.incrementRowColumn( column: '', value: 0, // optional max: 0, // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/list-rows.md index 7763e2ae3d..01d7066501 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/list-rows.md @@ -10,4 +10,5 @@ RowList result = await tablesDB.listRows( databaseId: '', tableId: '', queries: [], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..5e088cedc3 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/list-transactions.md @@ -0,0 +1,11 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +TablesDB tablesDB = TablesDB(client); + +TransactionList result = await tablesDB.listTransactions( + queries: [], // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/update-row.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/update-row.md index c2cc84d7f6..08ab309363 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/update-row.md @@ -12,4 +12,5 @@ Row result = await tablesDB.updateRow( rowId: '', data: {}, // optional permissions: ["read("any")"], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..ef56443e99 --- /dev/null +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/update-transaction.md @@ -0,0 +1,13 @@ +import 'package:appwrite/appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.updateTransaction( + transactionId: '', + commit: false, // optional + rollback: false, // optional +); diff --git a/docs/examples/1.8.x/client-flutter/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-flutter/examples/tablesdb/upsert-row.md index 6a958a1898..061bb0b85a 100644 --- a/docs/examples/1.8.x/client-flutter/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-flutter/examples/tablesdb/upsert-row.md @@ -12,4 +12,5 @@ Row result = await tablesDB.upsertRow( rowId: '', data: {}, // optional permissions: ["read("any")"], // optional + transactionId: '', // optional ); diff --git a/docs/examples/1.8.x/client-graphql/examples/account/create-email-verification.md b/docs/examples/1.8.x/client-graphql/examples/account/create-email-verification.md new file mode 100644 index 0000000000..1781188527 --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/account/create-email-verification.md @@ -0,0 +1,12 @@ +mutation { + accountCreateEmailVerification( + url: "https://example.com" + ) { + _id + _createdAt + userId + secret + expire + phrase + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/account/update-email-verification.md b/docs/examples/1.8.x/client-graphql/examples/account/update-email-verification.md new file mode 100644 index 0000000000..6386d34bfa --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/account/update-email-verification.md @@ -0,0 +1,13 @@ +mutation { + accountUpdateEmailVerification( + userId: "", + secret: "" + ) { + _id + _createdAt + userId + secret + expire + phrase + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/create-document.md b/docs/examples/1.8.x/client-graphql/examples/databases/create-document.md index 39e4bba1cb..411615f7a7 100644 --- a/docs/examples/1.8.x/client-graphql/examples/databases/create-document.md +++ b/docs/examples/1.8.x/client-graphql/examples/databases/create-document.md @@ -4,7 +4,8 @@ mutation { collectionId: "", documentId: "", data: "{\"username\":\"walter.obrien\",\"email\":\"walter.obrien@example.com\",\"fullName\":\"Walter O'Brien\",\"age\":30,\"isAdmin\":false}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/create-operations.md b/docs/examples/1.8.x/client-graphql/examples/databases/create-operations.md new file mode 100644 index 0000000000..1be3b39ee1 --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/databases/create-operations.md @@ -0,0 +1,23 @@ +mutation { + databasesCreateOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/create-transaction.md b/docs/examples/1.8.x/client-graphql/examples/databases/create-transaction.md new file mode 100644 index 0000000000..7fea034ab6 --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/databases/create-transaction.md @@ -0,0 +1,12 @@ +mutation { + databasesCreateTransaction( + ttl: 60 + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-graphql/examples/databases/decrement-document-attribute.md index 2e7970049d..e6032fd0e7 100644 --- a/docs/examples/1.8.x/client-graphql/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-graphql/examples/databases/decrement-document-attribute.md @@ -5,7 +5,8 @@ mutation { documentId: "", attribute: "", value: 0, - min: 0 + min: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/delete-document.md b/docs/examples/1.8.x/client-graphql/examples/databases/delete-document.md index 848371bca0..2e172aa5dd 100644 --- a/docs/examples/1.8.x/client-graphql/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/client-graphql/examples/databases/delete-document.md @@ -2,7 +2,8 @@ mutation { databasesDeleteDocument( databaseId: "", collectionId: "", - documentId: "" + documentId: "", + transactionId: "" ) { status } diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/delete-transaction.md b/docs/examples/1.8.x/client-graphql/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..cd29a0b8a6 --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/databases/delete-transaction.md @@ -0,0 +1,7 @@ +mutation { + databasesDeleteTransaction( + transactionId: "" + ) { + status + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/get-transaction.md b/docs/examples/1.8.x/client-graphql/examples/databases/get-transaction.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-graphql/examples/databases/increment-document-attribute.md index 322ed69ced..3518ff1583 100644 --- a/docs/examples/1.8.x/client-graphql/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-graphql/examples/databases/increment-document-attribute.md @@ -5,7 +5,8 @@ mutation { documentId: "", attribute: "", value: 0, - max: 0 + max: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/list-transactions.md b/docs/examples/1.8.x/client-graphql/examples/databases/list-transactions.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/update-document.md b/docs/examples/1.8.x/client-graphql/examples/databases/update-document.md index aea605d9d7..cf43d9eed0 100644 --- a/docs/examples/1.8.x/client-graphql/examples/databases/update-document.md +++ b/docs/examples/1.8.x/client-graphql/examples/databases/update-document.md @@ -4,7 +4,8 @@ mutation { collectionId: "", documentId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/update-transaction.md b/docs/examples/1.8.x/client-graphql/examples/databases/update-transaction.md new file mode 100644 index 0000000000..b56c7139ac --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/databases/update-transaction.md @@ -0,0 +1,14 @@ +mutation { + databasesUpdateTransaction( + transactionId: "", + commit: false, + rollback: false + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/databases/upsert-document.md b/docs/examples/1.8.x/client-graphql/examples/databases/upsert-document.md index 9d1e753081..d487c0d303 100644 --- a/docs/examples/1.8.x/client-graphql/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-graphql/examples/databases/upsert-document.md @@ -4,7 +4,8 @@ mutation { collectionId: "", documentId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..bb2be8085a --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-operations.md @@ -0,0 +1,23 @@ +mutation { + tablesDBCreateOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-row.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-row.md index c7d2ec7d03..109bc008d6 100644 --- a/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-row.md @@ -4,7 +4,8 @@ mutation { tableId: "", rowId: "", data: "{\"username\":\"walter.obrien\",\"email\":\"walter.obrien@example.com\",\"fullName\":\"Walter O'Brien\",\"age\":30,\"isAdmin\":false}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..0e874f0c78 --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/create-transaction.md @@ -0,0 +1,12 @@ +mutation { + tablesDBCreateTransaction( + ttl: 60 + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/decrement-row-column.md index 398ec19901..1d57d79b54 100644 --- a/docs/examples/1.8.x/client-graphql/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/decrement-row-column.md @@ -5,7 +5,8 @@ mutation { rowId: "", column: "", value: 0, - min: 0 + min: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/delete-row.md index 1a08b0f60d..3b44913049 100644 --- a/docs/examples/1.8.x/client-graphql/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/delete-row.md @@ -2,7 +2,8 @@ mutation { tablesDBDeleteRow( databaseId: "", tableId: "", - rowId: "" + rowId: "", + transactionId: "" ) { status } diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..4a2d6f15a2 --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/delete-transaction.md @@ -0,0 +1,7 @@ +mutation { + tablesDBDeleteTransaction( + transactionId: "" + ) { + status + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/increment-row-column.md index b7ff87f387..3ae008e718 100644 --- a/docs/examples/1.8.x/client-graphql/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/increment-row-column.md @@ -5,7 +5,8 @@ mutation { rowId: "", column: "", value: 0, - max: 0 + max: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/update-row.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/update-row.md index 5a5b288ab8..aa89e6ae01 100644 --- a/docs/examples/1.8.x/client-graphql/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/update-row.md @@ -4,7 +4,8 @@ mutation { tableId: "", rowId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..2094877303 --- /dev/null +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/update-transaction.md @@ -0,0 +1,14 @@ +mutation { + tablesDBUpdateTransaction( + transactionId: "", + commit: false, + rollback: false + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/client-graphql/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-graphql/examples/tablesdb/upsert-row.md index cc3b63de4a..3fe36ee7f1 100644 --- a/docs/examples/1.8.x/client-graphql/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-graphql/examples/tablesdb/upsert-row.md @@ -4,7 +4,8 @@ mutation { tableId: "", rowId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/client-react-native/examples/account/create-email-verification.md b/docs/examples/1.8.x/client-react-native/examples/account/create-email-verification.md new file mode 100644 index 0000000000..42260501c2 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/account/create-email-verification.md @@ -0,0 +1,13 @@ +import { Client, Account } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const account = new Account(client); + +const result = await account.createEmailVerification({ + url: 'https://example.com' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/account/update-email-verification.md b/docs/examples/1.8.x/client-react-native/examples/account/update-email-verification.md new file mode 100644 index 0000000000..4270380d5f --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/account/update-email-verification.md @@ -0,0 +1,14 @@ +import { Client, Account } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const account = new Account(client); + +const result = await account.updateEmailVerification({ + userId: '', + secret: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/create-document.md b/docs/examples/1.8.x/client-react-native/examples/databases/create-document.md index e7cffc13d4..3f7fd9af8f 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/create-document.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/create-document.md @@ -17,7 +17,8 @@ const result = await databases.createDocument({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/create-operations.md b/docs/examples/1.8.x/client-react-native/examples/databases/create-operations.md new file mode 100644 index 0000000000..bf02fd2c29 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/databases/create-operations.md @@ -0,0 +1,24 @@ +import { Client, Databases } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/create-transaction.md b/docs/examples/1.8.x/client-react-native/examples/databases/create-transaction.md new file mode 100644 index 0000000000..07a2103e59 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/databases/create-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.createTransaction({ + ttl: 60 // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-react-native/examples/databases/decrement-document-attribute.md index ddf43c9758..5edce7b091 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/decrement-document-attribute.md @@ -12,7 +12,8 @@ const result = await databases.decrementDocumentAttribute({ documentId: '', attribute: '', value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/delete-document.md b/docs/examples/1.8.x/client-react-native/examples/databases/delete-document.md index 828cefdda8..6cad3f9585 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/delete-document.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.deleteDocument({ databaseId: '', collectionId: '', - documentId: '' + documentId: '', + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/delete-transaction.md b/docs/examples/1.8.x/client-react-native/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..9ad2661362 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/databases/delete-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.deleteTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/get-document.md b/docs/examples/1.8.x/client-react-native/examples/databases/get-document.md index 7d28ee03d5..c61d396d3e 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/get-document.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/get-document.md @@ -10,7 +10,8 @@ const result = await databases.getDocument({ databaseId: '', collectionId: '', documentId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/get-transaction.md b/docs/examples/1.8.x/client-react-native/examples/databases/get-transaction.md new file mode 100644 index 0000000000..47f93691e0 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/databases/get-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.getTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-react-native/examples/databases/increment-document-attribute.md index c129c38a25..259a184e3a 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/increment-document-attribute.md @@ -12,7 +12,8 @@ const result = await databases.incrementDocumentAttribute({ documentId: '', attribute: '', value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/list-documents.md b/docs/examples/1.8.x/client-react-native/examples/databases/list-documents.md index 8d210b08e9..a744a531a1 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/list-documents.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.listDocuments({ databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/list-transactions.md b/docs/examples/1.8.x/client-react-native/examples/databases/list-transactions.md new file mode 100644 index 0000000000..2339673803 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/databases/list-transactions.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.listTransactions({ + queries: [] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/update-document.md b/docs/examples/1.8.x/client-react-native/examples/databases/update-document.md index ce4a6f2222..29674bd3d0 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/update-document.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/update-document.md @@ -11,7 +11,8 @@ const result = await databases.updateDocument({ collectionId: '', documentId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/update-transaction.md b/docs/examples/1.8.x/client-react-native/examples/databases/update-transaction.md new file mode 100644 index 0000000000..c333850656 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/databases/update-transaction.md @@ -0,0 +1,15 @@ +import { Client, Databases } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/databases/upsert-document.md b/docs/examples/1.8.x/client-react-native/examples/databases/upsert-document.md index a351ed7d4d..aa8fd1ca94 100644 --- a/docs/examples/1.8.x/client-react-native/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-react-native/examples/databases/upsert-document.md @@ -11,7 +11,8 @@ const result = await databases.upsertDocument({ collectionId: '', documentId: '', data: {}, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..1c76de77d2 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-operations.md @@ -0,0 +1,24 @@ +import { Client, TablesDB } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-row.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-row.md index a02a8376d5..6be799f547 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-row.md @@ -17,7 +17,8 @@ const result = await tablesDB.createRow({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..c2eca27695 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/create-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.createTransaction({ + ttl: 60 // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/decrement-row-column.md index e00eeb84bf..7bf6d77a46 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/decrement-row-column.md @@ -12,7 +12,8 @@ const result = await tablesDB.decrementRowColumn({ rowId: '', column: '', value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/delete-row.md index 624f1a191f..3ab81237eb 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/delete-row.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.deleteRow({ databaseId: '', tableId: '', - rowId: '' + rowId: '', + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..121e6b3f67 --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/delete-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.deleteTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/get-row.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/get-row.md index 081db46f18..a3a8775b4a 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/get-row.md @@ -10,7 +10,8 @@ const result = await tablesDB.getRow({ databaseId: '', tableId: '', rowId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..475e2d83ee --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/get-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.getTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/increment-row-column.md index d4b2cf98ad..4bda1efb24 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/increment-row-column.md @@ -12,7 +12,8 @@ const result = await tablesDB.incrementRowColumn({ rowId: '', column: '', value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/list-rows.md index 6148e97e90..7cab86bc64 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/list-rows.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.listRows({ databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..9d3004a90c --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/list-transactions.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.listTransactions({ + queries: [] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/update-row.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/update-row.md index 01ed6e6acc..a83e3ea3e1 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/update-row.md @@ -11,7 +11,8 @@ const result = await tablesDB.updateRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..de29a5bd2c --- /dev/null +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/update-transaction.md @@ -0,0 +1,15 @@ +import { Client, TablesDB } from "react-native-appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-react-native/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-react-native/examples/tablesdb/upsert-row.md index 72fad15ac4..7a82e0711e 100644 --- a/docs/examples/1.8.x/client-react-native/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-react-native/examples/tablesdb/upsert-row.md @@ -11,7 +11,8 @@ const result = await tablesDB.upsertRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-rest/examples/account/create-email-verification.md b/docs/examples/1.8.x/client-rest/examples/account/create-email-verification.md new file mode 100644 index 0000000000..63fcd5765e --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/account/create-email-verification.md @@ -0,0 +1,11 @@ +POST /v1/account/verifications/email HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "url": "https://example.com" +} diff --git a/docs/examples/1.8.x/client-rest/examples/account/create-phone-verification.md b/docs/examples/1.8.x/client-rest/examples/account/create-phone-verification.md index 57b3b7d160..b48c9249b3 100644 --- a/docs/examples/1.8.x/client-rest/examples/account/create-phone-verification.md +++ b/docs/examples/1.8.x/client-rest/examples/account/create-phone-verification.md @@ -1,4 +1,4 @@ -POST /v1/account/verification/phone HTTP/1.1 +POST /v1/account/verifications/phone HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/client-rest/examples/account/create-verification.md b/docs/examples/1.8.x/client-rest/examples/account/create-verification.md index ed5479dbe5..63fcd5765e 100644 --- a/docs/examples/1.8.x/client-rest/examples/account/create-verification.md +++ b/docs/examples/1.8.x/client-rest/examples/account/create-verification.md @@ -1,4 +1,4 @@ -POST /v1/account/verification HTTP/1.1 +POST /v1/account/verifications/email HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/client-rest/examples/account/update-email-verification.md b/docs/examples/1.8.x/client-rest/examples/account/update-email-verification.md new file mode 100644 index 0000000000..c7c6c34e52 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/account/update-email-verification.md @@ -0,0 +1,12 @@ +PUT /v1/account/verifications/email HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "userId": "", + "secret": "" +} diff --git a/docs/examples/1.8.x/client-rest/examples/account/update-phone-verification.md b/docs/examples/1.8.x/client-rest/examples/account/update-phone-verification.md index 1d4dc22520..faa6478150 100644 --- a/docs/examples/1.8.x/client-rest/examples/account/update-phone-verification.md +++ b/docs/examples/1.8.x/client-rest/examples/account/update-phone-verification.md @@ -1,4 +1,4 @@ -PUT /v1/account/verification/phone HTTP/1.1 +PUT /v1/account/verifications/phone HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/client-rest/examples/account/update-verification.md b/docs/examples/1.8.x/client-rest/examples/account/update-verification.md index a4dcbf76a3..c7c6c34e52 100644 --- a/docs/examples/1.8.x/client-rest/examples/account/update-verification.md +++ b/docs/examples/1.8.x/client-rest/examples/account/update-verification.md @@ -1,4 +1,4 @@ -PUT /v1/account/verification HTTP/1.1 +PUT /v1/account/verifications/email HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/client-rest/examples/databases/create-document.md b/docs/examples/1.8.x/client-rest/examples/databases/create-document.md index 12f2159402..c53babd482 100644 --- a/docs/examples/1.8.x/client-rest/examples/databases/create-document.md +++ b/docs/examples/1.8.x/client-rest/examples/databases/create-document.md @@ -15,5 +15,6 @@ X-Appwrite-JWT: "age": 30, "isAdmin": false }, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/databases/create-operations.md b/docs/examples/1.8.x/client-rest/examples/databases/create-operations.md new file mode 100644 index 0000000000..602effd9a2 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/databases/create-operations.md @@ -0,0 +1,21 @@ +POST /v1/databases/transactions/{transactionId}/operations HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "operations": [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] +} diff --git a/docs/examples/1.8.x/client-rest/examples/databases/create-transaction.md b/docs/examples/1.8.x/client-rest/examples/databases/create-transaction.md new file mode 100644 index 0000000000..c58528731e --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/databases/create-transaction.md @@ -0,0 +1,11 @@ +POST /v1/databases/transactions HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "ttl": 60 +} diff --git a/docs/examples/1.8.x/client-rest/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-rest/examples/databases/decrement-document-attribute.md index 85ee70588b..be1d8d5bb6 100644 --- a/docs/examples/1.8.x/client-rest/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-rest/examples/databases/decrement-document-attribute.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "value": 0, - "min": 0 + "min": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/databases/delete-document.md b/docs/examples/1.8.x/client-rest/examples/databases/delete-document.md index 2ee4f92ec4..3fa0a3ca21 100644 --- a/docs/examples/1.8.x/client-rest/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/client-rest/examples/databases/delete-document.md @@ -6,3 +6,6 @@ X-Appwrite-Project: X-Appwrite-Session: X-Appwrite-JWT: +{ + "transactionId": "" +} diff --git a/docs/examples/1.8.x/client-rest/examples/databases/delete-transaction.md b/docs/examples/1.8.x/client-rest/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..1982dbb5a4 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/databases/delete-transaction.md @@ -0,0 +1,8 @@ +DELETE /v1/databases/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + diff --git a/docs/examples/1.8.x/client-rest/examples/databases/get-transaction.md b/docs/examples/1.8.x/client-rest/examples/databases/get-transaction.md new file mode 100644 index 0000000000..09cc2e6c95 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/databases/get-transaction.md @@ -0,0 +1,6 @@ +GET /v1/databases/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/client-rest/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-rest/examples/databases/increment-document-attribute.md index 68b091a31e..9eb873d6ff 100644 --- a/docs/examples/1.8.x/client-rest/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-rest/examples/databases/increment-document-attribute.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "value": 0, - "max": 0 + "max": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/databases/list-transactions.md b/docs/examples/1.8.x/client-rest/examples/databases/list-transactions.md new file mode 100644 index 0000000000..f080df9228 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/databases/list-transactions.md @@ -0,0 +1,6 @@ +GET /v1/databases/transactions HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/client-rest/examples/databases/update-document.md b/docs/examples/1.8.x/client-rest/examples/databases/update-document.md index ffc5d36011..f39cabfec3 100644 --- a/docs/examples/1.8.x/client-rest/examples/databases/update-document.md +++ b/docs/examples/1.8.x/client-rest/examples/databases/update-document.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/databases/update-transaction.md b/docs/examples/1.8.x/client-rest/examples/databases/update-transaction.md new file mode 100644 index 0000000000..e8358a9051 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/databases/update-transaction.md @@ -0,0 +1,12 @@ +PATCH /v1/databases/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "commit": false, + "rollback": false +} diff --git a/docs/examples/1.8.x/client-rest/examples/databases/upsert-document.md b/docs/examples/1.8.x/client-rest/examples/databases/upsert-document.md index d2baeac6a8..c84d74a5ff 100644 --- a/docs/examples/1.8.x/client-rest/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-rest/examples/databases/upsert-document.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..dd3a05e271 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/create-operations.md @@ -0,0 +1,21 @@ +POST /v1/tablesdb/transactions/{transactionId}/operations HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "operations": [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] +} diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/create-row.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/create-row.md index 34d8ab5152..2abe0cc316 100644 --- a/docs/examples/1.8.x/client-rest/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/create-row.md @@ -15,5 +15,6 @@ X-Appwrite-JWT: "age": 30, "isAdmin": false }, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..e796ea2b57 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/create-transaction.md @@ -0,0 +1,11 @@ +POST /v1/tablesdb/transactions HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "ttl": 60 +} diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/decrement-row-column.md index 676e090150..b8dd25fdc5 100644 --- a/docs/examples/1.8.x/client-rest/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/decrement-row-column.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "value": 0, - "min": 0 + "min": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/delete-row.md index f3ba056f7e..908bc4cc1f 100644 --- a/docs/examples/1.8.x/client-rest/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/delete-row.md @@ -6,3 +6,6 @@ X-Appwrite-Project: X-Appwrite-Session: X-Appwrite-JWT: +{ + "transactionId": "" +} diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..54421d1c47 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/delete-transaction.md @@ -0,0 +1,8 @@ +DELETE /v1/tablesdb/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..4276a3fb94 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/get-transaction.md @@ -0,0 +1,6 @@ +GET /v1/tablesdb/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/increment-row-column.md index 5172cb420b..be9effd073 100644 --- a/docs/examples/1.8.x/client-rest/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/increment-row-column.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "value": 0, - "max": 0 + "max": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..91b6108463 --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/list-transactions.md @@ -0,0 +1,6 @@ +GET /v1/tablesdb/transactions HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/update-row.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/update-row.md index 40d276a0fe..7249d93906 100644 --- a/docs/examples/1.8.x/client-rest/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/update-row.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..f0f96d735f --- /dev/null +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/update-transaction.md @@ -0,0 +1,12 @@ +PATCH /v1/tablesdb/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "commit": false, + "rollback": false +} diff --git a/docs/examples/1.8.x/client-rest/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-rest/examples/tablesdb/upsert-row.md index 581790fc01..93f6236eca 100644 --- a/docs/examples/1.8.x/client-rest/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-rest/examples/tablesdb/upsert-row.md @@ -8,5 +8,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/client-web/examples/account/create-email-verification.md b/docs/examples/1.8.x/client-web/examples/account/create-email-verification.md new file mode 100644 index 0000000000..8f93533c35 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/account/create-email-verification.md @@ -0,0 +1,13 @@ +import { Client, Account } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const account = new Account(client); + +const result = await account.createEmailVerification({ + url: 'https://example.com' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/account/update-email-verification.md b/docs/examples/1.8.x/client-web/examples/account/update-email-verification.md new file mode 100644 index 0000000000..4f1e03f3c6 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/account/update-email-verification.md @@ -0,0 +1,14 @@ +import { Client, Account } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const account = new Account(client); + +const result = await account.updateEmailVerification({ + userId: '', + secret: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/create-document.md b/docs/examples/1.8.x/client-web/examples/databases/create-document.md index 08606c9b4f..8417575ebf 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/create-document.md +++ b/docs/examples/1.8.x/client-web/examples/databases/create-document.md @@ -17,7 +17,8 @@ const result = await databases.createDocument({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/create-operations.md b/docs/examples/1.8.x/client-web/examples/databases/create-operations.md new file mode 100644 index 0000000000..2ebc085d44 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/databases/create-operations.md @@ -0,0 +1,24 @@ +import { Client, Databases } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/create-transaction.md b/docs/examples/1.8.x/client-web/examples/databases/create-transaction.md new file mode 100644 index 0000000000..5371412cc9 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/databases/create-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.createTransaction({ + ttl: 60 // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/client-web/examples/databases/decrement-document-attribute.md index 98629c4e6c..f8e0ae9829 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/client-web/examples/databases/decrement-document-attribute.md @@ -12,7 +12,8 @@ const result = await databases.decrementDocumentAttribute({ documentId: '', attribute: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/delete-document.md b/docs/examples/1.8.x/client-web/examples/databases/delete-document.md index 4192085653..4d10afdac5 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/client-web/examples/databases/delete-document.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.deleteDocument({ databaseId: '', collectionId: '', - documentId: '' + documentId: '', + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/delete-transaction.md b/docs/examples/1.8.x/client-web/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..afe55c547a --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/databases/delete-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.deleteTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/get-document.md b/docs/examples/1.8.x/client-web/examples/databases/get-document.md index b3a7558907..5a44aeb73e 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/get-document.md +++ b/docs/examples/1.8.x/client-web/examples/databases/get-document.md @@ -10,7 +10,8 @@ const result = await databases.getDocument({ databaseId: '', collectionId: '', documentId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/get-transaction.md b/docs/examples/1.8.x/client-web/examples/databases/get-transaction.md new file mode 100644 index 0000000000..cc51199a76 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/databases/get-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.getTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/client-web/examples/databases/increment-document-attribute.md index 8adb5d8091..eaf718e98d 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/client-web/examples/databases/increment-document-attribute.md @@ -12,7 +12,8 @@ const result = await databases.incrementDocumentAttribute({ documentId: '', attribute: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/list-documents.md b/docs/examples/1.8.x/client-web/examples/databases/list-documents.md index fb1d508fed..ece656a644 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/client-web/examples/databases/list-documents.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.listDocuments({ databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/list-transactions.md b/docs/examples/1.8.x/client-web/examples/databases/list-transactions.md new file mode 100644 index 0000000000..f2ce1f7536 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/databases/list-transactions.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.listTransactions({ + queries: [] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/update-document.md b/docs/examples/1.8.x/client-web/examples/databases/update-document.md index bf3554812d..33a6d73a12 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/update-document.md +++ b/docs/examples/1.8.x/client-web/examples/databases/update-document.md @@ -11,7 +11,8 @@ const result = await databases.updateDocument({ collectionId: '', documentId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/update-transaction.md b/docs/examples/1.8.x/client-web/examples/databases/update-transaction.md new file mode 100644 index 0000000000..9274b0f9bf --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/databases/update-transaction.md @@ -0,0 +1,15 @@ +import { Client, Databases } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/databases/upsert-document.md b/docs/examples/1.8.x/client-web/examples/databases/upsert-document.md index c56bc5534d..e14ad5fc6b 100644 --- a/docs/examples/1.8.x/client-web/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/client-web/examples/databases/upsert-document.md @@ -11,7 +11,8 @@ const result = await databases.upsertDocument({ collectionId: '', documentId: '', data: {}, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/client-web/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..c25b051430 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/create-operations.md @@ -0,0 +1,24 @@ +import { Client, TablesDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/create-row.md b/docs/examples/1.8.x/client-web/examples/tablesdb/create-row.md index 1dd1fe4241..3bbcf89d4f 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/create-row.md @@ -17,7 +17,8 @@ const result = await tablesDB.createRow({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/client-web/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..17787dc9a3 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/create-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.createTransaction({ + ttl: 60 // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/client-web/examples/tablesdb/decrement-row-column.md index 59f66d973f..d6c64645f3 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/decrement-row-column.md @@ -12,7 +12,8 @@ const result = await tablesDB.decrementRowColumn({ rowId: '', column: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/client-web/examples/tablesdb/delete-row.md index 637114d413..54c005c702 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/delete-row.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.deleteRow({ databaseId: '', tableId: '', - rowId: '' + rowId: '', + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/client-web/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..2ff1198225 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/delete-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.deleteTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/get-row.md b/docs/examples/1.8.x/client-web/examples/tablesdb/get-row.md index 4e436432b7..b345d145aa 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/get-row.md @@ -10,7 +10,8 @@ const result = await tablesDB.getRow({ databaseId: '', tableId: '', rowId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/client-web/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..8e2f24cd4c --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/get-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.getTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/client-web/examples/tablesdb/increment-row-column.md index a7f3a8c312..5baca80c35 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/increment-row-column.md @@ -12,7 +12,8 @@ const result = await tablesDB.incrementRowColumn({ rowId: '', column: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/client-web/examples/tablesdb/list-rows.md index 63149aaba4..c0efd8486c 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/list-rows.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.listRows({ databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/client-web/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..fbf0908a81 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/list-transactions.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.listTransactions({ + queries: [] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/update-row.md b/docs/examples/1.8.x/client-web/examples/tablesdb/update-row.md index 1dba006762..ecbcd4fc7a 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/update-row.md @@ -11,7 +11,8 @@ const result = await tablesDB.updateRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/client-web/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..2d987e4235 --- /dev/null +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/update-transaction.md @@ -0,0 +1,15 @@ +import { Client, TablesDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/client-web/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/client-web/examples/tablesdb/upsert-row.md index 1add1c45b9..ddac9ff327 100644 --- a/docs/examples/1.8.x/client-web/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/client-web/examples/tablesdb/upsert-row.md @@ -11,7 +11,8 @@ const result = await tablesDB.upsertRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-cli/examples/account/create-email-verification.md b/docs/examples/1.8.x/console-cli/examples/account/create-email-verification.md new file mode 100644 index 0000000000..f9f37f2f8f --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/account/create-email-verification.md @@ -0,0 +1,2 @@ +appwrite account create-email-verification \ + --url https://example.com diff --git a/docs/examples/1.8.x/console-cli/examples/account/update-email-verification.md b/docs/examples/1.8.x/console-cli/examples/account/update-email-verification.md new file mode 100644 index 0000000000..02ff32aa57 --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/account/update-email-verification.md @@ -0,0 +1,3 @@ +appwrite account update-email-verification \ + --user-id \ + --secret diff --git a/docs/examples/1.8.x/console-cli/examples/databases/create-operations.md b/docs/examples/1.8.x/console-cli/examples/databases/create-operations.md new file mode 100644 index 0000000000..367b435c9d --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/databases/create-operations.md @@ -0,0 +1,2 @@ +appwrite databases create-operations \ + --transaction-id diff --git a/docs/examples/1.8.x/console-cli/examples/databases/create-transaction.md b/docs/examples/1.8.x/console-cli/examples/databases/create-transaction.md new file mode 100644 index 0000000000..ef348e75ad --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/databases/create-transaction.md @@ -0,0 +1 @@ +appwrite databases create-transaction diff --git a/docs/examples/1.8.x/console-cli/examples/databases/delete-transaction.md b/docs/examples/1.8.x/console-cli/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..13c02b676b --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/databases/delete-transaction.md @@ -0,0 +1,2 @@ +appwrite databases delete-transaction \ + --transaction-id diff --git a/docs/examples/1.8.x/console-cli/examples/databases/get-transaction.md b/docs/examples/1.8.x/console-cli/examples/databases/get-transaction.md new file mode 100644 index 0000000000..7fc80e40d2 --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/databases/get-transaction.md @@ -0,0 +1,2 @@ +appwrite databases get-transaction \ + --transaction-id diff --git a/docs/examples/1.8.x/console-cli/examples/databases/list-transactions.md b/docs/examples/1.8.x/console-cli/examples/databases/list-transactions.md new file mode 100644 index 0000000000..f0cc259b43 --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/databases/list-transactions.md @@ -0,0 +1 @@ +appwrite databases list-transactions diff --git a/docs/examples/1.8.x/console-cli/examples/databases/update-transaction.md b/docs/examples/1.8.x/console-cli/examples/databases/update-transaction.md new file mode 100644 index 0000000000..cda11d4e5f --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/databases/update-transaction.md @@ -0,0 +1,2 @@ +appwrite databases update-transaction \ + --transaction-id diff --git a/docs/examples/1.8.x/console-cli/examples/migrations/create-csv-migration.md b/docs/examples/1.8.x/console-cli/examples/migrations/create-csv-migration.md index 4b72b6f689..10e7b42b6c 100644 --- a/docs/examples/1.8.x/console-cli/examples/migrations/create-csv-migration.md +++ b/docs/examples/1.8.x/console-cli/examples/migrations/create-csv-migration.md @@ -1,4 +1,4 @@ appwrite migrations create-csv-migration \ --bucket-id \ --file-id \ - --resource-id [ID1:ID2] + --resource-id diff --git a/docs/examples/1.8.x/console-cli/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/console-cli/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..dbea61862b --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/tablesdb/create-operations.md @@ -0,0 +1,2 @@ +appwrite tables-db create-operations \ + --transaction-id diff --git a/docs/examples/1.8.x/console-cli/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/console-cli/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..c6487fd74a --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/tablesdb/create-transaction.md @@ -0,0 +1 @@ +appwrite tables-db create-transaction diff --git a/docs/examples/1.8.x/console-cli/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/console-cli/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..59e40d2fda --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/tablesdb/delete-transaction.md @@ -0,0 +1,2 @@ +appwrite tables-db delete-transaction \ + --transaction-id diff --git a/docs/examples/1.8.x/console-cli/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/console-cli/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..29ea9d75da --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/tablesdb/get-transaction.md @@ -0,0 +1,2 @@ +appwrite tables-db get-transaction \ + --transaction-id diff --git a/docs/examples/1.8.x/console-cli/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/console-cli/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..4dfbc2e567 --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/tablesdb/list-transactions.md @@ -0,0 +1 @@ +appwrite tables-db list-transactions diff --git a/docs/examples/1.8.x/console-cli/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/console-cli/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..6fa6d9510e --- /dev/null +++ b/docs/examples/1.8.x/console-cli/examples/tablesdb/update-transaction.md @@ -0,0 +1,2 @@ +appwrite tables-db update-transaction \ + --transaction-id diff --git a/docs/examples/1.8.x/console-web/examples/account/create-email-verification.md b/docs/examples/1.8.x/console-web/examples/account/create-email-verification.md new file mode 100644 index 0000000000..b0e52db469 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/account/create-email-verification.md @@ -0,0 +1,13 @@ +import { Client, Account } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const account = new Account(client); + +const result = await account.createEmailVerification({ + url: 'https://example.com' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/account/update-email-verification.md b/docs/examples/1.8.x/console-web/examples/account/update-email-verification.md new file mode 100644 index 0000000000..e0e09fd4ce --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/account/update-email-verification.md @@ -0,0 +1,14 @@ +import { Client, Account } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const account = new Account(client); + +const result = await account.updateEmailVerification({ + userId: '', + secret: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/create-document.md b/docs/examples/1.8.x/console-web/examples/databases/create-document.md index 40fbd4ad85..80f3fe66ad 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/create-document.md +++ b/docs/examples/1.8.x/console-web/examples/databases/create-document.md @@ -17,7 +17,8 @@ const result = await databases.createDocument({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/create-documents.md b/docs/examples/1.8.x/console-web/examples/databases/create-documents.md index 901133ac0a..10738b0f11 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/console-web/examples/databases/create-documents.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.createDocuments({ databaseId: '', collectionId: '', - documents: [] + documents: [], + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/create-operations.md b/docs/examples/1.8.x/console-web/examples/databases/create-operations.md new file mode 100644 index 0000000000..ec511b0ddc --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/databases/create-operations.md @@ -0,0 +1,24 @@ +import { Client, Databases } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/create-transaction.md b/docs/examples/1.8.x/console-web/examples/databases/create-transaction.md new file mode 100644 index 0000000000..fc84f1d14f --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/databases/create-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.createTransaction({ + ttl: 60 // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/console-web/examples/databases/decrement-document-attribute.md index ec014643bb..64f469c6ef 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/console-web/examples/databases/decrement-document-attribute.md @@ -12,7 +12,8 @@ const result = await databases.decrementDocumentAttribute({ documentId: '', attribute: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/delete-document.md b/docs/examples/1.8.x/console-web/examples/databases/delete-document.md index 11cf317147..c2cdad3d84 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/console-web/examples/databases/delete-document.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.deleteDocument({ databaseId: '', collectionId: '', - documentId: '' + documentId: '', + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/delete-documents.md b/docs/examples/1.8.x/console-web/examples/databases/delete-documents.md index 45601a5985..0749194c97 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/console-web/examples/databases/delete-documents.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.deleteDocuments({ databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/delete-transaction.md b/docs/examples/1.8.x/console-web/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..16b7c64022 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/databases/delete-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.deleteTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/get-document.md b/docs/examples/1.8.x/console-web/examples/databases/get-document.md index 00595b1033..8d893df7d9 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/get-document.md +++ b/docs/examples/1.8.x/console-web/examples/databases/get-document.md @@ -10,7 +10,8 @@ const result = await databases.getDocument({ databaseId: '', collectionId: '', documentId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/get-transaction.md b/docs/examples/1.8.x/console-web/examples/databases/get-transaction.md new file mode 100644 index 0000000000..8b6733b423 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/databases/get-transaction.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.getTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/console-web/examples/databases/increment-document-attribute.md index 2207e94563..dbba4b0688 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/console-web/examples/databases/increment-document-attribute.md @@ -12,7 +12,8 @@ const result = await databases.incrementDocumentAttribute({ documentId: '', attribute: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/list-documents.md b/docs/examples/1.8.x/console-web/examples/databases/list-documents.md index dda036951c..f0a7a27890 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/console-web/examples/databases/list-documents.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.listDocuments({ databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/list-transactions.md b/docs/examples/1.8.x/console-web/examples/databases/list-transactions.md new file mode 100644 index 0000000000..53e8d61f3e --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/databases/list-transactions.md @@ -0,0 +1,13 @@ +import { Client, Databases } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.listTransactions({ + queries: [] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/update-document.md b/docs/examples/1.8.x/console-web/examples/databases/update-document.md index 168ad11bda..8a92d5b9f4 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/update-document.md +++ b/docs/examples/1.8.x/console-web/examples/databases/update-document.md @@ -11,7 +11,8 @@ const result = await databases.updateDocument({ collectionId: '', documentId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/update-documents.md b/docs/examples/1.8.x/console-web/examples/databases/update-documents.md index 7462502c81..9f9054bad2 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/console-web/examples/databases/update-documents.md @@ -10,7 +10,8 @@ const result = await databases.updateDocuments({ databaseId: '', collectionId: '', data: {}, // optional - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/update-transaction.md b/docs/examples/1.8.x/console-web/examples/databases/update-transaction.md new file mode 100644 index 0000000000..4a219f4beb --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/databases/update-transaction.md @@ -0,0 +1,15 @@ +import { Client, Databases } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const databases = new Databases(client); + +const result = await databases.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/upsert-document.md b/docs/examples/1.8.x/console-web/examples/databases/upsert-document.md index 3f8705f7c8..e7a52fd7cd 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/console-web/examples/databases/upsert-document.md @@ -11,7 +11,8 @@ const result = await databases.upsertDocument({ collectionId: '', documentId: '', data: {}, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/databases/upsert-documents.md b/docs/examples/1.8.x/console-web/examples/databases/upsert-documents.md index b045516281..cc561de247 100644 --- a/docs/examples/1.8.x/console-web/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/console-web/examples/databases/upsert-documents.md @@ -9,7 +9,8 @@ const databases = new Databases(client); const result = await databases.upsertDocuments({ databaseId: '', collectionId: '', - documents: [] + documents: [], + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/messaging/create-push.md b/docs/examples/1.8.x/console-web/examples/messaging/create-push.md index f0f54aa72f..783d8fe535 100644 --- a/docs/examples/1.8.x/console-web/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/console-web/examples/messaging/create-push.md @@ -15,7 +15,7 @@ const result = await messaging.createPush({ targets: [], // optional data: {}, // optional action: '', // optional - image: '[ID1:ID2]', // optional + image: '', // optional icon: '', // optional sound: '', // optional color: '', // optional diff --git a/docs/examples/1.8.x/console-web/examples/messaging/update-push.md b/docs/examples/1.8.x/console-web/examples/messaging/update-push.md index 5f5d6e5da2..e1b0cc6b9d 100644 --- a/docs/examples/1.8.x/console-web/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/console-web/examples/messaging/update-push.md @@ -15,7 +15,7 @@ const result = await messaging.updatePush({ body: '', // optional data: {}, // optional action: '', // optional - image: '[ID1:ID2]', // optional + image: '', // optional icon: '', // optional sound: '', // optional color: '', // optional diff --git a/docs/examples/1.8.x/console-web/examples/migrations/create-csv-migration.md b/docs/examples/1.8.x/console-web/examples/migrations/create-csv-migration.md index b25193ed21..f32adcb53c 100644 --- a/docs/examples/1.8.x/console-web/examples/migrations/create-csv-migration.md +++ b/docs/examples/1.8.x/console-web/examples/migrations/create-csv-migration.md @@ -9,7 +9,7 @@ const migrations = new Migrations(client); const result = await migrations.createCsvMigration({ bucketId: '', fileId: '', - resourceId: '[ID1:ID2]', + resourceId: '', internalFile: false // optional }); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/console-web/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..744627adae --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/create-operations.md @@ -0,0 +1,24 @@ +import { Client, TablesDB } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/create-row.md b/docs/examples/1.8.x/console-web/examples/tablesdb/create-row.md index 6123b5fc31..1991d44258 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/create-row.md @@ -17,7 +17,8 @@ const result = await tablesDB.createRow({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/console-web/examples/tablesdb/create-rows.md index b827beb048..1054433a74 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/create-rows.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.createRows({ databaseId: '', tableId: '', - rows: [] + rows: [], + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/console-web/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..68465d4968 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/create-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.createTransaction({ + ttl: 60 // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/console-web/examples/tablesdb/decrement-row-column.md index 067afc7820..2f46b6d958 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/decrement-row-column.md @@ -12,7 +12,8 @@ const result = await tablesDB.decrementRowColumn({ rowId: '', column: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/console-web/examples/tablesdb/delete-row.md index 9b7def4f00..1bcb477c18 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/delete-row.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.deleteRow({ databaseId: '', tableId: '', - rowId: '' + rowId: '', + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/console-web/examples/tablesdb/delete-rows.md index 16868a0c6e..c955326753 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/delete-rows.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.deleteRows({ databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/console-web/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..b4f427a727 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/delete-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.deleteTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/get-row.md b/docs/examples/1.8.x/console-web/examples/tablesdb/get-row.md index f170078430..831a9d1af2 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/get-row.md @@ -10,7 +10,8 @@ const result = await tablesDB.getRow({ databaseId: '', tableId: '', rowId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/console-web/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..99d405e0a2 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/get-transaction.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.getTransaction({ + transactionId: '' +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/console-web/examples/tablesdb/increment-row-column.md index 95694d49a4..a0047abb86 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/increment-row-column.md @@ -12,7 +12,8 @@ const result = await tablesDB.incrementRowColumn({ rowId: '', column: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/console-web/examples/tablesdb/list-rows.md index 46159b3d42..d87bd450d0 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/list-rows.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.listRows({ databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/console-web/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..8ecfcefee1 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/list-transactions.md @@ -0,0 +1,13 @@ +import { Client, TablesDB } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.listTransactions({ + queries: [] // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/update-row.md b/docs/examples/1.8.x/console-web/examples/tablesdb/update-row.md index 5d6109c04c..6193d79567 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/update-row.md @@ -11,7 +11,8 @@ const result = await tablesDB.updateRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/console-web/examples/tablesdb/update-rows.md index 0ce117efa3..7601955b8b 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/update-rows.md @@ -10,7 +10,8 @@ const result = await tablesDB.updateRows({ databaseId: '', tableId: '', data: {}, // optional - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/console-web/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..9095edc161 --- /dev/null +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/update-transaction.md @@ -0,0 +1,15 @@ +import { Client, TablesDB } from "@appwrite.io/console"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const tablesDB = new TablesDB(client); + +const result = await tablesDB.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); + +console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-row.md index 665f181d8b..f56eff55fa 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-row.md @@ -11,7 +11,8 @@ const result = await tablesDB.upsertRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-rows.md index 05e78e3efa..173d0e3065 100644 --- a/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/console-web/examples/tablesdb/upsert-rows.md @@ -9,7 +9,8 @@ const tablesDB = new TablesDB(client); const result = await tablesDB.upsertRows({ databaseId: '', tableId: '', - rows: [] + rows: [], + transactionId: '' // optional }); console.log(result); diff --git a/docs/examples/1.8.x/server-dart/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-dart/examples/account/create-email-verification.md new file mode 100644 index 0000000000..b10173d190 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/account/create-email-verification.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setSession(''); // The user session to authenticate with + +Account account = Account(client); + +Token result = await account.createEmailVerification( + url: 'https://example.com', +); diff --git a/docs/examples/1.8.x/server-dart/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-dart/examples/account/update-email-verification.md new file mode 100644 index 0000000000..b48535a31a --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/account/update-email-verification.md @@ -0,0 +1,13 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setSession(''); // The user session to authenticate with + +Account account = Account(client); + +Token result = await account.updateEmailVerification( + userId: '', + secret: '', +); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/create-document.md b/docs/examples/1.8.x/server-dart/examples/databases/create-document.md index e3bae98162..0f663a67f6 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/create-document.md @@ -19,4 +19,5 @@ Document result = await databases.createDocument( "isAdmin": false }, permissions: ["read("any")"], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/create-documents.md b/docs/examples/1.8.x/server-dart/examples/databases/create-documents.md index ba0e34950b..6c77b78fe2 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/create-documents.md @@ -11,4 +11,5 @@ DocumentList result = await databases.createDocuments( databaseId: '', collectionId: '', documents: [], + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/create-operations.md b/docs/examples/1.8.x/server-dart/examples/databases/create-operations.md new file mode 100644 index 0000000000..2fe1121bf4 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/databases/create-operations.md @@ -0,0 +1,23 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +Databases databases = Databases(client); + +Transaction result = await databases.createOperations( + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ], // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-dart/examples/databases/create-transaction.md new file mode 100644 index 0000000000..69af666c73 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/databases/create-transaction.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +Databases databases = Databases(client); + +Transaction result = await databases.createTransaction( + ttl: 60, // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-dart/examples/databases/decrement-document-attribute.md index e46244874d..6fb7ab68e6 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/decrement-document-attribute.md @@ -14,4 +14,5 @@ Document result = await databases.decrementDocumentAttribute( attribute: '', value: 0, // (optional) min: 0, // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/delete-document.md b/docs/examples/1.8.x/server-dart/examples/databases/delete-document.md index dd04d89959..eb9c3eba36 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/delete-document.md @@ -11,4 +11,5 @@ await databases.deleteDocument( databaseId: '', collectionId: '', documentId: '', + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-dart/examples/databases/delete-documents.md index 66bd5584c7..2e4e0c3cc2 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/delete-documents.md @@ -11,4 +11,5 @@ await databases.deleteDocuments( databaseId: '', collectionId: '', queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-dart/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..6cebc33f83 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/databases/delete-transaction.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +Databases databases = Databases(client); + +await databases.deleteTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/get-document.md b/docs/examples/1.8.x/server-dart/examples/databases/get-document.md index 45745186e6..cd87138b7e 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/get-document.md @@ -12,4 +12,5 @@ Document result = await databases.getDocument( collectionId: '', documentId: '', queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-dart/examples/databases/get-transaction.md new file mode 100644 index 0000000000..dfa1b583c1 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/databases/get-transaction.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +Databases databases = Databases(client); + +Transaction result = await databases.getTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-dart/examples/databases/increment-document-attribute.md index a2d2622629..ab108ebb27 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/increment-document-attribute.md @@ -14,4 +14,5 @@ Document result = await databases.incrementDocumentAttribute( attribute: '', value: 0, // (optional) max: 0, // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/list-documents.md b/docs/examples/1.8.x/server-dart/examples/databases/list-documents.md index cdecc59e33..74d849a2cb 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/list-documents.md @@ -11,4 +11,5 @@ DocumentList result = await databases.listDocuments( databaseId: '', collectionId: '', queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-dart/examples/databases/list-transactions.md new file mode 100644 index 0000000000..856e5e86ac --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/databases/list-transactions.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +Databases databases = Databases(client); + +TransactionList result = await databases.listTransactions( + queries: [], // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/update-document.md b/docs/examples/1.8.x/server-dart/examples/databases/update-document.md index 47a1867c10..077a08f606 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/update-document.md @@ -13,4 +13,5 @@ Document result = await databases.updateDocument( documentId: '', data: {}, // (optional) permissions: ["read("any")"], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/update-documents.md b/docs/examples/1.8.x/server-dart/examples/databases/update-documents.md index 70b7cbf86d..babc2d96fb 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/update-documents.md @@ -12,4 +12,5 @@ DocumentList result = await databases.updateDocuments( collectionId: '', data: {}, // (optional) queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-dart/examples/databases/update-transaction.md new file mode 100644 index 0000000000..b2b35f20eb --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/databases/update-transaction.md @@ -0,0 +1,14 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +Databases databases = Databases(client); + +Transaction result = await databases.updateTransaction( + transactionId: '', + commit: false, // (optional) + rollback: false, // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-dart/examples/databases/upsert-document.md index 93e306ebce..be4216da67 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/upsert-document.md @@ -13,4 +13,5 @@ Document result = await databases.upsertDocument( documentId: '', data: {}, permissions: ["read("any")"], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-dart/examples/databases/upsert-documents.md index cd35014f63..009fe18b4a 100644 --- a/docs/examples/1.8.x/server-dart/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-dart/examples/databases/upsert-documents.md @@ -11,4 +11,5 @@ DocumentList result = await databases.upsertDocuments( databaseId: '', collectionId: '', documents: [], + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/messaging/create-push.md b/docs/examples/1.8.x/server-dart/examples/messaging/create-push.md index 58d82c7a0a..4b9f7d3c52 100644 --- a/docs/examples/1.8.x/server-dart/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-dart/examples/messaging/create-push.md @@ -16,7 +16,7 @@ Message result = await messaging.createPush( targets: [], // (optional) data: {}, // (optional) action: '', // (optional) - image: '[ID1:ID2]', // (optional) + image: '', // (optional) icon: '', // (optional) sound: '', // (optional) color: '', // (optional) diff --git a/docs/examples/1.8.x/server-dart/examples/messaging/update-push.md b/docs/examples/1.8.x/server-dart/examples/messaging/update-push.md index f7cc117b64..cbae5dfabb 100644 --- a/docs/examples/1.8.x/server-dart/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-dart/examples/messaging/update-push.md @@ -16,7 +16,7 @@ Message result = await messaging.updatePush( body: '', // (optional) data: {}, // (optional) action: '', // (optional) - image: '[ID1:ID2]', // (optional) + image: '', // (optional) icon: '', // (optional) sound: '', // (optional) color: '', // (optional) diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..2b5c046b14 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-operations.md @@ -0,0 +1,23 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.createOperations( + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ], // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-row.md index c2f5dd8293..255bd9615e 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-row.md @@ -19,4 +19,5 @@ Row result = await tablesDB.createRow( "isAdmin": false }, permissions: ["read("any")"], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-rows.md index c22fdba506..6366006c31 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-rows.md @@ -11,4 +11,5 @@ RowList result = await tablesDB.createRows( databaseId: '', tableId: '', rows: [], + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..721ac4cf8b --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/create-transaction.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.createTransaction( + ttl: 60, // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/decrement-row-column.md index 8c376563d8..304e6b0219 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/decrement-row-column.md @@ -14,4 +14,5 @@ Row result = await tablesDB.decrementRowColumn( column: '', value: 0, // (optional) min: 0, // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-row.md index f3966c0930..da1e280cba 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-row.md @@ -11,4 +11,5 @@ await tablesDB.deleteRow( databaseId: '', tableId: '', rowId: '', + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-rows.md index eb2aebb3e6..6738ac78fc 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-rows.md @@ -11,4 +11,5 @@ await tablesDB.deleteRows( databaseId: '', tableId: '', queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..8dc80418a0 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/delete-transaction.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +TablesDB tablesDB = TablesDB(client); + +await tablesDB.deleteTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/get-row.md index 0af17b612a..a0d7a83b39 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/get-row.md @@ -12,4 +12,5 @@ Row result = await tablesDB.getRow( tableId: '', rowId: '', queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..267af59aa9 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/get-transaction.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.getTransaction( + transactionId: '', +); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/increment-row-column.md index bbe262e5c9..049a48a7d0 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/increment-row-column.md @@ -14,4 +14,5 @@ Row result = await tablesDB.incrementRowColumn( column: '', value: 0, // (optional) max: 0, // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/list-rows.md index 83bbe38fca..a429de72f6 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/list-rows.md @@ -11,4 +11,5 @@ RowList result = await tablesDB.listRows( databaseId: '', tableId: '', queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..d4b3a5e2c3 --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/list-transactions.md @@ -0,0 +1,12 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +TablesDB tablesDB = TablesDB(client); + +TransactionList result = await tablesDB.listTransactions( + queries: [], // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/update-row.md index d66c24f505..e4f683cae0 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/update-row.md @@ -13,4 +13,5 @@ Row result = await tablesDB.updateRow( rowId: '', data: {}, // (optional) permissions: ["read("any")"], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/update-rows.md index a0973b47d1..a7c0d61b45 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/update-rows.md @@ -12,4 +12,5 @@ RowList result = await tablesDB.updateRows( tableId: '', data: {}, // (optional) queries: [], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..bb3837d4ec --- /dev/null +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/update-transaction.md @@ -0,0 +1,14 @@ +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +TablesDB tablesDB = TablesDB(client); + +Transaction result = await tablesDB.updateTransaction( + transactionId: '', + commit: false, // (optional) + rollback: false, // (optional) +); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-row.md index fbe4d2928a..f9b8c848ae 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-row.md @@ -13,4 +13,5 @@ Row result = await tablesDB.upsertRow( rowId: '', data: {}, // (optional) permissions: ["read("any")"], // (optional) + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-rows.md index 031aa50bea..d48e9094f4 100644 --- a/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-dart/examples/tablesdb/upsert-rows.md @@ -11,4 +11,5 @@ RowList result = await tablesDB.upsertRows( databaseId: '', tableId: '', rows: [], + transactionId: '', // (optional) ); diff --git a/docs/examples/1.8.x/server-dotnet/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-dotnet/examples/account/create-email-verification.md new file mode 100644 index 0000000000..6efee895e0 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/account/create-email-verification.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetSession(""); // The user session to authenticate with + +Account account = new Account(client); + +Token result = await account.CreateEmailVerification( + url: "https://example.com" +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-dotnet/examples/account/update-email-verification.md new file mode 100644 index 0000000000..a336682be3 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/account/update-email-verification.md @@ -0,0 +1,15 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetSession(""); // The user session to authenticate with + +Account account = new Account(client); + +Token result = await account.UpdateEmailVerification( + userId: "", + secret: "" +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/create-document.md b/docs/examples/1.8.x/server-dotnet/examples/databases/create-document.md index 4a7444db7a..9fcfdd041d 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/create-document.md @@ -20,5 +20,6 @@ Document result = await databases.CreateDocument( age = 30, isAdmin = false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/create-documents.md b/docs/examples/1.8.x/server-dotnet/examples/databases/create-documents.md index dad710f0df..cc6cfb7606 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/create-documents.md @@ -12,5 +12,6 @@ Databases databases = new Databases(client); DocumentList result = await databases.CreateDocuments( databaseId: "", collectionId: "", - documents: new List() + documents: new List(), + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/create-operations.md b/docs/examples/1.8.x/server-dotnet/examples/databases/create-operations.md new file mode 100644 index 0000000000..701c6432b8 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/create-operations.md @@ -0,0 +1,25 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +Databases databases = new Databases(client); + +Transaction result = await databases.CreateOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/databases/create-transaction.md new file mode 100644 index 0000000000..f8d7b34ffd --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/create-transaction.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +Databases databases = new Databases(client); + +Transaction result = await databases.CreateTransaction( + ttl: 60 // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-dotnet/examples/databases/decrement-document-attribute.md index 2e48d4578e..9ff62a08aa 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/decrement-document-attribute.md @@ -15,5 +15,6 @@ Document result = await databases.DecrementDocumentAttribute( documentId: "", attribute: "", value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/delete-document.md b/docs/examples/1.8.x/server-dotnet/examples/databases/delete-document.md index 221b80e254..34bdbdafcd 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/delete-document.md @@ -12,5 +12,6 @@ Databases databases = new Databases(client); await databases.DeleteDocument( databaseId: "", collectionId: "", - documentId: "" + documentId: "", + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-dotnet/examples/databases/delete-documents.md index a9bc9c277b..52f711b842 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/delete-documents.md @@ -12,5 +12,6 @@ Databases databases = new Databases(client); await databases.DeleteDocuments( databaseId: "", collectionId: "", - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..713a75787e --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/delete-transaction.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +Databases databases = new Databases(client); + +await databases.DeleteTransaction( + transactionId: "" +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/get-document.md b/docs/examples/1.8.x/server-dotnet/examples/databases/get-document.md index d7e9b68807..bbafc3c888 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/get-document.md @@ -13,5 +13,6 @@ Document result = await databases.GetDocument( databaseId: "", collectionId: "", documentId: "", - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/databases/get-transaction.md new file mode 100644 index 0000000000..d66ab6e205 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/get-transaction.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +Databases databases = new Databases(client); + +Transaction result = await databases.GetTransaction( + transactionId: "" +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-dotnet/examples/databases/increment-document-attribute.md index 923c8d63e2..37a4ed76eb 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/increment-document-attribute.md @@ -15,5 +15,6 @@ Document result = await databases.IncrementDocumentAttribute( documentId: "", attribute: "", value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/list-documents.md b/docs/examples/1.8.x/server-dotnet/examples/databases/list-documents.md index f59e4576bd..643c42015d 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/list-documents.md @@ -12,5 +12,6 @@ Databases databases = new Databases(client); DocumentList result = await databases.ListDocuments( databaseId: "", collectionId: "", - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-dotnet/examples/databases/list-transactions.md new file mode 100644 index 0000000000..3f2ce0df24 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/list-transactions.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +Databases databases = new Databases(client); + +TransactionList result = await databases.ListTransactions( + queries: new List() // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/update-document.md b/docs/examples/1.8.x/server-dotnet/examples/databases/update-document.md index 3121c15e08..838b2790a9 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/update-document.md @@ -14,5 +14,6 @@ Document result = await databases.UpdateDocument( collectionId: "", documentId: "", data: [object], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/update-documents.md b/docs/examples/1.8.x/server-dotnet/examples/databases/update-documents.md index 63ded21ac9..077ec04da6 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/update-documents.md @@ -13,5 +13,6 @@ DocumentList result = await databases.UpdateDocuments( databaseId: "", collectionId: "", data: [object], // optional - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/databases/update-transaction.md new file mode 100644 index 0000000000..056f0d86f0 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/update-transaction.md @@ -0,0 +1,16 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +Databases databases = new Databases(client); + +Transaction result = await databases.UpdateTransaction( + transactionId: "", + commit: false, // optional + rollback: false // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-document.md index c0876bfa73..e12c5dd0d7 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-document.md @@ -14,5 +14,6 @@ Document result = await databases.UpsertDocument( collectionId: "", documentId: "", data: [object], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-documents.md index 6c124c16e5..4fefbfcc38 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-dotnet/examples/databases/upsert-documents.md @@ -12,5 +12,6 @@ Databases databases = new Databases(client); DocumentList result = await databases.UpsertDocuments( databaseId: "", collectionId: "", - documents: new List() + documents: new List(), + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/messaging/create-push.md b/docs/examples/1.8.x/server-dotnet/examples/messaging/create-push.md index 1d2dbec1f2..ec90fa6d90 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-dotnet/examples/messaging/create-push.md @@ -19,7 +19,7 @@ Message result = await messaging.CreatePush( targets: new List(), // optional data: [object], // optional action: "", // optional - image: "[ID1:ID2]", // optional + image: "", // optional icon: "", // optional sound: "", // optional color: "", // optional diff --git a/docs/examples/1.8.x/server-dotnet/examples/messaging/update-push.md b/docs/examples/1.8.x/server-dotnet/examples/messaging/update-push.md index 37da215e82..b45752c815 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-dotnet/examples/messaging/update-push.md @@ -19,7 +19,7 @@ Message result = await messaging.UpdatePush( body: "", // optional data: [object], // optional action: "", // optional - image: "[ID1:ID2]", // optional + image: "", // optional icon: "", // optional sound: "", // optional color: "", // optional diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..0a8da3e8cc --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-operations.md @@ -0,0 +1,25 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +Transaction result = await tablesDB.CreateOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-row.md index 01a21b0dcd..8d56063f1f 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-row.md @@ -20,5 +20,6 @@ Row result = await tablesDB.CreateRow( age = 30, isAdmin = false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-rows.md index c23e795a84..c73c474f45 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-rows.md @@ -12,5 +12,6 @@ TablesDB tablesDB = new TablesDB(client); RowList result = await tablesDB.CreateRows( databaseId: "", tableId: "", - rows: new List() + rows: new List(), + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..b42b087539 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/create-transaction.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +Transaction result = await tablesDB.CreateTransaction( + ttl: 60 // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/decrement-row-column.md index 66d98b65b9..19498d035f 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/decrement-row-column.md @@ -15,5 +15,6 @@ Row result = await tablesDB.DecrementRowColumn( rowId: "", column: "", value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-row.md index 86d7fbf392..81bd084f62 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-row.md @@ -12,5 +12,6 @@ TablesDB tablesDB = new TablesDB(client); await tablesDB.DeleteRow( databaseId: "", tableId: "", - rowId: "" + rowId: "", + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-rows.md index 13d5758fdb..c0f656cda5 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-rows.md @@ -12,5 +12,6 @@ TablesDB tablesDB = new TablesDB(client); await tablesDB.DeleteRows( databaseId: "", tableId: "", - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..6e41c80c02 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/delete-transaction.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +await tablesDB.DeleteTransaction( + transactionId: "" +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/get-row.md index 99d79ac3dd..66f6a230e3 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/get-row.md @@ -13,5 +13,6 @@ Row result = await tablesDB.GetRow( databaseId: "", tableId: "", rowId: "", - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..73e0904982 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/get-transaction.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +Transaction result = await tablesDB.GetTransaction( + transactionId: "" +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/increment-row-column.md index 48eabc34d4..cbac61f159 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/increment-row-column.md @@ -15,5 +15,6 @@ Row result = await tablesDB.IncrementRowColumn( rowId: "", column: "", value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/list-rows.md index d3f860e869..79f809d35d 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/list-rows.md @@ -12,5 +12,6 @@ TablesDB tablesDB = new TablesDB(client); RowList result = await tablesDB.ListRows( databaseId: "", tableId: "", - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..b1a00e1a44 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/list-transactions.md @@ -0,0 +1,14 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +TransactionList result = await tablesDB.ListTransactions( + queries: new List() // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-row.md index 5eb5acdbd2..40f4eb4314 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-row.md @@ -14,5 +14,6 @@ Row result = await tablesDB.UpdateRow( tableId: "", rowId: "", data: [object], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-rows.md index 401464d66a..368977a0cc 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-rows.md @@ -13,5 +13,6 @@ RowList result = await tablesDB.UpdateRows( databaseId: "", tableId: "", data: [object], // optional - queries: new List() // optional + queries: new List(), // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..3b44fd5d37 --- /dev/null +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/update-transaction.md @@ -0,0 +1,16 @@ +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +Transaction result = await tablesDB.UpdateTransaction( + transactionId: "", + commit: false, // optional + rollback: false // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-row.md index e1f68a7dfb..18b8419146 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-row.md @@ -14,5 +14,6 @@ Row result = await tablesDB.UpsertRow( tableId: "", rowId: "", data: [object], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-rows.md index 199dc2ba85..fde5df7149 100644 --- a/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-dotnet/examples/tablesdb/upsert-rows.md @@ -12,5 +12,6 @@ TablesDB tablesDB = new TablesDB(client); RowList result = await tablesDB.UpsertRows( databaseId: "", tableId: "", - rows: new List() + rows: new List(), + transactionId: "" // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-go/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-go/examples/account/create-email-verification.md new file mode 100644 index 0000000000..d10b88e21d --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/account/create-email-verification.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/account" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithSession("") +) + +service := account.New(client) + +response, error := service.CreateEmailVerification( + "https://example.com", +) diff --git a/docs/examples/1.8.x/server-go/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-go/examples/account/update-email-verification.md new file mode 100644 index 0000000000..780405d514 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/account/update-email-verification.md @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/account" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithSession("") +) + +service := account.New(client) + +response, error := service.UpdateEmailVerification( + "", + "", +) diff --git a/docs/examples/1.8.x/server-go/examples/databases/create-document.md b/docs/examples/1.8.x/server-go/examples/databases/create-document.md index ea6305a06e..1c7a489129 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-go/examples/databases/create-document.md @@ -26,4 +26,5 @@ response, error := service.CreateDocument( "isAdmin": false }, databases.WithCreateDocumentPermissions(interface{}{"read("any")"}), + databases.WithCreateDocumentTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/create-documents.md b/docs/examples/1.8.x/server-go/examples/databases/create-documents.md index 8bd0a5761a..ae08b2e7d8 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-go/examples/databases/create-documents.md @@ -18,4 +18,5 @@ response, error := service.CreateDocuments( "", "", []interface{}{}, + databases.WithCreateDocumentsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/create-operations.md b/docs/examples/1.8.x/server-go/examples/databases/create-operations.md new file mode 100644 index 0000000000..c73ad57738 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/databases/create-operations.md @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/databases" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := databases.New(client) + +response, error := service.CreateOperations( + "", + databases.WithCreateOperationsOperations(interface{}{ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + }), +) diff --git a/docs/examples/1.8.x/server-go/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-go/examples/databases/create-transaction.md new file mode 100644 index 0000000000..f74b9152c1 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/databases/create-transaction.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/databases" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := databases.New(client) + +response, error := service.CreateTransaction( + databases.WithCreateTransactionTtl(60), +) diff --git a/docs/examples/1.8.x/server-go/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-go/examples/databases/decrement-document-attribute.md index af463743b5..7cb2c1c3c3 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-go/examples/databases/decrement-document-attribute.md @@ -21,4 +21,5 @@ response, error := service.DecrementDocumentAttribute( "", databases.WithDecrementDocumentAttributeValue(0), databases.WithDecrementDocumentAttributeMin(0), + databases.WithDecrementDocumentAttributeTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/delete-document.md b/docs/examples/1.8.x/server-go/examples/databases/delete-document.md index 6e9b58a56d..80e44b89eb 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-go/examples/databases/delete-document.md @@ -18,4 +18,5 @@ response, error := service.DeleteDocument( "", "", "", + databases.WithDeleteDocumentTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-go/examples/databases/delete-documents.md index 43e0d4cb36..5c070a0dc4 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-go/examples/databases/delete-documents.md @@ -18,4 +18,5 @@ response, error := service.DeleteDocuments( "", "", databases.WithDeleteDocumentsQueries([]interface{}{}), + databases.WithDeleteDocumentsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-go/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..b06f8bf6f3 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/databases/delete-transaction.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/databases" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := databases.New(client) + +response, error := service.DeleteTransaction( + "", +) diff --git a/docs/examples/1.8.x/server-go/examples/databases/get-document.md b/docs/examples/1.8.x/server-go/examples/databases/get-document.md index 5e63077aac..e075084f61 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-go/examples/databases/get-document.md @@ -19,4 +19,5 @@ response, error := service.GetDocument( "", "", databases.WithGetDocumentQueries([]interface{}{}), + databases.WithGetDocumentTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-go/examples/databases/get-transaction.md new file mode 100644 index 0000000000..4c15d73231 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/databases/get-transaction.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/databases" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := databases.New(client) + +response, error := service.GetTransaction( + "", +) diff --git a/docs/examples/1.8.x/server-go/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-go/examples/databases/increment-document-attribute.md index d2e91ee4c1..510d6486b8 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-go/examples/databases/increment-document-attribute.md @@ -21,4 +21,5 @@ response, error := service.IncrementDocumentAttribute( "", databases.WithIncrementDocumentAttributeValue(0), databases.WithIncrementDocumentAttributeMax(0), + databases.WithIncrementDocumentAttributeTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/list-documents.md b/docs/examples/1.8.x/server-go/examples/databases/list-documents.md index 0aaef36c59..3d83145a61 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-go/examples/databases/list-documents.md @@ -18,4 +18,5 @@ response, error := service.ListDocuments( "", "", databases.WithListDocumentsQueries([]interface{}{}), + databases.WithListDocumentsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-go/examples/databases/list-transactions.md new file mode 100644 index 0000000000..662874bb8c --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/databases/list-transactions.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/databases" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := databases.New(client) + +response, error := service.ListTransactions( + databases.WithListTransactionsQueries([]interface{}{}), +) diff --git a/docs/examples/1.8.x/server-go/examples/databases/update-document.md b/docs/examples/1.8.x/server-go/examples/databases/update-document.md index 90c0947536..314385d6a8 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-go/examples/databases/update-document.md @@ -20,4 +20,5 @@ response, error := service.UpdateDocument( "", databases.WithUpdateDocumentData(map[string]interface{}{}), databases.WithUpdateDocumentPermissions(interface{}{"read("any")"}), + databases.WithUpdateDocumentTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/update-documents.md b/docs/examples/1.8.x/server-go/examples/databases/update-documents.md index 7caee918e4..729656affd 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-go/examples/databases/update-documents.md @@ -19,4 +19,5 @@ response, error := service.UpdateDocuments( "", databases.WithUpdateDocumentsData(map[string]interface{}{}), databases.WithUpdateDocumentsQueries([]interface{}{}), + databases.WithUpdateDocumentsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-go/examples/databases/update-transaction.md new file mode 100644 index 0000000000..76ef4acb72 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/databases/update-transaction.md @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/databases" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := databases.New(client) + +response, error := service.UpdateTransaction( + "", + databases.WithUpdateTransactionCommit(false), + databases.WithUpdateTransactionRollback(false), +) diff --git a/docs/examples/1.8.x/server-go/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-go/examples/databases/upsert-document.md index 00cf8ad408..471c39185b 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-go/examples/databases/upsert-document.md @@ -20,4 +20,5 @@ response, error := service.UpsertDocument( "", map[string]interface{}{}, databases.WithUpsertDocumentPermissions(interface{}{"read("any")"}), + databases.WithUpsertDocumentTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-go/examples/databases/upsert-documents.md index a81ee4446e..9088883b1f 100644 --- a/docs/examples/1.8.x/server-go/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-go/examples/databases/upsert-documents.md @@ -18,4 +18,5 @@ response, error := service.UpsertDocuments( "", "", []interface{}{}, + databases.WithUpsertDocumentsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/messaging/create-push.md b/docs/examples/1.8.x/server-go/examples/messaging/create-push.md index fe2371bacd..a607f4391b 100644 --- a/docs/examples/1.8.x/server-go/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-go/examples/messaging/create-push.md @@ -23,7 +23,7 @@ response, error := service.CreatePush( messaging.WithCreatePushTargets([]interface{}{}), messaging.WithCreatePushData(map[string]interface{}{}), messaging.WithCreatePushAction(""), - messaging.WithCreatePushImage("[ID1:ID2]"), + messaging.WithCreatePushImage(""), messaging.WithCreatePushIcon(""), messaging.WithCreatePushSound(""), messaging.WithCreatePushColor(""), diff --git a/docs/examples/1.8.x/server-go/examples/messaging/update-push.md b/docs/examples/1.8.x/server-go/examples/messaging/update-push.md index 190627fa43..d364159e35 100644 --- a/docs/examples/1.8.x/server-go/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-go/examples/messaging/update-push.md @@ -23,7 +23,7 @@ response, error := service.UpdatePush( messaging.WithUpdatePushBody(""), messaging.WithUpdatePushData(map[string]interface{}{}), messaging.WithUpdatePushAction(""), - messaging.WithUpdatePushImage("[ID1:ID2]"), + messaging.WithUpdatePushImage(""), messaging.WithUpdatePushIcon(""), messaging.WithUpdatePushSound(""), messaging.WithUpdatePushColor(""), diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-go/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..330ece2bb9 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/create-operations.md @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/tablesdb" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := tablesdb.New(client) + +response, error := service.CreateOperations( + "", + tablesdb.WithCreateOperationsOperations(interface{}{ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + }), +) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-go/examples/tablesdb/create-row.md index 596f11cf75..24054ace1d 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/create-row.md @@ -26,4 +26,5 @@ response, error := service.CreateRow( "isAdmin": false }, tablesdb.WithCreateRowPermissions(interface{}{"read("any")"}), + tablesdb.WithCreateRowTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-go/examples/tablesdb/create-rows.md index 2d83be06df..6ddeb067db 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/create-rows.md @@ -18,4 +18,5 @@ response, error := service.CreateRows( "", "", []interface{}{}, + tablesdb.WithCreateRowsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-go/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..165f897cf8 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/create-transaction.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/tablesdb" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := tablesdb.New(client) + +response, error := service.CreateTransaction( + tablesdb.WithCreateTransactionTtl(60), +) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-go/examples/tablesdb/decrement-row-column.md index cd8d6c8983..a74bdda219 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/decrement-row-column.md @@ -21,4 +21,5 @@ response, error := service.DecrementRowColumn( "", tablesdb.WithDecrementRowColumnValue(0), tablesdb.WithDecrementRowColumnMin(0), + tablesdb.WithDecrementRowColumnTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-go/examples/tablesdb/delete-row.md index 8571a54c6c..39338452bc 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/delete-row.md @@ -18,4 +18,5 @@ response, error := service.DeleteRow( "", "", "", + tablesdb.WithDeleteRowTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-go/examples/tablesdb/delete-rows.md index 364a4c942f..b9fa49b5fb 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/delete-rows.md @@ -18,4 +18,5 @@ response, error := service.DeleteRows( "", "", tablesdb.WithDeleteRowsQueries([]interface{}{}), + tablesdb.WithDeleteRowsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-go/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..16ee050534 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/delete-transaction.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/tablesdb" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := tablesdb.New(client) + +response, error := service.DeleteTransaction( + "", +) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-go/examples/tablesdb/get-row.md index 3a555f07c5..025c6b55a1 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/get-row.md @@ -19,4 +19,5 @@ response, error := service.GetRow( "", "", tablesdb.WithGetRowQueries([]interface{}{}), + tablesdb.WithGetRowTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-go/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..d478007b62 --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/get-transaction.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/tablesdb" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := tablesdb.New(client) + +response, error := service.GetTransaction( + "", +) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-go/examples/tablesdb/increment-row-column.md index d072099cc6..4548f3cbb1 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/increment-row-column.md @@ -21,4 +21,5 @@ response, error := service.IncrementRowColumn( "", tablesdb.WithIncrementRowColumnValue(0), tablesdb.WithIncrementRowColumnMax(0), + tablesdb.WithIncrementRowColumnTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-go/examples/tablesdb/list-rows.md index 34a7b6fb98..784fbc81d9 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/list-rows.md @@ -18,4 +18,5 @@ response, error := service.ListRows( "", "", tablesdb.WithListRowsQueries([]interface{}{}), + tablesdb.WithListRowsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-go/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..7379d8555e --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/list-transactions.md @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/tablesdb" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := tablesdb.New(client) + +response, error := service.ListTransactions( + tablesdb.WithListTransactionsQueries([]interface{}{}), +) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-go/examples/tablesdb/update-row.md index 1e819bb589..12ea0b10a4 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/update-row.md @@ -20,4 +20,5 @@ response, error := service.UpdateRow( "", tablesdb.WithUpdateRowData(map[string]interface{}{}), tablesdb.WithUpdateRowPermissions(interface{}{"read("any")"}), + tablesdb.WithUpdateRowTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-go/examples/tablesdb/update-rows.md index 3541dce134..ff6a81e57c 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/update-rows.md @@ -19,4 +19,5 @@ response, error := service.UpdateRows( "", tablesdb.WithUpdateRowsData(map[string]interface{}{}), tablesdb.WithUpdateRowsQueries([]interface{}{}), + tablesdb.WithUpdateRowsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-go/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..9842a4555c --- /dev/null +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/update-transaction.md @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "github.com/appwrite/sdk-for-go/client" + "github.com/appwrite/sdk-for-go/tablesdb" +) + +client := client.New( + client.WithEndpoint("https://.cloud.appwrite.io/v1") + client.WithProject("") + client.WithKey("") +) + +service := tablesdb.New(client) + +response, error := service.UpdateTransaction( + "", + tablesdb.WithUpdateTransactionCommit(false), + tablesdb.WithUpdateTransactionRollback(false), +) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-row.md index 9fec778142..4caa5415e9 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-row.md @@ -20,4 +20,5 @@ response, error := service.UpsertRow( "", tablesdb.WithUpsertRowData(map[string]interface{}{}), tablesdb.WithUpsertRowPermissions(interface{}{"read("any")"}), + tablesdb.WithUpsertRowTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-rows.md index 5ded736cd0..a74d6ee9b1 100644 --- a/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-go/examples/tablesdb/upsert-rows.md @@ -18,4 +18,5 @@ response, error := service.UpsertRows( "", "", []interface{}{}, + tablesdb.WithUpsertRowsTransactionId(""), ) diff --git a/docs/examples/1.8.x/server-graphql/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-graphql/examples/account/create-email-verification.md new file mode 100644 index 0000000000..1781188527 --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/account/create-email-verification.md @@ -0,0 +1,12 @@ +mutation { + accountCreateEmailVerification( + url: "https://example.com" + ) { + _id + _createdAt + userId + secret + expire + phrase + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-graphql/examples/account/update-email-verification.md new file mode 100644 index 0000000000..6386d34bfa --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/account/update-email-verification.md @@ -0,0 +1,13 @@ +mutation { + accountUpdateEmailVerification( + userId: "", + secret: "" + ) { + _id + _createdAt + userId + secret + expire + phrase + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/create-document.md b/docs/examples/1.8.x/server-graphql/examples/databases/create-document.md index 39e4bba1cb..411615f7a7 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/create-document.md @@ -4,7 +4,8 @@ mutation { collectionId: "", documentId: "", data: "{\"username\":\"walter.obrien\",\"email\":\"walter.obrien@example.com\",\"fullName\":\"Walter O'Brien\",\"age\":30,\"isAdmin\":false}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/create-documents.md b/docs/examples/1.8.x/server-graphql/examples/databases/create-documents.md index 8ce79dcbb5..01a8914d0e 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/create-documents.md @@ -2,7 +2,8 @@ mutation { databasesCreateDocuments( databaseId: "", collectionId: "", - documents: [] + documents: [], + transactionId: "" ) { total documents { diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/create-operations.md b/docs/examples/1.8.x/server-graphql/examples/databases/create-operations.md new file mode 100644 index 0000000000..1be3b39ee1 --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/databases/create-operations.md @@ -0,0 +1,23 @@ +mutation { + databasesCreateOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-graphql/examples/databases/create-transaction.md new file mode 100644 index 0000000000..7fea034ab6 --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/databases/create-transaction.md @@ -0,0 +1,12 @@ +mutation { + databasesCreateTransaction( + ttl: 60 + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-graphql/examples/databases/decrement-document-attribute.md index 2e7970049d..e6032fd0e7 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/decrement-document-attribute.md @@ -5,7 +5,8 @@ mutation { documentId: "", attribute: "", value: 0, - min: 0 + min: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/delete-document.md b/docs/examples/1.8.x/server-graphql/examples/databases/delete-document.md index 848371bca0..2e172aa5dd 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/delete-document.md @@ -2,7 +2,8 @@ mutation { databasesDeleteDocument( databaseId: "", collectionId: "", - documentId: "" + documentId: "", + transactionId: "" ) { status } diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-graphql/examples/databases/delete-documents.md index 5822d3b950..aed5f6333f 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/delete-documents.md @@ -2,7 +2,8 @@ mutation { databasesDeleteDocuments( databaseId: "", collectionId: "", - queries: [] + queries: [], + transactionId: "" ) { total documents { diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-graphql/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..cd29a0b8a6 --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/databases/delete-transaction.md @@ -0,0 +1,7 @@ +mutation { + databasesDeleteTransaction( + transactionId: "" + ) { + status + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-graphql/examples/databases/get-transaction.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-graphql/examples/databases/increment-document-attribute.md index 322ed69ced..3518ff1583 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/increment-document-attribute.md @@ -5,7 +5,8 @@ mutation { documentId: "", attribute: "", value: 0, - max: 0 + max: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-graphql/examples/databases/list-transactions.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/update-document.md b/docs/examples/1.8.x/server-graphql/examples/databases/update-document.md index aea605d9d7..cf43d9eed0 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/update-document.md @@ -4,7 +4,8 @@ mutation { collectionId: "", documentId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/update-documents.md b/docs/examples/1.8.x/server-graphql/examples/databases/update-documents.md index 83c0c07f84..d6eb18de2a 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/update-documents.md @@ -3,7 +3,8 @@ mutation { databaseId: "", collectionId: "", data: "{}", - queries: [] + queries: [], + transactionId: "" ) { total documents { diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-graphql/examples/databases/update-transaction.md new file mode 100644 index 0000000000..b56c7139ac --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/databases/update-transaction.md @@ -0,0 +1,14 @@ +mutation { + databasesUpdateTransaction( + transactionId: "", + commit: false, + rollback: false + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-graphql/examples/databases/upsert-document.md index 9d1e753081..d487c0d303 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/upsert-document.md @@ -4,7 +4,8 @@ mutation { collectionId: "", documentId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-graphql/examples/databases/upsert-documents.md index 2bfb765915..7852ba93f8 100644 --- a/docs/examples/1.8.x/server-graphql/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-graphql/examples/databases/upsert-documents.md @@ -2,7 +2,8 @@ mutation { databasesUpsertDocuments( databaseId: "", collectionId: "", - documents: [] + documents: [], + transactionId: "" ) { total documents { diff --git a/docs/examples/1.8.x/server-graphql/examples/functions/create-duplicate-deployment.md b/docs/examples/1.8.x/server-graphql/examples/functions/create-duplicate-deployment.md index cdd92c2a02..bc3587fcec 100644 --- a/docs/examples/1.8.x/server-graphql/examples/functions/create-duplicate-deployment.md +++ b/docs/examples/1.8.x/server-graphql/examples/functions/create-duplicate-deployment.md @@ -24,12 +24,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/functions/create-template-deployment.md b/docs/examples/1.8.x/server-graphql/examples/functions/create-template-deployment.md index 12c50c32f3..0ce968e5f4 100644 --- a/docs/examples/1.8.x/server-graphql/examples/functions/create-template-deployment.md +++ b/docs/examples/1.8.x/server-graphql/examples/functions/create-template-deployment.md @@ -27,12 +27,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/functions/create-vcs-deployment.md b/docs/examples/1.8.x/server-graphql/examples/functions/create-vcs-deployment.md index ebfced2c68..60a78c41ca 100644 --- a/docs/examples/1.8.x/server-graphql/examples/functions/create-vcs-deployment.md +++ b/docs/examples/1.8.x/server-graphql/examples/functions/create-vcs-deployment.md @@ -25,12 +25,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/functions/update-deployment-status.md b/docs/examples/1.8.x/server-graphql/examples/functions/update-deployment-status.md index 50df97fd21..68735b35ca 100644 --- a/docs/examples/1.8.x/server-graphql/examples/functions/update-deployment-status.md +++ b/docs/examples/1.8.x/server-graphql/examples/functions/update-deployment-status.md @@ -23,12 +23,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/messaging/create-push.md b/docs/examples/1.8.x/server-graphql/examples/messaging/create-push.md index 92264d1b67..dc924dfd32 100644 --- a/docs/examples/1.8.x/server-graphql/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-graphql/examples/messaging/create-push.md @@ -8,7 +8,7 @@ mutation { targets: [], data: "{}", action: "", - image: "[ID1:ID2]", + image: "", icon: "", sound: "", color: "", diff --git a/docs/examples/1.8.x/server-graphql/examples/messaging/update-push.md b/docs/examples/1.8.x/server-graphql/examples/messaging/update-push.md index 8ee2f57610..3436e0cf2f 100644 --- a/docs/examples/1.8.x/server-graphql/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-graphql/examples/messaging/update-push.md @@ -8,7 +8,7 @@ mutation { body: "", data: "{}", action: "", - image: "[ID1:ID2]", + image: "", icon: "", sound: "", color: "", diff --git a/docs/examples/1.8.x/server-graphql/examples/sites/create-duplicate-deployment.md b/docs/examples/1.8.x/server-graphql/examples/sites/create-duplicate-deployment.md index 6226282651..1b2d3dc131 100644 --- a/docs/examples/1.8.x/server-graphql/examples/sites/create-duplicate-deployment.md +++ b/docs/examples/1.8.x/server-graphql/examples/sites/create-duplicate-deployment.md @@ -23,12 +23,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/sites/create-template-deployment.md b/docs/examples/1.8.x/server-graphql/examples/sites/create-template-deployment.md index 72562556e4..f63d8c5e5a 100644 --- a/docs/examples/1.8.x/server-graphql/examples/sites/create-template-deployment.md +++ b/docs/examples/1.8.x/server-graphql/examples/sites/create-template-deployment.md @@ -27,12 +27,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/sites/create-vcs-deployment.md b/docs/examples/1.8.x/server-graphql/examples/sites/create-vcs-deployment.md index ccc18cf2e0..6c5241e734 100644 --- a/docs/examples/1.8.x/server-graphql/examples/sites/create-vcs-deployment.md +++ b/docs/examples/1.8.x/server-graphql/examples/sites/create-vcs-deployment.md @@ -25,12 +25,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/sites/update-deployment-status.md b/docs/examples/1.8.x/server-graphql/examples/sites/update-deployment-status.md index 92751c167f..24064428e2 100644 --- a/docs/examples/1.8.x/server-graphql/examples/sites/update-deployment-status.md +++ b/docs/examples/1.8.x/server-graphql/examples/sites/update-deployment-status.md @@ -23,12 +23,12 @@ mutation { providerRepositoryName providerRepositoryOwner providerRepositoryUrl - providerBranch providerCommitHash providerCommitAuthorUrl providerCommitAuthor providerCommitMessage providerCommitUrl + providerBranch providerBranchUrl } } diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..bb2be8085a --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-operations.md @@ -0,0 +1,23 @@ +mutation { + tablesDBCreateOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-row.md index c7d2ec7d03..109bc008d6 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-row.md @@ -4,7 +4,8 @@ mutation { tableId: "", rowId: "", data: "{\"username\":\"walter.obrien\",\"email\":\"walter.obrien@example.com\",\"fullName\":\"Walter O'Brien\",\"age\":30,\"isAdmin\":false}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-rows.md index 25dc9a367d..9364b5676d 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-rows.md @@ -2,7 +2,8 @@ mutation { tablesDBCreateRows( databaseId: "", tableId: "", - rows: [] + rows: [], + transactionId: "" ) { total rows { diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..0e874f0c78 --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/create-transaction.md @@ -0,0 +1,12 @@ +mutation { + tablesDBCreateTransaction( + ttl: 60 + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/decrement-row-column.md index 398ec19901..1d57d79b54 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/decrement-row-column.md @@ -5,7 +5,8 @@ mutation { rowId: "", column: "", value: 0, - min: 0 + min: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-row.md index 1a08b0f60d..3b44913049 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-row.md @@ -2,7 +2,8 @@ mutation { tablesDBDeleteRow( databaseId: "", tableId: "", - rowId: "" + rowId: "", + transactionId: "" ) { status } diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-rows.md index dfa7c13779..9dae8fc679 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-rows.md @@ -2,7 +2,8 @@ mutation { tablesDBDeleteRows( databaseId: "", tableId: "", - queries: [] + queries: [], + transactionId: "" ) { total rows { diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..4a2d6f15a2 --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/delete-transaction.md @@ -0,0 +1,7 @@ +mutation { + tablesDBDeleteTransaction( + transactionId: "" + ) { + status + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/increment-row-column.md index b7ff87f387..3ae008e718 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/increment-row-column.md @@ -5,7 +5,8 @@ mutation { rowId: "", column: "", value: 0, - max: 0 + max: 0, + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-row.md index 5a5b288ab8..aa89e6ae01 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-row.md @@ -4,7 +4,8 @@ mutation { tableId: "", rowId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-rows.md index 4816748352..5a6203a4dc 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-rows.md @@ -3,7 +3,8 @@ mutation { databaseId: "", tableId: "", data: "{}", - queries: [] + queries: [], + transactionId: "" ) { total rows { diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..2094877303 --- /dev/null +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/update-transaction.md @@ -0,0 +1,14 @@ +mutation { + tablesDBUpdateTransaction( + transactionId: "", + commit: false, + rollback: false + ) { + _id + _createdAt + _updatedAt + status + operations + expiresAt + } +} diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-row.md index cc3b63de4a..3fe36ee7f1 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-row.md @@ -4,7 +4,8 @@ mutation { tableId: "", rowId: "", data: "{}", - permissions: ["read("any")"] + permissions: ["read("any")"], + transactionId: "" ) { _id _sequence diff --git a/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-rows.md index f4e01c0af7..bbfc09c763 100644 --- a/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-graphql/examples/tablesdb/upsert-rows.md @@ -2,7 +2,8 @@ mutation { tablesDBUpsertRows( databaseId: "", tableId: "", - rows: [] + rows: [], + transactionId: "" ) { total rows { diff --git a/docs/examples/1.8.x/server-kotlin/java/account/create-email-verification.md b/docs/examples/1.8.x/server-kotlin/java/account/create-email-verification.md new file mode 100644 index 0000000000..de80353b29 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/account/create-email-verification.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setSession(""); // The user session to authenticate with + +Account account = new Account(client); + +account.createEmailVerification( + "https://example.com", // url + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/account/update-email-verification.md b/docs/examples/1.8.x/server-kotlin/java/account/update-email-verification.md new file mode 100644 index 0000000000..92dfd8d00c --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/account/update-email-verification.md @@ -0,0 +1,24 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Account; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setSession(""); // The user session to authenticate with + +Account account = new Account(client); + +account.updateEmailVerification( + "", // userId + "", // secret + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/create-document.md b/docs/examples/1.8.x/server-kotlin/java/databases/create-document.md index d5e777d157..9c6357dfae 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/create-document.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/create-document.md @@ -21,6 +21,7 @@ databases.createDocument( "isAdmin" to false ), // data listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/create-documents.md b/docs/examples/1.8.x/server-kotlin/java/databases/create-documents.md index 0de0c276ed..3a4540974b 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/create-documents.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/create-documents.md @@ -13,6 +13,7 @@ databases.createDocuments( "", // databaseId "", // collectionId listOf(), // documents + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/create-operations.md b/docs/examples/1.8.x/server-kotlin/java/databases/create-operations.md new file mode 100644 index 0000000000..2dad8a15ac --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/databases/create-operations.md @@ -0,0 +1,34 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +Databases databases = new Databases(client); + +databases.createOperations( + "", // transactionId + listOf( + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ), // operations (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/create-transaction.md b/docs/examples/1.8.x/server-kotlin/java/databases/create-transaction.md new file mode 100644 index 0000000000..5fb7c5936a --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/databases/create-transaction.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +Databases databases = new Databases(client); + +databases.createTransaction( + 60, // ttl (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-kotlin/java/databases/decrement-document-attribute.md index a44cc51260..a852083bce 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/decrement-document-attribute.md @@ -16,6 +16,7 @@ databases.decrementDocumentAttribute( "", // attribute 0, // value (optional) 0, // min (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/delete-document.md b/docs/examples/1.8.x/server-kotlin/java/databases/delete-document.md index f6e6209f36..2f7003b234 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/delete-document.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/delete-document.md @@ -13,6 +13,7 @@ databases.deleteDocument( "", // databaseId "", // collectionId "", // documentId + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/delete-documents.md b/docs/examples/1.8.x/server-kotlin/java/databases/delete-documents.md index e8394b1ff9..958c40c382 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/delete-documents.md @@ -13,6 +13,7 @@ databases.deleteDocuments( "", // databaseId "", // collectionId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/delete-transaction.md b/docs/examples/1.8.x/server-kotlin/java/databases/delete-transaction.md new file mode 100644 index 0000000000..200bbbdc26 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/databases/delete-transaction.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +Databases databases = new Databases(client); + +databases.deleteTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/get-document.md b/docs/examples/1.8.x/server-kotlin/java/databases/get-document.md index 2719073a7d..489447f599 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/get-document.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/get-document.md @@ -14,6 +14,7 @@ databases.getDocument( "", // collectionId "", // documentId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/get-transaction.md b/docs/examples/1.8.x/server-kotlin/java/databases/get-transaction.md new file mode 100644 index 0000000000..d896ca0751 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/databases/get-transaction.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +Databases databases = new Databases(client); + +databases.getTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-kotlin/java/databases/increment-document-attribute.md index b5b5054e25..be837d00f8 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/increment-document-attribute.md @@ -16,6 +16,7 @@ databases.incrementDocumentAttribute( "", // attribute 0, // value (optional) 0, // max (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/list-documents.md b/docs/examples/1.8.x/server-kotlin/java/databases/list-documents.md index 36982c0eb0..1e84348c1a 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/list-documents.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/list-documents.md @@ -13,6 +13,7 @@ databases.listDocuments( "", // databaseId "", // collectionId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/list-transactions.md b/docs/examples/1.8.x/server-kotlin/java/databases/list-transactions.md new file mode 100644 index 0000000000..281fc1205b --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/databases/list-transactions.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +Databases databases = new Databases(client); + +databases.listTransactions( + listOf(), // queries (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/update-document.md b/docs/examples/1.8.x/server-kotlin/java/databases/update-document.md index f7b05c9601..f3019ab95b 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/update-document.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/update-document.md @@ -15,6 +15,7 @@ databases.updateDocument( "", // documentId mapOf( "a" to "b" ), // data (optional) listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/update-documents.md b/docs/examples/1.8.x/server-kotlin/java/databases/update-documents.md index b4138b41d2..a685ac81fc 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/update-documents.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/update-documents.md @@ -14,6 +14,7 @@ databases.updateDocuments( "", // collectionId mapOf( "a" to "b" ), // data (optional) listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/update-transaction.md b/docs/examples/1.8.x/server-kotlin/java/databases/update-transaction.md new file mode 100644 index 0000000000..8479ed31aa --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/databases/update-transaction.md @@ -0,0 +1,25 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.Databases; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +Databases databases = new Databases(client); + +databases.updateTransaction( + "", // transactionId + false, // commit (optional) + false, // rollback (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/upsert-document.md b/docs/examples/1.8.x/server-kotlin/java/databases/upsert-document.md index daa44141e2..39864b9ac3 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/upsert-document.md @@ -15,6 +15,7 @@ databases.upsertDocument( "", // documentId mapOf( "a" to "b" ), // data listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/databases/upsert-documents.md b/docs/examples/1.8.x/server-kotlin/java/databases/upsert-documents.md index 95e9a33ef2..b8fcd8781a 100644 --- a/docs/examples/1.8.x/server-kotlin/java/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-kotlin/java/databases/upsert-documents.md @@ -13,6 +13,7 @@ databases.upsertDocuments( "", // databaseId "", // collectionId listOf(), // documents + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/messaging/create-push.md b/docs/examples/1.8.x/server-kotlin/java/messaging/create-push.md index 277ab9655c..14e8ca2679 100644 --- a/docs/examples/1.8.x/server-kotlin/java/messaging/create-push.md +++ b/docs/examples/1.8.x/server-kotlin/java/messaging/create-push.md @@ -18,7 +18,7 @@ messaging.createPush( listOf(), // targets (optional) mapOf( "a" to "b" ), // data (optional) "", // action (optional) - "[ID1:ID2]", // image (optional) + "", // image (optional) "", // icon (optional) "", // sound (optional) "", // color (optional) diff --git a/docs/examples/1.8.x/server-kotlin/java/messaging/update-push.md b/docs/examples/1.8.x/server-kotlin/java/messaging/update-push.md index b7038de6a4..ce56683674 100644 --- a/docs/examples/1.8.x/server-kotlin/java/messaging/update-push.md +++ b/docs/examples/1.8.x/server-kotlin/java/messaging/update-push.md @@ -18,7 +18,7 @@ messaging.updatePush( "", // body (optional) mapOf( "a" to "b" ), // data (optional) "", // action (optional) - "[ID1:ID2]", // image (optional) + "", // image (optional) "", // icon (optional) "", // sound (optional) "", // color (optional) diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-operations.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-operations.md new file mode 100644 index 0000000000..9504f623b3 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-operations.md @@ -0,0 +1,34 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.createOperations( + "", // transactionId + listOf( + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ), // operations (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-row.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-row.md index 6c7d84702d..d041511c11 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-row.md @@ -21,6 +21,7 @@ tablesDB.createRow( "isAdmin" to false ), // data listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-rows.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-rows.md index 21bdd21879..956d812165 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-rows.md @@ -13,6 +13,7 @@ tablesDB.createRows( "", // databaseId "", // tableId listOf(), // rows + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-transaction.md new file mode 100644 index 0000000000..3529956c54 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/create-transaction.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.createTransaction( + 60, // ttl (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/decrement-row-column.md index b9f250f48f..78a811676d 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/decrement-row-column.md @@ -16,6 +16,7 @@ tablesDB.decrementRowColumn( "", // column 0, // value (optional) 0, // min (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-row.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-row.md index fd66525a8d..5da1ba0cf3 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-row.md @@ -13,6 +13,7 @@ tablesDB.deleteRow( "", // databaseId "", // tableId "", // rowId + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-rows.md index 43b772e1a3..80ca0bb40f 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-rows.md @@ -13,6 +13,7 @@ tablesDB.deleteRows( "", // databaseId "", // tableId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..816b6e5dee --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/delete-transaction.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.deleteTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/get-row.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/get-row.md index 03cf3fb234..d642ebcaf1 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/get-row.md @@ -14,6 +14,7 @@ tablesDB.getRow( "", // tableId "", // rowId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/get-transaction.md new file mode 100644 index 0000000000..dab07dce4e --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/get-transaction.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.getTransaction( + "", // transactionId + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/increment-row-column.md index db48d05c37..33715721a8 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/increment-row-column.md @@ -16,6 +16,7 @@ tablesDB.incrementRowColumn( "", // column 0, // value (optional) 0, // max (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/list-rows.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/list-rows.md index 52cf2a1670..96520e2bc5 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/list-rows.md @@ -13,6 +13,7 @@ tablesDB.listRows( "", // databaseId "", // tableId listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/list-transactions.md new file mode 100644 index 0000000000..acc4902da4 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/list-transactions.md @@ -0,0 +1,23 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.listTransactions( + listOf(), // queries (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-row.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-row.md index bedc816f14..b4f9631222 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-row.md @@ -15,6 +15,7 @@ tablesDB.updateRow( "", // rowId mapOf( "a" to "b" ), // data (optional) listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-rows.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-rows.md index 169b57c3e5..7d39e4422c 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-rows.md @@ -14,6 +14,7 @@ tablesDB.updateRows( "", // tableId mapOf( "a" to "b" ), // data (optional) listOf(), // queries (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-transaction.md new file mode 100644 index 0000000000..f043d5dc44 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/update-transaction.md @@ -0,0 +1,25 @@ +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.TablesDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +TablesDB tablesDB = new TablesDB(client); + +tablesDB.updateTransaction( + "", // transactionId + false, // commit (optional) + false, // rollback (optional) + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-row.md index d6155fcd1b..b6a986ef4d 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-row.md @@ -15,6 +15,7 @@ tablesDB.upsertRow( "", // rowId mapOf( "a" to "b" ), // data (optional) listOf("read("any")"), // permissions (optional) + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-rows.md index da15f6a0db..c4b2bf3857 100644 --- a/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-kotlin/java/tablesdb/upsert-rows.md @@ -13,6 +13,7 @@ tablesDB.upsertRows( "", // databaseId "", // tableId listOf(), // rows + "", // transactionId (optional) new CoroutineCallback<>((result, error) -> { if (error != null) { error.printStackTrace(); diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/account/create-email-verification.md b/docs/examples/1.8.x/server-kotlin/kotlin/account/create-email-verification.md new file mode 100644 index 0000000000..4ef178fb9f --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/account/create-email-verification.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setSession("") // The user session to authenticate with + +val account = Account(client) + +val response = account.createEmailVerification( + url = "https://example.com" +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/account/update-email-verification.md b/docs/examples/1.8.x/server-kotlin/kotlin/account/update-email-verification.md new file mode 100644 index 0000000000..6eb97bccc2 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/account/update-email-verification.md @@ -0,0 +1,15 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Account + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setSession("") // The user session to authenticate with + +val account = Account(client) + +val response = account.updateEmailVerification( + userId = "", + secret = "" +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-document.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-document.md index 1c1d628729..46cb711b62 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-document.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-document.md @@ -20,5 +20,6 @@ val response = databases.createDocument( "age" to 30, "isAdmin" to false ), - permissions = listOf("read("any")") // optional + permissions = listOf("read("any")"), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-documents.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-documents.md index 41a98dc016..114d5cc707 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-documents.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-documents.md @@ -12,5 +12,6 @@ val databases = Databases(client) val response = databases.createDocuments( databaseId = "", collectionId = "", - documents = listOf() + documents = listOf(), + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-operations.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-operations.md new file mode 100644 index 0000000000..1c741818b9 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-operations.md @@ -0,0 +1,25 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val databases = Databases(client) + +val response = databases.createOperations( + transactionId = "", + operations = listOf( + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ) // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-transaction.md new file mode 100644 index 0000000000..83ff583038 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/create-transaction.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val databases = Databases(client) + +val response = databases.createTransaction( + ttl = 60 // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/decrement-document-attribute.md index d0226c0bdb..3ccd662d59 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/decrement-document-attribute.md @@ -15,5 +15,6 @@ val response = databases.decrementDocumentAttribute( documentId = "", attribute = "", value = 0, // optional - min = 0 // optional + min = 0, // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-document.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-document.md index a9eea6b648..3be4372987 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-document.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-document.md @@ -12,5 +12,6 @@ val databases = Databases(client) val response = databases.deleteDocument( databaseId = "", collectionId = "", - documentId = "" + documentId = "", + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-documents.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-documents.md index c4caa63aae..9b9ea263c4 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-documents.md @@ -12,5 +12,6 @@ val databases = Databases(client) val response = databases.deleteDocuments( databaseId = "", collectionId = "", - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-transaction.md new file mode 100644 index 0000000000..ef11e9fad8 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/delete-transaction.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val databases = Databases(client) + +val response = databases.deleteTransaction( + transactionId = "" +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/get-document.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/get-document.md index d21a19869b..98855d0984 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/get-document.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/get-document.md @@ -13,5 +13,6 @@ val response = databases.getDocument( databaseId = "", collectionId = "", documentId = "", - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/get-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/get-transaction.md new file mode 100644 index 0000000000..1e44376ab7 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/get-transaction.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val databases = Databases(client) + +val response = databases.getTransaction( + transactionId = "" +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/increment-document-attribute.md index b56ed91d75..fb358868d2 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/increment-document-attribute.md @@ -15,5 +15,6 @@ val response = databases.incrementDocumentAttribute( documentId = "", attribute = "", value = 0, // optional - max = 0 // optional + max = 0, // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/list-documents.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/list-documents.md index ed9cb3165d..ab75493964 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/list-documents.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/list-documents.md @@ -12,5 +12,6 @@ val databases = Databases(client) val response = databases.listDocuments( databaseId = "", collectionId = "", - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/list-transactions.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/list-transactions.md new file mode 100644 index 0000000000..0d122b108d --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/list-transactions.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val databases = Databases(client) + +val response = databases.listTransactions( + queries = listOf() // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-document.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-document.md index 4dd0349823..c64a705676 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-document.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-document.md @@ -14,5 +14,6 @@ val response = databases.updateDocument( collectionId = "", documentId = "", data = mapOf( "a" to "b" ), // optional - permissions = listOf("read("any")") // optional + permissions = listOf("read("any")"), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-documents.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-documents.md index 9d6c2b5ea8..b5b76fcaee 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-documents.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-documents.md @@ -13,5 +13,6 @@ val response = databases.updateDocuments( databaseId = "", collectionId = "", data = mapOf( "a" to "b" ), // optional - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-transaction.md new file mode 100644 index 0000000000..834d0dc78d --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/update-transaction.md @@ -0,0 +1,16 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.Databases + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val databases = Databases(client) + +val response = databases.updateTransaction( + transactionId = "", + commit = false, // optional + rollback = false // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-document.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-document.md index d8be0e13db..d6d6800864 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-document.md @@ -14,5 +14,6 @@ val response = databases.upsertDocument( collectionId = "", documentId = "", data = mapOf( "a" to "b" ), - permissions = listOf("read("any")") // optional + permissions = listOf("read("any")"), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-documents.md b/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-documents.md index ca861c61b2..db9e2b3e2d 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/databases/upsert-documents.md @@ -12,5 +12,6 @@ val databases = Databases(client) val response = databases.upsertDocuments( databaseId = "", collectionId = "", - documents = listOf() + documents = listOf(), + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/messaging/create-push.md b/docs/examples/1.8.x/server-kotlin/kotlin/messaging/create-push.md index 5b07f5355b..d0d765a32a 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/messaging/create-push.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/messaging/create-push.md @@ -18,7 +18,7 @@ val response = messaging.createPush( targets = listOf(), // optional data = mapOf( "a" to "b" ), // optional action = "", // optional - image = "[ID1:ID2]", // optional + image = "", // optional icon = "", // optional sound = "", // optional color = "", // optional diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/messaging/update-push.md b/docs/examples/1.8.x/server-kotlin/kotlin/messaging/update-push.md index 710a37e518..0b9c4c6535 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/messaging/update-push.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/messaging/update-push.md @@ -18,7 +18,7 @@ val response = messaging.updatePush( body = "", // optional data = mapOf( "a" to "b" ), // optional action = "", // optional - image = "[ID1:ID2]", // optional + image = "", // optional icon = "", // optional sound = "", // optional color = "", // optional diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-operations.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-operations.md new file mode 100644 index 0000000000..40c98d1c81 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-operations.md @@ -0,0 +1,25 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val tablesDB = TablesDB(client) + +val response = tablesDB.createOperations( + transactionId = "", + operations = listOf( + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ) // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-row.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-row.md index 774800d8f4..b06038964b 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-row.md @@ -20,5 +20,6 @@ val response = tablesDB.createRow( "age" to 30, "isAdmin" to false ), - permissions = listOf("read("any")") // optional + permissions = listOf("read("any")"), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-rows.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-rows.md index 1da47b5c18..8cef6028a2 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-rows.md @@ -12,5 +12,6 @@ val tablesDB = TablesDB(client) val response = tablesDB.createRows( databaseId = "", tableId = "", - rows = listOf() + rows = listOf(), + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-transaction.md new file mode 100644 index 0000000000..31385700c5 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/create-transaction.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val tablesDB = TablesDB(client) + +val response = tablesDB.createTransaction( + ttl = 60 // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/decrement-row-column.md index e284ec3980..30a8d54b1a 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/decrement-row-column.md @@ -15,5 +15,6 @@ val response = tablesDB.decrementRowColumn( rowId = "", column = "", value = 0, // optional - min = 0 // optional + min = 0, // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-row.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-row.md index f24b9353e0..6ba7d6057c 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-row.md @@ -12,5 +12,6 @@ val tablesDB = TablesDB(client) val response = tablesDB.deleteRow( databaseId = "", tableId = "", - rowId = "" + rowId = "", + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-rows.md index c915a5c55a..da2b709f8a 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-rows.md @@ -12,5 +12,6 @@ val tablesDB = TablesDB(client) val response = tablesDB.deleteRows( databaseId = "", tableId = "", - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..2ef1f27a25 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/delete-transaction.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val tablesDB = TablesDB(client) + +val response = tablesDB.deleteTransaction( + transactionId = "" +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/get-row.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/get-row.md index ec54631646..f92a1ccf27 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/get-row.md @@ -13,5 +13,6 @@ val response = tablesDB.getRow( databaseId = "", tableId = "", rowId = "", - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/get-transaction.md new file mode 100644 index 0000000000..f4467dc914 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/get-transaction.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val tablesDB = TablesDB(client) + +val response = tablesDB.getTransaction( + transactionId = "" +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/increment-row-column.md index cac151e41b..af3676e75b 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/increment-row-column.md @@ -15,5 +15,6 @@ val response = tablesDB.incrementRowColumn( rowId = "", column = "", value = 0, // optional - max = 0 // optional + max = 0, // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/list-rows.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/list-rows.md index b0f5df476b..711e4e1a31 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/list-rows.md @@ -12,5 +12,6 @@ val tablesDB = TablesDB(client) val response = tablesDB.listRows( databaseId = "", tableId = "", - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/list-transactions.md new file mode 100644 index 0000000000..a060b9fac3 --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/list-transactions.md @@ -0,0 +1,14 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val tablesDB = TablesDB(client) + +val response = tablesDB.listTransactions( + queries = listOf() // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-row.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-row.md index 9c5248f4e8..0fefb78e5f 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-row.md @@ -14,5 +14,6 @@ val response = tablesDB.updateRow( tableId = "", rowId = "", data = mapOf( "a" to "b" ), // optional - permissions = listOf("read("any")") // optional + permissions = listOf("read("any")"), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-rows.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-rows.md index c285d5b4fb..61041a7783 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-rows.md @@ -13,5 +13,6 @@ val response = tablesDB.updateRows( databaseId = "", tableId = "", data = mapOf( "a" to "b" ), // optional - queries = listOf() // optional + queries = listOf(), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-transaction.md new file mode 100644 index 0000000000..a3797ca5ca --- /dev/null +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/update-transaction.md @@ -0,0 +1,16 @@ +import io.appwrite.Client +import io.appwrite.coroutines.CoroutineCallback +import io.appwrite.services.TablesDB + +val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val tablesDB = TablesDB(client) + +val response = tablesDB.updateTransaction( + transactionId = "", + commit = false, // optional + rollback = false // optional +) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-row.md index 3fcbc61617..5bcc73b4b1 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-row.md @@ -14,5 +14,6 @@ val response = tablesDB.upsertRow( tableId = "", rowId = "", data = mapOf( "a" to "b" ), // optional - permissions = listOf("read("any")") // optional + permissions = listOf("read("any")"), // optional + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-rows.md index 7059c6018b..2f08375c4a 100644 --- a/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-kotlin/kotlin/tablesdb/upsert-rows.md @@ -12,5 +12,6 @@ val tablesDB = TablesDB(client) val response = tablesDB.upsertRows( databaseId = "", tableId = "", - rows = listOf() + rows = listOf(), + transactionId = "" // optional ) diff --git a/docs/examples/1.8.x/server-nodejs/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-nodejs/examples/account/create-email-verification.md new file mode 100644 index 0000000000..e2aaf8015a --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/account/create-email-verification.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setSession(''); // The user session to authenticate with + +const account = new sdk.Account(client); + +const result = await account.createEmailVerification({ + url: 'https://example.com' +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-nodejs/examples/account/update-email-verification.md new file mode 100644 index 0000000000..eb6507e332 --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/account/update-email-verification.md @@ -0,0 +1,13 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setSession(''); // The user session to authenticate with + +const account = new sdk.Account(client); + +const result = await account.updateEmailVerification({ + userId: '', + secret: '' +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/create-document.md b/docs/examples/1.8.x/server-nodejs/examples/databases/create-document.md index 175e06301e..6fe77c42be 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/create-document.md @@ -18,5 +18,6 @@ const result = await databases.createDocument({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/create-documents.md b/docs/examples/1.8.x/server-nodejs/examples/databases/create-documents.md index 73d08aa21e..8815d8d90f 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/create-documents.md @@ -10,5 +10,6 @@ const databases = new sdk.Databases(client); const result = await databases.createDocuments({ databaseId: '', collectionId: '', - documents: [] + documents: [], + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/create-operations.md b/docs/examples/1.8.x/server-nodejs/examples/databases/create-operations.md new file mode 100644 index 0000000000..da8452e3db --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/create-operations.md @@ -0,0 +1,23 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const databases = new sdk.Databases(client); + +const result = await databases.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/databases/create-transaction.md new file mode 100644 index 0000000000..f3da2919f8 --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/create-transaction.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const databases = new sdk.Databases(client); + +const result = await databases.createTransaction({ + ttl: 60 // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-nodejs/examples/databases/decrement-document-attribute.md index 87e4d7d25c..c01b250b08 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/decrement-document-attribute.md @@ -13,5 +13,6 @@ const result = await databases.decrementDocumentAttribute({ documentId: '', attribute: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/delete-document.md b/docs/examples/1.8.x/server-nodejs/examples/databases/delete-document.md index 429554b74b..bfc19777f9 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/delete-document.md @@ -10,5 +10,6 @@ const databases = new sdk.Databases(client); const result = await databases.deleteDocument({ databaseId: '', collectionId: '', - documentId: '' + documentId: '', + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-nodejs/examples/databases/delete-documents.md index 0965d8ddaf..9440d20999 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/delete-documents.md @@ -10,5 +10,6 @@ const databases = new sdk.Databases(client); const result = await databases.deleteDocuments({ databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..53d676e74c --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/delete-transaction.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const databases = new sdk.Databases(client); + +const result = await databases.deleteTransaction({ + transactionId: '' +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/get-document.md b/docs/examples/1.8.x/server-nodejs/examples/databases/get-document.md index 7cc71cd0c3..7abea4e44e 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/get-document.md @@ -11,5 +11,6 @@ const result = await databases.getDocument({ databaseId: '', collectionId: '', documentId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/databases/get-transaction.md new file mode 100644 index 0000000000..9b7297c7e7 --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/get-transaction.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const databases = new sdk.Databases(client); + +const result = await databases.getTransaction({ + transactionId: '' +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-nodejs/examples/databases/increment-document-attribute.md index 2b47f5a75d..843d163bca 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/increment-document-attribute.md @@ -13,5 +13,6 @@ const result = await databases.incrementDocumentAttribute({ documentId: '', attribute: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/list-documents.md b/docs/examples/1.8.x/server-nodejs/examples/databases/list-documents.md index 148bf83c8f..7405f3e28d 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/list-documents.md @@ -10,5 +10,6 @@ const databases = new sdk.Databases(client); const result = await databases.listDocuments({ databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-nodejs/examples/databases/list-transactions.md new file mode 100644 index 0000000000..9a36eb0f93 --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/list-transactions.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const databases = new sdk.Databases(client); + +const result = await databases.listTransactions({ + queries: [] // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/update-document.md b/docs/examples/1.8.x/server-nodejs/examples/databases/update-document.md index 8a9a6856b4..3e953760a1 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/update-document.md @@ -12,5 +12,6 @@ const result = await databases.updateDocument({ collectionId: '', documentId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/update-documents.md b/docs/examples/1.8.x/server-nodejs/examples/databases/update-documents.md index 2cfb8c7800..dc79e433aa 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/update-documents.md @@ -11,5 +11,6 @@ const result = await databases.updateDocuments({ databaseId: '', collectionId: '', data: {}, // optional - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/databases/update-transaction.md new file mode 100644 index 0000000000..57654495ba --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/update-transaction.md @@ -0,0 +1,14 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const databases = new sdk.Databases(client); + +const result = await databases.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-document.md index 5ec3e0541e..0aaec4e6cb 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-document.md @@ -12,5 +12,6 @@ const result = await databases.upsertDocument({ collectionId: '', documentId: '', data: {}, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-documents.md index 8deec536ff..16ed70fae9 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-nodejs/examples/databases/upsert-documents.md @@ -10,5 +10,6 @@ const databases = new sdk.Databases(client); const result = await databases.upsertDocuments({ databaseId: '', collectionId: '', - documents: [] + documents: [], + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/messaging/create-push.md b/docs/examples/1.8.x/server-nodejs/examples/messaging/create-push.md index c0a7f4713f..4c64813f25 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-nodejs/examples/messaging/create-push.md @@ -16,7 +16,7 @@ const result = await messaging.createPush({ targets: [], // optional data: {}, // optional action: '', // optional - image: '[ID1:ID2]', // optional + image: '', // optional icon: '', // optional sound: '', // optional color: '', // optional diff --git a/docs/examples/1.8.x/server-nodejs/examples/messaging/update-push.md b/docs/examples/1.8.x/server-nodejs/examples/messaging/update-push.md index 5e857f1ff6..6f5899f8c7 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-nodejs/examples/messaging/update-push.md @@ -16,7 +16,7 @@ const result = await messaging.updatePush({ body: '', // optional data: {}, // optional action: '', // optional - image: '[ID1:ID2]', // optional + image: '', // optional icon: '', // optional sound: '', // optional color: '', // optional diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..25492396dd --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-operations.md @@ -0,0 +1,23 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const tablesDB = new sdk.TablesDB(client); + +const result = await tablesDB.createOperations({ + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-row.md index 29ddab6652..4468c168e8 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-row.md @@ -18,5 +18,6 @@ const result = await tablesDB.createRow({ "age": 30, "isAdmin": false }, - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-rows.md index 61eb1d1db8..20807c1612 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-rows.md @@ -10,5 +10,6 @@ const tablesDB = new sdk.TablesDB(client); const result = await tablesDB.createRows({ databaseId: '', tableId: '', - rows: [] + rows: [], + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..249406e333 --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/create-transaction.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const tablesDB = new sdk.TablesDB(client); + +const result = await tablesDB.createTransaction({ + ttl: 60 // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/decrement-row-column.md index e3b13a887e..0310399239 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/decrement-row-column.md @@ -13,5 +13,6 @@ const result = await tablesDB.decrementRowColumn({ rowId: '', column: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-row.md index 9802f0d03e..68a965dc97 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-row.md @@ -10,5 +10,6 @@ const tablesDB = new sdk.TablesDB(client); const result = await tablesDB.deleteRow({ databaseId: '', tableId: '', - rowId: '' + rowId: '', + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-rows.md index 6f4d7cd68b..ce1d0f4ba1 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-rows.md @@ -10,5 +10,6 @@ const tablesDB = new sdk.TablesDB(client); const result = await tablesDB.deleteRows({ databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..28d086b9cf --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/delete-transaction.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const tablesDB = new sdk.TablesDB(client); + +const result = await tablesDB.deleteTransaction({ + transactionId: '' +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/get-row.md index 7ea3d1fca2..fe67e2fda3 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/get-row.md @@ -11,5 +11,6 @@ const result = await tablesDB.getRow({ databaseId: '', tableId: '', rowId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..208368bc00 --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/get-transaction.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const tablesDB = new sdk.TablesDB(client); + +const result = await tablesDB.getTransaction({ + transactionId: '' +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/increment-row-column.md index f5cac2ebaa..aaa6cd6205 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/increment-row-column.md @@ -13,5 +13,6 @@ const result = await tablesDB.incrementRowColumn({ rowId: '', column: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/list-rows.md index 6d3b883bd4..3f29781a91 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/list-rows.md @@ -10,5 +10,6 @@ const tablesDB = new sdk.TablesDB(client); const result = await tablesDB.listRows({ databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..3ad0c95425 --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/list-transactions.md @@ -0,0 +1,12 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const tablesDB = new sdk.TablesDB(client); + +const result = await tablesDB.listTransactions({ + queries: [] // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-row.md index 1c7f0af197..58583af745 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-row.md @@ -12,5 +12,6 @@ const result = await tablesDB.updateRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-rows.md index 31628d7150..d66fc28a62 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-rows.md @@ -11,5 +11,6 @@ const result = await tablesDB.updateRows({ databaseId: '', tableId: '', data: {}, // optional - queries: [] // optional + queries: [], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..03501d2cbf --- /dev/null +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/update-transaction.md @@ -0,0 +1,14 @@ +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const tablesDB = new sdk.TablesDB(client); + +const result = await tablesDB.updateTransaction({ + transactionId: '', + commit: false, // optional + rollback: false // optional +}); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-row.md index 9963bb6ced..bfb833356a 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-row.md @@ -12,5 +12,6 @@ const result = await tablesDB.upsertRow({ tableId: '', rowId: '', data: {}, // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-rows.md index cca2b777bb..c985c9515b 100644 --- a/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-nodejs/examples/tablesdb/upsert-rows.md @@ -10,5 +10,6 @@ const tablesDB = new sdk.TablesDB(client); const result = await tablesDB.upsertRows({ databaseId: '', tableId: '', - rows: [] + rows: [], + transactionId: '' // optional }); diff --git a/docs/examples/1.8.x/server-php/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-php/examples/account/create-email-verification.md new file mode 100644 index 0000000000..691d6fa300 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/account/create-email-verification.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setSession(''); // The user session to authenticate with + +$account = new Account($client); + +$result = $account->createEmailVerification( + url: 'https://example.com' +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-php/examples/account/update-email-verification.md new file mode 100644 index 0000000000..95cd1b5e42 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/account/update-email-verification.md @@ -0,0 +1,16 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setSession(''); // The user session to authenticate with + +$account = new Account($client); + +$result = $account->updateEmailVerification( + userId: '', + secret: '' +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/create-document.md b/docs/examples/1.8.x/server-php/examples/databases/create-document.md index 9f2e8f3643..19d3cfb566 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-php/examples/databases/create-document.md @@ -21,5 +21,6 @@ $result = $databases->createDocument( 'age' => 30, 'isAdmin' => false ], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/create-documents.md b/docs/examples/1.8.x/server-php/examples/databases/create-documents.md index bc05f67260..ced7a5a83f 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-php/examples/databases/create-documents.md @@ -13,5 +13,6 @@ $databases = new Databases($client); $result = $databases->createDocuments( databaseId: '', collectionId: '', - documents: [] + documents: [], + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/create-operations.md b/docs/examples/1.8.x/server-php/examples/databases/create-operations.md new file mode 100644 index 0000000000..05038cb6f6 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/databases/create-operations.md @@ -0,0 +1,26 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$databases = new Databases($client); + +$result = $databases->createOperations( + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-php/examples/databases/create-transaction.md new file mode 100644 index 0000000000..ea6faf73b1 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/databases/create-transaction.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$databases = new Databases($client); + +$result = $databases->createTransaction( + ttl: 60 // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-php/examples/databases/decrement-document-attribute.md index 6464a26818..dfb1873cdd 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-php/examples/databases/decrement-document-attribute.md @@ -16,5 +16,6 @@ $result = $databases->decrementDocumentAttribute( documentId: '', attribute: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/delete-document.md b/docs/examples/1.8.x/server-php/examples/databases/delete-document.md index def7f24569..6e4d7aa2a6 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-php/examples/databases/delete-document.md @@ -13,5 +13,6 @@ $databases = new Databases($client); $result = $databases->deleteDocument( databaseId: '', collectionId: '', - documentId: '' + documentId: '', + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-php/examples/databases/delete-documents.md index 3552d85317..3b2b0c79c5 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-php/examples/databases/delete-documents.md @@ -13,5 +13,6 @@ $databases = new Databases($client); $result = $databases->deleteDocuments( databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-php/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..0559aace08 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/databases/delete-transaction.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$databases = new Databases($client); + +$result = $databases->deleteTransaction( + transactionId: '' +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/get-document.md b/docs/examples/1.8.x/server-php/examples/databases/get-document.md index a3204c50a7..834602d89f 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-php/examples/databases/get-document.md @@ -14,5 +14,6 @@ $result = $databases->getDocument( databaseId: '', collectionId: '', documentId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-php/examples/databases/get-transaction.md new file mode 100644 index 0000000000..16ca28da1a --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/databases/get-transaction.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$databases = new Databases($client); + +$result = $databases->getTransaction( + transactionId: '' +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-php/examples/databases/increment-document-attribute.md index 9ad4bdfdec..63162d3224 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-php/examples/databases/increment-document-attribute.md @@ -16,5 +16,6 @@ $result = $databases->incrementDocumentAttribute( documentId: '', attribute: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/list-documents.md b/docs/examples/1.8.x/server-php/examples/databases/list-documents.md index 07183ac8bf..10dcc82340 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-php/examples/databases/list-documents.md @@ -13,5 +13,6 @@ $databases = new Databases($client); $result = $databases->listDocuments( databaseId: '', collectionId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-php/examples/databases/list-transactions.md new file mode 100644 index 0000000000..858e905ba5 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/databases/list-transactions.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$databases = new Databases($client); + +$result = $databases->listTransactions( + queries: [] // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/update-document.md b/docs/examples/1.8.x/server-php/examples/databases/update-document.md index f1c8a34680..d903252886 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-php/examples/databases/update-document.md @@ -15,5 +15,6 @@ $result = $databases->updateDocument( collectionId: '', documentId: '', data: [], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/update-documents.md b/docs/examples/1.8.x/server-php/examples/databases/update-documents.md index 51b4e18bc2..72632461a9 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-php/examples/databases/update-documents.md @@ -14,5 +14,6 @@ $result = $databases->updateDocuments( databaseId: '', collectionId: '', data: [], // optional - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-php/examples/databases/update-transaction.md new file mode 100644 index 0000000000..750eb861f9 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/databases/update-transaction.md @@ -0,0 +1,17 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$databases = new Databases($client); + +$result = $databases->updateTransaction( + transactionId: '', + commit: false, // optional + rollback: false // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-php/examples/databases/upsert-document.md index 6cff8296a3..6db7462ac7 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-php/examples/databases/upsert-document.md @@ -15,5 +15,6 @@ $result = $databases->upsertDocument( collectionId: '', documentId: '', data: [], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-php/examples/databases/upsert-documents.md index d9f9efda5c..06d3a319af 100644 --- a/docs/examples/1.8.x/server-php/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-php/examples/databases/upsert-documents.md @@ -13,5 +13,6 @@ $databases = new Databases($client); $result = $databases->upsertDocuments( databaseId: '', collectionId: '', - documents: [] + documents: [], + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/messaging/create-push.md b/docs/examples/1.8.x/server-php/examples/messaging/create-push.md index 46aeeb3b8b..51fc0d0a92 100644 --- a/docs/examples/1.8.x/server-php/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-php/examples/messaging/create-push.md @@ -19,7 +19,7 @@ $result = $messaging->createPush( targets: [], // optional data: [], // optional action: '', // optional - image: '[ID1:ID2]', // optional + image: '', // optional icon: '', // optional sound: '', // optional color: '', // optional diff --git a/docs/examples/1.8.x/server-php/examples/messaging/update-push.md b/docs/examples/1.8.x/server-php/examples/messaging/update-push.md index e1df0b9132..05a51783c9 100644 --- a/docs/examples/1.8.x/server-php/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-php/examples/messaging/update-push.md @@ -19,7 +19,7 @@ $result = $messaging->updatePush( body: '', // optional data: [], // optional action: '', // optional - image: '[ID1:ID2]', // optional + image: '', // optional icon: '', // optional sound: '', // optional color: '', // optional diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-php/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..429a0bb546 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/create-operations.md @@ -0,0 +1,26 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$tablesDB = new TablesDB($client); + +$result = $tablesDB->createOperations( + transactionId: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-php/examples/tablesdb/create-row.md index fa5137b99e..873ecaf448 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/create-row.md @@ -21,5 +21,6 @@ $result = $tablesDB->createRow( 'age' => 30, 'isAdmin' => false ], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-php/examples/tablesdb/create-rows.md index 011443859f..44c9c7d140 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/create-rows.md @@ -13,5 +13,6 @@ $tablesDB = new TablesDB($client); $result = $tablesDB->createRows( databaseId: '', tableId: '', - rows: [] + rows: [], + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-php/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..32488185b1 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/create-transaction.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$tablesDB = new TablesDB($client); + +$result = $tablesDB->createTransaction( + ttl: 60 // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-php/examples/tablesdb/decrement-row-column.md index a58bd71071..ede258e8bd 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/decrement-row-column.md @@ -16,5 +16,6 @@ $result = $tablesDB->decrementRowColumn( rowId: '', column: '', value: null, // optional - min: null // optional + min: null, // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-php/examples/tablesdb/delete-row.md index 4ffc112d66..df87c5077b 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/delete-row.md @@ -13,5 +13,6 @@ $tablesDB = new TablesDB($client); $result = $tablesDB->deleteRow( databaseId: '', tableId: '', - rowId: '' + rowId: '', + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-php/examples/tablesdb/delete-rows.md index 10a3c87ff2..79ed607c47 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/delete-rows.md @@ -13,5 +13,6 @@ $tablesDB = new TablesDB($client); $result = $tablesDB->deleteRows( databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-php/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..d1650158c9 --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/delete-transaction.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$tablesDB = new TablesDB($client); + +$result = $tablesDB->deleteTransaction( + transactionId: '' +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-php/examples/tablesdb/get-row.md index 00ba9b65b5..4bbea5594d 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/get-row.md @@ -14,5 +14,6 @@ $result = $tablesDB->getRow( databaseId: '', tableId: '', rowId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-php/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..146e7d191b --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/get-transaction.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$tablesDB = new TablesDB($client); + +$result = $tablesDB->getTransaction( + transactionId: '' +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-php/examples/tablesdb/increment-row-column.md index d72a1e374f..66bf2e8489 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/increment-row-column.md @@ -16,5 +16,6 @@ $result = $tablesDB->incrementRowColumn( rowId: '', column: '', value: null, // optional - max: null // optional + max: null, // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-php/examples/tablesdb/list-rows.md index c3b713703e..5f8c9aa1ef 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/list-rows.md @@ -13,5 +13,6 @@ $tablesDB = new TablesDB($client); $result = $tablesDB->listRows( databaseId: '', tableId: '', - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-php/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..15095d6f0c --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/list-transactions.md @@ -0,0 +1,15 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$tablesDB = new TablesDB($client); + +$result = $tablesDB->listTransactions( + queries: [] // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-php/examples/tablesdb/update-row.md index 70e5d159fd..c01eba8d57 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/update-row.md @@ -15,5 +15,6 @@ $result = $tablesDB->updateRow( tableId: '', rowId: '', data: [], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-php/examples/tablesdb/update-rows.md index 8a676289d2..681a9f0d8b 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/update-rows.md @@ -14,5 +14,6 @@ $result = $tablesDB->updateRows( databaseId: '', tableId: '', data: [], // optional - queries: [] // optional + queries: [], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-php/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..fed3810b5a --- /dev/null +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/update-transaction.md @@ -0,0 +1,17 @@ +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$tablesDB = new TablesDB($client); + +$result = $tablesDB->updateTransaction( + transactionId: '', + commit: false, // optional + rollback: false // optional +); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-row.md index 235f0e577b..bec3c0af92 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-row.md @@ -15,5 +15,6 @@ $result = $tablesDB->upsertRow( tableId: '', rowId: '', data: [], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-rows.md index c1890f1ea3..fb93df8bcd 100644 --- a/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-php/examples/tablesdb/upsert-rows.md @@ -13,5 +13,6 @@ $tablesDB = new TablesDB($client); $result = $tablesDB->upsertRows( databaseId: '', tableId: '', - rows: [] + rows: [], + transactionId: '' // optional ); \ No newline at end of file diff --git a/docs/examples/1.8.x/server-python/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-python/examples/account/create-email-verification.md new file mode 100644 index 0000000000..a76a4bdb89 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/account/create-email-verification.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.account import Account + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_session('') # The user session to authenticate with + +account = Account(client) + +result = account.create_email_verification( + url = 'https://example.com' +) diff --git a/docs/examples/1.8.x/server-python/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-python/examples/account/update-email-verification.md new file mode 100644 index 0000000000..5e99587e86 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/account/update-email-verification.md @@ -0,0 +1,14 @@ +from appwrite.client import Client +from appwrite.services.account import Account + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_session('') # The user session to authenticate with + +account = Account(client) + +result = account.update_email_verification( + user_id = '', + secret = '' +) diff --git a/docs/examples/1.8.x/server-python/examples/databases/create-document.md b/docs/examples/1.8.x/server-python/examples/databases/create-document.md index 3d7dee1a4f..f42a3d82b6 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-python/examples/databases/create-document.md @@ -19,5 +19,6 @@ result = databases.create_document( "age": 30, "isAdmin": False }, - permissions = ["read("any")"] # optional + permissions = ["read("any")"], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/create-documents.md b/docs/examples/1.8.x/server-python/examples/databases/create-documents.md index 1b94e5165a..97fa4c6840 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-python/examples/databases/create-documents.md @@ -11,5 +11,6 @@ databases = Databases(client) result = databases.create_documents( database_id = '', collection_id = '', - documents = [] + documents = [], + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/create-operations.md b/docs/examples/1.8.x/server-python/examples/databases/create-operations.md new file mode 100644 index 0000000000..d8fc1fa772 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/databases/create-operations.md @@ -0,0 +1,24 @@ +from appwrite.client import Client +from appwrite.services.databases import Databases + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +databases = Databases(client) + +result = databases.create_operations( + transaction_id = '', + operations = [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-python/examples/databases/create-transaction.md new file mode 100644 index 0000000000..a733b658f8 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/databases/create-transaction.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.databases import Databases + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +databases = Databases(client) + +result = databases.create_transaction( + ttl = 60 # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-python/examples/databases/decrement-document-attribute.md index 3efedf766e..09ed9fcb47 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-python/examples/databases/decrement-document-attribute.md @@ -14,5 +14,6 @@ result = databases.decrement_document_attribute( document_id = '', attribute = '', value = None, # optional - min = None # optional + min = None, # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/delete-document.md b/docs/examples/1.8.x/server-python/examples/databases/delete-document.md index 57f8b3bd9d..89d85853e4 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-python/examples/databases/delete-document.md @@ -11,5 +11,6 @@ databases = Databases(client) result = databases.delete_document( database_id = '', collection_id = '', - document_id = '' + document_id = '', + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-python/examples/databases/delete-documents.md index a315f0c200..63130fb05e 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-python/examples/databases/delete-documents.md @@ -11,5 +11,6 @@ databases = Databases(client) result = databases.delete_documents( database_id = '', collection_id = '', - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-python/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..fab1f2a586 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/databases/delete-transaction.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.databases import Databases + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +databases = Databases(client) + +result = databases.delete_transaction( + transaction_id = '' +) diff --git a/docs/examples/1.8.x/server-python/examples/databases/get-document.md b/docs/examples/1.8.x/server-python/examples/databases/get-document.md index aff5008fa0..6cd0bc2b95 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-python/examples/databases/get-document.md @@ -12,5 +12,6 @@ result = databases.get_document( database_id = '', collection_id = '', document_id = '', - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-python/examples/databases/get-transaction.md new file mode 100644 index 0000000000..2a89f3d83d --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/databases/get-transaction.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.databases import Databases + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +databases = Databases(client) + +result = databases.get_transaction( + transaction_id = '' +) diff --git a/docs/examples/1.8.x/server-python/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-python/examples/databases/increment-document-attribute.md index 9ae1cedfe4..3e85656c10 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-python/examples/databases/increment-document-attribute.md @@ -14,5 +14,6 @@ result = databases.increment_document_attribute( document_id = '', attribute = '', value = None, # optional - max = None # optional + max = None, # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/list-documents.md b/docs/examples/1.8.x/server-python/examples/databases/list-documents.md index 8b450cd020..cecac30585 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-python/examples/databases/list-documents.md @@ -11,5 +11,6 @@ databases = Databases(client) result = databases.list_documents( database_id = '', collection_id = '', - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-python/examples/databases/list-transactions.md new file mode 100644 index 0000000000..a410c96b05 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/databases/list-transactions.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.databases import Databases + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +databases = Databases(client) + +result = databases.list_transactions( + queries = [] # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/databases/update-document.md b/docs/examples/1.8.x/server-python/examples/databases/update-document.md index 9ef6527934..c9ef02f72e 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-python/examples/databases/update-document.md @@ -13,5 +13,6 @@ result = databases.update_document( collection_id = '', document_id = '', data = {}, # optional - permissions = ["read("any")"] # optional + permissions = ["read("any")"], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/update-documents.md b/docs/examples/1.8.x/server-python/examples/databases/update-documents.md index 5a50d1a912..2aab8c61c4 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-python/examples/databases/update-documents.md @@ -12,5 +12,6 @@ result = databases.update_documents( database_id = '', collection_id = '', data = {}, # optional - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-python/examples/databases/update-transaction.md new file mode 100644 index 0000000000..571f98c7ce --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/databases/update-transaction.md @@ -0,0 +1,15 @@ +from appwrite.client import Client +from appwrite.services.databases import Databases + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +databases = Databases(client) + +result = databases.update_transaction( + transaction_id = '', + commit = False, # optional + rollback = False # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-python/examples/databases/upsert-document.md index c491ea4f44..e1a2f44d8c 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-python/examples/databases/upsert-document.md @@ -13,5 +13,6 @@ result = databases.upsert_document( collection_id = '', document_id = '', data = {}, - permissions = ["read("any")"] # optional + permissions = ["read("any")"], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-python/examples/databases/upsert-documents.md index 5136d5fcb1..f0720e34c0 100644 --- a/docs/examples/1.8.x/server-python/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-python/examples/databases/upsert-documents.md @@ -11,5 +11,6 @@ databases = Databases(client) result = databases.upsert_documents( database_id = '', collection_id = '', - documents = [] + documents = [], + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/messaging/create-push.md b/docs/examples/1.8.x/server-python/examples/messaging/create-push.md index 8671b56a39..b706234227 100644 --- a/docs/examples/1.8.x/server-python/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-python/examples/messaging/create-push.md @@ -17,7 +17,7 @@ result = messaging.create_push( targets = [], # optional data = {}, # optional action = '', # optional - image = '[ID1:ID2]', # optional + image = '', # optional icon = '', # optional sound = '', # optional color = '', # optional diff --git a/docs/examples/1.8.x/server-python/examples/messaging/update-push.md b/docs/examples/1.8.x/server-python/examples/messaging/update-push.md index e3bb02e71f..ce5d39466f 100644 --- a/docs/examples/1.8.x/server-python/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-python/examples/messaging/update-push.md @@ -17,7 +17,7 @@ result = messaging.update_push( body = '', # optional data = {}, # optional action = '', # optional - image = '[ID1:ID2]', # optional + image = '', # optional icon = '', # optional sound = '', # optional color = '', # optional diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-python/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..a4881a9e8f --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/create-operations.md @@ -0,0 +1,24 @@ +from appwrite.client import Client +from appwrite.services.tables_db import TablesDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +tables_db = TablesDB(client) + +result = tables_db.create_operations( + transaction_id = '', + operations = [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-python/examples/tablesdb/create-row.md index d4c1cdad14..d2de58617f 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/create-row.md @@ -19,5 +19,6 @@ result = tables_db.create_row( "age": 30, "isAdmin": False }, - permissions = ["read("any")"] # optional + permissions = ["read("any")"], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-python/examples/tablesdb/create-rows.md index 656a47aa0b..1527e0b30d 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/create-rows.md @@ -11,5 +11,6 @@ tables_db = TablesDB(client) result = tables_db.create_rows( database_id = '', table_id = '', - rows = [] + rows = [], + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-python/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..05cc80eaa2 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/create-transaction.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.tables_db import TablesDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +tables_db = TablesDB(client) + +result = tables_db.create_transaction( + ttl = 60 # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-python/examples/tablesdb/decrement-row-column.md index 096bc4dbaa..d207bb1b4d 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/decrement-row-column.md @@ -14,5 +14,6 @@ result = tables_db.decrement_row_column( row_id = '', column = '', value = None, # optional - min = None # optional + min = None, # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-python/examples/tablesdb/delete-row.md index 569b607020..3943ab27a5 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/delete-row.md @@ -11,5 +11,6 @@ tables_db = TablesDB(client) result = tables_db.delete_row( database_id = '', table_id = '', - row_id = '' + row_id = '', + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-python/examples/tablesdb/delete-rows.md index c3e836e7c6..290d6d346b 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/delete-rows.md @@ -11,5 +11,6 @@ tables_db = TablesDB(client) result = tables_db.delete_rows( database_id = '', table_id = '', - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-python/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..6d2957f3d6 --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/delete-transaction.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.tables_db import TablesDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +tables_db = TablesDB(client) + +result = tables_db.delete_transaction( + transaction_id = '' +) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-python/examples/tablesdb/get-row.md index c806214297..4398c9a43d 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/get-row.md @@ -12,5 +12,6 @@ result = tables_db.get_row( database_id = '', table_id = '', row_id = '', - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-python/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..e50c63af9d --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/get-transaction.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.tables_db import TablesDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +tables_db = TablesDB(client) + +result = tables_db.get_transaction( + transaction_id = '' +) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-python/examples/tablesdb/increment-row-column.md index bcb88f7a31..8e121f65f6 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/increment-row-column.md @@ -14,5 +14,6 @@ result = tables_db.increment_row_column( row_id = '', column = '', value = None, # optional - max = None # optional + max = None, # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-python/examples/tablesdb/list-rows.md index 9ae7549fb0..eb0a4ed1b3 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/list-rows.md @@ -11,5 +11,6 @@ tables_db = TablesDB(client) result = tables_db.list_rows( database_id = '', table_id = '', - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-python/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..e597c2d6fd --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/list-transactions.md @@ -0,0 +1,13 @@ +from appwrite.client import Client +from appwrite.services.tables_db import TablesDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +tables_db = TablesDB(client) + +result = tables_db.list_transactions( + queries = [] # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-python/examples/tablesdb/update-row.md index 86d0cf2b8a..89dbfb0587 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/update-row.md @@ -13,5 +13,6 @@ result = tables_db.update_row( table_id = '', row_id = '', data = {}, # optional - permissions = ["read("any")"] # optional + permissions = ["read("any")"], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-python/examples/tablesdb/update-rows.md index 386ddf8b88..4717581276 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/update-rows.md @@ -12,5 +12,6 @@ result = tables_db.update_rows( database_id = '', table_id = '', data = {}, # optional - queries = [] # optional + queries = [], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-python/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..97b518dc6e --- /dev/null +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/update-transaction.md @@ -0,0 +1,15 @@ +from appwrite.client import Client +from appwrite.services.tables_db import TablesDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +tables_db = TablesDB(client) + +result = tables_db.update_transaction( + transaction_id = '', + commit = False, # optional + rollback = False # optional +) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-row.md index 068fded0c3..8539e12e96 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-row.md @@ -13,5 +13,6 @@ result = tables_db.upsert_row( table_id = '', row_id = '', data = {}, # optional - permissions = ["read("any")"] # optional + permissions = ["read("any")"], # optional + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-rows.md index 06436c0fa6..d42e259fb0 100644 --- a/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-python/examples/tablesdb/upsert-rows.md @@ -11,5 +11,6 @@ tables_db = TablesDB(client) result = tables_db.upsert_rows( database_id = '', table_id = '', - rows = [] + rows = [], + transaction_id = '' # optional ) diff --git a/docs/examples/1.8.x/server-rest/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-rest/examples/account/create-email-verification.md new file mode 100644 index 0000000000..63fcd5765e --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/account/create-email-verification.md @@ -0,0 +1,11 @@ +POST /v1/account/verifications/email HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "url": "https://example.com" +} diff --git a/docs/examples/1.8.x/server-rest/examples/account/create-phone-verification.md b/docs/examples/1.8.x/server-rest/examples/account/create-phone-verification.md index 57b3b7d160..b48c9249b3 100644 --- a/docs/examples/1.8.x/server-rest/examples/account/create-phone-verification.md +++ b/docs/examples/1.8.x/server-rest/examples/account/create-phone-verification.md @@ -1,4 +1,4 @@ -POST /v1/account/verification/phone HTTP/1.1 +POST /v1/account/verifications/phone HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/server-rest/examples/account/create-verification.md b/docs/examples/1.8.x/server-rest/examples/account/create-verification.md index ed5479dbe5..63fcd5765e 100644 --- a/docs/examples/1.8.x/server-rest/examples/account/create-verification.md +++ b/docs/examples/1.8.x/server-rest/examples/account/create-verification.md @@ -1,4 +1,4 @@ -POST /v1/account/verification HTTP/1.1 +POST /v1/account/verifications/email HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/server-rest/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-rest/examples/account/update-email-verification.md new file mode 100644 index 0000000000..c7c6c34e52 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/account/update-email-verification.md @@ -0,0 +1,12 @@ +PUT /v1/account/verifications/email HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "userId": "", + "secret": "" +} diff --git a/docs/examples/1.8.x/server-rest/examples/account/update-phone-verification.md b/docs/examples/1.8.x/server-rest/examples/account/update-phone-verification.md index 1d4dc22520..faa6478150 100644 --- a/docs/examples/1.8.x/server-rest/examples/account/update-phone-verification.md +++ b/docs/examples/1.8.x/server-rest/examples/account/update-phone-verification.md @@ -1,4 +1,4 @@ -PUT /v1/account/verification/phone HTTP/1.1 +PUT /v1/account/verifications/phone HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/server-rest/examples/account/update-verification.md b/docs/examples/1.8.x/server-rest/examples/account/update-verification.md index a4dcbf76a3..c7c6c34e52 100644 --- a/docs/examples/1.8.x/server-rest/examples/account/update-verification.md +++ b/docs/examples/1.8.x/server-rest/examples/account/update-verification.md @@ -1,4 +1,4 @@ -PUT /v1/account/verification HTTP/1.1 +PUT /v1/account/verifications/email HTTP/1.1 Host: cloud.appwrite.io Content-Type: application/json X-Appwrite-Response-Format: 1.8.0 diff --git a/docs/examples/1.8.x/server-rest/examples/databases/create-document.md b/docs/examples/1.8.x/server-rest/examples/databases/create-document.md index 57c38f0ba7..e1ca57e0bf 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/create-document.md @@ -16,5 +16,6 @@ X-Appwrite-JWT: "age": 30, "isAdmin": false }, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/create-documents.md b/docs/examples/1.8.x/server-rest/examples/databases/create-documents.md index cee5405fb2..4e23244620 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/create-documents.md @@ -8,5 +8,6 @@ X-Appwrite-Key: X-Appwrite-JWT: { - "documents": [] + "documents": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/create-operations.md b/docs/examples/1.8.x/server-rest/examples/databases/create-operations.md new file mode 100644 index 0000000000..212d60df29 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/databases/create-operations.md @@ -0,0 +1,22 @@ +POST /v1/databases/transactions/{transactionId}/operations HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "operations": [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] +} diff --git a/docs/examples/1.8.x/server-rest/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-rest/examples/databases/create-transaction.md new file mode 100644 index 0000000000..3647e2d128 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/databases/create-transaction.md @@ -0,0 +1,12 @@ +POST /v1/databases/transactions HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "ttl": 60 +} diff --git a/docs/examples/1.8.x/server-rest/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-rest/examples/databases/decrement-document-attribute.md index 78694a804d..0bd736b0e4 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/decrement-document-attribute.md @@ -9,5 +9,6 @@ X-Appwrite-Key: { "value": 0, - "min": 0 + "min": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/delete-document.md b/docs/examples/1.8.x/server-rest/examples/databases/delete-document.md index b5580b04bf..1031bfe18d 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/delete-document.md @@ -7,3 +7,6 @@ X-Appwrite-Session: X-Appwrite-Key: X-Appwrite-JWT: +{ + "transactionId": "" +} diff --git a/docs/examples/1.8.x/server-rest/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-rest/examples/databases/delete-documents.md index cb27719953..13ad4c6600 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/delete-documents.md @@ -6,5 +6,6 @@ X-Appwrite-Project: X-Appwrite-Key: { - "queries": [] + "queries": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-rest/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..09fc4e21f7 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/databases/delete-transaction.md @@ -0,0 +1,9 @@ +DELETE /v1/databases/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + diff --git a/docs/examples/1.8.x/server-rest/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-rest/examples/databases/get-transaction.md new file mode 100644 index 0000000000..e3d89d72de --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/databases/get-transaction.md @@ -0,0 +1,7 @@ +GET /v1/databases/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/server-rest/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-rest/examples/databases/increment-document-attribute.md index cd6b4122eb..924f0e9b0c 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/increment-document-attribute.md @@ -9,5 +9,6 @@ X-Appwrite-Key: { "value": 0, - "max": 0 + "max": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-rest/examples/databases/list-transactions.md new file mode 100644 index 0000000000..7a6f680a5f --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/databases/list-transactions.md @@ -0,0 +1,7 @@ +GET /v1/databases/transactions HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/server-rest/examples/databases/update-document.md b/docs/examples/1.8.x/server-rest/examples/databases/update-document.md index 9a156375de..dafd249c31 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/update-document.md @@ -9,5 +9,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/update-documents.md b/docs/examples/1.8.x/server-rest/examples/databases/update-documents.md index 69ea7a0d6f..69d2dccd13 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/update-documents.md @@ -7,5 +7,6 @@ X-Appwrite-Key: { "data": {}, - "queries": [] + "queries": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-rest/examples/databases/update-transaction.md new file mode 100644 index 0000000000..21f1921e41 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/databases/update-transaction.md @@ -0,0 +1,13 @@ +PATCH /v1/databases/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "commit": false, + "rollback": false +} diff --git a/docs/examples/1.8.x/server-rest/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-rest/examples/databases/upsert-document.md index 97b61bfc7f..e4a9c7796a 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/upsert-document.md @@ -9,5 +9,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-rest/examples/databases/upsert-documents.md index 4bcb9cb0c0..7b15435e90 100644 --- a/docs/examples/1.8.x/server-rest/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-rest/examples/databases/upsert-documents.md @@ -6,5 +6,6 @@ X-Appwrite-Project: X-Appwrite-Key: { - "documents": [] + "documents": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/messaging/create-push.md b/docs/examples/1.8.x/server-rest/examples/messaging/create-push.md index a70702c014..f873bfe6ee 100644 --- a/docs/examples/1.8.x/server-rest/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-rest/examples/messaging/create-push.md @@ -14,7 +14,7 @@ X-Appwrite-Key: "targets": [], "data": {}, "action": "", - "image": "[ID1:ID2]", + "image": "", "icon": "", "sound": "", "color": "", diff --git a/docs/examples/1.8.x/server-rest/examples/messaging/update-push.md b/docs/examples/1.8.x/server-rest/examples/messaging/update-push.md index b3b953bc31..a3a6f84ae6 100644 --- a/docs/examples/1.8.x/server-rest/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-rest/examples/messaging/update-push.md @@ -13,7 +13,7 @@ X-Appwrite-Key: "body": "", "data": {}, "action": "", - "image": "[ID1:ID2]", + "image": "", "icon": "", "sound": "", "color": "", diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..87ca296db2 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-operations.md @@ -0,0 +1,22 @@ +POST /v1/tablesdb/transactions/{transactionId}/operations HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "operations": [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] +} diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-row.md index 3c42d0f172..cec287f4b3 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-row.md @@ -16,5 +16,6 @@ X-Appwrite-JWT: "age": 30, "isAdmin": false }, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-rows.md index 176b4cdb02..0ff4426b84 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-rows.md @@ -8,5 +8,6 @@ X-Appwrite-Key: X-Appwrite-JWT: { - "rows": [] + "rows": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..a2b8b184bd --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/create-transaction.md @@ -0,0 +1,12 @@ +POST /v1/tablesdb/transactions HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "ttl": 60 +} diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/decrement-row-column.md index 26d8e1118c..74b06974f1 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/decrement-row-column.md @@ -9,5 +9,6 @@ X-Appwrite-Key: { "value": 0, - "min": 0 + "min": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-row.md index 3dbbf45a3c..b1376ee7cd 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-row.md @@ -7,3 +7,6 @@ X-Appwrite-Session: X-Appwrite-Key: X-Appwrite-JWT: +{ + "transactionId": "" +} diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-rows.md index c57d62ede3..22eae7d599 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-rows.md @@ -6,5 +6,6 @@ X-Appwrite-Project: X-Appwrite-Key: { - "queries": [] + "queries": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..ed6e20dcc8 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/delete-transaction.md @@ -0,0 +1,9 @@ +DELETE /v1/tablesdb/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..690351d711 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/get-transaction.md @@ -0,0 +1,7 @@ +GET /v1/tablesdb/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/increment-row-column.md index d687727806..e9047669cd 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/increment-row-column.md @@ -9,5 +9,6 @@ X-Appwrite-Key: { "value": 0, - "max": 0 + "max": 0, + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..8b7f9301e3 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/list-transactions.md @@ -0,0 +1,7 @@ +GET /v1/tablesdb/transactions HTTP/1.1 +Host: cloud.appwrite.io +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/update-row.md index 51f10f7f97..5c37e3d929 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/update-row.md @@ -9,5 +9,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/update-rows.md index 2f282d8e13..c872907d30 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/update-rows.md @@ -7,5 +7,6 @@ X-Appwrite-Key: { "data": {}, - "queries": [] + "queries": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..118366e4a6 --- /dev/null +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/update-transaction.md @@ -0,0 +1,13 @@ +PATCH /v1/tablesdb/transactions/{transactionId} HTTP/1.1 +Host: cloud.appwrite.io +Content-Type: application/json +X-Appwrite-Response-Format: 1.8.0 +X-Appwrite-Project: +X-Appwrite-Key: +X-Appwrite-Session: +X-Appwrite-JWT: + +{ + "commit": false, + "rollback": false +} diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-row.md index edb74043fb..9f698fb195 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-row.md @@ -9,5 +9,6 @@ X-Appwrite-JWT: { "data": {}, - "permissions": ["read(\"any\")"] + "permissions": ["read(\"any\")"], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-rows.md index 147e4f66c3..822c7aaec2 100644 --- a/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-rest/examples/tablesdb/upsert-rows.md @@ -6,5 +6,6 @@ X-Appwrite-Project: X-Appwrite-Key: { - "rows": [] + "rows": [], + "transactionId": "" } diff --git a/docs/examples/1.8.x/server-ruby/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-ruby/examples/account/create-email-verification.md new file mode 100644 index 0000000000..11bf56b73f --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/account/create-email-verification.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_session('') # The user session to authenticate with + +account = Account.new(client) + +result = account.create_email_verification( + url: 'https://example.com' +) diff --git a/docs/examples/1.8.x/server-ruby/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-ruby/examples/account/update-email-verification.md new file mode 100644 index 0000000000..33b009a549 --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/account/update-email-verification.md @@ -0,0 +1,15 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_session('') # The user session to authenticate with + +account = Account.new(client) + +result = account.update_email_verification( + user_id: '', + secret: '' +) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/create-document.md b/docs/examples/1.8.x/server-ruby/examples/databases/create-document.md index 22ce5745fd..d12a3dbb8d 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/create-document.md @@ -20,5 +20,6 @@ result = databases.create_document( "age" => 30, "isAdmin" => false }, - permissions: ["read("any")"] # optional + permissions: ["read("any")"], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/create-documents.md b/docs/examples/1.8.x/server-ruby/examples/databases/create-documents.md index 16abc5e465..db45bd78a9 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/create-documents.md @@ -12,5 +12,6 @@ databases = Databases.new(client) result = databases.create_documents( database_id: '', collection_id: '', - documents: [] + documents: [], + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/create-operations.md b/docs/examples/1.8.x/server-ruby/examples/databases/create-operations.md new file mode 100644 index 0000000000..687932bd3e --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/databases/create-operations.md @@ -0,0 +1,25 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +databases = Databases.new(client) + +result = databases.create_operations( + transaction_id: '', + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-ruby/examples/databases/create-transaction.md new file mode 100644 index 0000000000..83d2e4ea4d --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/databases/create-transaction.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +databases = Databases.new(client) + +result = databases.create_transaction( + ttl: 60 # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-ruby/examples/databases/decrement-document-attribute.md index 9fd0191a0f..ecf15864da 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/decrement-document-attribute.md @@ -15,5 +15,6 @@ result = databases.decrement_document_attribute( document_id: '', attribute: '', value: null, # optional - min: null # optional + min: null, # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/delete-document.md b/docs/examples/1.8.x/server-ruby/examples/databases/delete-document.md index 2102d2695b..079247fc05 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/delete-document.md @@ -12,5 +12,6 @@ databases = Databases.new(client) result = databases.delete_document( database_id: '', collection_id: '', - document_id: '' + document_id: '', + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-ruby/examples/databases/delete-documents.md index d0f10d0b41..838660747c 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/delete-documents.md @@ -12,5 +12,6 @@ databases = Databases.new(client) result = databases.delete_documents( database_id: '', collection_id: '', - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-ruby/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..2024818ad4 --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/databases/delete-transaction.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +databases = Databases.new(client) + +result = databases.delete_transaction( + transaction_id: '' +) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/get-document.md b/docs/examples/1.8.x/server-ruby/examples/databases/get-document.md index f43a1a2924..47404fee80 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/get-document.md @@ -13,5 +13,6 @@ result = databases.get_document( database_id: '', collection_id: '', document_id: '', - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-ruby/examples/databases/get-transaction.md new file mode 100644 index 0000000000..7d8349dc7d --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/databases/get-transaction.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +databases = Databases.new(client) + +result = databases.get_transaction( + transaction_id: '' +) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-ruby/examples/databases/increment-document-attribute.md index 3e8bfe0b2a..8f78675cdd 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/increment-document-attribute.md @@ -15,5 +15,6 @@ result = databases.increment_document_attribute( document_id: '', attribute: '', value: null, # optional - max: null # optional + max: null, # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/list-documents.md b/docs/examples/1.8.x/server-ruby/examples/databases/list-documents.md index 6617198d3f..666bfbd5ce 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/list-documents.md @@ -12,5 +12,6 @@ databases = Databases.new(client) result = databases.list_documents( database_id: '', collection_id: '', - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-ruby/examples/databases/list-transactions.md new file mode 100644 index 0000000000..c041a05b5e --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/databases/list-transactions.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +databases = Databases.new(client) + +result = databases.list_transactions( + queries: [] # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/update-document.md b/docs/examples/1.8.x/server-ruby/examples/databases/update-document.md index 485eb0485a..5831d68b5d 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/update-document.md @@ -14,5 +14,6 @@ result = databases.update_document( collection_id: '', document_id: '', data: {}, # optional - permissions: ["read("any")"] # optional + permissions: ["read("any")"], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/update-documents.md b/docs/examples/1.8.x/server-ruby/examples/databases/update-documents.md index 2f6907294f..c85f594e55 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/update-documents.md @@ -13,5 +13,6 @@ result = databases.update_documents( database_id: '', collection_id: '', data: {}, # optional - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-ruby/examples/databases/update-transaction.md new file mode 100644 index 0000000000..e53c148b18 --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/databases/update-transaction.md @@ -0,0 +1,16 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +databases = Databases.new(client) + +result = databases.update_transaction( + transaction_id: '', + commit: false, # optional + rollback: false # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-ruby/examples/databases/upsert-document.md index 238081864f..e5daa554c4 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/upsert-document.md @@ -14,5 +14,6 @@ result = databases.upsert_document( collection_id: '', document_id: '', data: {}, - permissions: ["read("any")"] # optional + permissions: ["read("any")"], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-ruby/examples/databases/upsert-documents.md index 30c42aa439..b470b8d31f 100644 --- a/docs/examples/1.8.x/server-ruby/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-ruby/examples/databases/upsert-documents.md @@ -12,5 +12,6 @@ databases = Databases.new(client) result = databases.upsert_documents( database_id: '', collection_id: '', - documents: [] + documents: [], + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/messaging/create-push.md b/docs/examples/1.8.x/server-ruby/examples/messaging/create-push.md index 5c58fa542b..f4555aa967 100644 --- a/docs/examples/1.8.x/server-ruby/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-ruby/examples/messaging/create-push.md @@ -18,7 +18,7 @@ result = messaging.create_push( targets: [], # optional data: {}, # optional action: '', # optional - image: '[ID1:ID2]', # optional + image: '', # optional icon: '', # optional sound: '', # optional color: '', # optional diff --git a/docs/examples/1.8.x/server-ruby/examples/messaging/update-push.md b/docs/examples/1.8.x/server-ruby/examples/messaging/update-push.md index 42a5104ccb..19b273bb24 100644 --- a/docs/examples/1.8.x/server-ruby/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-ruby/examples/messaging/update-push.md @@ -18,7 +18,7 @@ result = messaging.update_push( body: '', # optional data: {}, # optional action: '', # optional - image: '[ID1:ID2]', # optional + image: '', # optional icon: '', # optional sound: '', # optional color: '', # optional diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..dfc7180990 --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-operations.md @@ -0,0 +1,25 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +tables_db = TablesDB.new(client) + +result = tables_db.create_operations( + transaction_id: '', + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-row.md index 5e19136676..5622711642 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-row.md @@ -20,5 +20,6 @@ result = tables_db.create_row( "age" => 30, "isAdmin" => false }, - permissions: ["read("any")"] # optional + permissions: ["read("any")"], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-rows.md index f258d4d36f..76ee28699a 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-rows.md @@ -12,5 +12,6 @@ tables_db = TablesDB.new(client) result = tables_db.create_rows( database_id: '', table_id: '', - rows: [] + rows: [], + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..e3525afa19 --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/create-transaction.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +tables_db = TablesDB.new(client) + +result = tables_db.create_transaction( + ttl: 60 # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/decrement-row-column.md index 21439740ed..62b01977b1 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/decrement-row-column.md @@ -15,5 +15,6 @@ result = tables_db.decrement_row_column( row_id: '', column: '', value: null, # optional - min: null # optional + min: null, # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-row.md index 704f52fc39..9747cb938a 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-row.md @@ -12,5 +12,6 @@ tables_db = TablesDB.new(client) result = tables_db.delete_row( database_id: '', table_id: '', - row_id: '' + row_id: '', + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-rows.md index 5b15c1748a..cf95cfb229 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-rows.md @@ -12,5 +12,6 @@ tables_db = TablesDB.new(client) result = tables_db.delete_rows( database_id: '', table_id: '', - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..8fa7b3b8ac --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/delete-transaction.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +tables_db = TablesDB.new(client) + +result = tables_db.delete_transaction( + transaction_id: '' +) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/get-row.md index 621c2e12f6..bdc1cf5fe6 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/get-row.md @@ -13,5 +13,6 @@ result = tables_db.get_row( database_id: '', table_id: '', row_id: '', - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..ce8468ba3f --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/get-transaction.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +tables_db = TablesDB.new(client) + +result = tables_db.get_transaction( + transaction_id: '' +) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/increment-row-column.md index bf9b6cc230..a20d2f5b36 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/increment-row-column.md @@ -15,5 +15,6 @@ result = tables_db.increment_row_column( row_id: '', column: '', value: null, # optional - max: null # optional + max: null, # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/list-rows.md index af971fbe10..b205cece5d 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/list-rows.md @@ -12,5 +12,6 @@ tables_db = TablesDB.new(client) result = tables_db.list_rows( database_id: '', table_id: '', - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..e969bc9965 --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/list-transactions.md @@ -0,0 +1,14 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +tables_db = TablesDB.new(client) + +result = tables_db.list_transactions( + queries: [] # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-row.md index 7a48c5e3f6..02123051ca 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-row.md @@ -14,5 +14,6 @@ result = tables_db.update_row( table_id: '', row_id: '', data: {}, # optional - permissions: ["read("any")"] # optional + permissions: ["read("any")"], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-rows.md index 7316241139..7c538a137d 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-rows.md @@ -13,5 +13,6 @@ result = tables_db.update_rows( database_id: '', table_id: '', data: {}, # optional - queries: [] # optional + queries: [], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..2b8b3e7999 --- /dev/null +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/update-transaction.md @@ -0,0 +1,16 @@ +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +tables_db = TablesDB.new(client) + +result = tables_db.update_transaction( + transaction_id: '', + commit: false, # optional + rollback: false # optional +) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-row.md index 5eb4281002..9feb685927 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-row.md @@ -14,5 +14,6 @@ result = tables_db.upsert_row( table_id: '', row_id: '', data: {}, # optional - permissions: ["read("any")"] # optional + permissions: ["read("any")"], # optional + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-rows.md index c48211dcc0..e38f534ea9 100644 --- a/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-ruby/examples/tablesdb/upsert-rows.md @@ -12,5 +12,6 @@ tables_db = TablesDB.new(client) result = tables_db.upsert_rows( database_id: '', table_id: '', - rows: [] + rows: [], + transaction_id: '' # optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/account/create-email-verification.md b/docs/examples/1.8.x/server-swift/examples/account/create-email-verification.md new file mode 100644 index 0000000000..788fd9585a --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/account/create-email-verification.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setSession("") // The user session to authenticate with + +let account = Account(client) + +let token = try await account.createEmailVerification( + url: "https://example.com" +) + diff --git a/docs/examples/1.8.x/server-swift/examples/account/update-email-verification.md b/docs/examples/1.8.x/server-swift/examples/account/update-email-verification.md new file mode 100644 index 0000000000..10c8afe901 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/account/update-email-verification.md @@ -0,0 +1,14 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setSession("") // The user session to authenticate with + +let account = Account(client) + +let token = try await account.updateEmailVerification( + userId: "", + secret: "" +) + diff --git a/docs/examples/1.8.x/server-swift/examples/databases/create-document.md b/docs/examples/1.8.x/server-swift/examples/databases/create-document.md index cc25fd8df8..604bacdc2a 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/create-document.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/create-document.md @@ -18,6 +18,7 @@ let document = try await databases.createDocument( "age": 30, "isAdmin": false ], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/create-documents.md b/docs/examples/1.8.x/server-swift/examples/databases/create-documents.md index 2e992d9e3a..82a75125ae 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/create-documents.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/create-documents.md @@ -10,6 +10,7 @@ let databases = Databases(client) let documentList = try await databases.createDocuments( databaseId: "", collectionId: "", - documents: [] + documents: [], + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/create-operations.md b/docs/examples/1.8.x/server-swift/examples/databases/create-operations.md new file mode 100644 index 0000000000..7cab190bd3 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/databases/create-operations.md @@ -0,0 +1,24 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let databases = Databases(client) + +let transaction = try await databases.createOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "collectionId": "", + "documentId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/databases/create-transaction.md b/docs/examples/1.8.x/server-swift/examples/databases/create-transaction.md new file mode 100644 index 0000000000..333632c583 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/databases/create-transaction.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let databases = Databases(client) + +let transaction = try await databases.createTransaction( + ttl: 60 // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/databases/decrement-document-attribute.md b/docs/examples/1.8.x/server-swift/examples/databases/decrement-document-attribute.md index 81516fa26a..8c256ad208 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/decrement-document-attribute.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/decrement-document-attribute.md @@ -13,6 +13,7 @@ let document = try await databases.decrementDocumentAttribute( documentId: "", attribute: "", value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/delete-document.md b/docs/examples/1.8.x/server-swift/examples/databases/delete-document.md index 1db59709ab..9120c3d0d0 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/delete-document.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/delete-document.md @@ -10,6 +10,7 @@ let databases = Databases(client) let result = try await databases.deleteDocument( databaseId: "", collectionId: "", - documentId: "" + documentId: "", + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/delete-documents.md b/docs/examples/1.8.x/server-swift/examples/databases/delete-documents.md index d5321f2b26..79ec772b3b 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/delete-documents.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/delete-documents.md @@ -10,6 +10,7 @@ let databases = Databases(client) let documentList = try await databases.deleteDocuments( databaseId: "", collectionId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/delete-transaction.md b/docs/examples/1.8.x/server-swift/examples/databases/delete-transaction.md new file mode 100644 index 0000000000..8ac62ef945 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/databases/delete-transaction.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let databases = Databases(client) + +let result = try await databases.deleteTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/server-swift/examples/databases/get-document.md b/docs/examples/1.8.x/server-swift/examples/databases/get-document.md index c92856a731..319a7ec3fb 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/get-document.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/get-document.md @@ -11,6 +11,7 @@ let document = try await databases.getDocument( databaseId: "", collectionId: "", documentId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/get-transaction.md b/docs/examples/1.8.x/server-swift/examples/databases/get-transaction.md new file mode 100644 index 0000000000..bfabd08b78 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/databases/get-transaction.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let databases = Databases(client) + +let transaction = try await databases.getTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/server-swift/examples/databases/increment-document-attribute.md b/docs/examples/1.8.x/server-swift/examples/databases/increment-document-attribute.md index 64ba46b413..7dd8805dc0 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/increment-document-attribute.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/increment-document-attribute.md @@ -13,6 +13,7 @@ let document = try await databases.incrementDocumentAttribute( documentId: "", attribute: "", value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/list-documents.md b/docs/examples/1.8.x/server-swift/examples/databases/list-documents.md index 2cac9330b3..1147530d00 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/list-documents.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/list-documents.md @@ -10,6 +10,7 @@ let databases = Databases(client) let documentList = try await databases.listDocuments( databaseId: "", collectionId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/list-transactions.md b/docs/examples/1.8.x/server-swift/examples/databases/list-transactions.md new file mode 100644 index 0000000000..bb0d852d0a --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/databases/list-transactions.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let databases = Databases(client) + +let transactionList = try await databases.listTransactions( + queries: [] // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/databases/update-document.md b/docs/examples/1.8.x/server-swift/examples/databases/update-document.md index 7d452db284..b6260d754d 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/update-document.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/update-document.md @@ -12,6 +12,7 @@ let document = try await databases.updateDocument( collectionId: "", documentId: "", data: [:], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/update-documents.md b/docs/examples/1.8.x/server-swift/examples/databases/update-documents.md index 0e934b1424..f1fb34aa3c 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/update-documents.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/update-documents.md @@ -11,6 +11,7 @@ let documentList = try await databases.updateDocuments( databaseId: "", collectionId: "", data: [:], // optional - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/update-transaction.md b/docs/examples/1.8.x/server-swift/examples/databases/update-transaction.md new file mode 100644 index 0000000000..79f4939b5d --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/databases/update-transaction.md @@ -0,0 +1,15 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let databases = Databases(client) + +let transaction = try await databases.updateTransaction( + transactionId: "", + commit: false, // optional + rollback: false // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/databases/upsert-document.md b/docs/examples/1.8.x/server-swift/examples/databases/upsert-document.md index e78bd458a0..26897f4ca5 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/upsert-document.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/upsert-document.md @@ -12,6 +12,7 @@ let document = try await databases.upsertDocument( collectionId: "", documentId: "", data: [:], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/databases/upsert-documents.md b/docs/examples/1.8.x/server-swift/examples/databases/upsert-documents.md index 544f02f9c0..92c5fd9810 100644 --- a/docs/examples/1.8.x/server-swift/examples/databases/upsert-documents.md +++ b/docs/examples/1.8.x/server-swift/examples/databases/upsert-documents.md @@ -10,6 +10,7 @@ let databases = Databases(client) let documentList = try await databases.upsertDocuments( databaseId: "", collectionId: "", - documents: [] + documents: [], + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/messaging/create-push.md b/docs/examples/1.8.x/server-swift/examples/messaging/create-push.md index 498eccb51a..ba03b3330d 100644 --- a/docs/examples/1.8.x/server-swift/examples/messaging/create-push.md +++ b/docs/examples/1.8.x/server-swift/examples/messaging/create-push.md @@ -17,7 +17,7 @@ let message = try await messaging.createPush( targets: [], // optional data: [:], // optional action: "", // optional - image: "[ID1:ID2]", // optional + image: "", // optional icon: "", // optional sound: "", // optional color: "", // optional diff --git a/docs/examples/1.8.x/server-swift/examples/messaging/update-push.md b/docs/examples/1.8.x/server-swift/examples/messaging/update-push.md index e443161aa9..b7b5bb0b38 100644 --- a/docs/examples/1.8.x/server-swift/examples/messaging/update-push.md +++ b/docs/examples/1.8.x/server-swift/examples/messaging/update-push.md @@ -17,7 +17,7 @@ let message = try await messaging.updatePush( body: "", // optional data: [:], // optional action: "", // optional - image: "[ID1:ID2]", // optional + image: "", // optional icon: "", // optional sound: "", // optional color: "", // optional diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/create-operations.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-operations.md new file mode 100644 index 0000000000..5ee356e55b --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-operations.md @@ -0,0 +1,24 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.createOperations( + transactionId: "", + operations: [ + { + "action": "create", + "databaseId": "", + "tableId": "", + "rowId": "", + "data": { + "name": "Walter O'Brien" + } + } + ] // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/create-row.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-row.md index 0c59a65755..049ef2da3d 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/create-row.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-row.md @@ -18,6 +18,7 @@ let row = try await tablesDB.createRow( "age": 30, "isAdmin": false ], - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/create-rows.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-rows.md index 25ea512590..63fafbd9e5 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/create-rows.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-rows.md @@ -10,6 +10,7 @@ let tablesDB = TablesDB(client) let rowList = try await tablesDB.createRows( databaseId: "", tableId: "", - rows: [] + rows: [], + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/create-transaction.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-transaction.md new file mode 100644 index 0000000000..d826446ea2 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/create-transaction.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.createTransaction( + ttl: 60 // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/decrement-row-column.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/decrement-row-column.md index 196289e994..9c33055202 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/decrement-row-column.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/decrement-row-column.md @@ -13,6 +13,7 @@ let row = try await tablesDB.decrementRowColumn( rowId: "", column: "", value: 0, // optional - min: 0 // optional + min: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-row.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-row.md index 5449c74edb..a0a96eea4e 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-row.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-row.md @@ -10,6 +10,7 @@ let tablesDB = TablesDB(client) let result = try await tablesDB.deleteRow( databaseId: "", tableId: "", - rowId: "" + rowId: "", + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-rows.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-rows.md index 85d8957f78..7235112eca 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-rows.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-rows.md @@ -10,6 +10,7 @@ let tablesDB = TablesDB(client) let rowList = try await tablesDB.deleteRows( databaseId: "", tableId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-transaction.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..9a5d58bf42 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/delete-transaction.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let tablesDB = TablesDB(client) + +let result = try await tablesDB.deleteTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/get-row.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/get-row.md index 17e6ccbb52..ecadab16aa 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/get-row.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/get-row.md @@ -11,6 +11,7 @@ let row = try await tablesDB.getRow( databaseId: "", tableId: "", rowId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/get-transaction.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/get-transaction.md new file mode 100644 index 0000000000..af0bd03b12 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/get-transaction.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.getTransaction( + transactionId: "" +) + diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/increment-row-column.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/increment-row-column.md index 38aa7581c6..6c35ba8d4a 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/increment-row-column.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/increment-row-column.md @@ -13,6 +13,7 @@ let row = try await tablesDB.incrementRowColumn( rowId: "", column: "", value: 0, // optional - max: 0 // optional + max: 0, // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/list-rows.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/list-rows.md index 7320147685..92a2813f74 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/list-rows.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/list-rows.md @@ -10,6 +10,7 @@ let tablesDB = TablesDB(client) let rowList = try await tablesDB.listRows( databaseId: "", tableId: "", - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/list-transactions.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/list-transactions.md new file mode 100644 index 0000000000..c6acb295d6 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/list-transactions.md @@ -0,0 +1,13 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let tablesDB = TablesDB(client) + +let transactionList = try await tablesDB.listTransactions( + queries: [] // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/update-row.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/update-row.md index e06338b3d6..3ebd9e0970 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/update-row.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/update-row.md @@ -12,6 +12,7 @@ let row = try await tablesDB.updateRow( tableId: "", rowId: "", data: [:], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/update-rows.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/update-rows.md index 58894f5b85..f18a2a306c 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/update-rows.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/update-rows.md @@ -11,6 +11,7 @@ let rowList = try await tablesDB.updateRows( databaseId: "", tableId: "", data: [:], // optional - queries: [] // optional + queries: [], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/update-transaction.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/update-transaction.md new file mode 100644 index 0000000000..faa7d07d63 --- /dev/null +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/update-transaction.md @@ -0,0 +1,15 @@ +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let tablesDB = TablesDB(client) + +let transaction = try await tablesDB.updateTransaction( + transactionId: "", + commit: false, // optional + rollback: false // optional +) + diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-row.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-row.md index dc133f6cd1..1b076266a3 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-row.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-row.md @@ -12,6 +12,7 @@ let row = try await tablesDB.upsertRow( tableId: "", rowId: "", data: [:], // optional - permissions: ["read("any")"] // optional + permissions: ["read("any")"], // optional + transactionId: "" // optional ) diff --git a/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-rows.md b/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-rows.md index fe35f0da91..027087b252 100644 --- a/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-rows.md +++ b/docs/examples/1.8.x/server-swift/examples/tablesdb/upsert-rows.md @@ -10,6 +10,7 @@ let tablesDB = TablesDB(client) let rowList = try await tablesDB.upsertRows( databaseId: "", tableId: "", - rows: [] + rows: [], + transactionId: "" // optional ) diff --git a/docs/references/databases/create-operations.md b/docs/references/databases/create-operations.md new file mode 100644 index 0000000000..a737b95a55 --- /dev/null +++ b/docs/references/databases/create-operations.md @@ -0,0 +1 @@ +Create multiple operations in a single transaction. \ No newline at end of file diff --git a/docs/references/databases/create-transaction.md b/docs/references/databases/create-transaction.md new file mode 100644 index 0000000000..fdf369a789 --- /dev/null +++ b/docs/references/databases/create-transaction.md @@ -0,0 +1 @@ +Create a new transaction. \ No newline at end of file diff --git a/docs/references/databases/delete-transaction.md b/docs/references/databases/delete-transaction.md new file mode 100644 index 0000000000..f1395c228f --- /dev/null +++ b/docs/references/databases/delete-transaction.md @@ -0,0 +1 @@ +Delete a transaction by its unique ID. \ No newline at end of file diff --git a/docs/references/databases/get-index.md b/docs/references/databases/get-index.md index cdea5b4f27..cdc27fa967 100644 --- a/docs/references/databases/get-index.md +++ b/docs/references/databases/get-index.md @@ -1 +1 @@ -Get index by ID. \ No newline at end of file +Get an index by its unique ID. \ No newline at end of file diff --git a/docs/references/databases/get-transaction.md b/docs/references/databases/get-transaction.md new file mode 100644 index 0000000000..41900f7468 --- /dev/null +++ b/docs/references/databases/get-transaction.md @@ -0,0 +1 @@ +Get a transaction by its unique ID. \ No newline at end of file diff --git a/docs/references/databases/list-transactions.md b/docs/references/databases/list-transactions.md new file mode 100644 index 0000000000..9a63d9f04a --- /dev/null +++ b/docs/references/databases/list-transactions.md @@ -0,0 +1 @@ +List transactions across all databases. \ No newline at end of file diff --git a/docs/references/databases/update-transaction.md b/docs/references/databases/update-transaction.md new file mode 100644 index 0000000000..d9d5f45439 --- /dev/null +++ b/docs/references/databases/update-transaction.md @@ -0,0 +1 @@ +Update a transaction, to either commit or roll back its operations. \ No newline at end of file diff --git a/docs/references/tablesdb/create-operations.md b/docs/references/tablesdb/create-operations.md new file mode 100644 index 0000000000..a737b95a55 --- /dev/null +++ b/docs/references/tablesdb/create-operations.md @@ -0,0 +1 @@ +Create multiple operations in a single transaction. \ No newline at end of file diff --git a/docs/references/tablesdb/create-row.md b/docs/references/tablesdb/create-row.md index 9b25555eeb..2ddae7e5a7 100644 --- a/docs/references/tablesdb/create-row.md +++ b/docs/references/tablesdb/create-row.md @@ -1 +1 @@ -Create a new Row. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreateTable) API or directly from your database console. \ No newline at end of file +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. \ No newline at end of file diff --git a/docs/references/tablesdb/create-rows.md b/docs/references/tablesdb/create-rows.md index 6a19d7bc9f..b8b5e93582 100644 --- a/docs/references/tablesdb/create-rows.md +++ b/docs/references/tablesdb/create-rows.md @@ -1 +1 @@ -Create new Rows. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreateTable) API or directly from your database console. \ No newline at end of file +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. \ No newline at end of file diff --git a/docs/references/tablesdb/create-table.md b/docs/references/tablesdb/create-table.md index 006e8794df..c240440bf2 100644 --- a/docs/references/tablesdb/create-table.md +++ b/docs/references/tablesdb/create-table.md @@ -1 +1 @@ -Create a new Table. Before using this route, you should create a new database resource using either a [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreateTable) API or directly from your database console. \ No newline at end of file +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. \ No newline at end of file diff --git a/docs/references/tablesdb/create-transaction.md b/docs/references/tablesdb/create-transaction.md new file mode 100644 index 0000000000..fdf369a789 --- /dev/null +++ b/docs/references/tablesdb/create-transaction.md @@ -0,0 +1 @@ +Create a new transaction. \ No newline at end of file diff --git a/docs/references/tablesdb/delete-transaction.md b/docs/references/tablesdb/delete-transaction.md new file mode 100644 index 0000000000..f1395c228f --- /dev/null +++ b/docs/references/tablesdb/delete-transaction.md @@ -0,0 +1 @@ +Delete a transaction by its unique ID. \ No newline at end of file diff --git a/docs/references/tablesdb/get-transaction.md b/docs/references/tablesdb/get-transaction.md new file mode 100644 index 0000000000..41900f7468 --- /dev/null +++ b/docs/references/tablesdb/get-transaction.md @@ -0,0 +1 @@ +Get a transaction by its unique ID. \ No newline at end of file diff --git a/docs/references/tablesdb/list-transactions.md b/docs/references/tablesdb/list-transactions.md new file mode 100644 index 0000000000..9a63d9f04a --- /dev/null +++ b/docs/references/tablesdb/list-transactions.md @@ -0,0 +1 @@ +List transactions across all databases. \ No newline at end of file diff --git a/docs/references/tablesdb/update-transaction.md b/docs/references/tablesdb/update-transaction.md new file mode 100644 index 0000000000..d9d5f45439 --- /dev/null +++ b/docs/references/tablesdb/update-transaction.md @@ -0,0 +1 @@ +Update a transaction, to either commit or roll back its operations. \ No newline at end of file diff --git a/docs/references/tablesdb/upsert-row.md b/docs/references/tablesdb/upsert-row.md index 26edd7ad04..2ae62fedc9 100644 --- a/docs/references/tablesdb/upsert-row.md +++ b/docs/references/tablesdb/upsert-row.md @@ -1 +1 @@ -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/server/tablesdb#tablesDBCreateTable) API or directly from your database console. \ No newline at end of file +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. \ No newline at end of file diff --git a/docs/references/tablesdb/upsert-rows.md b/docs/references/tablesdb/upsert-rows.md index f980d8c30d..52f9d29398 100644 --- a/docs/references/tablesdb/upsert-rows.md +++ b/docs/references/tablesdb/upsert-rows.md @@ -1 +1 @@ -Create or update Rows. Before using this route, you should create a new table resource using either a [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreateTable) API or directly from your database console. +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. diff --git a/docs/sdks/android/CHANGELOG.md b/docs/sdks/android/CHANGELOG.md index 38d0c4be2d..a05da45c4e 100644 --- a/docs/sdks/android/CHANGELOG.md +++ b/docs/sdks/android/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 11.2.1 + +* Add transaction support for Databases and TablesDB + +## 11.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 8.2.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/apple/CHANGELOG.md b/docs/sdks/apple/CHANGELOG.md index f62eb708f1..9ffa37cdf8 100644 --- a/docs/sdks/apple/CHANGELOG.md +++ b/docs/sdks/apple/CHANGELOG.md @@ -1,5 +1,22 @@ # Change Log +## 13.3.0 + +* Add `onOpen`, `onClose` and `onError` callbacks to `Realtime` service + +## 13.2.2 + +* Fix issue: Missing AppwriteEnums dependency causing build failure + +## 13.2.1 + +* Add transaction support for Databases and TablesDB + +## 13.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 10.2.0 * Update sdk to use swift-native doc comments instead of jsdoc styled comments as per [Swift Documentation Comments](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) diff --git a/docs/sdks/cli/CHANGELOG.md b/docs/sdks/cli/CHANGELOG.md index 000a7e0938..ad355682a0 100644 --- a/docs/sdks/cli/CHANGELOG.md +++ b/docs/sdks/cli/CHANGELOG.md @@ -1,5 +1,27 @@ # Change Log +## 10.2.2 + +* Fix `logout` command showing duplicate sessions +* Fix `logout` command showing a blank email even when logged out +* Add syncing of `tablesDB` resource during `push tables` command + +## 10.2.1 + +* Add transaction support for Databases and TablesDB + +## 10.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + +## 10.0.1 + +* Fix CLI Dart model generation issues +* Fix row permissions and security sync +* Fix error when pushing columns with relationships +* Fix resource name from attributes to columns for TablesDB indexes + ## 10.0.0 * **Breaking:** Removed Avatars CLI command and all related subcommands; corresponding examples deleted diff --git a/docs/sdks/dart/CHANGELOG.md b/docs/sdks/dart/CHANGELOG.md index 7033bbdd1d..c5ea578d20 100644 --- a/docs/sdks/dart/CHANGELOG.md +++ b/docs/sdks/dart/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## 19.2.1 + +* Add transaction support for Databases and TablesDB + +## 19.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + +## 18.1.0 + +* Add `orderRandom` query support + ## 18.0.0 * Rename `CreditCard` enum value `unionChinaPay` to `unionPay` diff --git a/docs/sdks/dotnet/CHANGELOG.md b/docs/sdks/dotnet/CHANGELOG.md index bbfee108a7..dfd28ad686 100644 --- a/docs/sdks/dotnet/CHANGELOG.md +++ b/docs/sdks/dotnet/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## 0.21.2 + +* Fix: handle Object[] during array deserialization + +## 0.21.1 + +* Add transaction support for Databases and TablesDB + +## 0.20.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 0.15.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/flutter/CHANGELOG.md b/docs/sdks/flutter/CHANGELOG.md index 7ff4a445b3..7ac74d0c05 100644 --- a/docs/sdks/flutter/CHANGELOG.md +++ b/docs/sdks/flutter/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## 20.2.1 + +* Add transaction support for Databases and TablesDB + +## 20.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + +## 19.1.0 + +* Add `orderRandom` query support + ## 19.0.0 * Rename `CreditCard` enum value `unionChinaPay` to `unionPay` diff --git a/docs/sdks/go/CHANGELOG.md b/docs/sdks/go/CHANGELOG.md index 418c7db5e5..243fdc14a1 100644 --- a/docs/sdks/go/CHANGELOG.md +++ b/docs/sdks/go/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log +## v0.13.1 + +* Add transaction support for Databases and TablesDB + +## v0.12.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service +* Add `orderRandom` query support + ## 0.9.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/kotlin/CHANGELOG.md b/docs/sdks/kotlin/CHANGELOG.md index c7194d5391..fe8c8bf46a 100644 --- a/docs/sdks/kotlin/CHANGELOG.md +++ b/docs/sdks/kotlin/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 12.2.1 + +* Add transaction support for Databases and TablesDB + +## 12.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 9.1.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/nodejs/CHANGELOG.md b/docs/sdks/nodejs/CHANGELOG.md index 7d6926dd1d..bd21b954f7 100644 --- a/docs/sdks/nodejs/CHANGELOG.md +++ b/docs/sdks/nodejs/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 20.2.1 + +* Add transaction support for Databases and TablesDB + +## 20.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 17.2.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/php/CHANGELOG.md b/docs/sdks/php/CHANGELOG.md index d5a323c4cb..3e5e810e84 100644 --- a/docs/sdks/php/CHANGELOG.md +++ b/docs/sdks/php/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 17.4.1 + +* Add transaction support for Databases and TablesDB + +## 17.3.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 15.1.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/python/CHANGELOG.md b/docs/sdks/python/CHANGELOG.md index ff63134a20..7d8327b919 100644 --- a/docs/sdks/python/CHANGELOG.md +++ b/docs/sdks/python/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 13.4.1 + +* Add transaction support for Databases and TablesDB + +## 13.3.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 11.1.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/react-native/CHANGELOG.md b/docs/sdks/react-native/CHANGELOG.md index eda0bca26e..f1f15907bc 100644 --- a/docs/sdks/react-native/CHANGELOG.md +++ b/docs/sdks/react-native/CHANGELOG.md @@ -1,5 +1,14 @@ # Change log +## 0.17.1 + +* Add transaction support for Databases and TablesDB + +## 0.16.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 0.11.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/ruby/CHANGELOG.md b/docs/sdks/ruby/CHANGELOG.md index 1f2e10beea..22f70c4c3a 100644 --- a/docs/sdks/ruby/CHANGELOG.md +++ b/docs/sdks/ruby/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 19.2.1 + +* Add transaction support for Databases and TablesDB + +## 19.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 16.1.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/docs/sdks/swift/CHANGELOG.md b/docs/sdks/swift/CHANGELOG.md index 6cb1cca595..ed5f82c6ea 100644 --- a/docs/sdks/swift/CHANGELOG.md +++ b/docs/sdks/swift/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## 13.2.2 + +* Fix issue: Missing AppwriteEnums dependency causing build failure + +## 13.2.1 + +* Add transaction support for Databases and TablesDB + +## 13.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 10.2.0 * Update sdk to use swift-native doc comments instead of jsdoc styled comments as per [Swift Documentation Comments](https://github.com/swiftlang/swift/blob/main/docs/DocumentationComments.md) diff --git a/docs/sdks/web/CHANGELOG.md b/docs/sdks/web/CHANGELOG.md index 328ef1d5a8..338ec9095c 100644 --- a/docs/sdks/web/CHANGELOG.md +++ b/docs/sdks/web/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 21.2.1 + +* Add transaction support for Databases and TablesDB + +## 21.1.0 + +* Deprecate `createVerification` method in `Account` service +* Add `createEmailVerification` method in `Account` service + ## 18.2.0 * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service diff --git a/src/Appwrite/Auth/OAuth2/Oidc.php b/src/Appwrite/Auth/OAuth2/Oidc.php index 670169fe89..c9810c48eb 100644 --- a/src/Appwrite/Auth/OAuth2/Oidc.php +++ b/src/Appwrite/Auth/OAuth2/Oidc.php @@ -273,6 +273,9 @@ class Oidc extends OAuth2 { if (empty($this->wellKnownConfiguration)) { $response = $this->request('GET', $this->getWellKnownEndpoint()); + if (empty($response)) { + throw new Exception('Invalid well-known configuration'); + } $this->wellKnownConfiguration = \json_decode($response, true); } diff --git a/src/Appwrite/Databases/TransactionState.php b/src/Appwrite/Databases/TransactionState.php new file mode 100644 index 0000000000..23dc6fc2e9 --- /dev/null +++ b/src/Appwrite/Databases/TransactionState.php @@ -0,0 +1,745 @@ +dbForProject = $dbForProject; + } + + + /** + * Get a document with transaction-aware logic + * + * @param string $collectionId Collection ID + * @param string $documentId Document ID + * @param string|null $transactionId Optional transaction ID + * @param array $queries Optional query filters + * @return Document + * @throws Exception + * @throws Exception\Query + * @throws Timeout + */ + public function getDocument( + string $collectionId, + string $documentId, + ?string $transactionId = null, + array $queries = [] + ): Document { + if ($transactionId === null) { + return $this->dbForProject->getDocument($collectionId, $documentId, $queries); + } + + $state = $this->getTransactionState($transactionId); + + if (isset($state[$collectionId][$documentId])) { + $docState = $state[$collectionId][$documentId]; + + if (!$docState['exists']) { + return new Document(); + } + + if ($docState['action'] === 'create') { + return $this->applyProjection($docState['document'], $queries); + } + + if ($docState['action'] === 'update' || $docState['action'] === 'upsert') { + // Merge with committed version + $committedDoc = $this->dbForProject->getDocument($collectionId, $documentId, $queries); + if (!$committedDoc->isEmpty()) { + foreach ($docState['document']->getAttributes() as $key => $value) { + if ($key !== '$id') { + $committedDoc->setAttribute($key, $value); + } + } + // Reapply projection in case transaction added new fields + return $this->applyProjection($committedDoc, $queries); + } elseif ($docState['action'] === 'upsert') { + return $this->applyProjection($docState['document'], $queries); + } + } + } + + return $this->dbForProject->getDocument($collectionId, $documentId, $queries); + } + + /** + * List documents with transaction-aware logic + * + * @param string $collectionId Collection ID + * @param string|null $transactionId Optional transaction ID + * @param array $queries Optional query filters + * @return array Array of Document objects + * @throws Exception + * @throws Exception\Query + * @throws Timeout + */ + public function listDocuments( + string $collectionId, + ?string $transactionId = null, + array $queries = [] + ): array { + // If no transaction, use normal database retrieval + if ($transactionId === null) { + return $this->dbForProject->find($collectionId, $queries); + } + + $state = $this->getTransactionState($transactionId); + $committedDocs = $this->dbForProject->find($collectionId, $queries); + $documentMap = []; + + // Build map of committed documents + foreach ($committedDocs as $doc) { + $documentMap[$doc->getId()] = $doc; + } + + // Apply transaction state changes + if (isset($state[$collectionId])) { + foreach ($state[$collectionId] as $docId => $docState) { + if (!$docState['exists']) { + // Document was deleted, remove from results + unset($documentMap[$docId]); + } elseif ($docState['action'] === 'create') { + // Document was created, add to results with projection + $documentMap[$docId] = $this->applyProjection($docState['document'], $queries); + } elseif ($docState['action'] === 'update' || $docState['action'] === 'upsert') { + if (isset($documentMap[$docId])) { + // Update existing document + foreach ($docState['document']->getAttributes() as $key => $value) { + if ($key !== '$id') { + $documentMap[$docId]->setAttribute($key, $value); + } + } + // Reapply projection in case transaction added new fields + $documentMap[$docId] = $this->applyProjection($documentMap[$docId], $queries); + } elseif ($docState['action'] === 'upsert') { + // Upsert created a new document, apply projection + $documentMap[$docId] = $this->applyProjection($docState['document'], $queries); + } + } + } + } + + return array_values($documentMap); + } + + /** + * Count documents with transaction-aware logic + * + * @param string $collectionId Collection ID + * @param string|null $transactionId Optional transaction ID + * @param array $queries Optional query filters + * @return int Document count + * @throws Exception + * @throws Exception\Query + * @throws Timeout + */ + public function countDocuments( + string $collectionId, + ?string $transactionId = null, + array $queries = [] + ): int { + if ($transactionId === null) { + return $this->dbForProject->count($collectionId, $queries, APP_LIMIT_COUNT); + } + + $state = $this->getTransactionState($transactionId); + + $baseCount = $this->dbForProject->count($collectionId, $queries, APP_LIMIT_COUNT); + + if (!isset($state[$collectionId])) { + return $baseCount; + } + + $committedDocs = $this->dbForProject->find($collectionId, $queries); + $committedDocIds = []; + foreach ($committedDocs as $doc) { + $committedDocIds[$doc->getId()] = true; + } + + $adjustedCount = $baseCount; + + $filters = $this->extractFilters($queries); + + foreach ($state[$collectionId] as $docId => $docState) { + if (!$docState['exists']) { + if (isset($committedDocIds[$docId])) { + $adjustedCount--; + } + } elseif ($docState['action'] === 'create') { + if ($this->documentMatchesFilters($docState['document'], $filters)) { + $adjustedCount++; + } + } elseif ($docState['action'] === 'update' || $docState['action'] === 'upsert') { + $wasInResults = isset($committedDocIds[$docId]); + $nowMatches = $this->documentMatchesFilters($docState['document'], $filters); + + if (!$wasInResults && $nowMatches && $docState['action'] === 'upsert') { + $adjustedCount++; + } elseif ($wasInResults && !$nowMatches) { + $adjustedCount--; + } elseif (!$wasInResults && $nowMatches) { + // Update shouldn't add a new doc, but upsert might have + if ($docState['action'] === 'upsert') { + $adjustedCount++; + } + } + } + } + + return max(0, $adjustedCount); + } + + /** + * Check if a document exists with transaction-aware logic + * + * @param string $collectionId Collection ID + * @param string $documentId Document ID + * @param string|null $transactionId Optional transaction ID + * @return bool True if document exists + */ + public function documentExists( + string $collectionId, + string $documentId, + ?string $transactionId = null + ): bool { + $doc = $this->getDocument($collectionId, $documentId, $transactionId); + return !$doc->isEmpty(); + } + + /** + * Apply bulk update to documents in transaction state that match queries + * + * This allows bulk operations within a transaction to see each other's changes. + * + * @param string $collectionId Collection ID + * @param Document $updateData Document with update values + * @param array $queries Query filters to match documents + * @param array &$state Transaction state (passed by reference) + * @return void + */ + public function applyBulkUpdateToState( + string $collectionId, + Document $updateData, + array $queries, + array &$state + ): void { + if (!isset($state[$collectionId])) { + return; + } + + $filters = $this->extractFilters($queries); + + foreach ($state[$collectionId] as $docId => $doc) { + if ($this->documentMatchesFilters($doc, $filters)) { + foreach ($updateData->getArrayCopy() as $key => $value) { + if ($key !== '$id') { + $doc->setAttribute($key, $value); + } + } + } + } + } + + /** + * Apply bulk delete to documents in transaction state that match queries + * + * This allows bulk operations within a transaction to see each other's changes. + * + * @param string $collectionId Collection ID + * @param array $queries Query filters to match documents + * @param array &$state Transaction state (passed by reference) + * @return void + */ + public function applyBulkDeleteToState( + string $collectionId, + array $queries, + array &$state + ): void { + if (!isset($state[$collectionId])) { + return; + } + + $filters = $this->extractFilters($queries); + + foreach ($state[$collectionId] as $docId => $doc) { + if ($this->documentMatchesFilters($doc, $filters)) { + unset($state[$collectionId][$docId]); + } + } + } + + /** + * Apply bulk upsert to documents in transaction state + * + * This merges partial upsert data with full documents from transaction state, + * preventing validation errors when upserting documents created in the same transaction. + * + * @param string $collectionId Collection ID + * @param array $documents Array of Document objects to upsert (can be partial) + * @param array &$state Transaction state (passed by reference) + * @return array Merged documents ready for database upsert + */ + public function applyBulkUpsertToState( + string $collectionId, + array $documents, + array &$state + ): array { + $mergedDocuments = []; + + foreach ($documents as $doc) { + if (!($doc instanceof Document)) { + continue; + } + + $docId = $doc->getId(); + if (!$docId) { + continue; + } + + if (isset($state[$collectionId][$docId])) { + foreach ($doc->getArrayCopy() as $key => $value) { + if ($key !== '$id') { + $state[$collectionId][$docId]->setAttribute($key, $value); + } + } + $mergedDocuments[] = $state[$collectionId][$docId]; + } else { + $mergedDocuments[] = $doc; + } + } + + return $mergedDocuments; + } + + /** + * Get the current state of a transaction by replaying its operations + * + * @param string $transactionId Transaction ID + * @return array State array with structure: [collectionId => [docId => ['action' => ..., 'document' => ..., 'exists' => ...]]] + * @throws Exception + * @throws Exception\Query + * @throws Timeout + */ + private function getTransactionState(string $transactionId): array + { + $transaction = Authorization::skip(fn () => $this->dbForProject->getDocument('transactions', $transactionId)); + if ($transaction->isEmpty() || $transaction->getAttribute('status') !== 'pending') { + return []; + } + + $operations = Authorization::skip(fn () => $this->dbForProject->find('transactionLogs', [ + Query::equal('transactionInternalId', [$transaction->getSequence()]), + Query::orderAsc(), + Query::limit(PHP_INT_MAX) + ])); + + $state = []; + + foreach ($operations as $operation) { + $databaseInternalId = $operation['databaseInternalId']; + $collectionInternalId = $operation['collectionInternalId']; + $collectionId = "database_{$databaseInternalId}_collection_{$collectionInternalId}"; + $documentId = $operation['documentId']; + $action = $operation['action']; + $data = $operation['data']; + + if ($data instanceof Document) { + $data = $data->getArrayCopy(); + } + + switch ($action) { + case 'create': + $docId = $documentId ?? ($data['$id'] ?? null); + if ($docId) { + if (!isset($data['$id'])) { + $data['$id'] = $docId; + } + $state[$collectionId][$docId] = [ + 'action' => 'create', + 'document' => new Document($data), + 'exists' => true + ]; + } + break; + + case 'update': + if (isset($state[$collectionId][$documentId])) { + $existingDocument = $state[$collectionId][$documentId]['document']; + foreach ($data as $key => $value) { + if ($key !== '$id') { + $existingDocument->setAttribute($key, $value); + } + } + // Only set action to 'update' if it's not already 'create' or 'upsert' + $currentAction = $state[$collectionId][$documentId]['action']; + if ($currentAction !== 'create' && $currentAction !== 'upsert') { + $state[$collectionId][$documentId]['action'] = 'update'; + } + } else { + $state[$collectionId][$documentId] = [ + 'action' => 'update', + 'document' => new Document($data), + 'exists' => true + ]; + } + break; + + case 'upsert': + $docId = $documentId ?? ($data['$id'] ?? null); + if (!$docId) { + break; + } + $state[$collectionId][$docId] = [ + 'action' => 'upsert', + 'document' => new Document($data), + 'exists' => true + ]; + break; + + case 'delete': + $state[$collectionId][$documentId] = [ + 'action' => 'delete', + 'exists' => false + ]; + break; + + case 'increment': + case 'decrement': + $attribute = $data['attribute'] ?? null; + $value = $data['value'] ?? 1; + + if ($attribute) { + if (isset($state[$collectionId][$documentId])) { + $existingDocument = $state[$collectionId][$documentId]['document']; + $currentValue = $existingDocument->getAttribute($attribute, 0); + $newValue = $action === 'increment' ? $currentValue + $value : $currentValue - $value; + $existingDocument->setAttribute($attribute, $newValue); + + $currentAction = $state[$collectionId][$documentId]['action']; + if ($currentAction !== 'create' && $currentAction !== 'upsert') { + $state[$collectionId][$documentId]['action'] = 'update'; + } + } else { + $newValue = $action === 'increment' ? $value : -$value; + $state[$collectionId][$documentId] = [ + 'action' => 'update', + 'document' => new Document([$attribute => $newValue]), + 'exists' => true + ]; + } + } + break; + + case 'bulkCreate': + if (\is_array($data)) { + foreach ($data as $doc) { + if ($doc instanceof Document) { + $doc = $doc->getArrayCopy(); + } + $state[$collectionId][$doc['$id']] = [ + 'action' => 'create', + 'document' => new Document($doc), + 'exists' => true + ]; + } + } + break; + + case 'bulkUpdate': + if (isset($data['queries']) && isset($data['data'])) { + $queries = Query::parseQueries($data['queries'] ?? []); + $updateData = $data['data']; + + foreach ($state[$collectionId] ?? [] as $docId => $entry) { + if (!$entry['exists']) { + continue; + } + + $document = $entry['document']; + $filters = $this->extractFilters($queries); + + if ($this->documentMatchesFilters($document, $filters)) { + foreach ($updateData as $key => $value) { + if ($key !== '$id') { + $document->setAttribute($key, $value); + } + } + + $currentAction = $state[$collectionId][$docId]['action']; + if ($currentAction !== 'create' && $currentAction !== 'upsert') { + $state[$collectionId][$docId]['action'] = 'update'; + } + } + } + } + break; + + case 'bulkUpsert': + if (\is_array($data)) { + foreach ($data as $doc) { + if ($doc instanceof Document) { + $doc = $doc->getArrayCopy(); + } + + $docId = $doc['$id'] ?? null; + if (!$docId) { + continue; + } + + if (isset($state[$collectionId][$docId])) { + $existingDocument = $state[$collectionId][$docId]['document']; + foreach ($doc as $key => $value) { + $existingDocument->setAttribute($key, $value); + } + } else { + $state[$collectionId][$docId] = [ + 'action' => 'upsert', + 'document' => new Document($doc), + 'exists' => true + ]; + } + } + } + break; + + case 'bulkDelete': + if (isset($data['queries'])) { + $queries = Query::parseQueries($data['queries'] ?? []); + $filters = $this->extractFilters($queries); + + foreach ($state[$collectionId] ?? [] as $docId => $entry) { + if (!$entry['exists']) { + continue; + } + + $document = $entry['document']; + if ($this->documentMatchesFilters($document, $filters)) { + $state[$collectionId][$docId] = [ + 'action' => 'delete', + 'exists' => false + ]; + } + } + } + break; + } + } + + return $state; + } + + /** + * Apply projection (select) semantics from queries to a document + * + * @param Document $doc Document to apply projection to + * @param array $queries Query array that may contain select queries + * @return Document Projected document + */ + private function applyProjection(Document $doc, array $queries): Document + { + if (empty($queries)) { + return $doc; + } + + $selections = []; + foreach ($queries as $query) { + if ($query->getMethod() === Query::TYPE_SELECT) { + $values = $query->getValues(); + foreach ($values as $value) { + // Skip relationship selections (containing '.') + if (!\str_contains($value, '.')) { + $selections[] = $value; + } + } + } + } + + if (empty($selections) || \in_array('*', $selections)) { + return $doc; + } + + // Create a new document with only selected attributes + $projected = new Document(); + + // Always preserve internal attributes + $projected->setAttribute('$id', $doc->getId()); + $projected->setAttribute('$collection', $doc->getCollection()); + $projected->setAttribute('$createdAt', $doc->getCreatedAt()); + $projected->setAttribute('$updatedAt', $doc->getUpdatedAt()); + if ($doc->offsetExists('$permissions')) { + $projected->setAttribute('$permissions', $doc->getPermissions()); + } + + // Add selected attributes + foreach ($selections as $attribute) { + if ($doc->offsetExists($attribute)) { + $projected->setAttribute($attribute, $doc->getAttribute($attribute)); + } + } + + return $projected; + } + + /** + * Extract only filter queries from a query array + * + * @param array $queries Query array + * @return array Filtered queries + */ + private function extractFilters(array $queries): array + { + $filters = []; + foreach ($queries as $query) { + $method = $query->getMethod(); + if (!\in_array($method, [ + Query::TYPE_LIMIT, + Query::TYPE_OFFSET, + Query::TYPE_CURSOR_AFTER, + Query::TYPE_CURSOR_BEFORE, + Query::TYPE_SELECT, + Query::TYPE_ORDER_ASC, + Query::TYPE_ORDER_DESC + ])) { + $filters[] = $query; + } + } + return $filters; + } + + /** + * Check if a document matches filter queries + * + * @param Document $doc Document to check + * @param array $filters Pre-filtered Query filters (use extractFilters first) + * @return bool True if document matches all filters + */ + private function documentMatchesFilters(Document $doc, array $filters): bool + { + if (empty($filters)) { + return true; + } + + foreach ($filters as $filter) { + $attribute = $filter->getAttribute(); + $values = $filter->getValues(); + $docValue = $doc->getAttribute($attribute); + + switch ($filter->getMethod()) { + case Query::TYPE_EQUAL: + if (!\in_array($docValue, $values)) { + return false; + } + break; + + case Query::TYPE_NOT_EQUAL: + if (\in_array($docValue, $values)) { + return false; + } + break; + + case Query::TYPE_CONTAINS: + $matches = false; + foreach ($values as $value) { + if (\is_array($docValue) && \in_array($value, $docValue)) { + $matches = true; + break; + } + } + if (!$matches) { + return false; + } + break; + + case Query::TYPE_STARTS_WITH: + $matches = false; + foreach ($values as $value) { + if (\is_string($docValue) && \str_starts_with($docValue, $value)) { + $matches = true; + break; + } + } + if (!$matches) { + return false; + } + break; + + case Query::TYPE_ENDS_WITH: + $matches = false; + foreach ($values as $value) { + if (\is_string($docValue) && \str_ends_with($docValue, $value)) { + $matches = true; + break; + } + } + if (!$matches) { + return false; + } + break; + + case Query::TYPE_GREATER: + if (!($docValue > $values[0])) { + return false; + } + break; + + case Query::TYPE_GREATER_EQUAL: + if (!($docValue >= $values[0])) { + return false; + } + break; + + case Query::TYPE_LESSER: + if (!($docValue < $values[0])) { + return false; + } + break; + + case Query::TYPE_LESSER_EQUAL: + if (!($docValue <= $values[0])) { + return false; + } + break; + + case Query::TYPE_IS_NULL: + if (!\is_null($docValue)) { + return false; + } + break; + + case Query::TYPE_IS_NOT_NULL: + if (\is_null($docValue)) { + return false; + } + break; + + case Query::TYPE_BETWEEN: + if (!($docValue >= $values[0] && $docValue <= $values[1])) { + return false; + } + break; + } + } + + return true; + } +} diff --git a/src/Appwrite/Event/Event.php b/src/Appwrite/Event/Event.php index e9f3ccc2a2..16fe76bf8a 100644 --- a/src/Appwrite/Event/Event.php +++ b/src/Appwrite/Event/Event.php @@ -592,6 +592,7 @@ class Event $this->project = $event->getProject(); $this->user = $event->getUser(); $this->payload = $event->getPayload(); + $this->sensitive = $event->sensitive; $this->event = $event->getEvent(); $this->params = $event->getParams(); $this->context = $event->context; diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index 52282ad7af..6f8744568a 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -36,334 +36,346 @@ class Exception extends \Exception */ /** General */ - public const GENERAL_UNKNOWN = 'general_unknown'; - public const GENERAL_MOCK = 'general_mock'; - public const GENERAL_ACCESS_FORBIDDEN = 'general_access_forbidden'; - public const GENERAL_RESOURCE_BLOCKED = 'general_resource_blocked'; - public const GENERAL_UNKNOWN_ORIGIN = 'general_unknown_origin'; - public const GENERAL_API_DISABLED = 'general_api_disabled'; - public const GENERAL_SERVICE_DISABLED = 'general_service_disabled'; - public const GENERAL_UNAUTHORIZED_SCOPE = 'general_unauthorized_scope'; - public const GENERAL_RATE_LIMIT_EXCEEDED = 'general_rate_limit_exceeded'; - public const GENERAL_SMTP_DISABLED = 'general_smtp_disabled'; - public const GENERAL_PHONE_DISABLED = 'general_phone_disabled'; - public const GENERAL_ARGUMENT_INVALID = 'general_argument_invalid'; - public const GENERAL_COLUMN_QUERY_LIMIT_EXCEEDED = 'general_column_query_limit_exceeded'; - public const GENERAL_ATTRIBUTE_QUERY_LIMIT_EXCEEDED = 'general_attribute_query_limit_exceeded'; - public const GENERAL_QUERY_INVALID = 'general_query_invalid'; - public const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found'; - public const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found'; - public const GENERAL_SERVER_ERROR = 'general_server_error'; - public const GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported'; - public const GENERAL_CODES_DISABLED = 'general_codes_disabled'; - public const GENERAL_USAGE_DISABLED = 'general_usage_disabled'; - public const GENERAL_NOT_IMPLEMENTED = 'general_not_implemented'; - public const GENERAL_INVALID_EMAIL = 'general_invalid_email'; - public const GENERAL_INVALID_PHONE = 'general_invalid_phone'; - public const GENERAL_REGION_ACCESS_DENIED = 'general_region_access_denied'; - public const GENERAL_BAD_REQUEST = 'general_bad_request'; + public const string GENERAL_UNKNOWN = 'general_unknown'; + public const string GENERAL_MOCK = 'general_mock'; + public const string GENERAL_ACCESS_FORBIDDEN = 'general_access_forbidden'; + public const string GENERAL_RESOURCE_BLOCKED = 'general_resource_blocked'; + public const string GENERAL_UNKNOWN_ORIGIN = 'general_unknown_origin'; + public const string GENERAL_API_DISABLED = 'general_api_disabled'; + public const string GENERAL_SERVICE_DISABLED = 'general_service_disabled'; + public const string GENERAL_UNAUTHORIZED_SCOPE = 'general_unauthorized_scope'; + public const string GENERAL_RATE_LIMIT_EXCEEDED = 'general_rate_limit_exceeded'; + public const string GENERAL_SMTP_DISABLED = 'general_smtp_disabled'; + public const string GENERAL_PHONE_DISABLED = 'general_phone_disabled'; + public const string GENERAL_ARGUMENT_INVALID = 'general_argument_invalid'; + public const string GENERAL_COLUMN_QUERY_LIMIT_EXCEEDED = 'general_column_query_limit_exceeded'; + public const string GENERAL_ATTRIBUTE_QUERY_LIMIT_EXCEEDED = 'general_attribute_query_limit_exceeded'; + public const string GENERAL_QUERY_INVALID = 'general_query_invalid'; + public const string GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found'; + public const string GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found'; + public const string GENERAL_SERVER_ERROR = 'general_server_error'; + public const string GENERAL_PROTOCOL_UNSUPPORTED = 'general_protocol_unsupported'; + public const string GENERAL_CODES_DISABLED = 'general_codes_disabled'; + public const string GENERAL_USAGE_DISABLED = 'general_usage_disabled'; + public const string GENERAL_NOT_IMPLEMENTED = 'general_not_implemented'; + public const string GENERAL_INVALID_EMAIL = 'general_invalid_email'; + public const string GENERAL_INVALID_PHONE = 'general_invalid_phone'; + public const string GENERAL_REGION_ACCESS_DENIED = 'general_region_access_denied'; + public const string GENERAL_BAD_REQUEST = 'general_bad_request'; /** Users */ - public const USER_COUNT_EXCEEDED = 'user_count_exceeded'; - public const USER_CONSOLE_COUNT_EXCEEDED = 'user_console_count_exceeded'; - public const USER_JWT_INVALID = 'user_jwt_invalid'; - public const USER_ALREADY_EXISTS = 'user_already_exists'; - public const USER_BLOCKED = 'user_blocked'; - public const USER_INVALID_TOKEN = 'user_invalid_token'; - public const USER_PASSWORD_RESET_REQUIRED = 'user_password_reset_required'; - public const USER_EMAIL_NOT_WHITELISTED = 'user_email_not_whitelisted'; - public const USER_IP_NOT_WHITELISTED = 'user_ip_not_whitelisted'; - public const USER_INVALID_CODE = 'user_invalid_code'; - public const USER_INVALID_CREDENTIALS = 'user_invalid_credentials'; - public const USER_ANONYMOUS_CONSOLE_PROHIBITED = 'user_anonymous_console_prohibited'; - public const USER_SESSION_ALREADY_EXISTS = 'user_session_already_exists'; - public const USER_NOT_FOUND = 'user_not_found'; - public const USER_PASSWORD_RECENTLY_USED = 'password_recently_used'; - public const USER_PASSWORD_PERSONAL_DATA = 'password_personal_data'; - public const USER_EMAIL_ALREADY_EXISTS = 'user_email_already_exists'; - public const USER_PASSWORD_MISMATCH = 'user_password_mismatch'; - public const USER_SESSION_NOT_FOUND = 'user_session_not_found'; - public const USER_IDENTITY_NOT_FOUND = 'user_identity_not_found'; - public const USER_UNAUTHORIZED = 'user_unauthorized'; - public const USER_AUTH_METHOD_UNSUPPORTED = 'user_auth_method_unsupported'; - public const USER_PHONE_ALREADY_EXISTS = 'user_phone_already_exists'; - public const USER_PHONE_NOT_FOUND = 'user_phone_not_found'; - public const USER_PHONE_NOT_VERIFIED = 'user_phone_not_verified'; - public const USER_EMAIL_NOT_FOUND = 'user_email_not_found'; - public const USER_EMAIL_NOT_VERIFIED = 'user_email_not_verified'; - public const USER_MISSING_ID = 'user_missing_id'; - public const USER_MORE_FACTORS_REQUIRED = 'user_more_factors_required'; - public const USER_INVALID_CHALLENGE = 'user_invalid_challenge'; - public const USER_AUTHENTICATOR_NOT_FOUND = 'user_authenticator_not_found'; - public const USER_AUTHENTICATOR_ALREADY_VERIFIED = 'user_authenticator_already_verified'; - public const USER_RECOVERY_CODES_ALREADY_EXISTS = 'user_recovery_codes_already_exists'; - public const USER_RECOVERY_CODES_NOT_FOUND = 'user_recovery_codes_not_found'; - public const USER_CHALLENGE_REQUIRED = 'user_challenge_required'; - public const USER_OAUTH2_BAD_REQUEST = 'user_oauth2_bad_request'; - public const USER_OAUTH2_UNAUTHORIZED = 'user_oauth2_unauthorized'; - public const USER_OAUTH2_PROVIDER_ERROR = 'user_oauth2_provider_error'; - public const USER_EMAIL_ALREADY_VERIFIED = 'user_email_already_verified'; - public const USER_PHONE_ALREADY_VERIFIED = 'user_phone_already_verified'; - public const USER_DELETION_PROHIBITED = 'user_deletion_prohibited'; - public const USER_TARGET_NOT_FOUND = 'user_target_not_found'; - public const USER_TARGET_ALREADY_EXISTS = 'user_target_already_exists'; - public const USER_API_KEY_AND_SESSION_SET = 'user_key_and_session_set'; + public const string USER_COUNT_EXCEEDED = 'user_count_exceeded'; + public const string USER_CONSOLE_COUNT_EXCEEDED = 'user_console_count_exceeded'; + public const string USER_JWT_INVALID = 'user_jwt_invalid'; + public const string USER_ALREADY_EXISTS = 'user_already_exists'; + public const string USER_BLOCKED = 'user_blocked'; + public const string USER_INVALID_TOKEN = 'user_invalid_token'; + public const string USER_PASSWORD_RESET_REQUIRED = 'user_password_reset_required'; + public const string USER_EMAIL_NOT_WHITELISTED = 'user_email_not_whitelisted'; + public const string USER_IP_NOT_WHITELISTED = 'user_ip_not_whitelisted'; + public const string USER_INVALID_CODE = 'user_invalid_code'; + public const string USER_INVALID_CREDENTIALS = 'user_invalid_credentials'; + public const string USER_ANONYMOUS_CONSOLE_PROHIBITED = 'user_anonymous_console_prohibited'; + public const string USER_SESSION_ALREADY_EXISTS = 'user_session_already_exists'; + public const string USER_NOT_FOUND = 'user_not_found'; + public const string USER_PASSWORD_RECENTLY_USED = 'password_recently_used'; + public const string USER_PASSWORD_PERSONAL_DATA = 'password_personal_data'; + public const string USER_EMAIL_ALREADY_EXISTS = 'user_email_already_exists'; + public const string USER_PASSWORD_MISMATCH = 'user_password_mismatch'; + public const string USER_SESSION_NOT_FOUND = 'user_session_not_found'; + public const string USER_IDENTITY_NOT_FOUND = 'user_identity_not_found'; + public const string USER_UNAUTHORIZED = 'user_unauthorized'; + public const string USER_AUTH_METHOD_UNSUPPORTED = 'user_auth_method_unsupported'; + public const string USER_PHONE_ALREADY_EXISTS = 'user_phone_already_exists'; + public const string USER_PHONE_NOT_FOUND = 'user_phone_not_found'; + public const string USER_PHONE_NOT_VERIFIED = 'user_phone_not_verified'; + public const string USER_EMAIL_NOT_FOUND = 'user_email_not_found'; + public const string USER_EMAIL_NOT_VERIFIED = 'user_email_not_verified'; + public const string USER_MISSING_ID = 'user_missing_id'; + public const string USER_MORE_FACTORS_REQUIRED = 'user_more_factors_required'; + public const string USER_INVALID_CHALLENGE = 'user_invalid_challenge'; + public const string USER_AUTHENTICATOR_NOT_FOUND = 'user_authenticator_not_found'; + public const string USER_AUTHENTICATOR_ALREADY_VERIFIED = 'user_authenticator_already_verified'; + public const string USER_RECOVERY_CODES_ALREADY_EXISTS = 'user_recovery_codes_already_exists'; + public const string USER_RECOVERY_CODES_NOT_FOUND = 'user_recovery_codes_not_found'; + public const string USER_CHALLENGE_REQUIRED = 'user_challenge_required'; + public const string USER_OAUTH2_BAD_REQUEST = 'user_oauth2_bad_request'; + public const string USER_OAUTH2_UNAUTHORIZED = 'user_oauth2_unauthorized'; + public const string USER_OAUTH2_PROVIDER_ERROR = 'user_oauth2_provider_error'; + public const string USER_EMAIL_ALREADY_VERIFIED = 'user_email_already_verified'; + public const string USER_PHONE_ALREADY_VERIFIED = 'user_phone_already_verified'; + public const string USER_DELETION_PROHIBITED = 'user_deletion_prohibited'; + public const string USER_TARGET_NOT_FOUND = 'user_target_not_found'; + public const string USER_TARGET_ALREADY_EXISTS = 'user_target_already_exists'; + public const string USER_API_KEY_AND_SESSION_SET = 'user_key_and_session_set'; - public const API_KEY_EXPIRED = 'api_key_expired'; + public const string API_KEY_EXPIRED = 'api_key_expired'; /** Teams */ - public const TEAM_NOT_FOUND = 'team_not_found'; - public const TEAM_INVITE_NOT_FOUND = 'team_invite_not_found'; - public const TEAM_INVALID_SECRET = 'team_invalid_secret'; - public const TEAM_MEMBERSHIP_MISMATCH = 'team_membership_mismatch'; - public const TEAM_INVITE_MISMATCH = 'team_invite_mismatch'; - public const TEAM_ALREADY_EXISTS = 'team_already_exists'; + public const string TEAM_NOT_FOUND = 'team_not_found'; + public const string TEAM_INVITE_NOT_FOUND = 'team_invite_not_found'; + public const string TEAM_INVALID_SECRET = 'team_invalid_secret'; + public const string TEAM_MEMBERSHIP_MISMATCH = 'team_membership_mismatch'; + public const string TEAM_INVITE_MISMATCH = 'team_invite_mismatch'; + public const string TEAM_ALREADY_EXISTS = 'team_already_exists'; /** Console */ - public const RESOURCE_ALREADY_EXISTS = 'resource_already_exists'; + public const string RESOURCE_ALREADY_EXISTS = 'resource_already_exists'; /** Membership */ - public const MEMBERSHIP_NOT_FOUND = 'membership_not_found'; - public const MEMBERSHIP_ALREADY_CONFIRMED = 'membership_already_confirmed'; - public const MEMBERSHIP_DELETION_PROHIBITED = 'membership_deletion_prohibited'; - public const MEMBERSHIP_DOWNGRADE_PROHIBITED = 'membership_downgrade_prohibited'; + public const string MEMBERSHIP_NOT_FOUND = 'membership_not_found'; + public const string MEMBERSHIP_ALREADY_CONFIRMED = 'membership_already_confirmed'; + public const string MEMBERSHIP_DELETION_PROHIBITED = 'membership_deletion_prohibited'; + public const string MEMBERSHIP_DOWNGRADE_PROHIBITED = 'membership_downgrade_prohibited'; /** Avatars */ - public const AVATAR_SET_NOT_FOUND = 'avatar_set_not_found'; - public const AVATAR_NOT_FOUND = 'avatar_not_found'; - public const AVATAR_IMAGE_NOT_FOUND = 'avatar_image_not_found'; - public const AVATAR_REMOTE_URL_FAILED = 'avatar_remote_url_failed'; - public const AVATAR_ICON_NOT_FOUND = 'avatar_icon_not_found'; - public const AVATAR_SVG_SANITIZATION_FAILED = 'avatar_svg_sanitization_failed'; + public const string AVATAR_SET_NOT_FOUND = 'avatar_set_not_found'; + public const string AVATAR_NOT_FOUND = 'avatar_not_found'; + public const string AVATAR_IMAGE_NOT_FOUND = 'avatar_image_not_found'; + public const string AVATAR_REMOTE_URL_FAILED = 'avatar_remote_url_failed'; + public const string AVATAR_ICON_NOT_FOUND = 'avatar_icon_not_found'; + public const string AVATAR_SVG_SANITIZATION_FAILED = 'avatar_svg_sanitization_failed'; /** Storage */ - public const STORAGE_FILE_ALREADY_EXISTS = 'storage_file_already_exists'; - public const STORAGE_FILE_NOT_FOUND = 'storage_file_not_found'; - public const STORAGE_DEVICE_NOT_FOUND = 'storage_device_not_found'; - public const STORAGE_FILE_EMPTY = 'storage_file_empty'; - public const STORAGE_FILE_TYPE_UNSUPPORTED = 'storage_file_type_unsupported'; - public const STORAGE_INVALID_FILE_SIZE = 'storage_invalid_file_size'; - public const STORAGE_INVALID_FILE = 'storage_invalid_file'; - public const STORAGE_BUCKET_ALREADY_EXISTS = 'storage_bucket_already_exists'; - public const STORAGE_BUCKET_NOT_FOUND = 'storage_bucket_not_found'; - public const STORAGE_INVALID_CONTENT_RANGE = 'storage_invalid_content_range'; - public const STORAGE_INVALID_RANGE = 'storage_invalid_range'; - public const STORAGE_INVALID_APPWRITE_ID = 'storage_invalid_appwrite_id'; - public const STORAGE_FILE_NOT_PUBLIC = 'storage_file_not_public'; + public const string STORAGE_FILE_ALREADY_EXISTS = 'storage_file_already_exists'; + public const string STORAGE_FILE_NOT_FOUND = 'storage_file_not_found'; + public const string STORAGE_DEVICE_NOT_FOUND = 'storage_device_not_found'; + public const string STORAGE_FILE_EMPTY = 'storage_file_empty'; + public const string STORAGE_FILE_TYPE_UNSUPPORTED = 'storage_file_type_unsupported'; + public const string STORAGE_INVALID_FILE_SIZE = 'storage_invalid_file_size'; + public const string STORAGE_INVALID_FILE = 'storage_invalid_file'; + public const string STORAGE_BUCKET_ALREADY_EXISTS = 'storage_bucket_already_exists'; + public const string STORAGE_BUCKET_NOT_FOUND = 'storage_bucket_not_found'; + public const string STORAGE_INVALID_CONTENT_RANGE = 'storage_invalid_content_range'; + public const string STORAGE_INVALID_RANGE = 'storage_invalid_range'; + public const string STORAGE_INVALID_APPWRITE_ID = 'storage_invalid_appwrite_id'; + public const string STORAGE_FILE_NOT_PUBLIC = 'storage_file_not_public'; /** VCS */ - public const INSTALLATION_NOT_FOUND = 'installation_not_found'; - public const PROVIDER_REPOSITORY_NOT_FOUND = 'provider_repository_not_found'; - public const REPOSITORY_NOT_FOUND = 'repository_not_found'; - public const PROVIDER_CONTRIBUTION_CONFLICT = 'provider_contribution_conflict'; - public const GENERAL_PROVIDER_FAILURE = 'general_provider_failure'; + public const string INSTALLATION_NOT_FOUND = 'installation_not_found'; + public const string PROVIDER_REPOSITORY_NOT_FOUND = 'provider_repository_not_found'; + public const string REPOSITORY_NOT_FOUND = 'repository_not_found'; + public const string PROVIDER_CONTRIBUTION_CONFLICT = 'provider_contribution_conflict'; + public const string GENERAL_PROVIDER_FAILURE = 'general_provider_failure'; /** Sites */ - public const SITE_NOT_FOUND = 'site_not_found'; - public const SITE_TEMPLATE_NOT_FOUND = 'site_template_not_found'; + public const string SITE_NOT_FOUND = 'site_not_found'; + public const string SITE_TEMPLATE_NOT_FOUND = 'site_template_not_found'; /** Functions */ - public const FUNCTION_NOT_FOUND = 'function_not_found'; - public const FUNCTION_RUNTIME_UNSUPPORTED = 'function_runtime_unsupported'; - public const FUNCTION_ENTRYPOINT_MISSING = 'function_entrypoint_missing'; - public const FUNCTION_SYNCHRONOUS_TIMEOUT = 'function_synchronous_timeout'; - public const FUNCTION_TEMPLATE_NOT_FOUND = 'function_template_not_found'; - public const FUNCTION_RUNTIME_NOT_DETECTED = 'function_runtime_not_detected'; - public const FUNCTION_EXECUTE_PERMISSION_MISSING = 'function_execute_permission_missing'; + public const string FUNCTION_NOT_FOUND = 'function_not_found'; + public const string FUNCTION_ALREADY_EXISTS = 'function_already_exists'; + public const string FUNCTION_RUNTIME_UNSUPPORTED = 'function_runtime_unsupported'; + public const string FUNCTION_ENTRYPOINT_MISSING = 'function_entrypoint_missing'; + public const string FUNCTION_SYNCHRONOUS_TIMEOUT = 'function_synchronous_timeout'; + public const string FUNCTION_TEMPLATE_NOT_FOUND = 'function_template_not_found'; + public const string FUNCTION_RUNTIME_NOT_DETECTED = 'function_runtime_not_detected'; + public const string FUNCTION_EXECUTE_PERMISSION_MISSING = 'function_execute_permission_missing'; /** Deployments */ - public const DEPLOYMENT_NOT_FOUND = 'deployment_not_found'; + public const string DEPLOYMENT_NOT_FOUND = 'deployment_not_found'; /** Builds */ - public const BUILD_NOT_FOUND = 'build_not_found'; - public const BUILD_NOT_READY = 'build_not_ready'; - public const BUILD_IN_PROGRESS = 'build_in_progress'; - public const BUILD_ALREADY_COMPLETED = 'build_already_completed'; - public const BUILD_CANCELED = 'build_canceled'; - public const BUILD_FAILED = 'build_failed'; + public const string BUILD_NOT_FOUND = 'build_not_found'; + public const string BUILD_NOT_READY = 'build_not_ready'; + public const string BUILD_IN_PROGRESS = 'build_in_progress'; + public const string BUILD_ALREADY_COMPLETED = 'build_already_completed'; + public const string BUILD_CANCELED = 'build_canceled'; + public const string BUILD_FAILED = 'build_failed'; /** Execution */ - public const EXECUTION_NOT_FOUND = 'execution_not_found'; - public const EXECUTION_IN_PROGRESS = 'execution_in_progress'; + public const string EXECUTION_NOT_FOUND = 'execution_not_found'; + public const string EXECUTION_IN_PROGRESS = 'execution_in_progress'; /** Log */ - public const LOG_NOT_FOUND = 'log_not_found'; + public const string LOG_NOT_FOUND = 'log_not_found'; /** Databases */ - public const DATABASE_NOT_FOUND = 'database_not_found'; - public const DATABASE_ALREADY_EXISTS = 'database_already_exists'; - public const DATABASE_TIMEOUT = 'database_timeout'; - public const DATABASE_QUERY_ORDER_NULL = 'database_query_order_null'; + public const string DATABASE_NOT_FOUND = 'database_not_found'; + public const string DATABASE_ALREADY_EXISTS = 'database_already_exists'; + public const string DATABASE_TIMEOUT = 'database_timeout'; + public const string DATABASE_QUERY_ORDER_NULL = 'database_query_order_null'; /** Collections */ - public const COLLECTION_NOT_FOUND = 'collection_not_found'; - public const COLLECTION_ALREADY_EXISTS = 'collection_already_exists'; - public const COLLECTION_LIMIT_EXCEEDED = 'collection_limit_exceeded'; + public const string COLLECTION_NOT_FOUND = 'collection_not_found'; + public const string COLLECTION_ALREADY_EXISTS = 'collection_already_exists'; + public const string COLLECTION_LIMIT_EXCEEDED = 'collection_limit_exceeded'; /** Tables */ - public const TABLE_NOT_FOUND = 'table_not_found'; - public const TABLE_ALREADY_EXISTS = 'table_already_exists'; - public const TABLE_LIMIT_EXCEEDED = 'table_limit_exceeded'; + public const string TABLE_NOT_FOUND = 'table_not_found'; + public const string TABLE_ALREADY_EXISTS = 'table_already_exists'; + public const string TABLE_LIMIT_EXCEEDED = 'table_limit_exceeded'; /** Documents */ - public const DOCUMENT_NOT_FOUND = 'document_not_found'; - public const DOCUMENT_INVALID_STRUCTURE = 'document_invalid_structure'; - public const DOCUMENT_MISSING_DATA = 'document_missing_data'; - public const DOCUMENT_MISSING_PAYLOAD = 'document_missing_payload'; - public const DOCUMENT_ALREADY_EXISTS = 'document_already_exists'; - public const DOCUMENT_UPDATE_CONFLICT = 'document_update_conflict'; - public const DOCUMENT_DELETE_RESTRICTED = 'document_delete_restricted'; + public const string DOCUMENT_NOT_FOUND = 'document_not_found'; + public const string DOCUMENT_INVALID_STRUCTURE = 'document_invalid_structure'; + public const string DOCUMENT_MISSING_DATA = 'document_missing_data'; + public const string DOCUMENT_MISSING_PAYLOAD = 'document_missing_payload'; + public const string DOCUMENT_ALREADY_EXISTS = 'document_already_exists'; + public const string DOCUMENT_UPDATE_CONFLICT = 'document_update_conflict'; + public const string DOCUMENT_DELETE_RESTRICTED = 'document_delete_restricted'; /** Rows */ - public const ROW_NOT_FOUND = 'row_not_found'; - public const ROW_INVALID_STRUCTURE = 'row_invalid_structure'; - public const ROW_MISSING_DATA = 'row_missing_data'; - public const ROW_MISSING_PAYLOAD = 'row_missing_payload'; - public const ROW_ALREADY_EXISTS = 'row_already_exists'; - public const ROW_UPDATE_CONFLICT = 'row_update_conflict'; - public const ROW_DELETE_RESTRICTED = 'row_delete_restricted'; + public const string ROW_NOT_FOUND = 'row_not_found'; + public const string ROW_INVALID_STRUCTURE = 'row_invalid_structure'; + public const string ROW_MISSING_DATA = 'row_missing_data'; + public const string ROW_MISSING_PAYLOAD = 'row_missing_payload'; + public const string ROW_ALREADY_EXISTS = 'row_already_exists'; + public const string ROW_UPDATE_CONFLICT = 'row_update_conflict'; + public const string ROW_DELETE_RESTRICTED = 'row_delete_restricted'; /** Attributes */ - public const ATTRIBUTE_NOT_FOUND = 'attribute_not_found'; - public const ATTRIBUTE_UNKNOWN = 'attribute_unknown'; - public const ATTRIBUTE_NOT_AVAILABLE = 'attribute_not_available'; - public const ATTRIBUTE_FORMAT_UNSUPPORTED = 'attribute_format_unsupported'; - public const ATTRIBUTE_DEFAULT_UNSUPPORTED = 'attribute_default_unsupported'; - public const ATTRIBUTE_ALREADY_EXISTS = 'attribute_already_exists'; - public const ATTRIBUTE_LIMIT_EXCEEDED = 'attribute_limit_exceeded'; - public const ATTRIBUTE_VALUE_INVALID = 'attribute_value_invalid'; - public const ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid'; - public const ATTRIBUTE_INVALID_RESIZE = 'attribute_invalid_resize'; + public const string ATTRIBUTE_NOT_FOUND = 'attribute_not_found'; + public const string ATTRIBUTE_UNKNOWN = 'attribute_unknown'; + public const string ATTRIBUTE_NOT_AVAILABLE = 'attribute_not_available'; + public const string ATTRIBUTE_FORMAT_UNSUPPORTED = 'attribute_format_unsupported'; + public const string ATTRIBUTE_DEFAULT_UNSUPPORTED = 'attribute_default_unsupported'; + public const string ATTRIBUTE_ALREADY_EXISTS = 'attribute_already_exists'; + public const string ATTRIBUTE_LIMIT_EXCEEDED = 'attribute_limit_exceeded'; + public const string ATTRIBUTE_VALUE_INVALID = 'attribute_value_invalid'; + public const string ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid'; + public const string ATTRIBUTE_INVALID_RESIZE = 'attribute_invalid_resize'; public const ATTRIBUTE_TYPE_NOT_SUPPORTED = 'ATTRIBUTE_TYPE_NOT_SUPPORTED'; /** Columns */ - public const COLUMN_NOT_FOUND = 'column_not_found'; - public const COLUMN_UNKNOWN = 'column_unknown'; - public const COLUMN_NOT_AVAILABLE = 'column_not_available'; - public const COLUMN_FORMAT_UNSUPPORTED = 'column_format_unsupported'; - public const COLUMN_DEFAULT_UNSUPPORTED = 'column_default_unsupported'; - public const COLUMN_ALREADY_EXISTS = 'column_already_exists'; - public const COLUMN_LIMIT_EXCEEDED = 'column_limit_exceeded'; - public const COLUMN_VALUE_INVALID = 'column_value_invalid'; - public const COLUMN_TYPE_INVALID = 'column_type_invalid'; - public const COLUMN_INVALID_RESIZE = 'column_invalid_resize'; + public const string COLUMN_NOT_FOUND = 'column_not_found'; + public const string COLUMN_UNKNOWN = 'column_unknown'; + public const string COLUMN_NOT_AVAILABLE = 'column_not_available'; + public const string COLUMN_FORMAT_UNSUPPORTED = 'column_format_unsupported'; + public const string COLUMN_DEFAULT_UNSUPPORTED = 'column_default_unsupported'; + public const string COLUMN_ALREADY_EXISTS = 'column_already_exists'; + public const string COLUMN_LIMIT_EXCEEDED = 'column_limit_exceeded'; + public const string COLUMN_VALUE_INVALID = 'column_value_invalid'; + public const string COLUMN_TYPE_INVALID = 'column_type_invalid'; + public const string COLUMN_INVALID_RESIZE = 'column_invalid_resize'; public const COLUMN_TYPE_NOT_SUPPORTED = 'COLUMN_TYPE_NOT_SUPPORTED'; /** Relationship */ - public const RELATIONSHIP_VALUE_INVALID = 'relationship_value_invalid'; + public const string RELATIONSHIP_VALUE_INVALID = 'relationship_value_invalid'; /** Indexes */ - public const INDEX_NOT_FOUND = 'index_not_found'; - public const INDEX_LIMIT_EXCEEDED = 'index_limit_exceeded'; - public const INDEX_ALREADY_EXISTS = 'index_already_exists'; - public const INDEX_INVALID = 'index_invalid'; - public const INDEX_DEPENDENCY = 'index_dependency'; + public const string INDEX_NOT_FOUND = 'index_not_found'; + public const string INDEX_LIMIT_EXCEEDED = 'index_limit_exceeded'; + public const string INDEX_ALREADY_EXISTS = 'index_already_exists'; + public const string INDEX_INVALID = 'index_invalid'; + public const string INDEX_DEPENDENCY = 'index_dependency'; /** Column Indexes */ - public const COLUMN_INDEX_NOT_FOUND = 'column_index_not_found'; - public const COLUMN_INDEX_LIMIT_EXCEEDED = 'column_index_limit_exceeded'; - public const COLUMN_INDEX_ALREADY_EXISTS = 'column_index_already_exists'; - public const COLUMN_INDEX_INVALID = 'column_index_invalid'; - public const COLUMN_INDEX_DEPENDENCY = 'column_index_dependency'; + public const string COLUMN_INDEX_NOT_FOUND = 'column_index_not_found'; + public const string COLUMN_INDEX_LIMIT_EXCEEDED = 'column_index_limit_exceeded'; + public const string COLUMN_INDEX_ALREADY_EXISTS = 'column_index_already_exists'; + public const string COLUMN_INDEX_INVALID = 'column_index_invalid'; + public const string COLUMN_INDEX_DEPENDENCY = 'column_index_dependency'; + + /** Transactions */ + public const string TRANSACTION_NOT_FOUND = 'transaction_not_found'; + public const string TRANSACTION_ALREADY_EXISTS = 'transaction_already_exists'; + public const string TRANSACTION_INVALID = 'transaction_invalid'; + public const string TRANSACTION_FAILED = 'transaction_failed'; + public const string TRANSACTION_EXPIRED = 'transaction_expired'; + public const string TRANSACTION_CONFLICT = 'transaction_conflict'; + public const string TRANSACTION_LIMIT_EXCEEDED = 'transaction_limit_exceeded'; + public const string TRANSACTION_NOT_READY = 'transaction_not_ready'; + /** Projects */ - public const PROJECT_NOT_FOUND = 'project_not_found'; - public const PROJECT_PROVIDER_DISABLED = 'project_provider_disabled'; - public const PROJECT_PROVIDER_UNSUPPORTED = 'project_provider_unsupported'; - public const PROJECT_ALREADY_EXISTS = 'project_already_exists'; - public const PROJECT_INVALID_SUCCESS_URL = 'project_invalid_success_url'; - public const PROJECT_INVALID_FAILURE_URL = 'project_invalid_failure_url'; - public const PROJECT_RESERVED_PROJECT = 'project_reserved_project'; - public const PROJECT_KEY_EXPIRED = 'project_key_expired'; + public const string PROJECT_NOT_FOUND = 'project_not_found'; + public const string PROJECT_PROVIDER_DISABLED = 'project_provider_disabled'; + public const string PROJECT_PROVIDER_UNSUPPORTED = 'project_provider_unsupported'; + public const string PROJECT_ALREADY_EXISTS = 'project_already_exists'; + public const string PROJECT_INVALID_SUCCESS_URL = 'project_invalid_success_url'; + public const string PROJECT_INVALID_FAILURE_URL = 'project_invalid_failure_url'; + public const string PROJECT_RESERVED_PROJECT = 'project_reserved_project'; + public const string PROJECT_KEY_EXPIRED = 'project_key_expired'; - public const PROJECT_SMTP_CONFIG_INVALID = 'project_smtp_config_invalid'; + public const string PROJECT_SMTP_CONFIG_INVALID = 'project_smtp_config_invalid'; - public const PROJECT_TEMPLATE_DEFAULT_DELETION = 'project_template_default_deletion'; + public const string PROJECT_TEMPLATE_DEFAULT_DELETION = 'project_template_default_deletion'; - public const PROJECT_REGION_UNSUPPORTED = 'project_region_unsupported'; + public const string PROJECT_REGION_UNSUPPORTED = 'project_region_unsupported'; /** Webhooks */ - public const WEBHOOK_NOT_FOUND = 'webhook_not_found'; + public const string WEBHOOK_NOT_FOUND = 'webhook_not_found'; /** Router */ - public const ROUTER_HOST_NOT_FOUND = 'router_host_not_found'; - public const ROUTER_DOMAIN_NOT_CONFIGURED = 'router_domain_not_configured'; + public const string ROUTER_HOST_NOT_FOUND = 'router_host_not_found'; + public const string ROUTER_DOMAIN_NOT_CONFIGURED = 'router_domain_not_configured'; /** Proxy */ - public const RULE_RESOURCE_NOT_FOUND = 'rule_resource_not_found'; - public const RULE_NOT_FOUND = 'rule_not_found'; - public const RULE_ALREADY_EXISTS = 'rule_already_exists'; - public const RULE_VERIFICATION_FAILED = 'rule_verification_failed'; + public const string RULE_RESOURCE_NOT_FOUND = 'rule_resource_not_found'; + public const string RULE_NOT_FOUND = 'rule_not_found'; + public const string RULE_ALREADY_EXISTS = 'rule_already_exists'; + public const string RULE_VERIFICATION_FAILED = 'rule_verification_failed'; /** Keys */ - public const KEY_NOT_FOUND = 'key_not_found'; + public const string KEY_NOT_FOUND = 'key_not_found'; /** Variables */ - public const VARIABLE_NOT_FOUND = 'variable_not_found'; - public const VARIABLE_ALREADY_EXISTS = 'variable_already_exists'; - public const VARIABLE_CANNOT_UNSET_SECRET = 'variable_cannot_unset_secret'; + public const string VARIABLE_NOT_FOUND = 'variable_not_found'; + public const string VARIABLE_ALREADY_EXISTS = 'variable_already_exists'; + public const string VARIABLE_CANNOT_UNSET_SECRET = 'variable_cannot_unset_secret'; /** Platform */ - public const PLATFORM_NOT_FOUND = 'platform_not_found'; + public const string PLATFORM_NOT_FOUND = 'platform_not_found'; /** GraphqQL */ - public const GRAPHQL_NO_QUERY = 'graphql_no_query'; - public const GRAPHQL_TOO_MANY_QUERIES = 'graphql_too_many_queries'; + public const string GRAPHQL_NO_QUERY = 'graphql_no_query'; + public const string GRAPHQL_TOO_MANY_QUERIES = 'graphql_too_many_queries'; /** Migrations */ - public const MIGRATION_NOT_FOUND = 'migration_not_found'; - public const MIGRATION_ALREADY_EXISTS = 'migration_already_exists'; - public const MIGRATION_IN_PROGRESS = 'migration_in_progress'; - public const MIGRATION_PROVIDER_ERROR = 'migration_provider_error'; + public const string MIGRATION_NOT_FOUND = 'migration_not_found'; + public const string MIGRATION_ALREADY_EXISTS = 'migration_already_exists'; + public const string MIGRATION_IN_PROGRESS = 'migration_in_progress'; + public const string MIGRATION_PROVIDER_ERROR = 'migration_provider_error'; /** Realtime */ - public const REALTIME_MESSAGE_FORMAT_INVALID = 'realtime_message_format_invalid'; - public const REALTIME_TOO_MANY_MESSAGES = 'realtime_too_many_messages'; - public const REALTIME_POLICY_VIOLATION = 'realtime_policy_violation'; + public const string REALTIME_MESSAGE_FORMAT_INVALID = 'realtime_message_format_invalid'; + public const string REALTIME_TOO_MANY_MESSAGES = 'realtime_too_many_messages'; + public const string REALTIME_POLICY_VIOLATION = 'realtime_policy_violation'; /** Health */ - public const HEALTH_QUEUE_SIZE_EXCEEDED = 'health_queue_size_exceeded'; - public const HEALTH_CERTIFICATE_EXPIRED = 'health_certificate_expired'; - public const HEALTH_INVALID_HOST = 'health_invalid_host'; + public const string HEALTH_QUEUE_SIZE_EXCEEDED = 'health_queue_size_exceeded'; + public const string HEALTH_CERTIFICATE_EXPIRED = 'health_certificate_expired'; + public const string HEALTH_INVALID_HOST = 'health_invalid_host'; /** Provider */ - public const PROVIDER_NOT_FOUND = 'provider_not_found'; - public const PROVIDER_ALREADY_EXISTS = 'provider_already_exists'; - public const PROVIDER_INCORRECT_TYPE = 'provider_incorrect_type'; - public const PROVIDER_MISSING_CREDENTIALS = 'provider_missing_credentials'; + public const string PROVIDER_NOT_FOUND = 'provider_not_found'; + public const string PROVIDER_ALREADY_EXISTS = 'provider_already_exists'; + public const string PROVIDER_INCORRECT_TYPE = 'provider_incorrect_type'; + public const string PROVIDER_MISSING_CREDENTIALS = 'provider_missing_credentials'; /** Topic */ - public const TOPIC_NOT_FOUND = 'topic_not_found'; - public const TOPIC_ALREADY_EXISTS = 'topic_already_exists'; + public const string TOPIC_NOT_FOUND = 'topic_not_found'; + public const string TOPIC_ALREADY_EXISTS = 'topic_already_exists'; /** Subscriber */ - public const SUBSCRIBER_NOT_FOUND = 'subscriber_not_found'; - public const SUBSCRIBER_ALREADY_EXISTS = 'subscriber_already_exists'; + public const string SUBSCRIBER_NOT_FOUND = 'subscriber_not_found'; + public const string SUBSCRIBER_ALREADY_EXISTS = 'subscriber_already_exists'; /** Message */ - public const MESSAGE_NOT_FOUND = 'message_not_found'; - public const MESSAGE_MISSING_TARGET = 'message_missing_target'; - public const MESSAGE_ALREADY_SENT = 'message_already_sent'; - public const MESSAGE_ALREADY_PROCESSING = 'message_already_processing'; - public const MESSAGE_ALREADY_FAILED = 'message_already_failed'; - public const MESSAGE_ALREADY_SCHEDULED = 'message_already_scheduled'; - public const MESSAGE_TARGET_NOT_EMAIL = 'message_target_not_email'; - public const MESSAGE_TARGET_NOT_SMS = 'message_target_not_sms'; - public const MESSAGE_TARGET_NOT_PUSH = 'message_target_not_push'; - public const MESSAGE_MISSING_SCHEDULE = 'message_missing_schedule'; + public const string MESSAGE_NOT_FOUND = 'message_not_found'; + public const string MESSAGE_MISSING_TARGET = 'message_missing_target'; + public const string MESSAGE_ALREADY_SENT = 'message_already_sent'; + public const string MESSAGE_ALREADY_PROCESSING = 'message_already_processing'; + public const string MESSAGE_ALREADY_FAILED = 'message_already_failed'; + public const string MESSAGE_ALREADY_SCHEDULED = 'message_already_scheduled'; + public const string MESSAGE_TARGET_NOT_EMAIL = 'message_target_not_email'; + public const string MESSAGE_TARGET_NOT_SMS = 'message_target_not_sms'; + public const string MESSAGE_TARGET_NOT_PUSH = 'message_target_not_push'; + public const string MESSAGE_MISSING_SCHEDULE = 'message_missing_schedule'; /** Targets */ - public const TARGET_PROVIDER_INVALID_TYPE = 'target_provider_invalid_type'; + public const string TARGET_PROVIDER_INVALID_TYPE = 'target_provider_invalid_type'; /** Schedules */ - public const SCHEDULE_NOT_FOUND = 'schedule_not_found'; + public const string SCHEDULE_NOT_FOUND = 'schedule_not_found'; /** Tokens */ - public const TOKEN_NOT_FOUND = 'token_not_found'; - public const TOKEN_EXPIRED = 'token_expired'; - public const TOKEN_RESOURCE_TYPE_INVALID = 'token_resource_type_invalid'; + public const string TOKEN_NOT_FOUND = 'token_not_found'; + public const string TOKEN_EXPIRED = 'token_expired'; + public const string TOKEN_RESOURCE_TYPE_INVALID = 'token_resource_type_invalid'; protected string $type = ''; protected array $errors = []; @@ -371,8 +383,13 @@ class Exception extends \Exception private array $ctas = []; private ?string $view = null; - public function __construct(string $type = Exception::GENERAL_UNKNOWN, string $message = null, int|string $code = null, \Throwable $previous = null, ?string $view = null) - { + public function __construct( + string $type = Exception::GENERAL_UNKNOWN, + string $message = null, + int|string $code = null, + \Throwable $previous = null, + ?string $view = null + ) { $this->errors = Config::getParam('errors'); $this->type = $type; $this->view = $view; @@ -381,7 +398,7 @@ class Exception extends \Exception // Mark string errors like HY001 from PDO as 500 errors if (\is_string($this->code)) { if (\is_numeric($this->code)) { - $this->code = (int) $this->code; + $this->code = (int)$this->code; } else { $this->code = 500; } diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 8b5e121dcd..35b8089668 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -312,13 +312,17 @@ class Realtime extends MessagingAdapter throw new \Exception('Collection or the Table needs to be passed to Realtime for Document/Row events in the Database.'); } + $tableId = $payload->getAttribute('$tableId', ''); + $collectionId = $payload->getAttribute('$collectionId', ''); + $resourceId = $tableId ?: $collectionId; + $channels[] = 'rows'; - $channels[] = 'databases.' . $database->getId() . '.tables.' . $payload->getAttribute('$tableId') . '.rows'; - $channels[] = 'databases.' . $database->getId() . '.tables.' . $payload->getAttribute('$tableId') . '.rows.' . $payload->getId(); + $channels[] = 'databases.' . $database->getId() . '.tables.' . $resourceId . '.rows'; + $channels[] = 'databases.' . $database->getId() . '.tables.' . $resourceId . '.rows.' . $payload->getId(); $channels[] = 'documents'; - $channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents'; - $channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents.' . $payload->getId(); + $channels[] = 'databases.' . $database->getId() . '.collections.' . $resourceId . '.documents'; + $channels[] = 'databases.' . $database->getId() . '.collections.' . $resourceId . '.documents.' . $payload->getId(); $roles = $collection->getAttribute('documentSecurity', false) ? \array_merge($collection->getRead(), $payload->getRead()) diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index 2d82b9c486..588b193df4 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -89,7 +89,7 @@ abstract class Migration '1.7.2' => 'V22', '1.7.3' => 'V22', '1.7.4' => 'V22', - '1.8.0' => 'V23' + '1.8.0' => 'V23', ]; /** diff --git a/src/Appwrite/Migration/Version/V19.php b/src/Appwrite/Migration/Version/V19.php index d4dda02d75..f5cf84c95e 100644 --- a/src/Appwrite/Migration/Version/V19.php +++ b/src/Appwrite/Migration/Version/V19.php @@ -730,8 +730,8 @@ class V19 extends Migration if (empty($document->getAttribute('scheduleId', null))) { $schedule = $this->dbForPlatform->createDocument('schedules', new Document([ - 'region' => $project->getAttribute('region'), - 'resourceType' => 'function', + 'region' => $this->project->getAttribute('region'), + 'resourceType' => SCHEDULE_RESOURCE_TYPE_FUNCTION, 'resourceId' => $document->getId(), 'resourceInternalId' => $document->getSequence(), 'resourceUpdatedAt' => DateTime::now(), diff --git a/src/Appwrite/Migration/Version/V23.php b/src/Appwrite/Migration/Version/V23.php index d5caf2ab3c..7a6d58d59f 100644 --- a/src/Appwrite/Migration/Version/V23.php +++ b/src/Appwrite/Migration/Version/V23.php @@ -8,6 +8,9 @@ use Throwable; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Database\Exception\Conflict; +use Utopia\Database\Exception\Structure; +use Utopia\Database\Exception\Timeout; class V23 extends Migration { @@ -19,7 +22,24 @@ class V23 extends Migration /** * Disable SubQueries for Performance. */ - foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryDevKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) { + $subQueries = [ + 'subQueryAttributes', + 'subQueryAuthenticators', + 'subQueryChallenges', + 'subQueryDevKeys', + 'subQueryIndexes', + 'subQueryKeys', + 'subQueryMemberships', + 'subQueryPlatforms', + 'subQueryProjectVariables', + 'subQuerySessions', + 'subQueryTargets', + 'subQueryTokens', + 'subQueryTopicTargets', + 'subQueryVariables', + 'subQueryWebhooks', + ]; + foreach ($subQueries as $name) { Database::addFilter( $name, fn () => null, @@ -27,26 +47,158 @@ class V23 extends Migration ); } - Console::info('Migrating databases'); - $this->migrateDatabases(); + Console::info('Migrating collections'); + $this->migrateCollections(); + + if ($this->project->getSequence() != 'console') { + Console::info('Migrating Databases'); + $this->migrateDatabases(); + } + + Console::info('Migrating Buckets'); + $this->migrateBuckets(); + + Console::info('Migrating documents'); + $this->forEachDocument($this->migrateDocument(...)); } /** - * Migrate Databases. + * Migrate Collections. * * @return void * @throws Exception|Throwable */ - private function migrateDatabases(): void + private function migrateCollections(): void { - if ($this->project->getId() === 'console') { - return; + $projectInternalId = $this->project->getSequence(); + + if (empty($projectInternalId)) { + throw new Exception('Project ID is null'); } - // since required + default can't be used together - // so first creating the attribute then bulk updating the attribute - $this->createAttributeFromCollection($this->dbForProject, 'databases', 'type'); - $this->dbForProject->updateDocuments('databases', new Document(['type' => 'legacy'])); + $collectionType = match ($projectInternalId) { + 'console' => 'console', + default => 'projects', + }; + + $collections = $this->collections[$collectionType]; + + foreach ($collections as $collection) { + $id = $collection['$id']; + + if (empty($id)) { + continue; + } + + Console::log("Migrating collection \"{$id}\""); + + // Clear cache to ensure new $sequence is used + $this->dbForProject->purgeCachedCollection($id); + $this->dbForProject->purgeCachedDocument(Database::METADATA, $id); + + switch ($id) { + case '_metadata': + $this->createCollection('transactions'); + $this->createCollection('transactionLogs'); + break; + case 'projects': + $attributes = [ + 'pingCount', + 'pingedAt' + ]; + try { + $this->createAttributesFromCollection($this->dbForProject, $id, $attributes); + } catch (\Throwable $th) { + Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}"); + } + $this->dbForProject->purgeCachedCollection($id); + break; + case 'databases': + $attributes = [ + 'type', + ]; + try { + $this->createAttributesFromCollection($this->dbForProject, $id, $attributes); + } catch (\Throwable $th) { + Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}"); + } + $this->dbForProject->purgeCachedCollection($id); + break; + case 'schedules': + try { + $this->dbForProject->updateAttribute($id, 'resourceInternalId', required: false); + } catch (Throwable $th) { + Console::warning("'resourceInternalId' from {$id}: {$th->getMessage()}"); + } + $this->dbForProject->purgeCachedCollection($id); + break; + default: + break; + } + } } + /** + * Migrate all Database Table tables + * + * @return void + * @throws Exception + */ + private function migrateDatabases(): void + { + $this->dbForProject->foreach('databases', function (Document $database) { + Console::log("Migrating Collections of {$database->getId()} ({$database->getAttribute('name')})"); + + $databaseTable = "database_{$database->getSequence()}"; + $this->dbForProject->purgeCachedCollection($databaseTable); + + $this->dbForProject->foreach($databaseTable, function (Document $collection) use ($databaseTable) { + Console::log("Migrating Collection of {$collection->getId()} ({$collection->getAttribute('name')})"); + + $collectionTable = "{$databaseTable}_collection_{$collection->getSequence()}"; + $this->dbForProject->purgeCachedCollection($collectionTable); + }); + }); + } + + /** + * Migrate all Bucket tables + * + * @return void + * @throws \Exception + * @throws \PDOException + */ + protected function migrateBuckets(): void + { + $this->dbForProject->foreach('buckets', function (Document $bucket) { + Console::log("Migrating Bucket {$bucket->getId()} ({$bucket->getAttribute('name')})"); + + $bucketTable = "bucket_{$bucket->getSequence()}"; + $this->dbForProject->purgeCachedCollection($bucketTable); + }); + } + + /** + * Fix run on each document + * + * @param Document $document + * @return Document + * @throws Conflict + * @throws Structure + * @throws Timeout + * @throws \Utopia\Database\Exception + * @throws \Utopia\Database\Exception\Authorization + * @throws \Utopia\Database\Exception\Query + */ + private function migrateDocument(Document $document): Document + { + switch ($document->getCollection()) { + case 'databases': + $document->setAttribute('type', $document->getAttribute('type', 'legacy')); + break; + default: + break; + } + return $document; + } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php index 0939376c49..b22119fad1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php @@ -53,7 +53,7 @@ abstract class Action extends UtopiaAction /** * Get the SDK group name for the current action. */ - protected function getSdkGroup(): string + protected function getSDKGroup(): string { return $this->isCollectionsAPI() ? 'collections' : 'tables'; } @@ -61,7 +61,7 @@ abstract class Action extends UtopiaAction /** * Get the SDK namespace for the current action. */ - protected function getSdkNamespace(): string + protected function getSDKNamespace(): string { return $this->isCollectionsAPI() ? 'databases' : 'tablesDB'; } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Action.php index 22a90d2653..48124e2a11 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Action.php @@ -66,7 +66,7 @@ abstract class Action extends UtopiaAction * * Can be used for XList operations as well! */ - protected function getSdkGroup(): string + protected function getSDKGroup(): string { return $this->isCollectionsAPI() ? 'attributes' : 'columns'; } @@ -74,7 +74,7 @@ abstract class Action extends UtopiaAction /** * Get the SDK namespace for the current action. */ - protected function getSdkNamespace(): string + protected function getSDKNamespace(): string { return $this->isCollectionsAPI() ? 'databases' : 'tablesDB'; } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Create.php index 6c4be252a0..6c8e5dcf3d 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Create.php @@ -42,8 +42,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-boolean-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Update.php index 752e8c6c59..d4724ea551 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Boolean/Update.php @@ -42,8 +42,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-boolean-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Create.php index 5d5b8fe4bf..1f2098e7af 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Create.php @@ -43,8 +43,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-datetime-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Update.php index e1d1d40f75..cb4d0d924b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Datetime/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-datetime-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Delete.php index 8dec7530bf..eb51044323 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Delete.php @@ -43,8 +43,8 @@ class Delete extends Action ->label('audits.event', 'attribute.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/delete-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Create.php index bc58ca10af..cbfd66e4d9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Create.php @@ -43,8 +43,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-email-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Update.php index 53300725d7..2446722f7a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Email/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-email-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Create.php index cd22e87d1c..98ed83861d 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Create.php @@ -45,8 +45,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-enum-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Update.php index 951e43effe..23dc807360 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Enum/Update.php @@ -44,8 +44,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-enum-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Create.php index 2a8253c22c..83deb92edc 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Create.php @@ -45,8 +45,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-float-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Update.php index 327a766cee..7f295a1a94 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Float/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-float-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Get.php index 28ee584778..91fa3582f7 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Get.php @@ -47,8 +47,8 @@ class Get extends Action ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/get-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Create.php index aa699b4a49..6e6264466c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Create.php @@ -43,8 +43,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-ip-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Update.php index f61cf21732..6cedf10760 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/IP/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-ip-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Create.php index 81a11b0471..090d63c403 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Create.php @@ -45,8 +45,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-integer-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Update.php index 11cfb24943..b6ae79bd8a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Integer/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-integer-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Create.php index 4eb3345823..f691fc29cf 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Create.php @@ -44,8 +44,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-line-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Update.php index 8fcb867923..52f04ba5bc 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Line/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-line-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Create.php index 47c88497ba..aae715ba1e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Create.php @@ -44,8 +44,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-point-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Update.php index bffe802927..73964ab461 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Point/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-point-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Create.php index 6cc74254ae..6fbbd46d2c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Create.php @@ -44,8 +44,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-polygon-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Update.php index d78bfa8ef0..23eb06f45d 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Polygon/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-polygon-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Create.php index a062816329..75471b826c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Create.php @@ -45,8 +45,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-relationship-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Update.php index c19c4ff046..897cbd434f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/Relationship/Update.php @@ -41,8 +41,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-relationship-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Create.php index 592aa8ee93..1527c4d1d9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Create.php @@ -47,8 +47,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-string-attribute.md', auth: [AuthType::KEY], @@ -95,7 +95,7 @@ class Create extends Action array $plan ): void { if (!App::isDevelopment() && $encrypt && !empty($plan) && !($plan['databasesAllowEncrypt'] ?? false)) { - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Encrypted string ' . $this->getSdkGroup() . ' are not available on your plan. Please upgrade to create encrypted string ' . $this->getSdkGroup() . '.'); + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Encrypted string ' . $this->getSDKGroup() . ' are not available on your plan. Please upgrade to create encrypted string ' . $this->getSDKGroup() . '.'); } if ($encrypt && $size < APP_DATABASE_ENCRYPT_SIZE_MIN) { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Update.php index 03efac1430..8614dfb202 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/String/Update.php @@ -45,8 +45,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-string-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Create.php index 39153b3cb8..ce0175966b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Create.php @@ -43,8 +43,8 @@ class Create extends Action ->label('audits.event', 'attribute.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-url-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Update.php index 7ace4d0683..7ba12ad98a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/URL/Update.php @@ -43,8 +43,8 @@ class Update extends Action ->label('audits.event', 'attribute.update') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-url-attribute.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/XList.php index 1852290f76..6daa180df9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Attributes/XList.php @@ -41,8 +41,8 @@ class XList extends Action ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/list-attributes.md', auth: [AuthType::KEY], @@ -141,7 +141,7 @@ class XList extends Action $response->dynamic(new Document([ 'total' => $total, - $this->getSdkGroup() => $attributes, + $this->getSDKGroup() => $attributes, ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php index e06dae89bb..b810ce602f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php @@ -52,7 +52,7 @@ class Create extends Action ->label('audits.resource', 'database/{request.databaseId}/collection/{response.$id}') ->label('sdk', new Method( namespace: 'databases', - group: $this->getSdkGroup(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-collection.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Delete.php index d20570fb43..d124a47289 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Delete.php @@ -42,7 +42,7 @@ class Delete extends Action ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( namespace: 'databases', - group: $this->getSdkGroup(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/delete-collection.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php index e05e588201..3da89f352c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Action.php @@ -76,7 +76,7 @@ abstract class Action extends AppwriteAction * * Can be used for XList operations as well! */ - protected function getSdkGroup(): string + protected function getSDKGroup(): string { return $this->isCollectionsAPI() ? 'documents' : 'rows'; } @@ -84,7 +84,7 @@ abstract class Action extends AppwriteAction /** * Get the SDK namespace for the current action. */ - protected function getSdkNamespace(): string + protected function getSDKNamespace(): string { return $this->isCollectionsAPI() ? 'databases' : 'tablesDB'; } @@ -205,6 +205,31 @@ abstract class Action extends AppwriteAction return $this->isCollectionsAPI() ? 'collection' : 'table'; } + /** + * Get the correct attribute/column key for increment/decrement operations. + */ + protected function getAttributeKey(): string + { + return $this->isCollectionsAPI() ? 'attribute' : 'column'; + } + + /** + * Get the key used in ID parameters (e.g., 'collectionId' or 'tableId'). + */ + protected function getGroupId(): string + { + return $this->getCollectionsEventsContext() . 'Id'; + } + + /** + * Get the resource ID key for the current action. + */ + protected function getResourceId(): string + { + $resource = $this->isCollectionsAPI() ? 'document' : 'row'; + return $resource . 'Id'; + } + /** * Remove configured removable attributes from a document. * Used for relationship path handling to remove API-specific attributes. diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php index 289dee5a8d..0b3d0e9fb4 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php @@ -2,6 +2,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documents\Attribute; +use Appwrite\Auth\Auth; use Appwrite\Event\Event; use Appwrite\Event\StatsUsage; use Appwrite\Extend\Exception; @@ -14,10 +15,12 @@ use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use InvalidArgumentException; use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Limit as LimitException; use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Type as TypeException; +use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; @@ -52,8 +55,8 @@ class Decrement extends Action ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/decrement-document-attribute.md', auth: [AuthType::SESSION, AuthType::JWT, AuthType::ADMIN, AuthType::KEY], @@ -75,15 +78,20 @@ class Decrement extends Action ->param('attribute', '', new Key(), 'Attribute key.') ->param('value', 1, new Numeric(), 'Value to increment the attribute by. The value must be a number.', true) ->param('min', null, new Numeric(), 'Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('plan') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $min, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage): void + public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $min, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, array $plan): void { + $isAPIKey = Auth::isAppUser(Authorization::getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -94,6 +102,70 @@ class Decrement extends Action throw new Exception($this->getParentNotFoundException()); } + // Handle transaction staging + if ($transactionId !== null) { + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty() || $transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or non‑pending transaction'); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operation in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'documentId' => $documentId, + 'action' => 'decrement', + 'data' => [ + $this->getAttributeKey() => $attribute, + 'value' => $value, + 'min' => $min, + ], + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + 1 + ); + }); + + // Return successful response without actually decrementing + $groupId = $this->getGroupId(); + $mockDocument = new Document([ + '$id' => $documentId, + '$' . $groupId => $collectionId, + '$databaseId' => $databaseId, + $attribute => $value, + ]); + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_OK) + ->dynamic($mockDocument, $this->getResponseModel()); + return; + } + try { $document = $dbForProject->decreaseDocumentAttribute( collection: 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), @@ -107,9 +179,9 @@ class Decrement extends Action } catch (NotFoundException) { throw new Exception($this->getStructureNotFoundException()); } catch (LimitException) { - throw new Exception($this->getLimitException(), $this->getSdkNamespace() . ' "' . $attribute . '" has reached the minimum value of ' . $min); + throw new Exception($this->getLimitException(), $this->getSDKNamespace() . ' "' . $attribute . '" has reached the minimum value of ' . $min); } catch (TypeException) { - throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID, $this->getSdkNamespace() . ' "' . $attribute . '" is not a number'); + throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID, $this->getSDKNamespace() . ' "' . $attribute . '" is not a number'); } catch (InvalidArgumentException $e) { throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $e->getMessage()); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php index fe8bd2d225..ef64099fa8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php @@ -2,6 +2,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documents\Attribute; +use Appwrite\Auth\Auth; use Appwrite\Event\Event; use Appwrite\Event\StatsUsage; use Appwrite\Extend\Exception; @@ -14,10 +15,12 @@ use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use InvalidArgumentException; use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Limit as LimitException; use Utopia\Database\Exception\NotFound as NotFoundException; use Utopia\Database\Exception\Type as TypeException; +use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; @@ -52,8 +55,8 @@ class Increment extends Action ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/increment-document-attribute.md', auth: [AuthType::SESSION, AuthType::JWT, AuthType::ADMIN, AuthType::KEY], @@ -75,15 +78,20 @@ class Increment extends Action ->param('attribute', '', new Key(), 'Attribute key.') ->param('value', 1, new Numeric(), 'Value to increment the attribute by. The value must be a number.', true) ->param('max', null, new Numeric(), 'Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('plan') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $max, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage): void + public function action(string $databaseId, string $collectionId, string $documentId, string $attribute, int|float $value, int|float|null $max, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, array $plan): void { + $isAPIKey = Auth::isAppUser(Authorization::getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); if ($database->isEmpty()) { throw new Exception(Exception::DATABASE_NOT_FOUND); @@ -94,6 +102,70 @@ class Increment extends Action throw new Exception($this->getParentNotFoundException()); } + // Handle transaction staging + if ($transactionId !== null) { + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty() || $transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or non‑pending transaction'); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operation in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'documentId' => $documentId, + 'action' => 'increment', + 'data' => [ + $this->getAttributeKey() => $attribute, + 'value' => $value, + 'max' => $max, + ], + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + 1 + ); + }); + + // Return successful response without actually incrementing + $groupId = $this->getGroupId(); + $mockDocument = new Document([ + '$id' => $documentId, + '$' . $groupId => $collectionId, + '$databaseId' => $databaseId, + $attribute => $value, + ]); + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_OK) + ->dynamic($mockDocument, $this->getResponseModel()); + return; + } + try { $document = $dbForProject->increaseDocumentAttribute( collection: 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), @@ -107,9 +179,9 @@ class Increment extends Action } catch (NotFoundException) { throw new Exception($this->getStructureNotFoundException()); } catch (LimitException) { - throw new Exception($this->getLimitException(), $this->getSdkNamespace() . ' "' . $attribute . '" has reached the maximum value of ' . $max); + throw new Exception($this->getLimitException(), $this->getSDKNamespace() . ' "' . $attribute . '" has reached the maximum value of ' . $max); } catch (TypeException) { - throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID, $this->getSdkNamespace() . ' "' . $attribute . '" is not a number'); + throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID, $this->getSDKNamespace() . ' "' . $attribute . '" is not a number'); } catch (InvalidArgumentException $e) { throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $e->getMessage()); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php index 3467a9d11c..4b1251e016 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php @@ -17,6 +17,7 @@ use Utopia\Database\Document; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Exception\Restricted as RestrictedException; +use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\UID; use Utopia\Swoole\Response as SwooleResponse; @@ -50,8 +51,8 @@ class Delete extends Action ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/delete-documents.md', auth: [AuthType::ADMIN, AuthType::KEY], @@ -70,6 +71,7 @@ class Delete extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') @@ -81,7 +83,7 @@ class Delete extends Action ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, Event $queueForEvents, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void + public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, Event $queueForEvents, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void { $database = $dbForProject->getDocument('databases', $databaseId); if ($database->isEmpty()) { @@ -99,15 +101,63 @@ class Delete extends Action ); if ($hasRelationships) { - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk delete is not supported for ' . $this->getSdkNamespace() . ' with relationship attributes'); + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk delete is not supported for ' . $this->getSDKNamespace() . ' with relationship attributes'); } + $originalQueries = $queries; + try { $queries = Query::parseQueries($queries); } catch (QueryException $e) { throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } + // Handle transaction staging + if ($transactionId !== null) { + $transaction = $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty() || $transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or non‑pending transaction'); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operation in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => $originalQueries, + ], + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + ); + }); + + // Return successful response without actually deleting documents + $response->dynamic(new Document([ + $this->getSDKGroup() => [], + 'total' => 0, // Can't predict how many would be deleted + ]), $this->getResponseModel()); + return; + } + $documents = []; try { @@ -139,7 +189,7 @@ class Delete extends Action $response->dynamic(new Document([ 'total' => $modified, - $this->getSdkGroup() => $documents, + $this->getSDKGroup() => $documents, ]), $this->getResponseModel()); $this->triggerBulk( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php index 65bd255d32..e0d053b976 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php @@ -18,6 +18,7 @@ use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Exception\Relationship as RelationshipException; use Utopia\Database\Exception\Structure as StructureException; +use Utopia\Database\Helpers\ID; use Utopia\Database\Query; use Utopia\Database\Validator\Permissions; use Utopia\Database\Validator\UID; @@ -53,8 +54,8 @@ class Update extends Action ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-documents.md', auth: [AuthType::ADMIN, AuthType::KEY], @@ -74,6 +75,7 @@ class Update extends Action ->param('collectionId', '', new UID(), 'Collection ID.') ->param('data', [], new JSON(), 'Document data as JSON object. Include only attribute and value pairs to be updated.', true) ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') @@ -85,7 +87,7 @@ class Update extends Action ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string|array $data, array $queries, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, Event $queueForEvents, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void + public function action(string $databaseId, string $collectionId, string|array $data, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, Event $queueForEvents, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void { $data = \is_string($data) ? \json_decode($data, true) @@ -111,16 +113,18 @@ class Update extends Action ); if ($hasRelationships) { - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk update is not supported for ' . $this->getSdkNamespace() . ' with relationship attributes'); + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk update is not supported for ' . $this->getSDKNamespace() . ' with relationship attributes'); } + $originalQueries = $queries; + try { $queries = Query::parseQueries($queries); } catch (QueryException $e) { throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - if ($data['$permissions']) { + if (isset($data['$permissions'])) { $validator = new Permissions(); if (!$validator->isValid($data['$permissions'])) { throw new Exception(Exception::GENERAL_BAD_REQUEST, $validator->getDescription()); @@ -129,6 +133,53 @@ class Update extends Action $data = $this->removeReadonlyAttributes($data, privileged: true); + // Handle transaction staging + if ($transactionId !== null) { + $transaction = $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty() || $transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or non‑pending transaction'); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operation in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'action' => 'bulkUpdate', + 'data' => [ + 'data' => $data, + 'queries' => $originalQueries, + ], + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + ); + }); + + // Return successful response without actually updating documents + $response->dynamic(new Document([ + $this->getSDKGroup() => [], + 'total' => 0, // Can't predict how many would be updated + ]), $this->getResponseModel()); + return; + } + $documents = []; try { @@ -165,7 +216,7 @@ class Update extends Action $response->dynamic(new Document([ 'total' => $modified, - $this->getSdkGroup() => $documents + $this->getSDKGroup() => $documents ]), $this->getResponseModel()); $this->triggerBulk( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php index 4ce3990a38..a2156484a8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php @@ -18,6 +18,7 @@ use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Exception\Relationship as RelationshipException; use Utopia\Database\Exception\Structure as StructureException; +use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\UID; use Utopia\Swoole\Response as SwooleResponse; use Utopia\Validator\ArrayList; @@ -51,8 +52,8 @@ class Upsert extends Action ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/upsert-documents.md', auth: [AuthType::ADMIN, AuthType::KEY], @@ -72,6 +73,7 @@ class Upsert extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID.') ->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of document data as JSON objects. May contain partial documents.', false, ['plan']) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') @@ -83,7 +85,7 @@ class Upsert extends Action ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, array $documents, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, Event $queueForEvents, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void + public function action(string $databaseId, string $collectionId, array $documents, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, Event $queueForEvents, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void { $database = $dbForProject->getDocument('databases', $databaseId); if ($database->isEmpty()) { @@ -101,7 +103,7 @@ class Upsert extends Action ); if ($hasRelationships) { - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk upsert is not supported for ' . $this->getSdkNamespace() . ' with relationship attributes'); + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk upsert is not supported for ' . $this->getSDKNamespace() . ' with relationship attributes'); } foreach ($documents as $key => $document) { @@ -109,11 +111,57 @@ class Upsert extends Action $documents[$key] = new Document($document); } + // Handle transaction staging + if ($transactionId !== null) { + $transaction = $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty() || $transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or non‑pending transaction'); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operations in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'action' => 'bulkUpsert', + 'data' => $documents, + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + 1 + ); + }); + + // Return successful response without actually upserting documents + $response->dynamic(new Document([ + $this->getSDKGroup() => [], + 'total' => \count($documents), + ]), $this->getResponseModel()); + + return; + } + $upserted = []; try { $modified = $dbForProject->withPreserveDates(function () use ($dbForProject, $database, $collection, $documents, $plan, &$upserted) { - return $dbForProject->createOrUpdateDocuments( + return $dbForProject->upsertDocuments( 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documents, onNext: function (Document $document) use ($plan, &$upserted) { @@ -144,7 +192,7 @@ class Upsert extends Action $response->dynamic(new Document([ 'total' => $modified, - $this->getSdkGroup() => $upserted + $this->getSDKGroup() => $upserted ]), $this->getResponseModel()); $this->triggerBulk( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php index a8af1eda86..521190d3dc 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php @@ -63,8 +63,8 @@ class Create extends Action ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), desc: 'Create document', description: '/docs/references/databases/create-document.md', @@ -82,6 +82,7 @@ class Create extends Action new Parameter('documentId', optional: false), new Parameter('data', optional: false), new Parameter('permissions', optional: true), + new Parameter('transactionId', optional: true), ], deprecated: new Deprecated( since: '1.8.0', @@ -89,8 +90,8 @@ class Create extends Action ), ), new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: $this->getBulkActionName(self::getName()), desc: 'Create documents', description: '/docs/references/databases/create-documents.md', @@ -106,6 +107,7 @@ class Create extends Action new Parameter('databaseId', optional: false), new Parameter('collectionId', optional: false), new Parameter('documents', optional: false), + new Parameter('transactionId', optional: true), ], deprecated: new Deprecated( since: '1.8.0', @@ -119,6 +121,7 @@ class Create extends Action ->param('data', [], new JSON(), 'Document data as JSON object.', true, example: '{"username":"walter.obrien","email":"walter.obrien@example.com","fullName":"Walter O\'Brien","age":30,"isAdmin":false}') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of documents data as JSON objects.', true, ['plan']) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('user') @@ -127,9 +130,10 @@ class Create extends Action ->inject('queueForRealtime') ->inject('queueForFunctions') ->inject('queueForWebhooks') + ->inject('plan') ->callback($this->action(...)); } - public function action(string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, ?array $documents, UtopiaResponse $response, Database $dbForProject, Document $user, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks): void + public function action(string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, ?array $documents, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, Document $user, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void { $data = \is_string($data) ? \json_decode($data, true) @@ -144,7 +148,7 @@ class Create extends Action } if (!empty($data) && !empty($documents)) { // Both single and bulk documents provided - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'You can only send one of the following parameters: data, ' . $this->getSdkGroup()); + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'You can only send one of the following parameters: data, ' . $this->getSDKGroup()); } if (!empty($data) && empty($documentId)) { // Single document provided without document ID @@ -157,12 +161,12 @@ class Create extends Action $documentId = $this->isCollectionsAPI() ? 'documentId' : 'rowId'; throw new Exception( Exception::GENERAL_BAD_REQUEST, - "Param \"$documentId\" is not allowed when creating multiple " . $this->getSdkGroup() . ', set "$id" on each instead.' + "Param \"$documentId\" is not allowed when creating multiple " . $this->getSDKGroup() . ', set "$id" on each instead.' ); } if (!empty($documents) && !empty($permissions)) { // Bulk documents provided with permissions - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Param "permissions" is disallowed when creating multiple ' . $this->getSdkGroup() . ', set "$permissions" on each instead'); + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Param "permissions" is disallowed when creating multiple ' . $this->getSDKGroup() . ', set "$permissions" on each instead'); } $isBulk = true; @@ -196,7 +200,7 @@ class Create extends Action ); if ($isBulk && $hasRelationships) { - throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk create is not supported for ' . $this->getSdkNamespace() .' with relationship ' . $this->getStructureContext()); + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk create is not supported for ' . $this->getSDKNamespace() .' with relationship ' . $this->getStructureContext()); } $setPermissions = function (Document $document, ?array $permissions) use ($user, $isAPIKey, $isPrivilegedUser, $isBulk) { @@ -361,6 +365,74 @@ class Create extends Action return $document; }, $documents); + // Handle transaction staging + if ($transactionId !== null) { + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + if ($transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::TRANSACTION_NOT_READY); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'documentId' => $isBulk ? null : $documentId, + 'action' => $isBulk ? 'bulkCreate' : 'create', + 'data' => $isBulk ? $documents : $documents[0], + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + ); + }); + + // Return successful response without actually creating documents + if ($isBulk) { + $response->dynamic(new Document([ + $this->getSDKGroup() => [], + 'total' => \count($documents), + ]), $this->getBulkResponseModel()); + } else { + $groupId = $this->getGroupId(); + $mockDocument = new Document([ + '$id' => $documents[0]['$id'] ?? $documentId, + '$' . $groupId => $collectionId, + '$databaseId' => $databaseId, + ...$documents[0] + ]); + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_CREATED) + ->dynamic($mockDocument, $this->getResponseModel()); + } + return; + } + try { $dbForProject->withPreserveDates( fn () => $dbForProject->createDocuments( @@ -405,7 +477,7 @@ class Create extends Action if ($isBulk) { $response->dynamic(new Document([ 'total' => count($documents), - $this->getSdkGroup() => $documents + $this->getSDKGroup() => $documents ]), $this->getBulkResponseModel()); $this->triggerBulk( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php index f34b4630c2..a4cef59e5f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documents; use Appwrite\Auth\Auth; +use Appwrite\Databases\TransactionState; use Appwrite\Event\Event; use Appwrite\Event\StatsUsage; use Appwrite\Extend\Exception; @@ -13,8 +14,10 @@ use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Restricted as RestrictedException; +use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Swoole\Response as SwooleResponse; @@ -51,8 +54,8 @@ class Delete extends Action ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/delete-document.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -71,16 +74,30 @@ class Delete extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('documentId', '', new UID(), 'Document ID.') + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('transactionState') + ->inject('plan') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string $documentId, ?\DateTime $requestTimestamp, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage): void - { + public function action( + string $databaseId, + string $collectionId, + string $documentId, + ?string $transactionId, + ?\DateTime $requestTimestamp, + UtopiaResponse $response, + Database $dbForProject, + Event $queueForEvents, + StatsUsage $queueForStatsUsage, + TransactionState $transactionState, + array $plan + ): void { $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); $isAPIKey = Auth::isAppUser(Authorization::getRoles()); @@ -97,12 +114,73 @@ class Delete extends Action } // Read permission should not be required for delete - $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId)); + $collectionTableId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); + + if ($transactionId !== null) { + // Use transaction-aware document retrieval to see changes from same transaction + $document = $transactionState->getDocument($collectionTableId, $documentId, $transactionId); + } else { + $document = Authorization::skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId)); + } if ($document->isEmpty()) { throw new Exception($this->getNotFoundException()); } + // Handle transaction staging + if ($transactionId !== null) { + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + if ($transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::TRANSACTION_NOT_READY); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operation in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'documentId' => $documentId, + 'action' => 'delete', + 'data' => [], + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + 1 + ); + }); + + // Return successful response without actually deleting document + $response->noContent(); + return; + } + try { $dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $database, $collection, $documentId) { $dbForProject->deleteDocument( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php index 7f621fb33a..3d8cd9198c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documents; use Appwrite\Auth\Auth; +use Appwrite\Databases\TransactionState; use Appwrite\Event\StatsUsage; use Appwrite\Extend\Exception; use Appwrite\SDK\AuthType; @@ -42,8 +43,8 @@ class Get extends Action ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/get-document.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -63,13 +64,15 @@ class Get extends Action ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('documentId', '', new UID(), 'Document ID.') ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID to read uncommitted changes within the transaction.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') + ->inject('transactionState') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage): void + public function action(string $databaseId, string $collectionId, string $documentId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void { $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -93,13 +96,17 @@ class Get extends Action try { $selects = Query::groupByType($queries)['selections'] ?? []; + $collectionTableId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); - if (! empty($selects)) { + // Use transaction-aware document retrieval if transactionId is provided + if ($transactionId !== null) { + $document = $transactionState->getDocument($collectionTableId, $documentId, $transactionId, $queries); + } elseif (! empty($selects)) { // has selects, allow relationship on documents! - $document = $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId, $queries); + $document = $dbForProject->getDocument($collectionTableId, $documentId, $queries); } else { // has no selects, disable relationship looping on documents! - $document = $dbForProject->skipRelationships(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId, $queries)); + $document = $dbForProject->skipRelationships(fn () => $dbForProject->getDocument($collectionTableId, $documentId, $queries)); } } catch (QueryException $e) { throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php index 93c8639520..241b0c4ede 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Logs/XList.php @@ -48,7 +48,7 @@ class XList extends Action ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: 'logs', name: self::getName(), description: '/docs/references/databases/get-document-logs.md', @@ -108,10 +108,7 @@ class XList extends Action $audit = new Audit($dbForProject); $type = $this->getCollectionsEventsContext(); $context = $this->getContext(); - $resource = match ($context) { - ROWS => "database/$databaseId/grid/$type/$collectionId/$context/{$document->getId()}", - default => "database/$databaseId/$type/$collectionId/$context/{$document->getId()}", - }; + $resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}"; $logs = $audit->getLogsByResource($resource, $queries); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php index e510aeb089..552c51a5fb 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documents; use Appwrite\Auth\Auth; +use Appwrite\Databases\TransactionState; use Appwrite\Event\Event; use Appwrite\Event\StatsUsage; use Appwrite\Extend\Exception; @@ -55,8 +56,8 @@ class Update extends Action ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-document.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -77,17 +78,19 @@ class Update extends Action ->param('documentId', '', new UID(), 'Document ID.') ->param('data', [], new JSON(), 'Document data as JSON object. Include only attribute and value pairs to be updated.', true) ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('transactionState') + ->inject('plan') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?\DateTime $requestTimestamp, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage): void + public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?string $transactionId, ?\DateTime $requestTimestamp, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, TransactionState $transactionState, array $plan): void { - $data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array if (empty($data) && \is_null($permissions)) { @@ -111,7 +114,14 @@ class Update extends Action // Read permission should not be required for update /** @var Document $document */ - $document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId)); + $collectionTableId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); + + if ($transactionId !== null) { + // Use transaction-aware document retrieval to see changes from same transaction + $document = $transactionState->getDocument($collectionTableId, $documentId, $transactionId); + } else { + $document = Authorization::skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId)); + } if ($document->isEmpty()) { throw new Exception($this->getNotFoundException()); @@ -231,6 +241,72 @@ class Update extends Action ->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1)) ->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations); + + // Handle transaction staging + if ($transactionId !== null) { + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + if ($transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::TRANSACTION_NOT_READY); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operation in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'documentId' => $documentId, + 'action' => 'update', + 'data' => $data, + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + 1 + ); + }); + + // Return successful response without actually updating document + $groupId = $this->getGroupId(); + $mockDocument = new Document([ + '$id' => $documentId, + '$' . $groupId => $collectionId, + '$databaseId' => $databaseId, + ...$document->getArrayCopy(), + ...$data + ]); + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_OK) + ->dynamic($mockDocument, $this->getResponseModel()); + return; + } + + try { $document = $dbForProject->withRequestTimestamp( $requestTimestamp, diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php index 3ac5e704e3..f113a99c7a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documents; use Appwrite\Auth\Auth; +use Appwrite\Databases\TransactionState; use Appwrite\Event\Event; use Appwrite\Event\StatsUsage; use Appwrite\Extend\Exception; @@ -57,8 +58,8 @@ class Upsert extends Action ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/upsert-document.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -80,16 +81,19 @@ class Upsert extends Action ->param('documentId', '', new CustomId(), 'Document ID.') ->param('data', [], new JSON(), 'Document data as JSON object. Include all required attributes of the document to be created or updated.') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('transactionState') + ->inject('plan') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?\DateTime $requestTimestamp, UtopiaResponse $response, Document $user, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage): void + public function action(string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?string $transactionId, ?\DateTime $requestTimestamp, UtopiaResponse $response, Document $user, Database $dbForProject, Event $queueForEvents, StatsUsage $queueForStatsUsage, TransactionState $transactionState, array $plan): void { $data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array @@ -122,9 +126,16 @@ class Upsert extends Action $permissions = Permission::aggregate($permissions, $allowedPermissions); + $collectionTableId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); + // If no permission, upsert permission from the old document if present (update scenario) else add default permission (create scenario) if (\is_null($permissions)) { - $oldDocument = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId)); + if ($transactionId !== null) { + // Use transaction-aware document retrieval to see changes from same transaction + $oldDocument = $transactionState->getDocument($collectionTableId, $documentId, $transactionId); + } else { + $oldDocument = Authorization::skip(fn () => $dbForProject->getDocument($collectionTableId, $documentId)); + } if ($oldDocument->isEmpty()) { if (!empty($user->getId())) { $defaultPermissions = []; @@ -240,10 +251,73 @@ class Upsert extends Action ->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $operations)) ->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations)); + // Handle transaction staging + if ($transactionId !== null) { + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + if ($transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::TRANSACTION_NOT_READY); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + // Enforce max operations per transaction + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + if (($existing + 1) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding 1 would exceed the maximum of ' . $maxBatch + ); + } + + // Stage the operation in transaction logs + $staged = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'documentId' => $documentId, + 'action' => 'upsert', + 'data' => $data, + ]); + + $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged) { + $dbForProject->createDocument('transactionLogs', $staged); + $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + 1 + ); + }); + + // Return successful response without actually upserting document + $groupId = $this->getGroupId(); + $mockDocument = new Document([ + '$id' => $documentId, + '$' . $groupId => $collectionId, + '$databaseId' => $databaseId, + ...$data + ]); + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_CREATED) + ->dynamic($mockDocument, $this->getResponseModel()); + return; + } + $upserted = []; try { $dbForProject->withPreserveDates(function () use (&$upserted, $dbForProject, $database, $collection, $newDocument) { - return $dbForProject->createOrUpdateDocuments( + return $dbForProject->upsertDocuments( 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), [$newDocument], onNext: function (Document $document) use (&$upserted) { @@ -264,7 +338,12 @@ class Upsert extends Action $collectionsCache = []; if (empty($upserted[0])) { - $upserted[0] = $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId); + if ($transactionId !== null) { + // For transactions, get the document with transaction changes applied + $upserted[0] = $transactionState->getDocument($collectionTableId, $documentId, $transactionId); + } else { + $upserted[0] = $dbForProject->getDocument($collectionTableId, $documentId); + } } $document = $upserted[0]; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php index 546cbeddd4..a30fed47ed 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documents; use Appwrite\Auth\Auth; +use Appwrite\Databases\TransactionState; use Appwrite\Event\StatsUsage; use Appwrite\Extend\Exception; use Appwrite\SDK\AuthType; @@ -45,8 +46,8 @@ class XList extends Action ->label('scope', 'documents.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/list-documents.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -65,13 +66,15 @@ class XList extends Action ->param('databaseId', '', new UID(), 'Database ID.') ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID to read uncommitted changes within the transaction.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') + ->inject('transactionState') ->callback($this->action(...)); } - public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage): void + public function action(string $databaseId, string $collectionId, array $queries, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, StatsUsage $queueForStatsUsage, TransactionState $transactionState): void { $isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); @@ -121,17 +124,22 @@ class XList extends Action try { $selectQueries = Query::groupByType($queries)['selections'] ?? []; + $collectionTableId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); - if (! empty($selectQueries)) { + // Use transaction-aware document retrieval if transactionId is provided + if ($transactionId !== null) { + $documents = $transactionState->listDocuments($collectionTableId, $transactionId, $queries); + $total = $transactionState->countDocuments($collectionTableId, $transactionId, $queries); + } elseif (! empty($selectQueries)) { // has selects, allow relationship on documents - $documents = $dbForProject->find('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries); + $documents = $dbForProject->find($collectionTableId, $queries); + $total = $dbForProject->count($collectionTableId, $queries, APP_LIMIT_COUNT); } else { // has no selects, disable relationship loading on documents /* @type Document[] $documents */ - $documents = $dbForProject->skipRelationships(fn () => $dbForProject->find('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries)); + $documents = $dbForProject->skipRelationships(fn () => $dbForProject->find($collectionTableId, $queries)); + $total = $dbForProject->count($collectionTableId, $queries, APP_LIMIT_COUNT); } - - $total = $dbForProject->count('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries, APP_LIMIT_COUNT); } catch (OrderException $e) { $documents = $this->isCollectionsAPI() ? 'documents' : 'rows'; $attribute = $this->isCollectionsAPI() ? 'attribute' : 'column'; @@ -161,7 +169,7 @@ class XList extends Action $response->dynamic(new Document([ 'total' => $total, // rows or documents - $this->getSdkGroup() => $documents, + $this->getSDKGroup() => $documents, ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php index af4b6bf733..89739570c7 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php @@ -37,7 +37,7 @@ class Get extends Action ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( namespace: 'databases', - group: $this->getSdkGroup(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/get-collection.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php index f136fdd29b..400d716e41 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php @@ -52,7 +52,7 @@ abstract class Action extends UtopiaAction /** * Get the SDK group name for the current action. */ - final protected function getSdkGroup(): string + final protected function getSDKGroup(): string { return 'indexes'; } @@ -60,7 +60,7 @@ abstract class Action extends UtopiaAction /** * Get the SDK namespace for the current action. */ - final protected function getSdkNamespace(): string + final protected function getSDKNamespace(): string { return $this->isCollectionsAPI() ? 'databases' : 'tablesDB'; } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php index 733259f091..9fb438d577 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php @@ -51,8 +51,8 @@ class Create extends Action ->label('audits.event', 'index.create') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/create-index.md', auth: [AuthType::KEY], @@ -160,7 +160,7 @@ class Create extends Action throw new Exception($this->getParentInvalidTypeException(), "Cannot create an index for a relationship $contextType: " . $oldAttributes[$attributeIndex]['key']); } - // ensure attribute is available + // Ensure attribute is available if ($attributeStatus !== 'available') { $contextType = ucfirst($contextType); throw new Exception($this->getParentNotAvailableException(), "$contextType not available: " . $oldAttributes[$attributeIndex]['key']); @@ -171,7 +171,7 @@ class Create extends Action } if ($attributeArray === true) { - $lengths[$i] = Database::ARRAY_INDEX_LENGTH; + $lengths[$i] = Database::MAX_ARRAY_INDEX_LENGTH; $orders[$i] = null; } } @@ -190,21 +190,18 @@ class Create extends Action 'orders' => $orders, ]); - $maxIndexLength = $dbForProject->getAdapter()->getMaxIndexLength(); - $internalIndexesKeys = $dbForProject->getAdapter()->getInternalIndexesKeys(); - $supportForIndexArray = $dbForProject->getAdapter()->getSupportForIndexArray(); - $supportForSpatialAttributes = $dbForProject->getAdapter()->getSupportForSpatialAttributes(); - $supportForSpatialIndexNull = $dbForProject->getAdapter()->getSupportForSpatialIndexNull(); - $supportForSpatialIndexOrder = $dbForProject->getAdapter()->getSupportForSpatialIndexOrder(); - $validator = new IndexValidator( $collection->getAttribute('attributes'), - $maxIndexLength, - $internalIndexesKeys, - $supportForIndexArray, - $supportForSpatialAttributes, - $supportForSpatialIndexNull, - $supportForSpatialIndexOrder + $collection->getAttribute('indexes'), + $dbForProject->getAdapter()->getMaxIndexLength(), + $dbForProject->getAdapter()->getInternalIndexesKeys(), + $dbForProject->getAdapter()->getSupportForIndexArray(), + $dbForProject->getAdapter()->getSupportForSpatialIndexNull(), + $dbForProject->getAdapter()->getSupportForSpatialIndexOrder(), + $dbForProject->getAdapter()->getSupportForVectors(), + $dbForProject->getAdapter()->getSupportForAttributes(), + $dbForProject->getAdapter()->getSupportForMultipleFulltextIndexes(), + $dbForProject->getAdapter()->getSupportForIdenticalIndexes() ); if (!$validator->isValid($index)) { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Delete.php index 9ba4c98046..2bccfdfb52 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Delete.php @@ -46,8 +46,8 @@ class Delete extends Action ->label('audits.event', 'index.delete') ->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/delete-index.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Get.php index 9e05cc79c7..3d118d1922 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Get.php @@ -37,8 +37,8 @@ class Get extends Action ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/get-index.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/XList.php index c0aa9457e7..60e52f883a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/XList.php @@ -42,8 +42,8 @@ class XList extends Action ->label('scope', 'collections.read') ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/list-indexes.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php index 1309793234..b202120bad 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Logs/XList.php @@ -49,7 +49,7 @@ class XList extends Action ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( namespace: 'databases', - group: $this->getSdkGroup(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/get-collection-logs.md', auth: [AuthType::ADMIN], @@ -104,11 +104,7 @@ class XList extends Action $audit = new Audit($dbForProject); $context = $this->getContext(); - $resource = match ($context) { - TABLES => "database/$databaseId/grid/$context/$collectionId", - default => "database/$databaseId/$context/$collectionId", - }; - + $resource = "database/$databaseId/$context/$collectionId"; $logs = $audit->getLogsByResource($resource, $queries); $output = []; diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php index 5bf740d7d1..49870002ce 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php @@ -45,7 +45,7 @@ class Update extends Action ->label('audits.resource', 'database/{request.databaseId}/collections/{request.collectionId}') ->label('sdk', new Method( namespace: 'databases', - group: $this->getSdkGroup(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/update-collection.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php index f2f7a2233a..b4cc5470d9 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php @@ -44,7 +44,7 @@ class XList extends Action ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( namespace: 'databases', - group: $this->getSdkGroup(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/databases/list-collections.md', auth: [AuthType::KEY], @@ -121,7 +121,7 @@ class XList extends Action $response->dynamic(new Document([ 'total' => $total, - $this->getSdkGroup() => $collections, + $this->getSDKGroup() => $collections, ]), $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Action.php new file mode 100644 index 0000000000..8915ae6141 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Action.php @@ -0,0 +1,66 @@ +context = TABLES; + } + return parent::setHttpPath($path); + } + + /** + * Get the current API context. + */ + protected function getContext(): string + { + return $this->context; + } + + /** + * Determine if the current action is for the Collections API. + */ + protected function isCollectionsAPI(): bool + { + return $this->getContext() === COLLECTIONS; + } + + /** + * Get the key used in event parameters (e.g., 'collectionId' or 'tableId'). + */ + protected function getGroupId(): string + { + return $this->getContext() . 'Id'; + } + + /** + * Get the resource type for the current action (either 'document' or 'row'). + */ + protected function getResource(): string + { + return $this->isCollectionsAPI() ? 'document' : 'row'; + } + + /** + * Get the resource ID key for the current action. + */ + protected function getResourceId(): string + { + return $this->getResource() . 'Id'; + } + + protected function getAttributeKey(): string + { + return $this->isCollectionsAPI() ? 'attribute' : 'column'; + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Create.php new file mode 100644 index 0000000000..c4c5bf8b51 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Create.php @@ -0,0 +1,88 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_POST) + ->setHttpPath('/v1/databases/transactions') + ->desc('Create transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', 'documents.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'databases', + group: 'transactions', + name: 'createTransaction', + description: '/docs/references/databases/create-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_CREATED, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('ttl', APP_DATABASE_TXN_TTL_DEFAULT, new Range(min: APP_DATABASE_TXN_TTL_MIN, max: APP_DATABASE_TXN_TTL_MAX), 'Seconds before the transaction expires.', true) + ->inject('response') + ->inject('dbForProject') + ->inject('user') + ->callback($this->action(...)); + } + + public function action(int $ttl, UtopiaResponse $response, Database $dbForProject, Document $user): void + { + $permissions = []; + if (!empty($user->getId())) { + $allowedPermissions = [ + Database::PERMISSION_READ, + Database::PERMISSION_UPDATE, + Database::PERMISSION_DELETE, + ]; + + foreach ($allowedPermissions as $permission) { + $permissions[] = (new Permission($permission, 'user', $user->getId()))->toString(); + } + } + + $transaction = Authorization::skip(fn () => $dbForProject->createDocument('transactions', new Document([ + '$id' => ID::unique(), + '$permissions' => $permissions, + 'status' => 'pending', + 'operations' => 0, + 'expiresAt' => DateTime::addSeconds(new \DateTime(), $ttl), + ]))); + + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_CREATED) + ->dynamic($transaction, UtopiaResponse::MODEL_TRANSACTION); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Delete.php new file mode 100644 index 0000000000..a5d2562572 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Delete.php @@ -0,0 +1,74 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) + ->setHttpPath('/v1/databases/transactions/:transactionId') + ->desc('Delete transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', 'documents.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'databases', + group: 'transactions', + name: 'deleteTransaction', + description: '/docs/references/databases/delete-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_NOCONTENT, + model: UtopiaResponse::MODEL_NONE, + ) + ], + contentType: ContentType::NONE + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->inject('response') + ->inject('dbForProject') + ->inject('queueForDeletes') + ->callback($this->action(...)); + } + + public function action(string $transactionId, UtopiaResponse $response, Database $dbForProject, DeleteEvent $queueForDeletes): void + { + $transaction = $dbForProject->getDocument('transactions', $transactionId); + + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + + $dbForProject->deleteDocument('transactions', $transactionId); + + $queueForDeletes + ->setType(DELETE_TYPE_DOCUMENT) + ->setDocument($transaction); + + $response->noContent(); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Get.php new file mode 100644 index 0000000000..1d4d22baa1 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Get.php @@ -0,0 +1,68 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_GET) + ->setHttpPath('/v1/databases/transactions/:transactionId') + ->desc('Get transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', 'rows.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'databases', + group: 'transactions', + name: 'getTransaction', + description: '/docs/references/databases/get-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_OK, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->inject('response') + ->inject('dbForProject') + ->callback($this->action(...)); + } + + public function action(string $transactionId, UtopiaResponse $response, Database $dbForProject): void + { + $transaction = $dbForProject->getDocument('transactions', $transactionId); + + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_OK) + ->dynamic($transaction, UtopiaResponse::MODEL_TRANSACTION); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Operations/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Operations/Create.php new file mode 100644 index 0000000000..bd94c1c7eb --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Operations/Create.php @@ -0,0 +1,247 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_POST) + ->setHttpPath('/v1/databases/transactions/:transactionId/operations') + ->desc('Create operations') + ->groups(['api', 'database', 'transactions']) + ->label('scope', 'documents.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'databases', + group: 'transactions', + name: 'createOperations', + description: '/docs/references/databases/create-operations.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_CREATED, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->param('operations', [], new ArrayList(new Operation(type: 'legacy')), 'Array of staged operations.', true) + ->inject('response') + ->inject('dbForProject') + ->inject('transactionState') + ->inject('plan') + ->callback($this->action(...)); + } + + public function action(string $transactionId, array $operations, UtopiaResponse $response, Database $dbForProject, TransactionState $transactionState, array $plan): void + { + if (empty($operations)) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Operations array cannot be empty'); + } + + $isAPIKey = Auth::isAppUser(Authorization::getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + + // API keys and admins can read any transaction, regular users need permissions + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + if ($transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid or non‑pending transaction'); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + $maxBatch = $plan['databasesTransactionSize'] ?? APP_LIMIT_DATABASE_TRANSACTION; + $existing = $transaction->getAttribute('operations', 0); + + if (($existing + \count($operations)) > $maxBatch) { + throw new Exception( + Exception::TRANSACTION_LIMIT_EXCEEDED, + 'Transaction already has ' . $existing . ' operations, adding ' . \count($operations) . ' would exceed the maximum of ' . $maxBatch + ); + } + + $databases = $collections = $staged = $dependants = []; + foreach ($operations as $operation) { + if (!$isAPIKey && !$isPrivilegedUser && \in_array($operation['action'], [ + 'bulkCreate', + 'bulkUpdate', + 'bulkUpsert', + 'bulkDelete' + ])) { + throw new Exception(Exception::USER_UNAUTHORIZED); + } + + $database = $databases[$operation['databaseId']] ??= Authorization::skip(fn () => $dbForProject->getDocument('databases', $operation['databaseId'])); + if ($database->isEmpty() || (!$database->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { + throw new Exception(Exception::DATABASE_NOT_FOUND); + } + + $collection = $collections[$operation[$this->getGroupId()]] ??= + Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $operation[$this->getGroupId()])); + + if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); + } + + if (\in_array($operation['action'], ['bulkCreate', 'bulkUpdate', 'bulkUpsert', 'bulkDelete'])) { + $hasRelationships = \array_filter( + $collection->getAttribute('attributes', []), + fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP + ); + if ($hasRelationships) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Bulk operations are not supported for ' . $this->getGroupId() . ' with relationship attributes'); + } + } + + // For update, upsert, delete, increment, decrement, check document existence first + $document = null; + if (\in_array($operation['action'], ['update', 'delete', 'upsert', 'increment', 'decrement'])) { + $documentId = $operation[$this->getResourceId()] ?? null; + if (empty($documentId)) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Document ID is required for ' . $operation['action'] . ' operations'); + } + + $collectionKey = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); + $isDependant = isset($dependants[$collectionKey][$documentId]); + + $document = $transactionState->getDocument($collectionKey, $documentId, $transactionId); + if ($document->isEmpty() && !$isDependant && $operation['action'] !== 'upsert') { + throw new Exception(Exception::DOCUMENT_NOT_FOUND); + } + } + + // Bulk operations skip permission validation entirely (API key/admin only, already checked above) + if (!\in_array($operation['action'], ['bulkCreate', 'bulkUpdate', 'bulkUpsert', 'bulkDelete'])) { + $permissionType = match ($operation['action']) { + 'create' => Database::PERMISSION_CREATE, + 'update', 'increment', 'decrement' => Database::PERMISSION_UPDATE, + 'delete' => Database::PERMISSION_DELETE, + 'upsert' => ($document && !$document->isEmpty()) ? Database::PERMISSION_UPDATE : Database::PERMISSION_CREATE, + default => throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Invalid action: ' . $operation['action']) + }; + + // For individual operations, enforce permissions unless using API key/admin + if (!$isAPIKey && !$isPrivilegedUser) { + $documentSecurity = $collection->getAttribute('documentSecurity', false); + $validator = new Authorization($permissionType); + $collectionValid = $validator->isValid($collection->getPermissionsByType($permissionType)); + $documentValid = false; + if ($document !== null && !$document->isEmpty() && $documentSecurity) { + if ($permissionType === Database::PERMISSION_UPDATE) { + $documentValid = $validator->isValid($document->getUpdate()); + } elseif ($permissionType === Database::PERMISSION_DELETE) { + $documentValid = $validator->isValid($document->getDelete()); + } + } + + if ($permissionType === Database::PERMISSION_CREATE || !$documentSecurity) { + if (!$collectionValid) { + throw new Exception(Exception::USER_UNAUTHORIZED); + } + } else { + if (!$collectionValid && !$documentValid) { + throw new Exception(Exception::USER_UNAUTHORIZED); + } + } + + // Users can only set permissions for roles they have + if (isset($operation['data']['$permissions'])) { + $permissions = $operation['data']['$permissions']; + $roles = Authorization::getRoles(); + foreach (Database::PERMISSIONS as $type) { + foreach ($permissions as $permission) { + $permission = Permission::parse($permission); + if ($permission->getPermission() != $type) { + continue; + } + $role = (new Role( + $permission->getRole(), + $permission->getIdentifier(), + $permission->getDimension() + ))->toString(); + if (!Authorization::isRole($role)) { + throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')'); + } + } + } + } + } + } + + $staged[] = new Document([ + '$id' => ID::unique(), + 'databaseInternalId' => $database->getSequence(), + 'collectionInternalId' => $collection->getSequence(), + 'transactionInternalId' => $transaction->getSequence(), + 'documentId' => $operation[$this->getResourceId()] ?? null, + 'action' => $operation['action'], + 'data' => $operation['data'] ?? [], + ]); + + // Track create operations for dependent update/increment/decrement/delete operations in same batch + if ($operation['action'] === 'create') { + $collectionKey = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); + $documentId = $operation[$this->getResourceId()] ?? null; + if ($documentId) { + $dependants[$collectionKey][$documentId] = true; + } + } + } + + $transaction = Authorization::skip(fn () => $dbForProject->withTransaction(function () use ($dbForProject, $transactionId, $staged, $existing, $operations) { + $dbForProject->createDocuments('transactionLogs', $staged); + return $dbForProject->increaseDocumentAttribute( + 'transactions', + $transactionId, + 'operations', + \count($operations) + ); + })); + + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_CREATED) + ->dynamic($transaction, UtopiaResponse::MODEL_TRANSACTION); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php new file mode 100644 index 0000000000..6e2bd63827 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/Update.php @@ -0,0 +1,878 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) + ->setHttpPath('/v1/databases/transactions/:transactionId') + ->desc('Update transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', 'documents.write') + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'databases', + group: 'transactions', + name: 'updateTransaction', + description: '/docs/references/databases/update-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_OK, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->param('commit', false, new Boolean(), 'Commit transaction?', true) + ->param('rollback', false, new Boolean(), 'Rollback transaction?', true) + ->inject('response') + ->inject('dbForProject') + ->inject('user') + ->inject('transactionState') + ->inject('queueForDeletes') + ->inject('queueForEvents') + ->inject('queueForStatsUsage') + ->inject('queueForRealtime') + ->inject('queueForFunctions') + ->inject('queueForWebhooks') + ->callback($this->action(...)); + } + + /** + * @param string $transactionId + * @param bool $commit + * @param bool $rollback + * @param UtopiaResponse $response + * @param Database $dbForProject + * @param Document $user + * @param TransactionState $transactionState + * @param Delete $queueForDeletes + * @param Event $queueForEvents + * @param StatsUsage $queueForStatsUsage + * @param Event $queueForRealtime + * @param Event $queueForFunctions + * @param Event $queueForWebhooks + * @return void + * @throws ConflictException + * @throws Exception + * @throws \Throwable + * @throws \Utopia\Database\Exception + * @throws Authorization + * @throws Structure + * @throws \Utopia\Exception + */ + public function action(string $transactionId, bool $commit, bool $rollback, UtopiaResponse $response, Database $dbForProject, Document $user, TransactionState $transactionState, Delete $queueForDeletes, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks): void + { + if (!$commit && !$rollback) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Either commit or rollback must be true'); + } + if ($commit && $rollback) { + throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Cannot commit and rollback at the same time'); + } + + $isAPIKey = Auth::isAppUser(Authorization::getRoles()); + $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); + + $transaction = ($isAPIKey || $isPrivilegedUser) + ? Authorization::skip(fn () => $dbForProject->getDocument('transactions', $transactionId)) + : $dbForProject->getDocument('transactions', $transactionId); + if ($transaction->isEmpty()) { + throw new Exception(Exception::TRANSACTION_NOT_FOUND); + } + if ($transaction->getAttribute('status', '') !== 'pending') { + throw new Exception(Exception::TRANSACTION_NOT_READY); + } + + $now = new \DateTime(); + $expiresAt = new \DateTime($transaction->getAttribute('expiresAt', 'now')); + if ($now > $expiresAt) { + throw new Exception(Exception::TRANSACTION_EXPIRED); + } + + if ($commit) { + + $operations = []; + $totalOperations = 0; + $databaseOperations = []; + + try { + $dbForProject->withTransaction(function () use ($dbForProject, $transactionState, $queueForDeletes, $transactionId, &$transaction, &$operations, &$totalOperations, &$databaseOperations, $queueForEvents, $queueForStatsUsage, $queueForRealtime, $queueForFunctions, $queueForWebhooks) { + Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([ + 'status' => 'committing', + ]))); + + $operations = Authorization::skip(fn () => $dbForProject->find('transactionLogs', [ + Query::equal('transactionInternalId', [$transaction->getSequence()]), + Query::orderAsc(), + Query::limit(PHP_INT_MAX), + ])); + + $state = []; + + foreach ($operations as $operation) { + $databaseInternalId = $operation['databaseInternalId']; + $collectionInternalId = $operation['collectionInternalId']; + $collectionId = "database_{$databaseInternalId}_collection_{$collectionInternalId}"; + $documentId = $operation['documentId']; + $createdAt = new \DateTime($operation['$createdAt']); + $action = $operation['action']; + $data = $operation['data']; + + if ($action === 'delete' && $documentId && empty($data)) { + $doc = $dbForProject->getDocument($collectionId, $documentId); + if (!$doc->isEmpty()) { + $operation['data'] = $doc->getArrayCopy(); + $data = $operation['data']; + } + } + + if (!\in_array($action, ['bulkCreate', 'bulkUpdate', 'bulkUpsert', 'bulkDelete'])) { + $totalOperations++; + $databaseOperations[$databaseInternalId] = ($databaseOperations[$databaseInternalId] ?? 0) + 1; + } + + if ($data instanceof Document) { + $data = $data->getArrayCopy(); + } + + switch ($action) { + case 'create': + $this->handleCreateOperation($dbForProject, $collectionId, $documentId, $data, $createdAt, $state); + break; + case 'update': + $this->handleUpdateOperation($dbForProject, $collectionId, $documentId, $data, $createdAt, $state); + break; + case 'upsert': + $this->handleUpsertOperation($dbForProject, $collectionId, $documentId, $data, $createdAt, $state); + break; + case 'delete': + $this->handleDeleteOperation($dbForProject, $collectionId, $documentId, $createdAt, $state); + break; + case 'increment': + $this->handleIncrementOperation($dbForProject, $collectionId, $documentId, $data, $createdAt, $state); + break; + case 'decrement': + $this->handleDecrementOperation($dbForProject, $collectionId, $documentId, $data, $createdAt, $state); + break; + case 'bulkCreate': + $count = $this->handleBulkCreateOperation($dbForProject, $collectionId, $data, $createdAt, $state); + $totalOperations += $count; + $databaseOperations[$databaseInternalId] = ($databaseOperations[$databaseInternalId] ?? 0) + $count; + break; + case 'bulkUpdate': + $count = $this->handleBulkUpdateOperation($dbForProject, $transactionState, $collectionId, $data, $createdAt, $state); + $totalOperations += $count; + $databaseOperations[$databaseInternalId] = ($databaseOperations[$databaseInternalId] ?? 0) + $count; + break; + case 'bulkUpsert': + $count = $this->handleBulkUpsertOperation($dbForProject, $transactionState, $collectionId, $data, $createdAt, $state); + $totalOperations += $count; + $databaseOperations[$databaseInternalId] = ($databaseOperations[$databaseInternalId] ?? 0) + $count; + break; + case 'bulkDelete': + $count = $this->handleBulkDeleteOperation($dbForProject, $transactionState, $collectionId, $data, $createdAt, $state); + $totalOperations += $count; + $databaseOperations[$databaseInternalId] = ($databaseOperations[$databaseInternalId] ?? 0) + $count; + break; + } + } + + $transaction = Authorization::skip(fn () => $dbForProject->updateDocument( + 'transactions', + $transactionId, + new Document(['status' => 'committed']) + )); + + $queueForDeletes + ->setType(DELETE_TYPE_DOCUMENT) + ->setDocument($transaction); + }); + + } catch (NotFoundException $e) { + Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([ + 'status' => 'failed', + ]))); + throw new Exception(Exception::DOCUMENT_NOT_FOUND, previous: $e); + } catch (DuplicateException|ConflictException $e) { + Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([ + 'status' => 'failed', + ]))); + throw new Exception(Exception::TRANSACTION_CONFLICT, previous: $e); + } catch (StructureException $e) { + Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([ + 'status' => 'failed', + ]))); + throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage()); + } catch (LimitException $e) { + Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([ + 'status' => 'failed', + ]))); + throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED, $e->getMessage()); + } catch (TransactionException $e) { + Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([ + 'status' => 'failed', + ]))); + throw new Exception(Exception::TRANSACTION_FAILED, $e->getMessage()); + } catch (QueryException $e) { + Authorization::skip(fn () => $dbForProject->updateDocument('transactions', $transactionId, new Document([ + 'status' => 'failed', + ]))); + throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); + } + + $queueForStatsUsage + ->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, $totalOperations); + + foreach ($databaseOperations as $sequence => $count) { + $queueForStatsUsage->addMetric( + str_replace('{databaseInternalId}', $sequence, METRIC_DATABASE_ID_OPERATIONS_WRITES), + $count + ); + } + + foreach ($operations as $operation) { + $databaseInternalId = $operation['databaseInternalId']; + $collectionInternalId = $operation['collectionInternalId']; + $collectionId = "database_{$databaseInternalId}_collection_{$collectionInternalId}"; + $action = $operation['action']; + $documentId = $operation['documentId']; + $data = $operation['data']; + + if ($data instanceof Document) { + $data = $data->getArrayCopy(); + } + + $database = Authorization::skip(fn () => $dbForProject->findOne('databases', [ + Query::equal('$sequence', [$databaseInternalId]) + ])); + + $collection = Authorization::skip(fn () => $dbForProject->findOne('database_' . $databaseInternalId, [ + Query::equal('$sequence', [$collectionInternalId]) + ])); + + $groupId = $this->getGroupId(); + $resourceId = $this->getResourceId(); + $contextKey = $this->getContext(); + $resource = $this->getResource(); + $resourcePlural = $resource . 's'; + + $queueForEvents + ->setParam('databaseId', $database->getId()) + ->setContext('database', $database) + ->setParam('collectionId', $collection->getId()) + ->setParam('tableId', $collection->getId()) + ->setContext($contextKey, $collection); + + $eventAction = ''; + $documentsToTrigger = []; + + switch ($action) { + case 'create': + $eventAction = 'create'; + $docId = $documentId ?? $data['$id'] ?? null; + if ($docId) { + $doc = $dbForProject->getDocument($collectionId, $docId); + if (!$doc->isEmpty()) { + $documentsToTrigger[] = $doc; + } + } + break; + case 'update': + case 'increment': + case 'decrement': + $eventAction = 'update'; + if ($documentId) { + $doc = $dbForProject->getDocument($collectionId, $documentId); + if (!$doc->isEmpty()) { + $documentsToTrigger[] = $doc; + } + } + break; + case 'delete': + $eventAction = 'delete'; + if ($documentId && !empty($data)) { + $documentsToTrigger[] = new Document(array_merge($data, ['$id' => $documentId])); + } + break; + case 'upsert': + $eventAction = 'update'; + $docId = $documentId ?? $data['$id'] ?? null; + if ($docId) { + $doc = $dbForProject->getDocument($collectionId, $docId); + if (!$doc->isEmpty()) { + $documentsToTrigger[] = $doc; + } + } + break; + case 'bulkCreate': + case 'bulkUpdate': + case 'bulkUpsert': + case 'bulkDelete': + break; + } + + $eventString = "databases.[databaseId].{$contextKey}s.[{$groupId}].{$resourcePlural}.[{$resourceId}]." . $eventAction; + + $queueForEvents->setEvent($eventString); + + foreach ($documentsToTrigger as $doc) { + $payload = $doc->getArrayCopy(); + $payload['$tableId'] = $collection->getId(); + $payload['$collectionId'] = $collection->getId(); + + $queueForEvents + ->setParam('documentId', $doc->getId()) + ->setParam('rowId', $doc->getId()) + ->setPayload($payload); + + $queueForRealtime->from($queueForEvents)->trigger(); + $queueForFunctions->from($queueForEvents)->trigger(); + $queueForWebhooks->from($queueForEvents)->trigger(); + } + + $queueForEvents->reset(); + $queueForRealtime->reset(); + $queueForFunctions->reset(); + $queueForWebhooks->reset(); + } + } + + if ($rollback) { + $transaction = Authorization::skip(fn () => $dbForProject->updateDocument( + 'transactions', + $transactionId, + new Document(['status' => 'failed']) + )); + + $queueForDeletes + ->setType(DELETE_TYPE_DOCUMENT) + ->setDocument($transaction); + } + + $response + ->setStatusCode(SwooleResponse::STATUS_CODE_OK) + ->dynamic($transaction, UtopiaResponse::MODEL_TRANSACTION); + } + + /** + * Handle create operation + * + * @param Database $dbForProject + * @param string $collectionId + * @param string|null $documentId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return void + * @throws \Utopia\Database\Exception + */ + private function handleCreateOperation( + Database $dbForProject, + string $collectionId, + ?string $documentId, + array $data, + \DateTime $createdAt, + array &$state + ): void { + if ($documentId && !isset($data['$id'])) { + $data['$id'] = $documentId; + } + $dbForProject->withRequestTimestamp($createdAt, function () use ($dbForProject, $collectionId, $data, &$state) { + $doc = $dbForProject->createDocument( + $collectionId, + new Document($data), + ); + $state[$collectionId][$doc->getId()] = $doc; + }); + } + + /** + * Handle update operation + * + * @param Database $dbForProject + * @param string $collectionId + * @param string $documentId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return void + * @throws ConflictException + * @throws \Utopia\Database\Exception + */ + private function handleUpdateOperation( + Database $dbForProject, + string $collectionId, + string $documentId, + array $data, + \DateTime $createdAt, + array &$state + ): void { + $dependent = isset($state[$collectionId][$documentId]); + + if ($dependent) { + $state[$collectionId][$documentId] = $dbForProject->updateDocument( + $collectionId, + $documentId, + new Document($data), + ); + return; + } + + $dbForProject->withRequestTimestamp($createdAt, function () use ($dbForProject, $collectionId, $documentId, $data, &$state) { + $document = $dbForProject->updateDocument( + $collectionId, + $documentId, + new Document($data), + ); + if ($document->isEmpty()) { + throw new NotFoundException(''); + } + $state[$collectionId][$documentId] = $document; + }); + } + + /** + * Handle upsert operation + * + * @param Database $dbForProject + * @param string $collectionId + * @param string|null $documentId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return void + * @throws \Utopia\Database\Exception + */ + private function handleUpsertOperation( + Database $dbForProject, + string $collectionId, + ?string $documentId, + array $data, + \DateTime $createdAt, + array &$state + ): void { + $dependent = isset($state[$collectionId][$documentId]); + + if ($dependent) { + // Merge partial upsert data with full document from transaction state + $existingDoc = $state[$collectionId][$documentId]; + foreach ($data as $key => $value) { + if ($key !== '$id') { + $existingDoc->setAttribute($key, $value); + } + } + + $state[$collectionId][$documentId] = $dbForProject->upsertDocument( + $collectionId, + $existingDoc, + ); + return; + } + + $dbForProject->withRequestTimestamp($createdAt, function () use ($dbForProject, $collectionId, $data, &$state) { + $doc = $dbForProject->upsertDocument( + $collectionId, + new Document($data), + ); + $state[$collectionId][$doc->getId()] = $doc; + }); + } + + /** + * Handle delete operation + * + * @param Database $dbForProject + * @param string $collectionId + * @param string $documentId + * @param \DateTime $createdAt + * @param array &$state + * @return void + * @throws \Utopia\Database\Exception + * @throws NotFoundException + */ + private function handleDeleteOperation( + Database $dbForProject, + string $collectionId, + string $documentId, + \DateTime $createdAt, + array &$state + ): void { + $dependent = isset($state[$collectionId][$documentId]); + + if ($dependent) { + $dbForProject->deleteDocument($collectionId, $documentId); + unset($state[$collectionId][$documentId]); + return; + } + + $dbForProject->withRequestTimestamp($createdAt, function () use ($dbForProject, $collectionId, $documentId, &$state) { + $deleted = $dbForProject->deleteDocument($collectionId, $documentId); + if (!$deleted) { + throw new NotFoundException(''); + } + if (isset($state[$collectionId][$documentId])) { + unset($state[$collectionId][$documentId]); + } + }); + } + + /** + * Get the attribute/column name from data, with fallback for cross-API compatibility + * + * @param array $data The operation data + * @return string The attribute/column name + */ + private function getAttributeNameFromData(array $data): string + { + $expectedKey = $this->getAttributeKey(); + if (isset($data[$expectedKey])) { + return $data[$expectedKey]; + } + + // Try the opposite key for cross-API compatibility + $fallbackKey = $expectedKey === 'attribute' ? 'column' : 'attribute'; + if (isset($data[$fallbackKey])) { + return $data[$fallbackKey]; + } + + return ''; + } + + /** + * Handle increment operation + * + * @param Database $dbForProject + * @param string $collectionId + * @param string $documentId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return void + * @throws ConflictException + * @throws \Utopia\Database\Exception + */ + private function handleIncrementOperation( + Database $dbForProject, + string $collectionId, + string $documentId, + array $data, + \DateTime $createdAt, + array &$state + ): void { + $dependent = isset($state[$collectionId][$documentId]); + $attribute = $this->getAttributeNameFromData($data); + + if ($dependent) { + $state[$collectionId][$documentId] = $dbForProject->increaseDocumentAttribute( + collection: $collectionId, + id: $documentId, + attribute: $attribute, + value: $data['value'] ?? 1, + max: $data['max'] ?? null + ); + return; + } + + $dbForProject->withRequestTimestamp($createdAt, function () use ($dbForProject, $collectionId, $documentId, $data, &$state, $attribute) { + $state[$collectionId][$documentId] = $dbForProject->increaseDocumentAttribute( + collection: $collectionId, + id: $documentId, + attribute: $attribute, + value: $data['value'] ?? 1, + max: $data['max'] ?? null + ); + }); + } + + /** + * Handle decrement operation + * + * @param Database $dbForProject + * @param string $collectionId + * @param string $documentId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return void + * @throws ConflictException + * @throws \Utopia\Database\Exception + */ + private function handleDecrementOperation( + Database $dbForProject, + string $collectionId, + string $documentId, + array $data, + \DateTime $createdAt, + array &$state + ): void { + $dependent = isset($state[$collectionId][$documentId]); + $attribute = $this->getAttributeNameFromData($data); + + if ($dependent) { + $state[$collectionId][$documentId] = $dbForProject->decreaseDocumentAttribute( + collection: $collectionId, + id: $documentId, + attribute: $attribute, + value: $data['value'] ?? 1, + min: $data['min'] ?? null + ); + return; + } + + $dbForProject->withRequestTimestamp($createdAt, function () use ($dbForProject, $collectionId, $documentId, $data, &$state, $attribute) { + $state[$collectionId][$documentId] = $dbForProject->decreaseDocumentAttribute( + collection: $collectionId, + id: $documentId, + attribute: $attribute, + value: $data['value'] ?? 1, + min: $data['min'] ?? null + ); + }); + } + + /** + * Handle bulk create operation + * + * @param Database $dbForProject + * @param string $collectionId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return int Number of documents created + * @throws \Utopia\Database\Exception + */ + private function handleBulkCreateOperation( + Database $dbForProject, + string $collectionId, + array $data, + \DateTime $createdAt, + array &$state + ): int { + $count = 0; + $dbForProject->withRequestTimestamp($createdAt, function () use ($dbForProject, $collectionId, $data, &$state, &$count) { + $documents = \array_map(function ($doc) { + return $doc instanceof Document ? $doc : new Document($doc); + }, $data); + + $count = $dbForProject->createDocuments( + $collectionId, + $documents, + onNext: function (Document $document) use (&$state, $collectionId) { + $state[$collectionId][$document->getId()] = $document; + } + ); + }); + return $count; + } + + /** + * Handle bulk update operation with manual timestamp checking + * + * @param Database $dbForProject + * @param TransactionState $transactionState + * @param string $collectionId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return int Number of documents updated + * @throws \Utopia\Database\Exception + * @throws \Utopia\Database\Exception\Query + * @throws ConflictException + */ + private function handleBulkUpdateOperation( + Database $dbForProject, + TransactionState $transactionState, + string $collectionId, + array $data, + \DateTime $createdAt, + array &$state + ): int { + $queries = Query::parseQueries($data['queries'] ?? []); + $updateData = new Document($data['data']); + + $dependentDocs = []; + + $transactionState->applyBulkUpdateToState($collectionId, $updateData, $queries, $state); + + // Clone the document before passing to updateDocuments to prevent mutation + // The database layer mutates the input document, which would corrupt transaction state + $count = $dbForProject->updateDocuments( + $collectionId, + clone $updateData, + $queries, + onNext: function (Document $updated, Document $old) use (&$state, $collectionId, $createdAt, &$dependentDocs) { + $dependent = isset($state[$collectionId][$updated->getId()]); + + if ($dependent) { + $dependentDocs[] = $updated->getId(); + } else { + $oldUpdatedAt = new \DateTime($old->getUpdatedAt()); + if ($oldUpdatedAt > $createdAt) { + throw new ConflictException('Document was updated after the request timestamp'); + } + $state[$collectionId][$updated->getId()] = $updated; + } + } + ); + + // Re-write dependent documents from state to database to fix partial updates + if (!empty($dependentDocs)) { + $documentsToRewrite = []; + foreach ($dependentDocs as $docId) { + if (isset($state[$collectionId][$docId])) { + $documentsToRewrite[] = $state[$collectionId][$docId]; + } + } + + if (!empty($documentsToRewrite)) { + $dbForProject->upsertDocuments( + $collectionId, + $documentsToRewrite, + onNext: function (Document $upserted) use (&$state, $collectionId) { + $state[$collectionId][$upserted->getId()] = $upserted; + } + ); + } + } + + return $count; + } + + /** + * Handle bulk upsert operation with manual timestamp checking + * + * @param Database $dbForProject + * @param TransactionState $transactionState + * @param string $collectionId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return int Number of documents upserted + * @throws ConflictException + * @throws \Utopia\Database\Exception + */ + private function handleBulkUpsertOperation( + Database $dbForProject, + TransactionState $transactionState, + string $collectionId, + array $data, + \DateTime $createdAt, + array &$state + ): int { + $documents = \array_map(function ($doc) { + return $doc instanceof Document ? $doc : new Document($doc); + }, $data); + + $mergedDocuments = $transactionState->applyBulkUpsertToState($collectionId, $documents, $state); + + $count = $dbForProject->upsertDocuments( + $collectionId, + $mergedDocuments, + onNext: function (Document $upserted, ?Document $old) use (&$state, $collectionId, $createdAt) { + if ($old !== null) { + $dependent = isset($state[$collectionId][$upserted->getId()]); + + if (!$dependent) { + $oldUpdatedAt = new \DateTime($old->getUpdatedAt()); + if ($oldUpdatedAt > $createdAt) { + throw new ConflictException('Document was updated after the request timestamp'); + } + } + } + + $state[$collectionId][$upserted->getId()] = $upserted; + } + ); + + return $count; + } + + /** + * Handle bulk delete operation with manual timestamp checking + * + * @param Database $dbForProject + * @param TransactionState $transactionState + * @param string $collectionId + * @param array $data + * @param \DateTime $createdAt + * @param array &$state + * @return int Number of documents deleted + * @throws \Utopia\Database\Exception\Query + * @throws ConflictException + * @throws \Utopia\Database\Exception + */ + private function handleBulkDeleteOperation( + Database $dbForProject, + TransactionState $transactionState, + string $collectionId, + array $data, + \DateTime $createdAt, + array &$state + ): int { + $queries = Query::parseQueries($data['queries'] ?? []); + + $count = $dbForProject->deleteDocuments( + $collectionId, + $queries, + onNext: function (Document $deleted, Document $old) use (&$state, $collectionId, $createdAt) { + $dependent = isset($state[$collectionId][$deleted->getId()]); + + if (!$dependent) { + $oldUpdatedAt = new \DateTime($old->getUpdatedAt()); + if ($oldUpdatedAt > $createdAt) { + throw new ConflictException('Document was updated after the transaction operation'); + } + } + + if (isset($state[$collectionId][$deleted->getId()])) { + unset($state[$collectionId][$deleted->getId()]); + } + } + ); + + $transactionState->applyBulkDeleteToState($collectionId, $queries, $state); + + return $count; + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/XList.php new file mode 100644 index 0000000000..33c66b90c7 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Transactions/XList.php @@ -0,0 +1,72 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_GET) + ->setHttpPath('/v1/databases/transactions') + ->desc('List transactions') + ->groups(['api', 'database', 'transactions']) + ->label('scope', 'rows.read') + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'databases', + group: 'transactions', + name: 'listTransactions', + description: '/docs/references/databases/list-transactions.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_OK, + model: UtopiaResponse::MODEL_TRANSACTION_LIST, + ) + ], + contentType: ContentType::JSON + )) + ->param('queries', [], new Transactions(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries).', true) + ->inject('response') + ->inject('dbForProject') + ->callback($this->action(...)); + } + + public function action(array $queries, UtopiaResponse $response, Database $dbForProject): void + { + try { + $queries = Query::parseQueries($queries); + } catch (QueryException $e) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); + } + + $response->dynamic(new Document([ + 'transactions' => $dbForProject->find('transactions', $queries), + 'total' => $dbForProject->count('transactions', $queries), + ]), UtopiaResponse::MODEL_TRANSACTION_LIST); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Create.php index 5222d2e133..039964b2c6 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Create.php @@ -37,8 +37,8 @@ class Create extends BooleanCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-boolean-column.md', auth: [AuthType::KEY], @@ -50,7 +50,7 @@ class Create extends BooleanCreate ] )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Boolean(), 'Default value for column when not provided. Cannot be set when column is required.', true) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Update.php index 3c6ef50813..7df901a1cc 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Boolean/Update.php @@ -39,8 +39,8 @@ class Update extends BooleanUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-boolean-column.md', auth: [AuthType::KEY], @@ -53,7 +53,7 @@ class Update extends BooleanUpdate contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Boolean()), 'Default value for column when not provided. Cannot be set when column is required.') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Create.php index 9598278ffc..db5a3059f1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Create.php @@ -39,8 +39,8 @@ class Create extends DatetimeCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-datetime-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Update.php index d7b5ec2448..151422af75 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Datetime/Update.php @@ -41,8 +41,8 @@ class Update extends DatetimeUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-datetime-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Delete.php index 50a148ce19..26f4ffa898 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Delete.php @@ -38,8 +38,8 @@ class Delete extends AttributesDelete ->label('audits.event', 'column.delete') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/delete-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Create.php index e28a216fff..3a8d492e4e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Create.php @@ -38,8 +38,8 @@ class Create extends EmailCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-email-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Update.php index 0fb856acb9..4d32489357 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Email/Update.php @@ -40,8 +40,8 @@ class Update extends EmailUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-email-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Create.php index 5b9d89c7e9..68dc2f8e08 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Create.php @@ -40,8 +40,8 @@ class Create extends EnumCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-enum-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Update.php index 0c00e3f268..3b611a5fde 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Enum/Update.php @@ -42,8 +42,8 @@ class Update extends EnumUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-enum-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Create.php index 5967b00196..9fe6987cab 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Create.php @@ -38,8 +38,8 @@ class Create extends FloatCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-float-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Update.php index 9486b3a75c..023e2e834e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Float/Update.php @@ -40,8 +40,8 @@ class Update extends FloatUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-float-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Get.php index d536a7aaf2..c20ef58a39 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Get.php @@ -44,8 +44,8 @@ class Get extends AttributesGet ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/get-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Create.php index 325a9382e5..81ca8da81f 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Create.php @@ -38,8 +38,8 @@ class Create extends IPCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-ip-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Update.php index b9e6368307..0db95b0206 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/IP/Update.php @@ -40,8 +40,8 @@ class Update extends IPUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-ip-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Create.php index bd6fec3f53..dfca51a6c5 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Create.php @@ -38,8 +38,8 @@ class Create extends IntegerCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-integer-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Update.php index be92811d1b..a1568d069b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Integer/Update.php @@ -40,8 +40,8 @@ class Update extends IntegerUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-integer-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Create.php index f60d4dd5b8..4aa173707b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Create.php @@ -40,8 +40,8 @@ class Create extends LineCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-line-column.md', auth: [AuthType::KEY], @@ -53,7 +53,7 @@ class Create extends LineCreate ] )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Spatial(Database::VAR_LINESTRING)), '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.', true) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Update.php index 19c6df202d..d3823445a2 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Line/Update.php @@ -41,8 +41,8 @@ class Update extends LineUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-line-column.md', auth: [AuthType::KEY], @@ -55,7 +55,7 @@ class Update extends LineUpdate contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Spatial(Database::VAR_LINESTRING)), '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.', true) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Create.php index 47d97e8077..b8ae563def 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Create.php @@ -40,8 +40,8 @@ class Create extends PointCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-point-column.md', auth: [AuthType::KEY], @@ -53,7 +53,7 @@ class Create extends PointCreate ] )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for column when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when column is required.', true) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Update.php index 2e98bf2cf9..3c855e137c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Point/Update.php @@ -41,8 +41,8 @@ class Update extends PointUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-point-column.md', auth: [AuthType::KEY], @@ -55,7 +55,7 @@ class Update extends PointUpdate contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Spatial(Database::VAR_POINT)), 'Default value for column when not provided, array of two numbers [longitude, latitude], representing a single coordinate. Cannot be set when column is required.', true) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Create.php index 371d5f8fd5..e0a2cf32cd 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Create.php @@ -40,8 +40,8 @@ class Create extends PolygonCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-polygon-column.md', auth: [AuthType::KEY], @@ -53,7 +53,7 @@ class Create extends PolygonCreate ] )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Spatial(Database::VAR_POLYGON)), '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.', true) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Update.php index c5654b77d4..866bbaf8b0 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Polygon/Update.php @@ -41,8 +41,8 @@ class Update extends PolygonUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-polygon-column.md', auth: [AuthType::KEY], @@ -55,7 +55,7 @@ class Update extends PolygonUpdate contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TablesDB service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Spatial(Database::VAR_POLYGON)), '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.', true) diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Create.php index b6f9663f77..0a6c76d8c5 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Create.php @@ -39,8 +39,8 @@ class Create extends RelationshipCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-relationship-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Update.php index 421e11af91..b645454be1 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/Relationship/Update.php @@ -39,8 +39,8 @@ class Update extends RelationshipUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-relationship-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Create.php index 14f0c8321e..6fe9fd679c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Create.php @@ -40,8 +40,8 @@ class Create extends StringCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-string-column.md', auth: [AuthType::KEY], @@ -53,7 +53,7 @@ class Create extends StringCreate ] )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('size', null, new Range(1, APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH, Validator::TYPE_INTEGER), 'Column size for text columns, in number of characters.') ->param('required', null, new Boolean(), 'Is column required?') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Update.php index fc45557f3b..5ec9b78dda 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/String/Update.php @@ -42,8 +42,8 @@ class Update extends StringUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-string-column.md', auth: [AuthType::KEY], @@ -56,7 +56,7 @@ class Update extends StringUpdate contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Column Key.') ->param('required', null, new Boolean(), 'Is column required?') ->param('default', null, new Nullable(new Text(0, 0)), 'Default value for column when not provided. Cannot be set when column is required.') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Create.php index bc53ad5250..99ec36b721 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Create.php @@ -38,8 +38,8 @@ class Create extends URLCreate ->label('audits.event', 'column.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/create-url-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Update.php index 36bd7dc054..51168b0383 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/URL/Update.php @@ -40,8 +40,8 @@ class Update extends URLUpdate ->label('audits.event', 'column.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-url-column.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/XList.php index ca41bb024d..13bf3257e3 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Columns/XList.php @@ -33,8 +33,8 @@ class XList extends AttributesXList ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/list-columns.md', auth: [AuthType::KEY], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Create.php index 3965e12a74..4f62200d7c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Create.php @@ -40,7 +40,7 @@ class Create extends CollectionCreate ->label('audits.event', 'table.create') ->label('audits.resource', 'database/{request.databaseId}/table/{response.$id}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: 'tables', name: self::getName(), description: '/docs/references/tablesdb/create-table.md', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Delete.php index 9bfdf42cef..de068d5b29 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Delete.php @@ -36,7 +36,7 @@ class Delete extends CollectionDelete ->label('audits.event', 'table.delete') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: 'tables', name: self::getName(), description: '/docs/references/tablesdb/delete-table.md', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Get.php index a7d33478f7..be6ec5d9e7 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Get.php @@ -33,7 +33,7 @@ class Get extends CollectionGet ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: 'tables', name: self::getName(), description: '/docs/references/tablesdb/get-table.md', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Create.php index a2a5c8b453..3802ee32b8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Create.php @@ -42,8 +42,8 @@ class Create extends IndexCreate ->label('audits.event', 'index.create') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: 'createIndex', // getName needs to be different from parent action to avoid conflict in path name description: '/docs/references/tablesdb/create-index.md', auth: [AuthType::KEY], @@ -56,7 +56,7 @@ class Create extends IndexCreate contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', null, new Key(), 'Index Key.') ->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE, Database::INDEX_SPATIAL]), 'Index type.') ->param('columns', null, new ArrayList(new Key(true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of columns to index. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' columns are allowed, each 32 characters long.') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Delete.php index 586bad78f4..57ab466ee8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Delete.php @@ -41,8 +41,8 @@ class Delete extends IndexDelete ->label('audits.event', 'index.delete') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: 'deleteIndex', // getName needs to be different from parent action to avoid conflict in path name description: '/docs/references/tablesdb/delete-index.md', auth: [AuthType::KEY], @@ -55,7 +55,7 @@ class Delete extends IndexDelete contentType: ContentType::NONE )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new Key(), 'Index Key.') ->inject('response') ->inject('dbForProject') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Get.php index 3f2978b547..271d842631 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/Get.php @@ -34,8 +34,8 @@ class Get extends IndexGet ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: 'getIndex', // getName needs to be different from parent action to avoid conflict in path name description: '/docs/references/tablesdb/get-index.md', auth: [AuthType::KEY], @@ -48,7 +48,7 @@ class Get extends IndexGet contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', null, new Key(), 'Index Key.') ->inject('response') ->inject('dbForProject') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/XList.php index c275fd2771..041b4aa70c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Indexes/XList.php @@ -34,8 +34,8 @@ class XList extends IndexXList ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: 'listIndexes', // getName needs to be different from parent action to avoid conflict in path name description: '/docs/references/tablesdb/list-indexes.md', auth: [AuthType::KEY], @@ -48,7 +48,7 @@ class XList extends IndexXList contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', [], new Indexes(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following columns: ' . implode(', ', Indexes::ALLOWED_ATTRIBUTES), true) ->inject('response') ->inject('dbForProject') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php index 6d386df4f6..0680649544 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Logs/XList.php @@ -30,8 +30,8 @@ class XList extends CollectionLogXList ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/get-table-logs.md', auth: [AuthType::ADMIN], diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Delete.php index c9729d714d..86e9a48f63 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Delete.php @@ -40,8 +40,8 @@ class Delete extends DocumentsDelete ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/delete-rows.md', auth: [AuthType::ADMIN, AuthType::KEY], @@ -54,8 +54,9 @@ class Delete extends DocumentsDelete contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Update.php index 13778b9474..5005ab4f41 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Update.php @@ -41,8 +41,8 @@ class Update extends DocumentsUpdate ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-rows.md', auth: [AuthType::ADMIN, AuthType::KEY], @@ -58,6 +58,7 @@ class Update extends DocumentsUpdate ->param('tableId', '', new UID(), 'Table ID.') ->param('data', [], new JSON(), 'Row data as JSON object. Include only column and value pairs to be updated.', true) ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Upsert.php index 26c5c8030c..d0a1f08003 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Bulk/Upsert.php @@ -41,8 +41,8 @@ class Upsert extends DocumentsUpsert ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/upsert-rows.md', auth: [AuthType::ADMIN, AuthType::KEY], @@ -58,6 +58,7 @@ class Upsert extends DocumentsUpsert ->param('databaseId', '', new UID(), 'Database ID.') ->param('tableId', '', new UID(), 'Table ID.') ->param('rows', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of row data as JSON objects. May contain partial rows.', false, ['plan']) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Decrement.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Decrement.php index 46e9c8d6af..d42cf5e9eb 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Decrement.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Decrement.php @@ -41,8 +41,8 @@ class Decrement extends DecrementDocumentAttribute ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/decrement-row-column.md', auth: [AuthType::SESSION, AuthType::JWT, AuthType::ADMIN, AuthType::KEY], @@ -60,10 +60,12 @@ class Decrement extends DecrementDocumentAttribute ->param('column', '', new Key(), 'Column key.') ->param('value', 1, new Numeric(), 'Value to increment the column by. The value must be a number.', true) ->param('min', null, new Numeric(), 'Minimum value for the column. If the current value is lesser than this value, an exception will be thrown.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('plan') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Increment.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Increment.php index d921e9b8be..c58e16c8e3 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Increment.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Column/Increment.php @@ -41,8 +41,8 @@ class Increment extends IncrementDocumentAttribute ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/increment-row-column.md', auth: [AuthType::SESSION, AuthType::JWT, AuthType::ADMIN, AuthType::KEY], @@ -60,10 +60,12 @@ class Increment extends IncrementDocumentAttribute ->param('column', '', new Key(), 'Column key.') ->param('value', 1, new Numeric(), 'Value to increment the column by. The value must be a number.', true) ->param('max', null, new Numeric(), 'Maximum value for the column. If the current value is greater than this value, an error will be thrown.', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('plan') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Create.php index cf38bac63b..bfc832f2b5 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Create.php @@ -50,8 +50,8 @@ class Create extends DocumentCreate ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), desc: 'Create row', description: '/docs/references/tablesdb/create-row.md', @@ -69,11 +69,12 @@ class Create extends DocumentCreate new Parameter('rowId', optional: false), new Parameter('data', optional: false), new Parameter('permissions', optional: true), + new Parameter('transactionId', optional: true), ] ), new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: $this->getBulkActionName(self::getName()), desc: 'Create rows', description: '/docs/references/tablesdb/create-rows.md', @@ -89,15 +90,17 @@ class Create extends DocumentCreate new Parameter('databaseId', optional: false), new Parameter('tableId', optional: false), new Parameter('rows', optional: false), + new Parameter('transactionId', optional: true), ] ) ]) ->param('databaseId', '', new UID(), 'Database ID.') ->param('rowId', '', new CustomId(), '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.', true) - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate). Make sure to define columns before creating rows.') + ->param('tableId', '', new UID(), '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('data', [], new JSON(), 'Row data as JSON object.', true, example: '{"username":"walter.obrien","email":"walter.obrien@example.com","fullName":"Walter O\'Brien","age":30,"isAdmin":false}') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('rows', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of rows data as JSON objects.', true, ['plan']) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('user') @@ -106,6 +109,7 @@ class Create extends DocumentCreate ->inject('queueForRealtime') ->inject('queueForFunctions') ->inject('queueForWebhooks') + ->inject('plan') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Delete.php index 7ac954c5dd..687b1c8c11 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Delete.php @@ -45,8 +45,8 @@ class Delete extends DocumentDelete ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/delete-row.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -59,13 +59,16 @@ class Delete extends DocumentDelete contentType: ContentType::NONE )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new UID(), 'Row ID.') + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('transactionState') + ->inject('plan') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Get.php index 5704f75d82..f8b70516b6 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Get.php @@ -35,8 +35,8 @@ class Get extends DocumentGet ->label('scope', ['rows.read', 'documents.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/get-row.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -49,12 +49,14 @@ class Get extends DocumentGet contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the Database service [server integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreate).') + ->param('tableId', '', new UID(), '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', '', new UID(), 'Row ID.') ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID to read uncommitted changes within the transaction.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') + ->inject('transactionState') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php index a80249070b..5f1efa2953 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Logs/XList.php @@ -30,7 +30,7 @@ class XList extends DocumentLogXList ->label('scope', ['rows.read', 'documents.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: 'logs', name: self::getName(), description: '/docs/references/tablesdb/get-row-logs.md', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Update.php index b0e321b262..cb1d5888cf 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Update.php @@ -42,8 +42,8 @@ class Update extends DocumentUpdate ->label('abuse-limit', APP_LIMIT_WRITE_RATE_DEFAULT * 2) ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/update-row.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -60,11 +60,14 @@ class Update extends DocumentUpdate ->param('rowId', '', new UID(), 'Row ID.') ->param('data', [], new JSON(), 'Row data as JSON object. Include only columns and value pairs to be updated.', true) ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('transactionState') + ->inject('plan') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Upsert.php index c2695379e3..0bc373cc93 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/Upsert.php @@ -43,8 +43,8 @@ class Upsert extends DocumentUpsert ->label('abuse-time', APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT) ->label('sdk', [ new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/upsert-row.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -62,12 +62,15 @@ class Upsert extends DocumentUpsert ->param('rowId', '', new UID(), 'Row ID.') ->param('data', [], new JSON(), 'Row data as JSON object. Include all required columns of the row to be created or updated.', true) ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) + ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('user') ->inject('dbForProject') ->inject('queueForEvents') ->inject('queueForStatsUsage') + ->inject('transactionState') + ->inject('plan') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/XList.php index 5d503f1c59..8c96997ea5 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Rows/XList.php @@ -35,8 +35,8 @@ class XList extends DocumentXList ->label('scope', ['rows.read', 'documents.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), - group: $this->getSdkGroup(), + namespace: $this->getSDKNamespace(), + group: $this->getSDKGroup(), name: self::getName(), description: '/docs/references/tablesdb/list-rows.md', auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT], @@ -49,11 +49,13 @@ class XList extends DocumentXList contentType: ContentType::JSON )) ->param('databaseId', '', new UID(), 'Database ID.') - ->param('tableId', '', new UID(), 'Table ID. You can create a new table using the TableDB service [server integration](https://appwrite.io/docs/server/tablesdbdb#tablesdbCreate).') + ->param('tableId', '', new UID(), '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', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('transactionId', null, new UID(), 'Transaction ID to read uncommitted changes within the transaction.', true) ->inject('response') ->inject('dbForProject') ->inject('queueForStatsUsage') + ->inject('transactionState') ->callback($this->action(...)); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Update.php index 0fcdf319d2..8424b37a6d 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Update.php @@ -39,7 +39,7 @@ class Update extends CollectionUpdate ->label('audits.event', 'table.update') ->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}') ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: 'tables', name: self::getName(), description: '/docs/references/tablesdb/update-table.md', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Usage/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Usage/Get.php index 87f720e689..0fb44ee94a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Usage/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/Usage/Get.php @@ -34,7 +34,7 @@ class Get extends CollectionUsageGet ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: null, name: self::getName(), description: '/docs/references/tablesdb/get-table-usage.md', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/XList.php index d9a92e41b1..a47a972371 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Tables/XList.php @@ -35,7 +35,7 @@ class XList extends CollectionXList ->label('scope', ['tables.read', 'collections.read']) ->label('resourceType', RESOURCE_TYPE_DATABASES) ->label('sdk', new Method( - namespace: $this->getSdkNamespace(), + namespace: $this->getSDKNamespace(), group: 'tables', name: self::getName(), description: '/docs/references/tablesdb/list-tables.md', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Create.php new file mode 100644 index 0000000000..bc79b86ca3 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Create.php @@ -0,0 +1,55 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_POST) + ->setHttpPath('/v1/tablesdb/transactions') + ->desc('Create transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', ['documents.write', 'rows.write']) + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'tablesDB', + group: 'transactions', + name: 'createTransaction', + description: '/docs/references/tablesdb/create-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_CREATED, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('ttl', APP_DATABASE_TXN_TTL_DEFAULT, new Range(min: APP_DATABASE_TXN_TTL_MIN, max: APP_DATABASE_TXN_TTL_MAX), 'Seconds before the transaction expires.', true) + ->inject('response') + ->inject('dbForProject') + ->inject('user') + ->callback($this->action(...)); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Delete.php new file mode 100644 index 0000000000..6f92a1b10b --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Delete.php @@ -0,0 +1,55 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_DELETE) + ->setHttpPath('/v1/tablesdb/transactions/:transactionId') + ->desc('Delete transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', ['documents.write', 'rows.write']) + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'tablesDB', + group: 'transactions', + name: 'deleteTransaction', + description: '/docs/references/tablesdb/delete-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_NOCONTENT, + model: UtopiaResponse::MODEL_NONE, + ) + ], + contentType: ContentType::NONE + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->inject('response') + ->inject('dbForProject') + ->inject('queueForDeletes') + ->callback($this->action(...)); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Get.php new file mode 100644 index 0000000000..ab7925c916 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Get.php @@ -0,0 +1,54 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_GET) + ->setHttpPath('/v1/tablesdb/transactions/:transactionId') + ->desc('Get transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', ['documents.read', 'rows.read']) + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'tablesDB', + group: 'transactions', + name: 'getTransaction', + description: '/docs/references/tablesdb/get-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_OK, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->inject('response') + ->inject('dbForProject') + ->callback($this->action(...)); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Operations/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Operations/Create.php new file mode 100644 index 0000000000..5a98f22f37 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Operations/Create.php @@ -0,0 +1,59 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_POST) + ->setHttpPath('/v1/tablesdb/transactions/:transactionId/operations') + ->desc('Create operations') + ->groups(['api', 'database', 'transactions']) + ->label('scope', ['documents.write', 'rows.write']) + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'tablesDB', + group: 'transactions', + name: 'createOperations', + description: '/docs/references/tablesdb/create-operations.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_CREATED, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->param('operations', [], new ArrayList(new Operation(type: 'tablesdb')), 'Array of staged operations.', true) + ->inject('response') + ->inject('dbForProject') + ->inject('transactionState') + ->inject('plan') + ->callback($this->action(...)); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Update.php new file mode 100644 index 0000000000..4d55af93a4 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/Update.php @@ -0,0 +1,65 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH) + ->setHttpPath('/v1/tablesdb/transactions/:transactionId') + ->desc('Update transaction') + ->groups(['api', 'database', 'transactions']) + ->label('scope', ['documents.write', 'rows.write']) + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'tablesDB', + group: 'transactions', + name: 'updateTransaction', + description: '/docs/references/tablesdb/update-transaction.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_OK, + model: UtopiaResponse::MODEL_TRANSACTION, + ) + ], + contentType: ContentType::JSON + )) + ->param('transactionId', '', new UID(), 'Transaction ID.') + ->param('commit', false, new Boolean(), 'Commit transaction?', true) + ->param('rollback', false, new Boolean(), 'Rollback transaction?', true) + ->inject('response') + ->inject('dbForProject') + ->inject('user') + ->inject('transactionState') + ->inject('queueForDeletes') + ->inject('queueForEvents') + ->inject('queueForStatsUsage') + ->inject('queueForRealtime') + ->inject('queueForFunctions') + ->inject('queueForWebhooks') + ->callback($this->action(...)); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/XList.php new file mode 100644 index 0000000000..9a9c22a1a8 --- /dev/null +++ b/src/Appwrite/Platform/Modules/Databases/Http/TablesDB/Transactions/XList.php @@ -0,0 +1,54 @@ +setHttpMethod(self::HTTP_REQUEST_METHOD_GET) + ->setHttpPath('/v1/tablesdb/transactions') + ->desc('List transactions') + ->groups(['api', 'database', 'transactions']) + ->label('scope', ['documents.read', 'rows.read']) + ->label('resourceType', RESOURCE_TYPE_DATABASES) + ->label('sdk', new Method( + namespace: 'tablesDB', + group: 'transactions', + name: 'listTransactions', + description: '/docs/references/tablesdb/list-transactions.md', + auth: [AuthType::KEY, AuthType::SESSION, AuthType::JWT], + responses: [ + new SDKResponse( + code: SwooleResponse::STATUS_CODE_OK, + model: UtopiaResponse::MODEL_TRANSACTION_LIST, + ) + ], + contentType: ContentType::JSON + )) + ->param('queries', [], new Transactions(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries).', true) + ->inject('response') + ->inject('dbForProject') + ->callback($this->action(...)); + } +} diff --git a/src/Appwrite/Platform/Modules/Databases/Services/Http.php b/src/Appwrite/Platform/Modules/Databases/Services/Http.php index ccd9dfd140..f683f537bc 100644 --- a/src/Appwrite/Platform/Modules/Databases/Services/Http.php +++ b/src/Appwrite/Platform/Modules/Databases/Services/Http.php @@ -3,9 +3,8 @@ namespace Appwrite\Platform\Modules\Databases\Services; use Appwrite\Platform\Modules\Databases\Http\Init\Timeout; -use Appwrite\Platform\Modules\Databases\Services\Registry\Collections as CollectionsRegistry; -use Appwrite\Platform\Modules\Databases\Services\Registry\Databases as DatabasesRegistry; -use Appwrite\Platform\Modules\Databases\Services\Registry\Tables as TablesRegistry; +use Appwrite\Platform\Modules\Databases\Services\Registry\Legacy as LegacyRegistry; +use Appwrite\Platform\Modules\Databases\Services\Registry\TablesDB as TablesDBRegistry; use Utopia\Platform\Service; class Http extends Service @@ -17,9 +16,8 @@ class Http extends Service $this->addAction(Timeout::getName(), new Timeout()); foreach ([ - DatabasesRegistry::class, - CollectionsRegistry::class, - TablesRegistry::class, + LegacyRegistry::class, + TablesDBRegistry::class, ] as $registrar) { new $registrar($this); } diff --git a/src/Appwrite/Platform/Modules/Databases/Services/Registry/Databases.php b/src/Appwrite/Platform/Modules/Databases/Services/Registry/Databases.php deleted file mode 100644 index 81c9174253..0000000000 --- a/src/Appwrite/Platform/Modules/Databases/Services/Registry/Databases.php +++ /dev/null @@ -1,31 +0,0 @@ -addAction(CreateDatabase::getName(), new CreateDatabase()); - $service->addAction(GetDatabase::getName(), new GetDatabase()); - $service->addAction(UpdateDatabase::getName(), new UpdateDatabase()); - $service->addAction(DeleteDatabase::getName(), new DeleteDatabase()); - $service->addAction(ListDatabases::getName(), new ListDatabases()); - $service->addAction(ListDatabaseLogs::getName(), new ListDatabaseLogs()); - $service->addAction(GetDatabaseUsage::getName(), new GetDatabaseUsage()); - $service->addAction(ListDatabaseUsage::getName(), new ListDatabaseUsage()); - } -} diff --git a/src/Appwrite/Platform/Modules/Databases/Services/Registry/Collections.php b/src/Appwrite/Platform/Modules/Databases/Services/Registry/Legacy.php similarity index 81% rename from src/Appwrite/Platform/Modules/Databases/Services/Registry/Collections.php rename to src/Appwrite/Platform/Modules/Databases/Services/Registry/Legacy.php index 404f784611..7de95da255 100644 --- a/src/Appwrite/Platform/Modules/Databases/Services/Registry/Collections.php +++ b/src/Appwrite/Platform/Modules/Databases/Services/Registry/Legacy.php @@ -54,6 +54,20 @@ use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Logs\XList as use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Update as UpdateCollection; use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Usage\Get as GetCollectionUsage; use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\XList as ListCollections; +use Appwrite\Platform\Modules\Databases\Http\Databases\Create as CreateDatabase; +use Appwrite\Platform\Modules\Databases\Http\Databases\Delete as DeleteDatabase; +use Appwrite\Platform\Modules\Databases\Http\Databases\Get as GetDatabase; +use Appwrite\Platform\Modules\Databases\Http\Databases\Logs\XList as ListDatabaseLogs; +use Appwrite\Platform\Modules\Databases\Http\Databases\Transactions\Create as CreateTransaction; +use Appwrite\Platform\Modules\Databases\Http\Databases\Transactions\Delete as DeleteTransaction; +use Appwrite\Platform\Modules\Databases\Http\Databases\Transactions\Get as GetTransaction; +use Appwrite\Platform\Modules\Databases\Http\Databases\Transactions\Operations\Create as CreateOperations; +use Appwrite\Platform\Modules\Databases\Http\Databases\Transactions\Update as UpdateTransaction; +use Appwrite\Platform\Modules\Databases\Http\Databases\Transactions\XList as ListTransactions; +use Appwrite\Platform\Modules\Databases\Http\Databases\Update as UpdateDatabase; +use Appwrite\Platform\Modules\Databases\Http\Databases\Usage\Get as GetDatabaseUsage; +use Appwrite\Platform\Modules\Databases\Http\Databases\Usage\XList as ListDatabaseUsage; +use Appwrite\Platform\Modules\Databases\Http\Databases\XList as ListDatabases; use Utopia\Platform\Service; /** @@ -64,15 +78,30 @@ use Utopia\Platform\Service; * - Documents * - Attributes * - Indexes + * - Transactions */ -class Collections extends Base +class Legacy extends Base { protected function register(Service $service): void { + $this->registerDatabaseActions($service); $this->registerCollectionActions($service); $this->registerDocumentActions($service); $this->registerAttributeActions($service); $this->registerIndexActions($service); + $this->registerTransactionActions($service); + } + + public function registerDatabaseActions(Service $service): void + { + $service->addAction(CreateDatabase::getName(), new CreateDatabase()); + $service->addAction(GetDatabase::getName(), new GetDatabase()); + $service->addAction(UpdateDatabase::getName(), new UpdateDatabase()); + $service->addAction(DeleteDatabase::getName(), new DeleteDatabase()); + $service->addAction(ListDatabases::getName(), new ListDatabases()); + $service->addAction(ListDatabaseLogs::getName(), new ListDatabaseLogs()); + $service->addAction(GetDatabaseUsage::getName(), new GetDatabaseUsage()); + $service->addAction(ListDatabaseUsage::getName(), new ListDatabaseUsage()); } private function registerCollectionActions(Service $service): void @@ -170,4 +199,14 @@ class Collections extends Base $service->addAction(DeleteIndex::getName(), new DeleteIndex()); $service->addAction(ListIndexes::getName(), new ListIndexes()); } + + private function registerTransactionActions(Service $service): void + { + $service->addAction(CreateTransaction::getName(), new CreateTransaction()); + $service->addAction(GetTransaction::getName(), new GetTransaction()); + $service->addAction(UpdateTransaction::getName(), new UpdateTransaction()); + $service->addAction(DeleteTransaction::getName(), new DeleteTransaction()); + $service->addAction(ListTransactions::getName(), new ListTransactions()); + $service->addAction(CreateOperations::getName(), new CreateOperations()); + } } diff --git a/src/Appwrite/Platform/Modules/Databases/Services/Registry/Tables.php b/src/Appwrite/Platform/Modules/Databases/Services/Registry/TablesDB.php similarity index 90% rename from src/Appwrite/Platform/Modules/Databases/Services/Registry/Tables.php rename to src/Appwrite/Platform/Modules/Databases/Services/Registry/TablesDB.php index d570745148..4a02ac684e 100644 --- a/src/Appwrite/Platform/Modules/Databases/Services/Registry/Tables.php +++ b/src/Appwrite/Platform/Modules/Databases/Services/Registry/TablesDB.php @@ -57,6 +57,12 @@ use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Rows\XList as ListR use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Update as UpdateTable; use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Usage\Get as GetTableUsage; use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\XList as ListTables; +use Appwrite\Platform\Modules\Databases\Http\TablesDB\Transactions\Create as CreateTransaction; +use Appwrite\Platform\Modules\Databases\Http\TablesDB\Transactions\Delete as DeleteTransaction; +use Appwrite\Platform\Modules\Databases\Http\TablesDB\Transactions\Get as GetTransaction; +use Appwrite\Platform\Modules\Databases\Http\TablesDB\Transactions\Operations\Create as CreateOperations; +use Appwrite\Platform\Modules\Databases\Http\TablesDB\Transactions\Update as UpdateTransaction; +use Appwrite\Platform\Modules\Databases\Http\TablesDB\Transactions\XList as ListTransactions; use Appwrite\Platform\Modules\Databases\Http\TablesDB\Update as UpdateTablesDatabase; use Appwrite\Platform\Modules\Databases\Http\TablesDB\Usage\Get as GetTablesDatabaseUsage; use Appwrite\Platform\Modules\Databases\Http\TablesDB\Usage\XList as ListTablesDatabaseUsage; @@ -72,7 +78,7 @@ use Utopia\Platform\Service; * - Columns * - Column-Indexes */ -class Tables extends Base +class TablesDB extends Base { protected function register(Service $service): void { @@ -81,6 +87,7 @@ class Tables extends Base $this->registerColumnActions($service); $this->registerIndexActions($service); $this->registerRowActions($service); + $this->registerTransactionActions($service); } private function registerDatabaseActions(Service $service): void @@ -188,4 +195,14 @@ class Tables extends Base $service->addAction(IncrementRowColumn::getName(), new IncrementRowColumn()); $service->addAction(DecrementRowColumn::getName(), new DecrementRowColumn()); } + + private function registerTransactionActions(Service $service): void + { + $service->addAction(CreateTransaction::getName(), new CreateTransaction()); + $service->addAction(GetTransaction::getName(), new GetTransaction()); + $service->addAction(UpdateTransaction::getName(), new UpdateTransaction()); + $service->addAction(DeleteTransaction::getName(), new DeleteTransaction()); + $service->addAction(ListTransactions::getName(), new ListTransactions()); + $service->addAction(CreateOperations::getName(), new CreateOperations()); + } } diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php index 4d93c8e8cd..bbe84c56ee 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php @@ -51,7 +51,7 @@ class Create extends Base description: <<createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => ScheduleExecutions::getSupportedResource(), + 'resourceType' => SCHEDULE_RESOURCE_TYPE_EXECUTION, 'resourceId' => $execution->getId(), 'resourceInternalId' => $execution->getSequence(), 'resourceUpdatedAt' => DateTime::now(), diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Delete.php b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Delete.php index 9c818cfacc..666cb8310c 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Delete.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Delete.php @@ -5,7 +5,6 @@ namespace Appwrite\Platform\Modules\Functions\Http\Executions; use Appwrite\Event\Event; use Appwrite\Extend\Exception; use Appwrite\Platform\Modules\Compute\Base; -use Appwrite\Platform\Tasks\ScheduleExecutions; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Method; @@ -100,7 +99,7 @@ class Delete extends Base if ($status === 'scheduled') { $schedule = $dbForPlatform->findOne('schedules', [ Query::equal('resourceId', [$execution->getId()]), - Query::equal('resourceType', [ScheduleExecutions::getSupportedResource()]), + Query::equal('resourceType', [SCHEDULE_RESOURCE_TYPE_EXECUTION]), Query::equal('active', [true]), ]); diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php b/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php index 21a74f9a81..932f515fc1 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Functions/Create.php @@ -23,6 +23,7 @@ use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -201,41 +202,45 @@ class Create extends Base throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'When connecting to VCS (Version Control System), you need to provide "installationId" and "providerBranch".'); } - $function = $dbForProject->createDocument('functions', new Document([ - '$id' => $functionId, - 'execute' => $execute, - 'enabled' => $enabled, - 'live' => true, - 'logging' => $logging, - 'name' => $name, - 'runtime' => $runtime, - 'deploymentInternalId' => '', - 'deploymentId' => '', - 'events' => $events, - 'schedule' => $schedule, - 'scheduleInternalId' => '', - 'scheduleId' => '', - 'timeout' => $timeout, - 'entrypoint' => $entrypoint, - 'commands' => $commands, - 'scopes' => $scopes, - 'search' => implode(' ', [$functionId, $name, $runtime]), - 'version' => 'v5', - 'installationId' => $installation->getId(), - 'installationInternalId' => $installation->getSequence(), - 'providerRepositoryId' => $providerRepositoryId, - 'repositoryId' => '', - 'repositoryInternalId' => '', - 'providerBranch' => $providerBranch, - 'providerRootDirectory' => $providerRootDirectory, - 'providerSilentMode' => $providerSilentMode, - 'specification' => $specification - ])); + try { + $function = $dbForProject->createDocument('functions', new Document([ + '$id' => $functionId, + 'execute' => $execute, + 'enabled' => $enabled, + 'live' => true, + 'logging' => $logging, + 'name' => $name, + 'runtime' => $runtime, + 'deploymentInternalId' => '', + 'deploymentId' => '', + 'events' => $events, + 'schedule' => $schedule, + 'scheduleInternalId' => '', + 'scheduleId' => '', + 'timeout' => $timeout, + 'entrypoint' => $entrypoint, + 'commands' => $commands, + 'scopes' => $scopes, + 'search' => implode(' ', [$functionId, $name, $runtime]), + 'version' => 'v5', + 'installationId' => $installation->getId(), + 'installationInternalId' => $installation->getSequence(), + 'providerRepositoryId' => $providerRepositoryId, + 'repositoryId' => '', + 'repositoryInternalId' => '', + 'providerBranch' => $providerBranch, + 'providerRootDirectory' => $providerRootDirectory, + 'providerSilentMode' => $providerSilentMode, + 'specification' => $specification + ])); + } catch (DuplicateException) { + throw new Exception(Exception::FUNCTION_ALREADY_EXISTS); + } $schedule = Authorization::skip( fn () => $dbForPlatform->createDocument('schedules', new Document([ 'region' => $project->getAttribute('region'), - 'resourceType' => 'function', + 'resourceType' => SCHEDULE_RESOURCE_TYPE_FUNCTION, 'resourceId' => $function->getId(), 'resourceInternalId' => $function->getSequence(), 'resourceUpdatedAt' => DateTime::now(), diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index c0d55aa7fb..95a9a9fae7 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -685,6 +685,7 @@ class Builds extends Action if ($version === 'v2') { $command = 'tar -zxf /tmp/code.tar.gz -C /usr/code && cd /usr/local/src/ && ./build.sh'; } else { + $outputDirectory = $deployment->getAttribute('buildOutput') ?? $resource->getAttribute('outputDirectory'); if ($resource->getCollection() === 'sites') { $listFilesCommand = ''; @@ -692,8 +693,8 @@ class Builds extends Action $listFilesCommand .= 'echo "{APPWRITE_DETECTION_SEPARATOR_START}" && cd /usr/local/build'; // Enter output directory, if set - if (!empty($resource->getAttribute('outputDirectory', ''))) { - $listFilesCommand .= ' && cd ' . \escapeshellarg($resource->getAttribute('outputDirectory', '')); + if (!empty($outputDirectory)) { + $listFilesCommand .= ' && cd ' . \escapeshellarg($outputDirectory); } // Print files, and end separation @@ -724,7 +725,7 @@ class Builds extends Action destination: APP_STORAGE_BUILDS . "/app-{$project->getId()}", variables: $vars, command: $command, - outputDirectory: $resource->getAttribute('outputDirectory', '') + outputDirectory: $outputDirectory ?? '' ); Console::log('createRuntime finished'); @@ -898,7 +899,7 @@ class Builds extends Action Console::log('Build details stored'); - $this->afterBuildSuccess($queueForRealtime, $dbForProject, $deployment); + $this->afterBuildSuccess($queueForRealtime, $dbForProject, $deployment, $runtime, $adapter); $logs = $deployment->getAttribute('buildLogs', ''); /** Screenshot site */ @@ -1389,13 +1390,28 @@ class Builds extends Action * @param Realtime $queueForRealtime * @param Database $dbForProject * @param Document $deployment + * @param array $runtime + * @param string|null $adapter * @return void + * @throws Exception */ - protected function afterBuildSuccess(Realtime $queueForRealtime, Database $dbForProject, Document &$deployment): void + protected function afterBuildSuccess(Realtime $queueForRealtime, Database $dbForProject, Document &$deployment, array $runtime, ?string $adapter): void { - assert($queueForRealtime instanceof Realtime); - assert($dbForProject instanceof Database); - assert($deployment instanceof Document); + if (!($queueForRealtime instanceof Realtime)) { + throw new Exception('queueForRealtime must be an instance of Realtime'); + } + if (!($dbForProject instanceof Database)) { + throw new Exception('dbForProject must be an instance of Database'); + } + if (!($deployment instanceof Document)) { + throw new Exception('deployment must be an instance of Document'); + } + if (!is_array($runtime)) { + throw new Exception('runtime must be an array'); + } + if (!is_string($adapter) && !is_null($adapter)) { + throw new Exception('adapter must be a string or null'); + } } protected function getRuntime(Document $resource, string $version): array diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Template/Create.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Template/Create.php index a2040d830b..dc90045b0c 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Template/Create.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Template/Create.php @@ -53,7 +53,7 @@ class Create extends Base description: <<param('git', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we use git push?', optional: true) ->param('production', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we push to production?', optional: true) ->param('message', null, new Nullable(new Text(256)), 'Commit Message', optional: true) + ->param('release', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we create releases?', optional: true) + ->param('commit', null, new Nullable(new WhiteList(['yes', 'no'])), 'Actually create releases (yes) or dry-run (no)?', optional: true) ->callback($this->action(...)); } - public function action(?string $selectedPlatform, ?string $selectedSDK, ?string $version, ?string $git, ?string $production, ?string $message): void + public function action(?string $selectedPlatform, ?string $selectedSDK, ?string $version, ?string $git, ?string $production, ?string $message, ?string $release, ?string $commit): void { $selectedPlatform ??= Console::confirm('Choose Platform ("' . APP_PLATFORM_CLIENT . '", "' . APP_PLATFORM_SERVER . '", "' . APP_PLATFORM_CONSOLE . '" or "*" for all):'); $selectedSDK ??= \strtolower(Console::confirm('Choose SDK ("*" for all):')); $version ??= Console::confirm('Choose an Appwrite version'); - $git ??= Console::confirm('Should we use git push? (yes/no)'); - $git = $git === 'yes'; + $createRelease = ($release === 'yes'); + $commitRelease = ($commit === 'yes'); - if ($git) { - $production ??= Console::confirm('Type "Appwrite" to push code to production git repos'); - $production = $production === 'Appwrite'; - $message ??= Console::confirm('Please enter your commit message:'); + if (!$createRelease) { + $git ??= Console::confirm('Should we use git push? (yes/no)'); + $git = ($git === 'yes'); - $createPr = Console::confirm('Should we create pull request automatically? (yes/no)'); - $createPr = $createPr === 'yes'; + $prUrls = []; + $createPr = false; + + if ($git) { + $production ??= Console::confirm('Type "Appwrite" to push code to production git repos'); + $production = $production === 'Appwrite'; + $message ??= Console::confirm('Please enter your commit message:'); + + $createPr = Console::confirm('Should we create pull request automatically? (yes/no)'); + $createPr = ($createPr === 'yes'); + } } if (!\in_array($version, [ @@ -243,6 +253,116 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND throw new \Exception('Language "' . $language['key'] . '" not supported'); } + if ($createRelease) { + $releaseVersion = $language['version']; + + $repoName = $language['gitUserName'] . '/' . $language['gitRepoName']; + $releaseNotes = $this->extractReleaseNotes($changelog, $releaseVersion); + if (empty($releaseNotes)) { + $releaseNotes = "Release version {$releaseVersion}"; + } + + $releaseTitle = $releaseVersion; + $releaseTarget = $language['repoBranch'] ?? 'main'; + + if ($repoName === '/') { + Console::warning("{$language['name']} SDK is not an SDK, skipping release"); + continue; + } + + // Check if release already exists + $checkReleaseCommand = 'gh release view "' . $releaseVersion . '" --repo "' . $repoName . '" --json url --jq ".url" 2>/dev/null'; + $existingReleaseUrl = trim(\shell_exec($checkReleaseCommand) ?? ''); + + if (!empty($existingReleaseUrl)) { + Console::warning("Release {$releaseVersion} already exists for {$language['name']} SDK, skipping..."); + Console::info("Existing release: {$existingReleaseUrl}"); + continue; + } + + // Check if the latest commit on the target branch already has a release + $latestCommitCommand = 'gh api repos/' . $repoName . '/commits/' . $releaseTarget . ' --jq ".sha" 2>/dev/null'; + $latestCommitSha = trim(\shell_exec($latestCommitCommand) ?? ''); + + if (!empty($latestCommitSha)) { + $latestReleaseTagCommand = 'gh api repos/' . $repoName . '/releases --jq ".[0] | .tag_name" 2>/dev/null'; + $latestReleaseTag = trim(\shell_exec($latestReleaseTagCommand) ?? ''); + + if (!empty($latestReleaseTag)) { + $tagCommitCommand = 'gh api repos/' . $repoName . '/git/ref/tags/' . $latestReleaseTag . ' --jq ".object.sha" 2>/dev/null'; + $tagCommitSha = trim(\shell_exec($tagCommitCommand) ?? ''); + + if (!empty($tagCommitSha) && $latestCommitSha === $tagCommitSha) { + Console::warning("Latest commit on {$releaseTarget} already has a release ({$latestReleaseTag}) for {$language['name']} SDK, skipping to avoid empty release..."); + continue; + } + } + } + + $previousVersion = ''; + $tagListCommand = 'gh release list --repo "' . $repoName . '" --limit 1 --json tagName --jq ".[0].tagName" 2>&1'; + $previousVersion = trim(\shell_exec($tagListCommand) ?? ''); + + $formattedNotes = "## What's Changed\n\n"; + $formattedNotes .= $releaseNotes . "\n\n"; + + if (!empty($previousVersion)) { + $formattedNotes .= "**Full Changelog**: https://github.com/" . $repoName . "/compare/" . $previousVersion . "..." . $releaseVersion; + } else { + $formattedNotes .= "**Full Changelog**: https://github.com/" . $repoName . "/releases/tag/" . $releaseVersion; + } + + if (!$commitRelease) { + Console::info("[DRY RUN] Would create release for {$language['name']} SDK:"); + Console::log(" Repository: {$repoName}"); + Console::log(" Version: {$releaseVersion}"); + Console::log(" Title: {$releaseTitle}"); + Console::log(" Target Branch: {$releaseTarget}"); + Console::log(" Previous Version: " . ($previousVersion ?: 'N/A')); + Console::log(" Release Notes:"); + Console::log(" " . str_replace("\n", "\n ", $formattedNotes)); + Console::log(''); + } else { + Console::info("Creating release {$releaseVersion} for {$language['name']} SDK..."); + + $tempNotesFile = \tempnam(\sys_get_temp_dir(), 'release_notes_'); + \file_put_contents($tempNotesFile, $formattedNotes); + + $releaseCommand = 'gh release create "' . $releaseVersion . '" \ + --repo "' . $repoName . '" \ + --title "' . $releaseTitle . '" \ + --notes-file "' . $tempNotesFile . '" \ + --target "' . $releaseTarget . '" \ + 2>&1'; + + $releaseOutput = []; + $releaseReturnCode = 0; + \exec($releaseCommand, $releaseOutput, $releaseReturnCode); + + \unlink($tempNotesFile); + + if ($releaseReturnCode === 0) { + // Extract release URL from output + $releaseUrl = ''; + foreach ($releaseOutput as $line) { + if (strpos($line, 'https://github.com/') !== false) { + $releaseUrl = trim($line); + break; + } + } + + Console::success("Successfully created release {$releaseVersion} for {$language['name']} SDK"); + if (!empty($releaseUrl)) { + Console::info("Release URL: {$releaseUrl}"); + } + } else { + $errorMessage = implode("\n", $releaseOutput); + Console::error("Failed to create release for {$language['name']} SDK: " . $errorMessage); + } + } + continue; + } + Console::info("Generating {$language['name']} SDK..."); $sdk = new SDK($config, new Swagger2($spec)); @@ -281,7 +401,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // Make sure we have a clean slate. // Otherwise, all files in this dir will be pushed, // regardless of whether they were just generated or not. - \exec('rm -rf ' . $result); + \exec('chmod -R u+w ' . $result . ' 2>/dev/null; rm -rf ' . $result); try { $sdk->generate($result); @@ -309,7 +429,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND git checkout ' . $gitBranch . ' || git checkout -b ' . $gitBranch . ' && \ git fetch origin ' . $gitBranch . ' || git push -u origin ' . $gitBranch . ' && \ git pull origin ' . $gitBranch . ' && \ - rm -rf ' . $target . '/* && \ + find . -mindepth 1 ! -path "./.git*" -delete && \ cp -r ' . $result . '/. ' . $target . '/ && \ git add . && \ git commit -m "' . $message . '" && \ @@ -317,7 +437,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND '); Console::success("Pushed {$language['name']} SDK to {$gitUrl}"); - if ($createPr) { $prTitle = "feat: {$language['name']} SDK update for version {$language['version']}"; $prBody = "This PR contains updates to the {$language['name']} SDK for version {$language['version']}."; @@ -347,19 +466,52 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND if ($prReturnCode === 0) { Console::success("Successfully created pull request for {$language['name']} SDK"); if (!empty($prOutput)) { - Console::info("PR URL: " . end($prOutput)); + $prUrls[$language['name']] = end($prOutput); } } else { $errorMessage = implode("\n", $prOutput); if (strpos($errorMessage, 'already exists') !== false) { - Console::warning("Pull request already exists for {$language['name']} SDK"); + Console::warning("Pull request already exists for {$language['name']} SDK, updating title and body..."); + + $updateCommand = 'cd ' . $target . ' && \ + gh pr edit "' . $gitBranch . '" \ + --repo "' . $repoName . '" \ + --title "' . $prTitle . '" \ + --body "' . $prBody . '" \ + 2>&1'; + + $updateOutput = []; + $updateReturnCode = 0; + \exec($updateCommand, $updateOutput, $updateReturnCode); + + if ($updateReturnCode === 0) { + Console::success("Successfully updated pull request for {$language['name']} SDK"); + + $prUrlCommand = 'cd ' . $target . ' && \ + gh pr view "' . $gitBranch . '" \ + --repo "' . $repoName . '" \ + --json url \ + --jq .url \ + 2>&1'; + + $prUrlOutput = []; + $prUrlReturnCode = 0; + \exec($prUrlCommand, $prUrlOutput, $prUrlReturnCode); + + if ($prUrlReturnCode === 0 && !empty($prUrlOutput)) { + $prUrls[$language['name']] = $prUrlOutput[0]; + } + } else { + $updateErrorMessage = implode("\n", $updateOutput); + Console::error("Failed to update pull request for {$language['name']} SDK: " . $updateErrorMessage); + } } else { Console::error("Failed to create pull request for {$language['name']} SDK: " . $errorMessage); } } } - \exec('rm -rf ' . $target); + \exec('chmod -R u+w ' . $target . ' && rm -rf ' . $target); Console::success("Remove temp directory '{$target}' for {$language['name']} SDK"); } @@ -379,5 +531,57 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND } } } + + if (!empty($prUrls)) { + Console::log(''); + Console::log('Pull Request Summary'); + foreach ($prUrls as $sdkName => $url) { + Console::log("{$sdkName}: {$url}"); + } + Console::log(''); + } + } + + /** + * Extract release notes from changelog for a specific version + * + * @param string $changelog + * @param string $version + * @return string + */ + private function extractReleaseNotes(string $changelog, string $version): string + { + if (empty($changelog)) { + return ''; + } + + // Changelog version header pattern: ## 0.14.0 + $pattern = '/^##\s+' . preg_quote($version, '/') . '\s*$/m'; + $startPos = false; + if (preg_match($pattern, $changelog, $matches, PREG_OFFSET_CAPTURE)) { + $startPos = $matches[0][1]; + } + + if ($startPos === false) { + return ''; + } + + $contentStart = strpos($changelog, "\n", $startPos); + if ($contentStart === false) { + return ''; + } + $contentStart++; + + $nextHeaderPattern = '/^##?\s+/m'; + $remainingContent = substr($changelog, $contentStart); + + if (preg_match($nextHeaderPattern, $remainingContent, $matches, PREG_OFFSET_CAPTURE)) { + $endPos = $matches[0][1]; + $notes = substr($remainingContent, 0, $endPos); + } else { + $notes = $remainingContent; + } + + return trim($notes); } } diff --git a/src/Appwrite/Platform/Tasks/ScheduleBase.php b/src/Appwrite/Platform/Tasks/ScheduleBase.php index 5cd25b09b4..e9a0e1d333 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleBase.php +++ b/src/Appwrite/Platform/Tasks/ScheduleBase.php @@ -49,6 +49,7 @@ abstract class ScheduleBase extends Action ->inject('publisherMigrations') ->inject('publisherFunctions') ->inject('publisherMessaging') + ->inject('isResourceBlocked') ->inject('dbForPlatform') ->inject('getProjectDB') ->inject('telemetry') @@ -71,7 +72,7 @@ abstract class ScheduleBase extends Action * 2. Create timer that sync all changes from 'schedules' collection to local copy. Only reading changes thanks to 'resourceUpdatedAt' attribute * 3. Create timer that prepares coroutines for soon-to-execute schedules. When it's ready, coroutine sleeps until exact time before sending request to worker. */ - public function action(BrokerPool $publisher, BrokerPool $publisherMigrations, BrokerPool $publisherFunctions, BrokerPool $publisherMessaging, Database $dbForPlatform, callable $getProjectDB, Telemetry $telemetry): void + public function action(BrokerPool $publisher, BrokerPool $publisherMigrations, BrokerPool $publisherFunctions, BrokerPool $publisherMessaging, callable $isResourceBlocked, Database $dbForPlatform, callable $getProjectDB, Telemetry $telemetry): void { Console::title(\ucfirst(static::getSupportedResource()) . ' scheduler V1'); Console::success(APP_NAME . ' ' . \ucfirst(static::getSupportedResource()) . ' scheduler v1 has started'); @@ -88,16 +89,16 @@ abstract class ScheduleBase extends Action // start with "0" to load all active documents. $lastSyncUpdate = "0"; - $this->collectSchedules($dbForPlatform, $getProjectDB, $lastSyncUpdate); + $this->collectSchedules($dbForPlatform, $getProjectDB, $lastSyncUpdate, $isResourceBlocked); Console::success("Starting timers at " . DateTime::now()); /** * The timer synchronize $schedules copy with database collection. */ - Timer::tick(static::UPDATE_TIMER * 1000, function () use ($dbForPlatform, $getProjectDB, &$lastSyncUpdate) { + Timer::tick(static::UPDATE_TIMER * 1000, function () use ($dbForPlatform, $getProjectDB, &$lastSyncUpdate, $isResourceBlocked) { $time = DateTime::now(); Console::log("Sync tick: Running at $time"); - $this->collectSchedules($dbForPlatform, $getProjectDB, $lastSyncUpdate); + $this->collectSchedules($dbForPlatform, $getProjectDB, $lastSyncUpdate, $isResourceBlocked); }); while (true) { @@ -112,7 +113,7 @@ abstract class ScheduleBase extends Action } } - private function collectSchedules(Database $dbForPlatform, callable $getProjectDB, string &$lastSyncUpdate): void + private function collectSchedules(Database $dbForPlatform, callable $getProjectDB, string &$lastSyncUpdate, callable $isResourceBlocked): void { // If we haven't synced yet, load all active schedules $initialLoad = $lastSyncUpdate === "0"; @@ -178,34 +179,40 @@ abstract class ScheduleBase extends Action $paginationQueries[] = Query::greaterThanEqual('resourceUpdatedAt', $lastSyncUpdate); } - $results = $dbForPlatform->find('schedules', $paginationQueries); + $collectionId = static::getCollectionId(); + $schedules = $dbForPlatform->find('schedules', $paginationQueries); + $sum = count($schedules); + $total += $sum; - $sum = count($results); - $total = $total + $sum; + foreach ($schedules as $schedule) { + $existing = $this->schedules[$schedule->getSequence()] ?? null; + $updated = strtotime($existing['resourceUpdatedAt'] ?? '0') !== strtotime($schedule['resourceUpdatedAt'] ?? '0'); - foreach ($results as $document) { - $localDocument = $this->schedules[$document->getSequence()] ?? null; - - if ($localDocument !== null) { - if (!$document['active']) { - Console::info("Removing: {$document['resourceType']}::{$document['resourceId']}"); - unset($this->schedules[$document->getSequence()]); - } elseif (strtotime($localDocument['resourceUpdatedAt']) !== strtotime($document['resourceUpdatedAt'])) { - Console::info("Updating: {$document['resourceType']}::{$document['resourceId']}"); - $this->schedules[$document->getSequence()] = $getSchedule($document); - } - } else { + if ($existing === null || $updated) { try { - $this->schedules[$document->getSequence()] = $getSchedule($document); + $candidate = $getSchedule($schedule); } catch (\Throwable $th) { - $collectionId = static::getCollectionId(); - Console::error("Failed to load schedule for project {$document['projectId']} {$collectionId} {$document['resourceId']}"); + Console::error("Failed to load schedule for project {$schedule['projectId']} {$collectionId} {$schedule['resourceId']}"); Console::error($th->getMessage()); + continue; } + + if (!$candidate['active']) { + unset($this->schedules[$schedule->getSequence()]); + continue; + } + + if ($isResourceBlocked($candidate['project'], $collectionId, $candidate['resourceId'])) { + unset($this->schedules[$schedule->getSequence()]); + continue; + } + + Console::info("Updating: {$schedule['resourceType']}::{$schedule['resourceId']}"); + $this->schedules[$schedule->getSequence()] = $candidate; } } - $latestDocument = \end($results); + $latestDocument = \end($schedules); } $lastSyncUpdate = $time; diff --git a/src/Appwrite/Platform/Tasks/ScheduleExecutions.php b/src/Appwrite/Platform/Tasks/ScheduleExecutions.php index 14a4259e17..83a3f51b03 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleExecutions.php +++ b/src/Appwrite/Platform/Tasks/ScheduleExecutions.php @@ -6,6 +6,12 @@ use Appwrite\Event\Func; use Swoole\Coroutine as Co; use Utopia\Database\Database; +/** + * ScheduleExecutions + * + * Handles delayed executions by processing one-time scheduled tasks + * that are executed at a specific future time. + */ class ScheduleExecutions extends ScheduleBase { public const UPDATE_TIMER = 3; // seconds @@ -18,12 +24,12 @@ class ScheduleExecutions extends ScheduleBase public static function getSupportedResource(): string { - return 'execution'; + return SCHEDULE_RESOURCE_TYPE_EXECUTION; } public static function getCollectionId(): string { - return 'executions'; + return RESOURCE_TYPE_EXECUTIONS; } protected function enqueueResources(Database $dbForPlatform, callable $getProjectDB): void diff --git a/src/Appwrite/Platform/Tasks/ScheduleFunctions.php b/src/Appwrite/Platform/Tasks/ScheduleFunctions.php index 6f072425e4..7fda2f75df 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleFunctions.php +++ b/src/Appwrite/Platform/Tasks/ScheduleFunctions.php @@ -7,8 +7,13 @@ use Cron\CronExpression; use Utopia\CLI\Console; use Utopia\Database\Database; use Utopia\Database\DateTime; -use Utopia\Pools\Group; +/** + * ScheduleFunctions + * + * Handles cron job related executions by processing cron expressions + * and scheduling function executions based on recurring schedules. + */ class ScheduleFunctions extends ScheduleBase { public const UPDATE_TIMER = 10; // seconds @@ -23,12 +28,12 @@ class ScheduleFunctions extends ScheduleBase public static function getSupportedResource(): string { - return 'function'; + return SCHEDULE_RESOURCE_TYPE_FUNCTION; } public static function getCollectionId(): string { - return 'functions'; + return RESOURCE_TYPE_FUNCTIONS; } protected function enqueueResources(Database $dbForPlatform, callable $getProjectDB): void diff --git a/src/Appwrite/Platform/Tasks/ScheduleMessages.php b/src/Appwrite/Platform/Tasks/ScheduleMessages.php index fe4afbe69c..57f6dd8002 100644 --- a/src/Appwrite/Platform/Tasks/ScheduleMessages.php +++ b/src/Appwrite/Platform/Tasks/ScheduleMessages.php @@ -17,12 +17,12 @@ class ScheduleMessages extends ScheduleBase public static function getSupportedResource(): string { - return 'message'; + return SCHEDULE_RESOURCE_TYPE_MESSAGE; } public static function getCollectionId(): string { - return 'messages'; + return RESOURCE_TYPE_MESSAGES; } protected function enqueueResources(Database $dbForPlatform, callable $getProjectDB): void diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index a07d0b3cbe..331a2668a3 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -93,7 +93,7 @@ class Deletes extends Action throw new Exception('Missing payload'); } - $type = $payload['type'] ?? ''; + $type = $payload['type'] ?? ''; $datetime = $payload['datetime'] ?? null; $hourlyUsageRetentionDatetime = $payload['hourlyUsageRetentionDatetime'] ?? null; $resource = $payload['resource'] ?? null; @@ -130,6 +130,9 @@ class Deletes extends Action case DELETE_TYPE_RULES: $this->deleteRule($dbForPlatform, $document, $certificates); break; + case DELETE_TYPE_TRANSACTION: + $this->deleteTransactionLogs($getProjectDB, $document, $project); + break; default: Console::error('No lazy delete operation available for document of type: ' . $document->getCollection()); break; @@ -182,6 +185,7 @@ class Deletes extends Action $this->deleteAuditLogs($project, $getProjectDB, $auditRetention); $this->deleteUsageStats($project, $getProjectDB, $getLogsDB, $hourlyUsageRetentionDatetime); $this->deleteExpiredSessions($project, $getProjectDB); + $this->deleteExpiredTransactions($project, $getProjectDB); break; default: throw new \Exception('No delete operation for type: ' . \strval($type)); @@ -305,9 +309,9 @@ class Deletes extends Action * @param Document $project * @param callable $getProjectDB * @param string $resource + * @param string|null $resourceType * @return void * @throws Authorization - * @param string|null $resourceType * @throws Exception */ private function deleteCacheByResource(Document $project, callable $getProjectDB, string $resource, string $resourceType = null): void @@ -395,7 +399,7 @@ class Deletes extends Action */ private function deleteUsageStats(Document $project, callable $getProjectDB, callable $getLogsDB, string $hourlyUsageRetentionDatetime): void { - /** @var Database $dbForProject*/ + /** @var Database $dbForProject */ $dbForProject = $getProjectDB($project); $selects = [...$this->selects, 'time']; @@ -410,7 +414,7 @@ class Deletes extends Action ], $dbForProject); if ($project->getId() !== 'console') { - /** @var Database $dbForLogs*/ + /** @var Database $dbForLogs */ $dbForLogs = call_user_func($getLogsDB, $project); // Delete Usage stats from logsDB @@ -452,16 +456,16 @@ class Deletes extends Action } /** - * @param Database $dbForPlatform - * @param Document $document - * @return void - * @throws Authorization - * @throws DatabaseException - * @throws Conflict - * @throws Restricted - * @throws Structure - * @throws Exception - */ + * @param Database $dbForPlatform + * @param Document $document + * @return void + * @throws Authorization + * @throws DatabaseException + * @throws Conflict + * @throws Restricted + * @throws Structure + * @throws Exception + */ protected function deleteProjectsByTeam(Database $dbForPlatform, callable $getProjectDB, CertificatesAdapter $certificates, Document $document): void { @@ -539,7 +543,7 @@ class Deletes extends Action ); } } catch (Throwable $e) { - Console::error('Error deleting '.$collection->getId().' '.$e->getMessage()); + Console::error('Error deleting ' . $collection->getId() . ' ' . $e->getMessage()); } }); @@ -1117,9 +1121,6 @@ class Deletes extends Action ): void { $start = \microtime(true); - $deleteBatchSize = Database::DELETE_BATCH_SIZE; - $deleteBatchSize = 500; // TODO: Set right value in DB library after investigation - /** * deleteDocuments uses a cursor, we need to add a unique order by field or use default */ @@ -1127,11 +1128,10 @@ class Deletes extends Action $count = $database->deleteDocuments( $collection, $queries, - $deleteBatchSize, - $callback + onNext: $callback ); } catch (Throwable $th) { - $tenant = $database->getSharedTables() ? 'Tenant:'.$database->getTenant() : ''; + $tenant = $database->getSharedTables() ? 'Tenant:' . $database->getTenant() : ''; Console::error("Failed to delete documents for collection:{$database->getNamespace()}_{$collection} {$tenant} :{$th->getMessage()}"); return; } @@ -1299,4 +1299,48 @@ class Deletes extends Action ); } } + + private function deleteTransactionLogs(callable $getProjectDB, Document $document, Document $project): void + { + $dbForProject = $getProjectDB($project); + $transactionId = $document->getId(); + $transactionInternalId = $document->getSequence(); + + try { + $dbForProject->deleteDocuments('transactionLogs', [ + Query::equal('transactionInternalId', [$transactionInternalId]), + ]); + Console::info("Transaction logs for transaction {$transactionId} deleted."); + } catch (Throwable $th) { + Console::error("Failed to delete transaction logs for transaction {$transactionId}: " . $th->getMessage()); + } + } + + private function deleteExpiredTransactions(Document $project, callable $getProjectDB): void + { + $dbForProject = $getProjectDB($project); + $transactionInternalIds = []; + + try { + $dbForProject->deleteDocuments('transactions', [ + Query::lessThan('expiresAt', DateTime::format(new \DateTime())), + ], onNext: function (Document $transaction) use ($dbForProject, $project, &$transactionInternalIds) { + $transactionInternalIds[] = $transaction->getSequence(); + }, onError: function (Throwable $th) use ($project) { + // Swallow errors to avoid breaking the cleanup process + }); + } catch (Throwable $th) { + Console::error("Failed to find expired transactions for project {$project->getId()}: " . $th->getMessage()); + } + + if (empty($transactionInternalIds)) { + return; + } + + $dbForProject->deleteDocuments('transactionLogs', [ + Query::equal('transactionInternalId', $transactionInternalIds), + ], onError: function (Throwable $th) use ($project) { + // Swallow errors to avoid breaking the cleanup process + }); + } } diff --git a/src/Appwrite/Platform/Workers/Mails.php b/src/Appwrite/Platform/Workers/Mails.php index 117b689863..efca484ebf 100644 --- a/src/Appwrite/Platform/Workers/Mails.php +++ b/src/Appwrite/Platform/Workers/Mails.php @@ -82,6 +82,7 @@ class Mails extends Action $preview = $payload['preview'] ?? ''; $variables['subject'] = $subject; + $variables['heading'] = $variables['heading'] ?? $subject; $variables['year'] = date("Y"); $attachment = $payload['attachment'] ?? []; diff --git a/src/Appwrite/Platform/Workers/Messaging.php b/src/Appwrite/Platform/Workers/Messaging.php index 668993fdae..abf46e67a4 100644 --- a/src/Appwrite/Platform/Workers/Messaging.php +++ b/src/Appwrite/Platform/Workers/Messaging.php @@ -593,6 +593,14 @@ class Messaging extends Action $content = $data['content']; $html = $data['html'] ?? false; + // For SMTP, move all recipients to BCC and use default recipient in TO field + if ($provider->getAttribute('provider') === 'smtp') { + foreach ($to as $recipient) { + $bcc[] = ['email' => $recipient]; + } + $to = []; + } + return new Email( $to, $subject, diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index 0c8f11c07b..5ec306c5bb 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -462,7 +462,7 @@ class StatsResources extends Action }); try { - $dbForLogs->createOrUpdateDocuments( + $dbForLogs->upsertDocuments( 'stats', $this->documents, ); diff --git a/src/Appwrite/Platform/Workers/StatsUsage.php b/src/Appwrite/Platform/Workers/StatsUsage.php index bd34d53b00..32cdb02dea 100644 --- a/src/Appwrite/Platform/Workers/StatsUsage.php +++ b/src/Appwrite/Platform/Workers/StatsUsage.php @@ -18,24 +18,24 @@ class StatsUsage extends Action /** * In memory per project metrics calculation */ - private array $stats = []; - private int $lastTriggeredTime = 0; - private int $keys = 0; - private const INFINITY_PERIOD = '_inf_'; - private const BATCH_SIZE_DEVELOPMENT = 1; - private const BATCH_SIZE_PRODUCTION = 10_000; + protected array $stats = []; + protected int $lastTriggeredTime = 0; + protected int $keys = 0; + protected const INFINITY_PERIOD = '_inf_'; + protected const BATCH_SIZE_DEVELOPMENT = 1; + protected const BATCH_SIZE_PRODUCTION = 10_000; /** * Stats for batch write separated per project * @var array */ - private array $projects = []; + protected array $projects = []; /** * Array of stat documents to batch write to logsDB * @var array */ - private array $statDocuments = []; + protected array $statDocuments = []; protected Registry $register; @@ -101,7 +101,7 @@ class StatsUsage extends Action return 'stats-usage'; } - private function getBatchSize(): int + protected function getBatchSize(): int { return System::getEnv('_APP_ENV', 'development') === 'development' ? self::BATCH_SIZE_DEVELOPMENT @@ -195,7 +195,7 @@ class StatsUsage extends Action * @param callable(): Database $getProjectDB * @return void */ - private function reduce(Document $project, Document $document, array &$metrics, callable $getProjectDB): void + protected function reduce(Document $project, Document $document, array &$metrics, callable $getProjectDB): void { $dbForProject = $getProjectDB($project); @@ -428,13 +428,14 @@ class StatsUsage extends Action /** * Sort by unique index key reduce locks/deadlocks */ - usort($projectStats['stats'], function ($a, $b) { + usort($projectStats['stats'], function ($a, $b) use ($sequence) { // Metric DESC $cmp = strcmp($b['metric'], $a['metric']); if ($cmp !== 0) { return $cmp; } + unset($this->projects[$sequence]); // Period ASC $cmp = strcmp($a['period'], $b['period']); if ($cmp !== 0) { @@ -452,7 +453,7 @@ class StatsUsage extends Action return strcmp($a['time'], $b['time']); }); - $dbForProject->createOrUpdateDocumentsWithIncrease('stats', 'value', $projectStats['stats']); + $dbForProject->upsertDocumentsWithIncrease('stats', 'value', $projectStats['stats']); Console::success('Batch successfully written to DB'); } catch (Throwable $e) { Console::error('Error processing stats: ' . $e->getMessage()); @@ -532,7 +533,7 @@ class StatsUsage extends Action return strcmp($a['time'], $b['time']); }); - $dbForLogs->createOrUpdateDocumentsWithIncrease( + $dbForLogs->upsertDocumentsWithIncrease( 'stats', 'value', $this->statDocuments diff --git a/src/Appwrite/SDK/Response.php b/src/Appwrite/SDK/Response.php index e87813024b..2b034691a8 100644 --- a/src/Appwrite/SDK/Response.php +++ b/src/Appwrite/SDK/Response.php @@ -2,12 +2,11 @@ namespace Appwrite\SDK; -class Response +readonly class Response { /** * @param int $code * @param string|array $model - * @param string $description */ public function __construct( private int $code, diff --git a/src/Appwrite/SDK/Specification/Format.php b/src/Appwrite/SDK/Specification/Format.php index 825f9bf01d..c687df143a 100644 --- a/src/Appwrite/SDK/Specification/Format.php +++ b/src/Appwrite/SDK/Specification/Format.php @@ -112,7 +112,7 @@ abstract class Format return $this->params[$key] ?? $default; } - protected function getEnumName(string $service, string $method, string $param): ?string + protected function getRequestEnumName(string $service, string $method, string $param): ?string { /* `$service` is `$namespace` */ switch ($service) { @@ -450,7 +450,7 @@ abstract class Format return null; } - public function getEnumKeys(string $service, string $method, string $param): array + public function getRequestEnumKeys(string $service, string $method, string $param): array { $values = []; switch ($service) { @@ -543,6 +543,175 @@ abstract class Format return $values; } + public function getResponseEnumName(string $model, string $param): ?string + { + switch ($model) { + case 'attributeString': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeInteger': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeFloat': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeBoolean': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeEmail': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeEnum': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeIp': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeUrl': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeDatetime': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeRelationship': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributePoint': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributeLine': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'attributePolygon': + switch ($param) { + case 'status': + return 'AttributeStatus'; + } + break; + case 'columnString': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnInteger': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnFloat': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnBoolean': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnEmail': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnEnum': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnIp': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnUrl': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnDatetime': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnRelationship': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnPoint': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnLine': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'columnPolygon': + switch ($param) { + case 'status': + return 'ColumnStatus'; + } + break; + case 'healthStatus': + switch ($param) { + case 'status': + return 'HealthCheckStatus'; + } + break; + } + return null; + } + protected function getNestedModels(Model $model, array &$usedModels): void { foreach ($model->getRules() as $rule) { diff --git a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php index c11e55e733..38613313db 100644 --- a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php @@ -8,7 +8,9 @@ use Appwrite\SDK\MethodType; use Appwrite\SDK\Response; use Appwrite\SDK\Specification\Format; use Appwrite\Template\Template; +use Appwrite\Utopia\Database\Validator\Operation; use Appwrite\Utopia\Response\Model; +use Appwrite\Utopia\Response\Model\Any; use Utopia\Database\Database; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -396,7 +398,37 @@ class OpenAPI3 extends Format $validator = $validator->getValidator(); } - switch ((!empty($validator)) ? \get_class($validator) : '') { + $class = !empty($validator) + ? \get_class($validator) + : ''; + + $base = !empty($class) + ? \get_parent_class($class) + : ''; + + switch ($base) { + case 'Appwrite\Utopia\Database\Validator\Queries\Base': + $class = $base; + break; + } + + if ($class === 'Utopia\Validator\AnyOf') { + $validator = $param['validator']->getValidators()[0]; + $class = \get_class($validator); + } + + $array = false; + if ($class === 'Utopia\Validator\ArrayList') { + $array = true; + $subclass = \get_class($validator->getValidator()); + switch ($subclass) { + case 'Appwrite\Utopia\Database\Validator\Operation': + $class = $subclass; + break; + } + } + + switch ($class) { case 'Utopia\Database\Validator\UID': case 'Utopia\Validator\Text': $node['schema']['type'] = $validator->getType(); @@ -418,6 +450,20 @@ class OpenAPI3 extends Format $node['schema']['format'] = 'datetime'; $node['schema']['x-example'] = Model::TYPE_DATETIME_EXAMPLE; break; + case 'Utopia\Database\Validator\Spatial': + /** @var Spatial $validator */ + $node['schema']['type'] = 'array'; + $node['schema']['items'] = [ + 'oneOf' => [ + ['type' => 'array'] + ] + ]; + $node['schema']['x-example'] = match ($validator->getSpatialType()) { + Database::VAR_POINT => '[1, 2]', + Database::VAR_LINESTRING => '[[1, 2], [3, 4], [5, 6]]', + Database::VAR_POLYGON => '[[[1, 2], [3, 4], [5, 6], [1, 2]]]', + }; + break; case 'Appwrite\Network\Validator\Email': $node['schema']['type'] = $validator->getType(); $node['schema']['format'] = 'email'; @@ -449,20 +495,7 @@ class OpenAPI3 extends Format 'type' => $validator->getValidator()->getType(), ]; break; - case 'Utopia\Database\Validator\Spatial': - /** @var Spatial $validator */ - $node['schema']['type'] = 'array'; - $node['schema']['items'] = [ - 'oneOf' => [ - ['type' => 'array'] - ] - ]; - $node['schema']['x-example'] = match ($validator->getSpatialType()) { - Database::VAR_POINT => '[1, 2]', - Database::VAR_LINESTRING => '[[1, 2], [3, 4], [5, 6]]', - Database::VAR_POLYGON => '[[[1, 2], [3, 4], [5, 6], [1, 2]]]', - }; - break; + case 'Appwrite\Utopia\Database\Validator\Queries\Base': case 'Appwrite\Utopia\Database\Validator\Queries\Columns': case 'Appwrite\Utopia\Database\Validator\Queries\Attributes': case 'Appwrite\Utopia\Database\Validator\Queries\Buckets': @@ -556,11 +589,10 @@ class OpenAPI3 extends Format break; } } - - if ($allowed) { + if ($allowed && $validator->getType() === 'string') { $node['schema']['enum'] = $validator->getList(); - $node['schema']['x-enum-name'] = $this->getEnumName($sdk->getNamespace() ?? '', $methodName, $name); - $node['schema']['x-enum-keys'] = $this->getEnumKeys($sdk->getNamespace() ?? '', $methodName, $name); + $node['schema']['x-enum-name'] = $this->getRequestEnumName($sdk->getNamespace() ?? '', $methodName, $name); + $node['schema']['x-enum-keys'] = $this->getRequestEnumKeys($sdk->getNamespace() ?? '', $methodName, $name); } if ($validator->getType() === 'integer') { $node['format'] = 'int32'; @@ -568,7 +600,35 @@ class OpenAPI3 extends Format break; case 'Appwrite\Utopia\Database\Validator\CompoundUID': $node['schema']['type'] = $validator->getType(); - $node['schema']['x-example'] = '[ID1:ID2]'; + $node['schema']['x-example'] = ''; + break; + case 'Appwrite\Utopia\Database\Validator\Operation': + if ($array) { + $validator = $validator->getValidator(); + } + + /** @var Operation $validator */ + $collectionIdKey = $validator->getCollectionIdKey(); + $documentIdKey = $validator->getDocumentIdKey(); + if ($array) { + $node['schema']['type'] = 'array'; + $node['schema']['items'] = ['type' => 'object']; + } else { + $node['schema']['type'] = 'object'; + } + $example = [ + 'action' => 'create', + 'databaseId' => '', + $collectionIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($collectionIdKey)).'>', + $documentIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($documentIdKey)).'>', + 'data' => [ + 'name' => 'Walter O\'Brien', + ], + ]; + if ($array) { + $example = [$example]; + } + $node['schema']['x-example'] = \str_replace("\n", "\n\t", \json_encode($example, JSON_PRETTY_PRINT)); break; default: $node['schema']['type'] = 'string'; @@ -777,8 +837,16 @@ class OpenAPI3 extends Format if ($rule['type'] === 'enum' && !empty($rule['enum'])) { if ($rule['array']) { $output['components']['schemas'][$model->getType()]['properties'][$name]['items']['enum'] = $rule['enum']; + $enumName = $this->getResponseEnumName($model->getType(), $name); + if ($enumName) { + $output['components']['schemas'][$model->getType()]['properties'][$name]['items']['x-enum-name'] = $enumName; + } } else { $output['components']['schemas'][$model->getType()]['properties'][$name]['enum'] = $rule['enum']; + $enumName = $this->getResponseEnumName($model->getType(), $name); + if ($enumName) { + $output['components']['schemas'][$model->getType()]['properties'][$name]['x-enum-name'] = $enumName; + } } } if (!in_array($name, $required)) { @@ -786,6 +854,7 @@ class OpenAPI3 extends Format } } + /** @var Any $model */ if ($model->isAny() && !empty($model->getSampleData())) { $examples = array_merge($examples, $model->getSampleData()); } diff --git a/src/Appwrite/SDK/Specification/Format/Swagger2.php b/src/Appwrite/SDK/Specification/Format/Swagger2.php index 4e784e8116..d497369b9a 100644 --- a/src/Appwrite/SDK/Specification/Format/Swagger2.php +++ b/src/Appwrite/SDK/Specification/Format/Swagger2.php @@ -8,7 +8,9 @@ use Appwrite\SDK\MethodType; use Appwrite\SDK\Response; use Appwrite\SDK\Specification\Format; use Appwrite\Template\Template; +use Appwrite\Utopia\Database\Validator\Operation; use Appwrite\Utopia\Response\Model; +use Appwrite\Utopia\Response\Model\Any; use Utopia\Database\Database; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -422,6 +424,17 @@ class Swagger2 extends Format $class = \get_class($validator); } + $array = false; + if ($class === 'Utopia\Validator\ArrayList') { + $array = true; + $subclass = \get_class($validator->getValidator()); + switch ($subclass) { + case 'Appwrite\Utopia\Database\Validator\Operation': + $class = $subclass; + break; + } + } + switch ($class) { case 'Utopia\Validator\Text': case 'Utopia\Database\Validator\UID': @@ -444,6 +457,20 @@ class Swagger2 extends Format $node['format'] = 'datetime'; $node['x-example'] = Model::TYPE_DATETIME_EXAMPLE; break; + case 'Utopia\Database\Validator\Spatial': + /** @var Spatial $validator */ + $node['type'] = 'array'; + $node['schema']['items'] = [ + 'oneOf' => [ + ['type' => 'array'] + ] + ]; + $node['x-example'] = match ($validator->getSpatialType()) { + Database::VAR_POINT => '[1, 2]', + Database::VAR_LINESTRING => '[[1, 2], [3, 4], [5, 6]]', + Database::VAR_POLYGON => '[[[1, 2], [3, 4], [5, 6], [1, 2]]]', + }; + break; case 'Appwrite\Network\Validator\Email': $node['type'] = $validator->getType(); $node['format'] = 'email'; @@ -464,20 +491,6 @@ class Swagger2 extends Format 'type' => $validator->getValidator()->getType(), ]; break; - case 'Utopia\Database\Validator\Spatial': - /** @var Spatial $validator */ - $node['type'] = 'array'; - $node['schema']['items'] = [ - 'oneOf' => [ - ['type' => 'array'] - ] - ]; - $node['x-example'] = match ($validator->getSpatialType()) { - Database::VAR_POINT => '[1, 2]', - Database::VAR_LINESTRING => '[[1, 2], [3, 4], [5, 6]]', - Database::VAR_POLYGON => '[[[1, 2], [3, 4], [5, 6], [1, 2]]]', - }; - break; case 'Utopia\Validator\JSON': case 'Utopia\Validator\Mock': case 'Utopia\Validator\Assoc': @@ -562,20 +575,47 @@ class Swagger2 extends Format break; } } - if ($allowed && $validator->getType() === 'string') { $node['enum'] = $validator->getList(); - $node['x-enum-name'] = $this->getEnumName($namespace, $methodName, $name); - $node['x-enum-keys'] = $this->getEnumKeys($namespace, $methodName, $name); + $node['x-enum-name'] = $this->getRequestEnumName($namespace, $methodName, $name); + $node['x-enum-keys'] = $this->getRequestEnumKeys($namespace, $methodName, $name); } - if ($validator->getType() === 'integer') { $node['format'] = 'int32'; } break; case 'Appwrite\Utopia\Database\Validator\CompoundUID': $node['type'] = $validator->getType(); - $node['x-example'] = '[ID1:ID2]'; + $node['x-example'] = ''; + break; + case 'Appwrite\Utopia\Database\Validator\Operation': + if ($array) { + $validator = $validator->getValidator(); + } + + /** @var Operation $validator */ + $collectionIdKey = $validator->getCollectionIdKey(); + $documentIdKey = $validator->getDocumentIdKey(); + if ($array) { + $node['type'] = 'array'; + $node['collectionFormat'] = 'multi'; + $node['items'] = ['type' => 'object']; + } else { + $node['type'] = 'object'; + } + $example = [ + 'action' => 'create', + 'databaseId' => '', + $collectionIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($collectionIdKey)).'>', + $documentIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($documentIdKey)).'>', + 'data' => [ + 'name' => 'Walter O\'Brien', + ], + ]; + if ($array) { + $example = [$example]; + } + $node['x-example'] = \str_replace("\n", "\n\t", \json_encode($example, JSON_PRETTY_PRINT)); break; default: $node['type'] = 'string'; @@ -799,8 +839,16 @@ class Swagger2 extends Format if ($rule['type'] === 'enum' && !empty($rule['enum'])) { if ($rule['array']) { $output['definitions'][$model->getType()]['properties'][$name]['items']['enum'] = $rule['enum']; + $enumName = $this->getResponseEnumName($model->getType(), $name); + if ($enumName) { + $output['definitions'][$model->getType()]['properties'][$name]['items']['x-enum-name'] = $enumName; + } } else { $output['definitions'][$model->getType()]['properties'][$name]['enum'] = $rule['enum']; + $enumName = $this->getResponseEnumName($model->getType(), $name); + if ($enumName) { + $output['definitions'][$model->getType()]['properties'][$name]['x-enum-name'] = $enumName; + } } } if (!in_array($name, $required)) { @@ -808,6 +856,7 @@ class Swagger2 extends Format } } + /** @var Any $model */ if ($model->isAny() && !empty($model->getSampleData())) { $examples = array_merge($examples, $model->getSampleData()); } diff --git a/src/Appwrite/Transformation/Adapter/Preview.php b/src/Appwrite/Transformation/Adapter/Preview.php index bfbb2e82fd..e69ab5252e 100644 --- a/src/Appwrite/Transformation/Adapter/Preview.php +++ b/src/Appwrite/Transformation/Adapter/Preview.php @@ -62,7 +62,7 @@ class Preview extends Adapter position: fixed; right: 16px; bottom: 16px; - z-index: 1; + z-index: calc(infinity); border-radius: var(--border-radius-S, 8px); border: var(--border-width-S, 1px) solid var(--color-border-neutral, #EDEDF0); background: var(--color-bgColor-neutral-primary, #FFF); diff --git a/src/Appwrite/Utopia/Database/Validator/Operation.php b/src/Appwrite/Utopia/Database/Validator/Operation.php new file mode 100644 index 0000000000..e6884ac677 --- /dev/null +++ b/src/Appwrite/Utopia/Database/Validator/Operation.php @@ -0,0 +1,219 @@ + */ + private array $required = [ + 'databaseId', + 'action', + ]; + + /** @var array */ + private array $requiresDocumentId = [ + 'create' => true, + 'update' => true, + 'upsert' => true, + 'delete' => true, + 'increment' => true, + 'decrement' => true, + ]; + + /** @var array */ + private array $requiresData = [ + 'create' => true, + 'update' => true, + 'upsert' => true, + 'delete' => false, // Delete doesn't need data + 'increment' => true, + 'decrement' => true, + 'bulkCreate' => true, + 'bulkUpdate' => true, + 'bulkUpsert' => true, + 'bulkDelete' => true, + ]; + + /** @var array */ + private array $actions = [ + 'create' => true, + 'update' => true, + 'upsert' => true, + 'delete' => true, + 'increment' => true, + 'decrement' => true, + 'bulkCreate' => true, + 'bulkUpdate' => true, + 'bulkUpsert' => true, + 'bulkDelete' => true, + ]; + + private string $collectionIdName = ''; + private string $documentIdName = ''; + + public function __construct(private readonly string $type) + { + switch ($this->type) { + case 'legacy': + $this->collectionIdName = 'collectionId'; + $this->documentIdName = 'documentId'; + break; + case 'tablesdb': + $this->collectionIdName = 'tableId'; + $this->documentIdName = 'rowId'; + break; + default: + throw new \InvalidArgumentException('Invalid type provided.'); + } + + $this->required[] = $this->collectionIdName; + } + + public function getDescription(): string + { + return $this->description; + } + + public function getCollectionIdKey(): string + { + return $this->collectionIdName; + } + + public function getDocumentIdKey(): string + { + return $this->documentIdName; + } + + public function isArray(): bool + { + return true; + } + + /** + * @param mixed $value + */ + public function isValid($value): bool + { + // Must be array‑like + if (!\is_array($value)) { + $this->description = 'Value must be an array'; + return false; + } + + // Mandatory keys + foreach ($this->required as $key) { + if (!\array_key_exists($key, $value)) { + $this->description = "Missing required key: {$key}"; + return false; + } + } + + // Required keys must be non‑empty + foreach ($this->required as $key) { + if (!\is_string($value[$key]) || \trim($value[$key]) === '') { + $this->description = "Key '{$key}' must be a non‑empty string"; + return false; + } + } + + // Validate action + if (!isset($this->actions[$value['action']])) { + $this->description = "Key 'action' must be one of: " . \implode(', ', array_keys($this->actions)); + return false; + } + + // If action requires documentId, it must be present + $actionRequiresDocumentId = ($this->requiresDocumentId[$value['action']] ?? false) === true; + if ($actionRequiresDocumentId && !\array_key_exists($this->documentIdName, $value)) { + $this->description = "Key '$this->documentIdName' is required for action '{$value['action']}'"; + return false; + } + + if (\array_key_exists($this->documentIdName, $value)) { + if (!\is_string($value[$this->documentIdName]) || \trim($value[$this->documentIdName]) === '') { + $this->description = "Key '$this->documentIdName' must be a non-empty string"; + return false; + } + } + + // Data validation - only required for certain actions + if (isset($this->requiresData[$value['action']]) && $this->requiresData[$value['action']]) { + // Data is required for this action + if (!\array_key_exists('data', $value)) { + $this->description = "Missing required key: data"; + return false; + } + if (!\is_array($value['data'])) { + $this->description = "Key 'data' must be an array"; + return false; + } + } elseif (\array_key_exists('data', $value)) { + // Data is optional but if provided, must be an array + if (!\is_array($value['data'])) { + $this->description = "Key 'data' must be an array"; + return false; + } + } + + // Bulk operation specific validations + $action = $value['action']; + + // BulkUpdate and BulkDelete require queries + if (\in_array($action, ['bulkUpdate', 'bulkDelete'])) { + if (!\array_key_exists('data', $value) || !\is_array($value['data'])) { + $this->description = "Key 'data' must be an array for {$action}"; + return false; + } + if (!\array_key_exists('queries', $value['data'])) { + $this->description = "Key 'queries' is required in data for {$action}"; + return false; + } + if (!\is_array($value['data']['queries'])) { + $this->description = "Key 'queries' must be an array for {$action}"; + return false; + } + } + + // BulkUpdate requires both queries and data + if ($action === 'bulkUpdate') { + if (!\array_key_exists('data', $value['data'])) { + $this->description = "Key 'data' is required in data for {$action}"; + return false; + } + if (!\is_array($value['data']['data'])) { + $this->description = "Key 'data.data' must be an array for {$action}"; + return false; + } + } + + // Increment and Decrement require specific keys + if (\in_array($action, ['increment', 'decrement'])) { + if (!\array_key_exists('data', $value) || !\is_array($value['data'])) { + $this->description = "Key 'data' must be an array for {$action}"; + return false; + } + // Get the attribute key name based on type + $attributeKey = $this->type === 'tablesdb' ? 'column' : 'attribute'; + if (!\array_key_exists($attributeKey, $value['data'])) { + $this->description = "Key '{$attributeKey}' is required in data for {$action}"; + return false; + } + // Validate 'value' is numeric if provided (defaults to 1 if omitted) + if (\array_key_exists('value', $value['data']) && !\is_numeric($value['data']['value'])) { + $this->description = "Key 'value' must be a numeric value for {$action}"; + return false; + } + } + + return true; + } + + public function getType(): string + { + return self::TYPE_OBJECT; + } +} diff --git a/src/Appwrite/Utopia/Database/Validator/Queries/Transactions.php b/src/Appwrite/Utopia/Database/Validator/Queries/Transactions.php new file mode 100644 index 0000000000..b49494c0af --- /dev/null +++ b/src/Appwrite/Utopia/Database/Validator/Queries/Transactions.php @@ -0,0 +1,17 @@ + */ + public const array ALLOWED_ATTRIBUTES = [ + 'status', + 'expiresAt', + ]; + + public function __construct() + { + parent::__construct('transactions', self::ALLOWED_ATTRIBUTES); + } +} diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 67fc83b9fd..b391f0ea72 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -126,6 +126,7 @@ use Appwrite\Utopia\Response\Model\TemplateSMS; use Appwrite\Utopia\Response\Model\TemplateVariable; use Appwrite\Utopia\Response\Model\Token; use Appwrite\Utopia\Response\Model\Topic; +use Appwrite\Utopia\Response\Model\Transaction; use Appwrite\Utopia\Response\Model\UsageBuckets; use Appwrite\Utopia\Response\Model\UsageCollection; use Appwrite\Utopia\Response\Model\UsageDatabase; @@ -230,6 +231,10 @@ class Response extends SwooleResponse public const MODEL_COLUMN_LINE = 'columnLine'; public const MODEL_COLUMN_POLYGON = 'columnPolygon'; + // Transactions + public const MODEL_TRANSACTION = 'transaction'; + public const MODEL_TRANSACTION_LIST = 'transactionList'; + // Users public const MODEL_ACCOUNT = 'account'; public const MODEL_USER = 'user'; @@ -478,6 +483,7 @@ class Response extends SwooleResponse ->setModel(new BaseList('Topic list', self::MODEL_TOPIC_LIST, 'topics', self::MODEL_TOPIC)) ->setModel(new BaseList('Subscriber list', self::MODEL_SUBSCRIBER_LIST, 'subscribers', self::MODEL_SUBSCRIBER)) ->setModel(new BaseList('Target list', self::MODEL_TARGET_LIST, 'targets', self::MODEL_TARGET)) + ->setModel(new BaseList('Transaction List', self::MODEL_TRANSACTION_LIST, 'transactions', self::MODEL_TRANSACTION)) ->setModel(new BaseList('Migrations List', self::MODEL_MIGRATION_LIST, 'migrations', self::MODEL_MIGRATION)) ->setModel(new BaseList('Migrations Firebase Projects List', self::MODEL_MIGRATION_FIREBASE_PROJECT_LIST, 'projects', self::MODEL_MIGRATION_FIREBASE_PROJECT)) ->setModel(new BaseList('Specifications List', self::MODEL_SPECIFICATION_LIST, 'specifications', self::MODEL_SPECIFICATION)) @@ -610,6 +616,7 @@ class Response extends SwooleResponse ->setModel(new Provider()) ->setModel(new Message()) ->setModel(new Topic()) + ->setModel(new Transaction()) ->setModel(new Subscriber()) ->setModel(new Target()) ->setModel(new Migration()) diff --git a/src/Appwrite/Utopia/Response/Model/Column.php b/src/Appwrite/Utopia/Response/Model/Column.php index 5562de39f2..cae8d1fadb 100644 --- a/src/Appwrite/Utopia/Response/Model/Column.php +++ b/src/Appwrite/Utopia/Response/Model/Column.php @@ -23,10 +23,11 @@ class Column extends Model 'example' => 'string', ]) ->addRule('status', [ - 'type' => self::TYPE_STRING, + 'type' => self::TYPE_ENUM, 'description' => 'Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`', 'default' => '', 'example' => 'available', + 'enum' => ['available', 'processing', 'deleting', 'stuck', 'failed'], ]) ->addRule('error', [ 'type' => self::TYPE_STRING, diff --git a/src/Appwrite/Utopia/Response/Model/ConsoleVariables.php b/src/Appwrite/Utopia/Response/Model/ConsoleVariables.php index b81502f0a1..4451769384 100644 --- a/src/Appwrite/Utopia/Response/Model/ConsoleVariables.php +++ b/src/Appwrite/Utopia/Response/Model/ConsoleVariables.php @@ -22,6 +22,12 @@ class ConsoleVariables extends Model 'default' => '', 'example' => '127.0.0.1', ]) + ->addRule('_APP_COMPUTE_BUILD_TIMEOUT', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Maximum build timeout in seconds.', + 'default' => '', + 'example' => 900, + ]) ->addRule('_APP_DOMAIN_TARGET_AAAA', [ 'type' => self::TYPE_STRING, 'description' => 'AAAA target for your Appwrite custom domains.', diff --git a/src/Appwrite/Utopia/Response/Model/Database.php b/src/Appwrite/Utopia/Response/Model/Database.php index 44a0d52af8..59f32b3162 100644 --- a/src/Appwrite/Utopia/Response/Model/Database.php +++ b/src/Appwrite/Utopia/Response/Model/Database.php @@ -41,10 +41,11 @@ class Database extends Model 'example' => false, ]) ->addRule('type', [ - 'type' => self::TYPE_STRING, + 'type' => self::TYPE_ENUM, 'description' => 'Database type.', 'default' => 'legacy', 'example' => 'legacy', + 'enum' => ['legacy', 'tablesdb'], ]) ; } diff --git a/src/Appwrite/Utopia/Response/Model/Document.php b/src/Appwrite/Utopia/Response/Model/Document.php index 5bad504a63..f9766c895c 100644 --- a/src/Appwrite/Utopia/Response/Model/Document.php +++ b/src/Appwrite/Utopia/Response/Model/Document.php @@ -82,7 +82,10 @@ class Document extends Any { $document->removeAttribute('$collection'); $document->removeAttribute('$tenant'); - $document->setAttribute('$sequence', (int)$document->getAttribute('$sequence', 0)); + + if (!$document->isEmpty()) { + $document->setAttribute('$sequence', (int)$document->getAttribute('$sequence', 0)); + } foreach ($document->getAttributes() as $attribute) { if (\is_array($attribute)) { diff --git a/src/Appwrite/Utopia/Response/Model/Message.php b/src/Appwrite/Utopia/Response/Model/Message.php index e52b6836c5..4c1e08b9cb 100644 --- a/src/Appwrite/Utopia/Response/Model/Message.php +++ b/src/Appwrite/Utopia/Response/Model/Message.php @@ -34,6 +34,7 @@ class Message extends Model 'description' => 'Message provider type.', 'default' => '', 'example' => MESSAGE_TYPE_EMAIL, + 'enum' => [MESSAGE_TYPE_EMAIL, MESSAGE_TYPE_SMS, MESSAGE_TYPE_PUSH], ]) ->addRule('topics', [ 'type' => self::TYPE_STRING, @@ -50,7 +51,7 @@ class Message extends Model 'example' => ['5e5ea5c16897e'], ]) ->addRule('targets', [ - 'type' => self::TYPE_STRING, + 'type' => self::TYPE_ENUM, 'description' => 'Target IDs set as recipients.', 'default' => '', 'array' => true, @@ -94,10 +95,11 @@ class Message extends Model ], ]) ->addRule('status', [ - 'type' => self::TYPE_STRING, + 'type' => self::TYPE_ENUM, 'description' => 'Status of delivery.', 'default' => 'draft', 'example' => 'Message status can be one of the following: draft, processing, scheduled, sent, or failed.', + 'enum' => ['draft', 'processing', 'scheduled', 'sent', 'failed'], ]); } diff --git a/src/Appwrite/Utopia/Response/Model/Platform.php b/src/Appwrite/Utopia/Response/Model/Platform.php index 65f3c343d4..151e43780d 100644 --- a/src/Appwrite/Utopia/Response/Model/Platform.php +++ b/src/Appwrite/Utopia/Response/Model/Platform.php @@ -41,10 +41,10 @@ class Platform extends Model ]) ->addRule('type', [ 'type' => self::TYPE_ENUM, - 'description' => 'Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, ios, android, and unity.', + 'description' => 'Platform type. Possible values are: web, flutter-web, flutter-ios, flutter-android, flutter-linux, flutter-macos, flutter-windows, apple-ios, apple-macos, apple-watchos, apple-tvos, android, unity, react-native-ios, react-native-android.', 'default' => '', 'example' => 'web', - 'enum' => ['web', 'flutter-web', 'flutter-ios', 'flutter-android', 'ios', 'android', 'unity'], + 'enum' => ['web', 'flutter-web', 'flutter-ios', 'flutter-android', 'flutter-linux', 'flutter-macos', 'flutter-windows', 'apple-ios', 'apple-macos', 'apple-watchos', 'apple-tvos', 'android', 'unity', 'react-native-ios', 'react-native-android'], ]) ->addRule('key', [ 'type' => self::TYPE_STRING, diff --git a/src/Appwrite/Utopia/Response/Model/Transaction.php b/src/Appwrite/Utopia/Response/Model/Transaction.php new file mode 100644 index 0000000000..aae2a9b572 --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/Transaction.php @@ -0,0 +1,60 @@ +addRule('$id', [ + 'type' => self::TYPE_STRING, + 'description' => 'Transaction ID.', + 'default' => '', + 'example' => '259125845563242502', + ]) + ->addRule('$createdAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Transaction creation time in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('$updatedAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Transaction update date in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]) + ->addRule('status', [ + 'type' => self::TYPE_STRING, + 'description' => 'Current status of the transaction. One of: pending, committing, committed, rolled_back, failed.', + 'default' => 'pending', + 'example' => 'pending', + ]) + ->addRule('operations', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Number of operations in the transaction.', + 'default' => 0, + 'example' => 5, + ]) + ->addRule('expiresAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Expiration time in ISO 8601 format.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE, + ]); + } + + public function getName(): string + { + return 'Transaction'; + } + + public function getType(): string + { + return Response::MODEL_TRANSACTION; + } +} diff --git a/src/Appwrite/Vcs/Comment.php b/src/Appwrite/Vcs/Comment.php index a66706a4a2..2a08b701f0 100644 --- a/src/Appwrite/Vcs/Comment.php +++ b/src/Appwrite/Vcs/Comment.php @@ -193,7 +193,7 @@ class Comment } $tip = $this->tips[array_rand($this->tips)]; - $text .= "\n
\n\n> [!NOTE]\n> $tip\n\n"; + $text .= "\n
\n\n> [!TIP]\n> $tip\n\n"; return $text; } diff --git a/tests/e2e/Services/Account/AccountBase.php b/tests/e2e/Services/Account/AccountBase.php index 8813e2784f..b2f85637a8 100644 --- a/tests/e2e/Services/Account/AccountBase.php +++ b/tests/e2e/Services/Account/AccountBase.php @@ -152,6 +152,8 @@ trait AccountBase public function testEmailOTPSession(): void { + $isConsoleProject = $this->getProject()['$id'] === 'console'; + $response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', @@ -183,6 +185,13 @@ trait AccountBase $this->assertNotEmpty($code); $this->assertStringContainsStringIgnoringCase('Use OTP ' . $code . ' to sign in to '. $this->getProject()['name'] . '. Expires in 15 minutes.', $lastEmail['text']); + // Only Console project has branded logo in email. + if ($isConsoleProject) { + $this->assertStringContainsStringIgnoringCase('Appwrite logo', $lastEmail['html']); + } else { + $this->assertStringNotContainsStringIgnoringCase('Appwrite logo', $lastEmail['html']); + } + $response = $this->client->call(Client::METHOD_POST, '/account/sessions/token', array_merge([ 'origin' => 'http://localhost', 'content-type' => 'application/json', diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index bd3fec8439..0993f68a58 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -924,7 +924,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals($email, $lastEmail['to'][0]['address']); $this->assertEquals($name, $lastEmail['to'][0]['name']); - $this->assertEquals('Account Verification', $lastEmail['subject']); + $this->assertEquals('Account Verification for ' . $this->getProject()['name'], $lastEmail['subject']); $this->assertStringContainsStringIgnoringCase('Verify your email to activate your ' . $this->getProject()['name'] . ' account.', $lastEmail['text']); $tokens = $this->extractQueryParamsFromEmailLink($lastEmail['html']); @@ -1228,7 +1228,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals($email, $lastEmail['to'][0]['address']); $this->assertEquals($name, $lastEmail['to'][0]['name']); - $this->assertEquals('Password Reset', $lastEmail['subject']); + $this->assertEquals('Password Reset for ' . $this->getProject()['name'], $lastEmail['subject']); $this->assertStringContainsStringIgnoringCase('Reset your ' . $this->getProject()['name'] . ' password using the link.', $lastEmail['text']); @@ -1539,6 +1539,77 @@ class AccountCustomClientTest extends Scope return []; } + public function testCreateOidcOAuth2Token(): array + { + $provider = 'oidc'; + $appId = '1'; + + // Valid well-known configuration + $secret = '{ + "wellKnownEndpoint": "https://accounts.google.com/.well-known/openid-configuration", + "authorizationEndpoint": "https://accounts.google.com/o/oauth2/v2/auth", + "tokenEndpoint": "https://oauth2.googleapis.com/token", + "userinfoEndpoint": "https://openidconnect.googleapis.com/v1/userinfo" + }'; + + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $this->getProject()['$id'] . '/oauth2', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => 'console', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'provider' => $provider, + 'appId' => $appId, + 'secret' => $secret, + 'enabled' => true, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, '/account/tokens/oauth2/' . $provider, array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'provider' => $provider, + 'success' => 'http://localhost/v1/mock/tests/general/oauth2/success', + 'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure', + ], true, false); + + $this->assertEquals(301, $response['headers']['status-code']); + + // Invalid well-known configuration + $secret = '{}'; + + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $this->getProject()['$id'] . '/oauth2', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => 'console', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'provider' => $provider, + 'appId' => $appId, + 'secret' => $secret, + 'enabled' => true, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, '/account/tokens/oauth2/' . $provider, array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ]), [ + 'provider' => $provider, + 'success' => 'http://localhost/v1/mock/tests/general/oauth2/success', + 'failure' => 'http://localhost/v1/mock/tests/general/oauth2/failure', + ]); + + $this->assertEquals(500, $response['headers']['status-code']); + + return []; + } + public function testBlockedAccount(): array { $email = uniqid() . 'user@localhost.test'; @@ -1850,6 +1921,26 @@ class AccountCustomClientTest extends Scope return $session; } + /** + * @depends testCreateAnonymousAccount + */ + public function testCreateAnonymousAccountVerification($session): array + { + $response = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, + ]), [ + 'url' => 'http://localhost/verification', + ]); + + $this->assertEquals(400, $response['body']['code']); + $this->assertEquals('user_email_not_found', $response['body']['type']); + + return []; + } + /** * @depends testCreateAnonymousAccount */ diff --git a/tests/e2e/Services/Console/ConsoleConsoleClientTest.php b/tests/e2e/Services/Console/ConsoleConsoleClientTest.php index 340cabc8c0..d94b64515a 100644 --- a/tests/e2e/Services/Console/ConsoleConsoleClientTest.php +++ b/tests/e2e/Services/Console/ConsoleConsoleClientTest.php @@ -24,9 +24,10 @@ class ConsoleConsoleClientTest extends Scope ], $this->getHeaders())); $this->assertEquals(200, $response['headers']['status-code']); - $this->assertCount(14, $response['body']); + $this->assertCount(15, $response['body']); $this->assertIsString($response['body']['_APP_DOMAIN_TARGET_CNAME']); $this->assertIsString($response['body']['_APP_DOMAIN_TARGET_A']); + $this->assertIsInt($response['body']['_APP_COMPUTE_BUILD_TIMEOUT']); $this->assertIsString($response['body']['_APP_DOMAIN_TARGET_AAAA']); $this->assertIsString($response['body']['_APP_DOMAIN_TARGET_CAA']); $this->assertIsInt($response['body']['_APP_STORAGE_LIMIT']); diff --git a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php index a432bc0acd..8827637427 100644 --- a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php +++ b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php @@ -1281,7 +1281,7 @@ trait DatabasesBase ]); $this->assertEquals(400, $fulltextReleaseYear['headers']['status-code']); - $this->assertEquals($fulltextReleaseYear['body']['message'], 'Attribute "releaseYear" cannot be part of a FULLTEXT index, must be of type string'); + $this->assertEquals($fulltextReleaseYear['body']['message'], 'Attribute "releaseYear" cannot be part of a fulltext index, must be of type string'); $noAttributes = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([ 'content-type' => 'application/json', @@ -1465,7 +1465,7 @@ trait DatabasesBase $this->assertEquals([128, 200], $index['body']['lengths']); // Test case for lengths array overriding - // set a length for an array attribute, it should get overriden with Database::ARRAY_INDEX_LENGTH + // set a length for an array attribute, it should get overriden with Database::MAX_ARRAY_INDEX_LENGTH $create = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/indexes", [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1483,7 +1483,7 @@ trait DatabasesBase 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] ]); - $this->assertEquals([Database::ARRAY_INDEX_LENGTH], $index['body']['lengths']); + $this->assertEquals([Database::MAX_ARRAY_INDEX_LENGTH], $index['body']['lengths']); // Test case for count of lengths greater than attributes (should throw 400) $create = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/indexes", [ @@ -4711,12 +4711,16 @@ trait DatabasesBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'queries' => [ + Query::select(['library.*'])->toString(), Query::equal('library.libraryName', ['Library 1'])->toString(), ], ]); - $this->assertEquals(400, $documents['headers']['status-code']); - $this->assertEquals('Invalid query: Cannot query nested attribute on: library', $documents['body']['message']); + $this->assertEquals(200, $documents['headers']['status-code']); + $this->assertEquals(1, $documents['body']['total']); + $this->assertCount(1, $documents['body']['documents']); + $this->assertEquals('Library 1', $documents['body']['documents'][0]['library']['libraryName']); + $this->assertEquals($person1['body']['$id'], $documents['body']['documents'][0]['$id']); $response = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $person['body']['$id'] . '/attributes/library', array_merge([ 'content-type' => 'application/json', diff --git a/tests/e2e/Services/Databases/Legacy/DatabasesPermissionsGuestTest.php b/tests/e2e/Services/Databases/Legacy/Permissions/DatabasesPermissionsGuestTest.php similarity index 99% rename from tests/e2e/Services/Databases/Legacy/DatabasesPermissionsGuestTest.php rename to tests/e2e/Services/Databases/Legacy/Permissions/DatabasesPermissionsGuestTest.php index abeef6c222..6496aa285a 100644 --- a/tests/e2e/Services/Databases/Legacy/DatabasesPermissionsGuestTest.php +++ b/tests/e2e/Services/Databases/Legacy/Permissions/DatabasesPermissionsGuestTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'AtomicityTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create collection with unique constraint + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'AtomicityTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add unique attribute + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'email', + 'size' => 256, + 'required' => true, + ]); + + // Add unique index + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'unique_email', + 'type' => Database::INDEX_UNIQUE, + 'attributes' => ['email'] + ]); + + sleep(3); + + // Create first document outside transaction + $doc1 = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => ID::unique(), + 'data' => [ + 'email' => 'existing@example.com' + ] + ]); + + $this->assertEquals(201, $doc1['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction['headers']['status-code'], 'Transaction creation should succeed. Response: ' . json_encode($transaction)); + $this->assertArrayHasKey('$id', $transaction['body'], 'Transaction response should have $id. Response body: ' . json_encode($transaction['body'])); + $transactionId = $transaction['body']['$id']; + + // Add operations - second one will fail due to unique constraint + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => [ + 'email' => 'newuser@example.com' // This should succeed + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => [ + 'email' => 'existing@example.com' // This will fail - duplicate + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => [ + 'email' => 'anotheruser@example.com' // This should not be created due to atomicity + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code'], 'Add operations failed. Response: ' . json_encode($response['body'])); + + // Attempt to commit - should fail due to unique constraint violation + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + if ($response['headers']['status-code'] === 200) { + // If transaction succeeded, all documents should be created + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Should have 4 documents total (1 original + 3 from transaction) + // But since we have a unique constraint violation, this might fail + $this->assertGreaterThanOrEqual(1, $documents['body']['total']); + } else { + $this->assertEquals(409, $response['headers']['status-code']); // Conflict error + + // Verify NO new documents were created (atomicity) + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(1, $documents['body']['total']); // Only the original document + $this->assertEquals('existing@example.com', $documents['body']['documents'][0]['email']); + } + } + + /** + * Test consistency - schema validation and constraints + */ + public function testConsistency(): void + { + // Create database + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ConsistencyTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create collection with required fields and constraints + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'ConsistencyTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add required string attribute + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'required_field', + 'size' => 256, + 'required' => true, + ]); + + // Add integer attribute with min/max constraints + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'age', + 'required' => true, + 'min' => 18, + 'max' => 100 + ]); + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $transactionId = $transaction['body']['$id']; + + // Add operations with both valid and invalid data + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => [ + 'required_field' => 'Valid User', + 'age' => 25 // Valid age + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => [ + 'required_field' => 'Too Young User', + 'age' => 10 // Below minimum - will fail constraint + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => [ + 'required_field' => 'Another Valid User', + 'age' => 30 // Valid but should not be created due to transaction failure + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Attempt to commit - should fail due to constraint violation + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertContains($response['headers']['status-code'], [400, 500], 'Transaction commit should fail due to validation. Response: ' . json_encode($response['body'])); + + // Verify no documents were created + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(0, $documents['body']['total']); + } + + /** + * Test isolation - concurrent transactions on same data + */ + public function testIsolation(): void + { + // Create database + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'IsolationTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create collection + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'IsolationTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add counter attribute + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/integer', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => true, + 'min' => 0, + 'max' => 1000000 + ]); + + sleep(2); + + // Create initial document with counter + $doc = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => 'shared_counter', + 'data' => [ + 'counter' => 0 + ] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create first transaction + $transaction1 = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction1['headers']['status-code'], 'Transaction 1 creation should succeed'); + $this->assertArrayHasKey('$id', $transaction1['body'], 'Transaction 1 response should have $id'); + $transactionId1 = $transaction1['body']['$id']; + + // Create second transaction + $transaction2 = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction2['headers']['status-code'], 'Transaction 2 creation should succeed'); + $this->assertArrayHasKey('$id', $transaction2['body'], 'Transaction 2 response should have $id'); + $transactionId2 = $transaction2['body']['$id']; + + // Transaction 1: Increment counter by 10 + $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId1}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'documentId' => 'shared_counter', + 'action' => 'increment', + 'data' => [ + 'attribute' => 'counter', + 'value' => 10 + ] + ] + ] + ]); + + // Transaction 2: Increment counter by 5 + $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId2}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'documentId' => 'shared_counter', + 'action' => 'increment', + 'data' => [ + 'attribute' => 'counter', + 'value' => 5 + ] + ] + ] + ]); + + // Commit first transaction + $response1 = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId1}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response1['headers']['status-code']); + + // Commit second transaction + $response2 = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response2['headers']['status-code']); + + // Check final value - both increments should be applied + $document = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/shared_counter", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Both increments should be applied: 0 + 10 + 5 = 15 + $this->assertEquals(15, $document['body']['counter']); + } + + /** + * Test durability - committed data persists + */ + public function testDurability(): void + { + // Create database + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DurabilityTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create collection + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'DurabilityTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add attribute + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create and commit transaction with multiple operations + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction['headers']['status-code'], 'Transaction creation should succeed'); + $this->assertArrayHasKey('$id', $transaction['body'], 'Transaction response should have $id'); + $transactionId = $transaction['body']['$id']; + + // Add multiple operations + $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'durable_doc_1', + 'data' => [ + 'data' => 'Important data 1' + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'durable_doc_2', + 'data' => [ + 'data' => 'Important data 2' + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'update', + 'documentId' => 'durable_doc_1', + 'data' => [ + 'data' => 'Updated important data 1' + ] + ] + ] + ]); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code'], 'Commit should succeed. Response: ' . json_encode($response['body'])); + $this->assertEquals('committed', $response['body']['status']); + + // List all documents to see what was created + $allDocs = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertGreaterThan(0, $allDocs['body']['total'], 'Should have created documents. Found: ' . json_encode($allDocs['body'])); + + // Verify documents exist and have correct data + $document1 = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $document1['headers']['status-code']); + $this->assertEquals('Updated important data 1', $document1['body']['data']); + + $document2 = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/durable_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $document2['headers']['status-code']); + $this->assertEquals('Important data 2', $document2['body']['data']); + + // Further update outside transaction to ensure persistence + $update = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'data' => [ + 'data' => 'Modified outside transaction' + ] + ]); + + $this->assertEquals(200, $update['headers']['status-code']); + + // Verify the update persisted + $document1 = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/durable_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Modified outside transaction', $document1['body']['data']); + + // List all documents to verify total count + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(2, $documents['body']['total']); + } +} diff --git a/tests/e2e/Services/Databases/Legacy/Transactions/TransactionsBase.php b/tests/e2e/Services/Databases/Legacy/Transactions/TransactionsBase.php new file mode 100644 index 0000000000..0f85de0ff5 --- /dev/null +++ b/tests/e2e/Services/Databases/Legacy/Transactions/TransactionsBase.php @@ -0,0 +1,4661 @@ +client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionTestDatabase' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Test creating a transaction with default TTL + $response = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertArrayHasKey('$id', $response['body']); + $this->assertArrayHasKey('status', $response['body']); + $this->assertArrayHasKey('operations', $response['body']); + $this->assertArrayHasKey('expiresAt', $response['body']); + $this->assertEquals('pending', $response['body']['status']); + $this->assertEquals(0, $response['body']['operations']); + + $transactionId1 = $response['body']['$id']; + + // Test creating a transaction with custom TTL + $response = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 900 + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals('pending', $response['body']['status']); + + $expiresAt = new \DateTime($response['body']['expiresAt']); + $now = new \DateTime(); + $diff = $expiresAt->getTimestamp() - $now->getTimestamp(); + $this->assertGreaterThan(800, $diff); + $this->assertLessThan(1000, $diff); + + $transactionId2 = $response['body']['$id']; + + // Test invalid TTL values + $response = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 30 // Below minimum + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 4000 // Above maximum + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test adding operations to a transaction + */ + public function testCreateOperations(): void + { + // Create database first + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionOperationsTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Create a collection for testing + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TransactionOperationsTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + $collectionId = $collection['body']['$id']; + + // Add attributes + $attribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + + // Wait for attribute to be created + sleep(2); + + // Add valid operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'doc1', + 'data' => [ + 'name' => 'Test Document 1' + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'doc2', + 'data' => [ + 'name' => 'Test Document 2' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(2, $response['body']['operations']); + + // Test adding more operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'update', + 'documentId' => 'doc1', + 'data' => [ + 'name' => 'Updated Document 1' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(3, $response['body']['operations']); + + // Test invalid database ID + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => 'invalid_database', + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code'], 'Invalid database should return 404. Got: ' . json_encode($response['body'])); + + // Test invalid collection ID + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => 'invalid_collection', + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + } + + /** + * Test committing a transaction + */ + public function testCommit(): void + { + // Create database first + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionCommitTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create collection + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TransactionCommitTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + $collectionId = $collection['body']['$id']; + + // Add attributes + $attribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Add operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'doc1', + 'data' => [ + 'name' => 'Test Document 1' + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'doc2', + 'data' => [ + 'name' => 'Test Document 2' + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'update', + 'documentId' => 'doc1', + 'data' => [ + 'name' => 'Updated Document 1' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(3, $response['body']['operations']); + + // Commit the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('committed', $response['body']['status']); + + // Verify documents were created + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $documents['headers']['status-code']); + $this->assertEquals(2, $documents['body']['total']); + + // Verify the update was applied + $doc1Found = false; + foreach ($documents['body']['documents'] as $doc) { + if ($doc['$id'] === 'doc1') { + $this->assertEquals('Updated Document 1', $doc['name']); + $doc1Found = true; + } + } + $this->assertTrue($doc1Found, 'Document doc1 should exist with updated name'); + + // Test committing already committed transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test rolling back a transaction + */ + public function testRollback(): void + { + // Create database first + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionRollbackTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Create a collection for rollback test + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TransactionRollbackTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add attribute + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'value', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Add operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'rollback_doc', + 'data' => [ + 'value' => 'Should not exist' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Rollback the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rollback' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('failed', $response['body']['status']); + + // Verify no documents were created + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $documents['headers']['status-code']); + $this->assertEquals(0, $documents['body']['total']); + } + + /** + * Test transaction expiration + */ + public function testTransactionExpiration(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ExpirationTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create transaction with minimum TTL (60 seconds) + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 60 + ]); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Add operation + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['data' => 'Should expire'] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Verify transaction was created with correct expiration + $txnDetails = $this->client->call(Client::METHOD_GET, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(200, $txnDetails['headers']['status-code']); + $this->assertEquals('pending', $txnDetails['body']['status']); + + // Verify expiration time is approximately 60 seconds from now + $expiresAt = new \DateTime($txnDetails['body']['expiresAt']); + $now = new \DateTime(); + $diff = $expiresAt->getTimestamp() - $now->getTimestamp(); + $this->assertGreaterThan(55, $diff); + $this->assertLessThan(65, $diff); + } + + /** + * Test maximum operations per transaction + */ + public function testTransactionSizeLimit(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'SizeLimitTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [Permission::create(Role::any())], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'value', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Try to add operations exceeding the limit (assuming limit is 100) + // We'll add 50 operations twice to test incremental limit + $operations = []; + for ($i = 0; $i < 50; $i++) { + $operations[] = [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'doc_' . $i, + 'data' => ['value' => 'Test ' . $i] + ]; + } + + // First batch should succeed + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => $operations + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(50, $response['body']['operations']); + + // Second batch of 50 more operations + $operations = []; + for ($i = 50; $i < 100; $i++) { + $operations[] = [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'documentId' => 'doc_' . $i, + 'action' => 'create', + 'data' => ['value' => 'Test ' . $i] + ]; + } + + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => $operations + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(100, $response['body']['operations']); + + // Try to add one more operation - should fail + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'doc_overflow', + 'data' => ['value' => 'This should fail'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test concurrent transactions with conflicting operations + */ + public function testConcurrentTransactionConflicts(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ConflictTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => true, + 'min' => 0, + 'max' => 1000000, + ]); + + sleep(2); + + // Create initial document + $doc = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'shared_doc', + 'data' => ['counter' => 100] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create two transactions + $txn1 = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $txn2 = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId1 = $txn1['body']['$id']; + $transactionId2 = $txn2['body']['$id']; + + // Both transactions try to update the same document + $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId1}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'update', + 'documentId' => 'shared_doc', + 'data' => ['counter' => 200] + ] + ] + ]); + + $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId2}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'update', + 'documentId' => 'shared_doc', + 'data' => ['counter' => 300] + ] + ] + ]); + + // Commit first transaction + $response1 = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId1}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response1['headers']['status-code']); + + // Commit second transaction - should fail with conflict + $response2 = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(409, $response2['headers']['status-code']); // Conflict + + // Verify the document has the value from first transaction + $doc = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/shared_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $doc['body']['counter']); + } + + /** + * Test deleting a document that's being updated in a transaction + */ + public function testDeleteDocumentDuringTransaction(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DeleteConflictDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create document + $doc = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'target_doc', + 'data' => ['data' => 'Original'] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add update operation to transaction + $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'update', + 'documentId' => 'target_doc', + 'data' => ['data' => 'Updated in transaction'] + ] + ] + ]); + + // Delete the document outside of transaction + $response = $this->client->call(Client::METHOD_DELETE, "/databases/{$databaseId}/collections/{$collectionId}/documents/target_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(204, $response['headers']['status-code']); + + // Try to commit transaction - should fail because document no longer exists + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(404, $response['headers']['status-code']); // Conflict + } + + /** + * Test bulk operations in transactions + */ + public function testBulkOperations(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkOpsDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); + + // Create some initial documents + for ($i = 1; $i <= 5; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'existing_' . $i, + 'data' => [ + 'name' => 'Existing ' . $i, + 'category' => 'old' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + // Bulk create + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkCreate', + 'data' => [ + ['$id' => 'bulk_1', 'name' => 'Bulk 1', 'category' => 'new'], + ['$id' => 'bulk_2', 'name' => 'Bulk 2', 'category' => 'new'], + ['$id' => 'bulk_3', 'name' => 'Bulk 3', 'category' => 'new'], + ] + ], + // Bulk update + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkUpdate', + 'data' => [ + 'queries' => [Query::equal('category', ['old'])->toString()], + 'data' => ['category' => 'updated'] + ] + ], + // Bulk delete + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => [Query::equal('name', ['Existing 5'])->toString()] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify results + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Should have 7 documents (5 existing - 1 deleted + 3 new) + $this->assertEquals(7, $documents['body']['total']); + + // Check categories were updated + $oldCategoryCount = 0; + $updatedCategoryCount = 0; + $newCategoryCount = 0; + + foreach ($documents['body']['documents'] as $doc) { + switch ($doc['category']) { + case 'old': + $oldCategoryCount++; + break; + case 'updated': + $updatedCategoryCount++; + break; + case 'new': + $newCategoryCount++; + break; + } + } + + $this->assertEquals(0, $oldCategoryCount); + $this->assertEquals(4, $updatedCategoryCount); // 4 existing docs updated + $this->assertEquals(3, $newCategoryCount); // 3 new docs + } + + /** + * Test transaction with mixed success and failure operations + */ + public function testPartialFailureRollback(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'PartialFailureDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes with constraints + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'email', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create unique index on email + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/indexes", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'unique_email', + 'type' => 'unique', + 'attributes' => ['email'], + ]); + + sleep(2); + + // Create an existing document + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => ID::unique(), + 'data' => ['email' => 'existing@example.com'] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add operations - mix of valid and invalid + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['email' => 'valid1@example.com'] // Valid + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['email' => 'valid2@example.com'] // Valid + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['email' => 'existing@example.com'] // Will fail - duplicate + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['email' => 'valid3@example.com'] // Would be valid but should rollback + ], + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Try to commit - should fail and rollback all operations + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(409, $response['headers']['status-code']); // Conflict due to duplicate + + // Verify NO new documents were created (atomicity) + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(1, $documents['body']['total']); // Only the original document + $this->assertEquals('existing@example.com', $documents['body']['documents'][0]['email']); + } + + /** + * Test double commit/rollback attempts + */ + public function testDoubleCommitRollback(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DoubleCommitDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [Permission::create(Role::any())], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Test double commit + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add operation + $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => ID::unique(), + 'data' => ['data' => 'Test'] + ] + ] + ]); + + // First commit + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Second commit attempt - should fail + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); // Bad request - already committed + + // Test double rollback + $transaction2 = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId2 = $transaction2['body']['$id']; + + // First rollback + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rollback' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Second rollback attempt - should fail + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rollback' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); // Bad request - already rolled back + } + + /** + * Test operations on non-existent documents + */ + public function testOperationsOnNonExistentDocuments(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'NonExistentDocDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Try to update non-existent document - should fail at staging time with early validation + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'update', + 'documentId' => 'non_existent_doc', + 'data' => ['data' => 'Should fail'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); // Document not found at staging time + + // Test delete non-existent document - should also fail at staging time with early validation + $transaction2 = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId2 = $transaction2['body']['$id']; + + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId2}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'delete', + 'documentId' => 'non_existent_doc', + 'data' => [] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); // Document not found at staging time + } + + /** + * Test createDocument with transactionId via normal route + */ + public function testCreateDocument(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'WriteRoutesTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $attributes = [ + ['key' => 'name', 'type' => 'string', 'size' => 256, 'required' => true], + ['key' => 'counter', 'type' => 'integer', 'required' => false, 'min' => 0, 'max' => 10000], + ['key' => 'category', 'type' => 'string', 'size' => 256, 'required' => false], + ['key' => 'data', 'type' => 'string', 'size' => 256, 'required' => false], + ]; + + foreach ($attributes as $attr) { + $type = $attr['type']; + unset($attr['type']); + + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/{$type}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), $attr); + + $this->assertEquals(202, $response['headers']['status-code']); + } + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Create document via normal route with transactionId + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'doc_from_route', + 'data' => [ + 'name' => 'Created via normal route', + 'counter' => 100, + 'category' => 'test' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Document should not exist outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_from_route", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should now exist + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_from_route", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Created via normal route', $response['body']['name']); + } + + /** + * Test updateDocument with transactionId via normal route + */ + public function testUpdateDocument(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'UpdateRouteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'min' => 0, + 'max' => 10000, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create document outside transaction + $doc = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'doc_to_update', + 'data' => [ + 'name' => 'Original name', + 'counter' => 50, + 'category' => 'original' + ] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Update document via normal route with transactionId + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'name' => 'Updated via normal route', + 'counter' => 150, + 'category' => 'updated' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should still have original values outside transaction + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Original name', $response['body']['name']); + $this->assertEquals(50, $response['body']['counter']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should now have updated values + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_to_update", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Updated via normal route', $response['body']['name']); + $this->assertEquals(150, $response['body']['counter']); + } + + /** + * Test upsertDocument with transactionId via normal route + */ + public function testUpsertDocument(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'UpsertRouteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'min' => 0, + 'max' => 10000, + ]); + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Upsert document (create) via normal route with transactionId + $response = $this->client->call(Client::METHOD_PUT, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'doc_upsert', + 'data' => [ + 'name' => 'Created by upsert', + 'counter' => 25 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Document should not exist outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Upsert same document (update) in same transaction + $response = $this->client->call(Client::METHOD_PUT, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'doc_upsert', + 'data' => [ + 'name' => 'Updated by upsert', + 'counter' => 75 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); // Upsert in transaction returns 201 + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should now exist with updated values + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Updated by upsert', $response['body']['name']); + $this->assertEquals(75, $response['body']['counter']); + } + + /** + * Test deleteDocument with transactionId via normal route + */ + public function testDeleteDocument(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DeleteRouteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create document outside transaction + $doc = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'doc_to_delete', + 'data' => ['name' => 'Will be deleted'] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Delete document via normal route with transactionId + $response = $this->client->call(Client::METHOD_DELETE, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'transactionId' => $transactionId + ]); + + $this->assertEquals(204, $response['headers']['status-code']); + + // Document should still exist outside transaction + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should no longer exist + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_to_delete", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + } + + /** + * Test bulkCreate with transactionId via normal route + */ + public function testBulkCreate(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkCreateTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk create via normal route with transactionId + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documents' => [ + [ + '$id' => 'bulk_create_1', + 'name' => 'Bulk created 1', + 'category' => 'bulk_created' + ], + [ + '$id' => 'bulk_create_2', + 'name' => 'Bulk created 2', + 'category' => 'bulk_created' + ], + [ + '$id' => 'bulk_create_3', + 'name' => 'Bulk created 3', + 'category' => 'bulk_created' + ] + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); // Bulk operations return 200 + + // Documents should not exist outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_created'])->toString()] + ]); + + $this->assertEquals(0, $response['body']['total']); + + // Individual document check + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/bulk_create_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should now exist + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_created'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + + // Verify individual documents + for ($i = 1; $i <= 3; $i++) { + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/bulk_create_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals("Bulk created {$i}", $response['body']['name']); + $this->assertEquals('bulk_created', $response['body']['category']); + } + } + + /** + * Test bulkUpdate with transactionId via normal route + */ + public function testBulkUpdate(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create documents for bulk testing + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'bulk_update_' . $i, + 'data' => [ + 'name' => 'Bulk doc ' . $i, + 'category' => 'bulk_test' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk update via normal route with transactionId + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('category', ['bulk_test'])->toString()], + 'data' => ['category' => 'bulk_updated'], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should still have original category outside transaction + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_test'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should now have updated category + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_updated'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + } + + /** + * Test bulkUpsert with transactionId via normal route + */ + public function testBulkUpsert(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpsertTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'min' => 0, + 'max' => 10000, + ]); + + sleep(3); + + // Create one document outside transaction + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'bulk_upsert_existing', + 'data' => [ + 'name' => 'Existing doc', + 'counter' => 10 + ] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk upsert via normal route with transactionId (updates existing, creates new) + $response = $this->client->call(Client::METHOD_PUT, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documents' => [ + [ + '$id' => 'bulk_upsert_existing', + 'name' => 'Updated existing', + 'counter' => 20 + ], + [ + '$id' => 'bulk_upsert_new', + 'name' => 'New doc', + 'counter' => 30 + ] + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Original document should be unchanged, new document shouldn't exist outside transaction + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/bulk_upsert_existing", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Existing doc', $response['body']['name']); + $this->assertEquals(10, $response['body']['counter']); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/bulk_upsert_new", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Check both documents exist with updated values + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/bulk_upsert_existing", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Updated existing', $response['body']['name']); + $this->assertEquals(20, $response['body']['counter']); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/bulk_upsert_new", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('New doc', $response['body']['name']); + $this->assertEquals(30, $response['body']['counter']); + } + + /** + * Test bulkDelete with transactionId via normal route + */ + public function testBulkDelete(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create documents for bulk testing + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'bulk_delete_' . $i, + 'data' => [ + 'name' => 'Delete doc ' . $i, + 'category' => 'bulk_delete_test' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk delete via normal route with transactionId + $response = $this->client->call(Client::METHOD_DELETE, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('category', ['bulk_delete_test'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); // Bulk delete with transaction returns 200 + + // Documents should still exist outside transaction + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_delete_test'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should now be deleted + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_delete_test'])->toString()] + ]); + + $this->assertEquals(0, $response['body']['total']); + } + + /** + * Test multiple single route operations in one transaction + */ + public function testMixedSingleOperations(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'MultipleSingleRoutesDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 256, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'priority', + 'required' => false, + 'min' => 1, + 'max' => 10, + ]); + + sleep(3); + + // Create an existing document outside transaction for testing + $existingDoc = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'existing_doc', + 'data' => [ + 'name' => 'Existing Document', + 'status' => 'active', + 'priority' => 5 + ] + ]); + + $this->assertEquals(201, $existingDoc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + $this->assertEquals(201, $transaction['headers']['status-code']); + + // 1. Create new document via normal route with transactionId + $response1 = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'new_doc_1', + 'data' => [ + 'name' => 'New Document 1', + 'status' => 'pending', + 'priority' => 1 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response1['headers']['status-code']); + + // 2. Create another document via normal route with transactionId + $response2 = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'new_doc_2', + 'data' => [ + 'name' => 'New Document 2', + 'status' => 'pending', + 'priority' => 2 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response2['headers']['status-code']); + + // 3. Update existing document via normal route with transactionId + $response3 = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/existing_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'updated', + 'priority' => 10 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response3['headers']['status-code']); + + // 4. Update the first new document (created in same transaction) + $response4 = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/new_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'active', + 'priority' => 8 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response4['headers']['status-code']); + + // 5. Delete the second new document (created in same transaction) + $response5 = $this->client->call(Client::METHOD_DELETE, "/databases/{$databaseId}/collections/{$collectionId}/documents/new_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'transactionId' => $transactionId + ]); + + $this->assertEquals(204, $response5['headers']['status-code']); + + // 6. Upsert a new document via normal route with transactionId + $response6 = $this->client->call(Client::METHOD_PUT, "/databases/{$databaseId}/collections/{$collectionId}/documents/upserted_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'upserted_doc', + 'data' => [ + 'name' => 'Upserted Document', + 'status' => 'new', + 'priority' => 3 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response6['headers']['status-code']); + + // Check transaction has correct number of operations + $txnDetails = $this->client->call(Client::METHOD_GET, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(200, $txnDetails['headers']['status-code']); + $this->assertEquals(6, $txnDetails['body']['operations']); // 6 operations total + + // Verify nothing exists outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/new_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/upserted_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Existing doc should still have original values + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/existing_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('active', $response['body']['status']); + $this->assertEquals(5, $response['body']['priority']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('committed', $response['body']['status']); + + // Verify final state after commit + // new_doc_1 should exist with updated values + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/new_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('New Document 1', $response['body']['name']); + $this->assertEquals('active', $response['body']['status']); + $this->assertEquals(8, $response['body']['priority']); + + // new_doc_2 should not exist (was deleted in transaction) + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/new_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // existing_doc should have updated values + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/existing_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('updated', $response['body']['status']); + $this->assertEquals(10, $response['body']['priority']); + + // upserted_doc should exist + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/upserted_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Upserted Document', $response['body']['name']); + $this->assertEquals('new', $response['body']['status']); + $this->assertEquals(3, $response['body']['priority']); + + // Verify total document count + $documents = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(3, $documents['body']['total']); // existing_doc, new_doc_1, upserted_doc + } + + /** + * Test mixed operations with transactions + */ + public function testMixedOperations(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'MixedOpsTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add operation via Operations\Add endpoint + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'create', + 'documentId' => 'mixed_doc1', + 'data' => ['name' => 'Via Operations Add'] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(1, $response['body']['operations']); + + // Add operation via normal route with transactionId + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'mixed_doc2', + 'data' => ['name' => 'Via normal route'], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Check transaction now has 2 operations + $txnDetails = $this->client->call(Client::METHOD_GET, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(2, $txnDetails['body']['operations']); + + // Both documents shouldn't exist yet + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/mixed_doc1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/mixed_doc2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Both documents should now exist + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/mixed_doc1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Via Operations Add', $response['body']['name']); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/mixed_doc2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Via normal route', $response['body']['name']); + } + + /** + * Test bulk update with queries that should match documents created in the same transaction + */ + public function testBulkUpdateWithTransactionAwareQueries(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkTxnAwareDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'age', + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for attributes to be created + + // Create some existing documents + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'existing_' . $i, + 'data' => [ + 'name' => 'Existing ' . $i, + 'age' => 20 + $i, + 'status' => 'inactive' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Create new documents with age > 25 in transaction + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'txn_doc_1', + 'data' => [ + 'name' => 'Transaction Doc 1', + 'age' => 30, + 'status' => 'inactive' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'txn_doc_2', + 'data' => [ + 'name' => 'Transaction Doc 2', + 'age' => 35, + 'status' => 'inactive' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Step 2: Bulk update all documents with age > 25 to have status 'active' + // This should match both existing_3 (age=23 doesn't match, age=24 doesn't match, but existing documents have age 21,22,23) + // Wait, let me fix the ages - existing docs have ages 21, 22, 23, so only txn docs should match + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'active' + ], + 'queries' => [Query::greaterThan('age', 25)->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify that documents created in the transaction were updated by the bulk update + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/txn_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('active', $response['body']['status'], 'Document created in transaction should be updated by bulk update query'); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/txn_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('active', $response['body']['status'], 'Document created in transaction should be updated by bulk update query'); + + // Verify existing documents were not affected + for ($i = 1; $i <= 3; $i++) { + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/existing_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('inactive', $response['body']['status'], "Existing document {$i} should remain inactive (age <= 25)"); + } + } + + /** + * Test bulk update with queries that should match documents updated in the same transaction + */ + public function testBulkUpdateMatchingUpdatedDocuments(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateTxnDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'priority', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for attributes to be created + + // Create existing documents + for ($i = 1; $i <= 4; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'doc_' . $i, + 'data' => [ + 'name' => 'Document ' . $i, + 'category' => 'normal', + 'priority' => 'low' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Update some documents to have category 'special' in transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'category' => 'special' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'category' => 'special' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Step 2: Bulk update all documents with category 'special' to have priority 'high' + // This should match the documents we just updated in the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'priority' => 'high' + ], + 'queries' => [Query::equal('category', ['special'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify that the updated documents were matched by bulk update + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('special', $response['body']['category']); + $this->assertEquals('high', $response['body']['priority'], 'Document updated in transaction should be matched by bulk update query'); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('special', $response['body']['category']); + $this->assertEquals('high', $response['body']['priority'], 'Document updated in transaction should be matched by bulk update query'); + + // Verify other documents were not affected + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_3", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('normal', $response['body']['category']); + $this->assertEquals('low', $response['body']['priority']); + } + + /** + * Test bulk delete with queries that should match documents created in the same transaction + */ + public function testBulkDeleteMatchingCreatedDocuments(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteTxnDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'type', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for attributes to be created + + // Create existing documents + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'existing_' . $i, + 'data' => [ + 'name' => 'Existing ' . $i, + 'type' => 'permanent' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Create temporary documents in transaction + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'temp_1', + 'data' => [ + 'name' => 'Temporary 1', + 'type' => 'temporary' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'temp_2', + 'data' => [ + 'name' => 'Temporary 2', + 'type' => 'temporary' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Step 2: Bulk delete all documents with type 'temporary' + // This should delete the documents we just created in the transaction + $response = $this->client->call(Client::METHOD_DELETE, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('type', ['temporary'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify temporary documents were deleted (should not exist) + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/temp_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Temporary document created and deleted in transaction should not exist'); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/temp_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Temporary document created and deleted in transaction should not exist'); + + // Verify existing documents were not affected + for ($i = 1; $i <= 3; $i++) { + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/existing_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code'], "Permanent document {$i} should still exist"); + $this->assertEquals('permanent', $response['body']['type']); + } + } + + /** + * Test bulk delete with queries that should match documents updated in the same transaction + */ + public function testBulkDeleteMatchingUpdatedDocuments(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteUpdateTxnDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Create attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for attributes to be created + + // Create existing documents + for ($i = 1; $i <= 5; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'documentId' => 'doc_' . $i, + 'data' => [ + 'name' => 'Document ' . $i, + 'status' => 'active' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Mark some documents for deletion by updating their status + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'marked_for_deletion' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_4", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'marked_for_deletion' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Step 2: Bulk delete all documents with status 'marked_for_deletion' + // This should delete the documents we just updated in the transaction + $response = $this->client->call(Client::METHOD_DELETE, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('status', ['marked_for_deletion'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify marked documents were deleted + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Document marked for deletion should have been deleted'); + + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_4", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Document marked for deletion should have been deleted'); + + // Verify other documents still exist + foreach ([1, 3, 5] as $i) { + $response = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/doc_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code'], "Document {$i} should still exist"); + $this->assertEquals('active', $response['body']['status']); + } + } + + /** + * Test increment and decrement operations in transaction + */ + public function testIncrementDecrementOperations(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'IncrementDecrementTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'CounterCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add integer attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'default' => 0, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'score', + 'required' => false, + 'default' => 100, + ]); + + sleep(2); + + // Create initial document + $doc = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => 'counter_doc', + 'data' => [ + 'counter' => 10, + 'score' => 50 + ] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add increment and decrement operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'increment', + 'documentId' => 'counter_doc', + 'data' => [ + 'attribute' => 'counter', + 'value' => 5, + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'decrement', + 'documentId' => 'counter_doc', + 'data' => [ + 'attribute' => 'score', + 'value' => 20, + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'increment', + 'documentId' => 'counter_doc', + 'data' => [ + 'attribute' => 'counter', + 'value' => 3, + 'max' => 20 + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'decrement', + 'documentId' => 'counter_doc', + 'data' => [ + 'attribute' => 'score', + 'value' => 30, + 'min' => 0 + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify final values + $doc = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/counter_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $doc['headers']['status-code']); + // counter: 10 + 5 + 3 = 18 (capped at 20 max) + $this->assertEquals(18, $doc['body']['counter']); + // score: 50 - 20 - 100 = -70, but min is 0 + $this->assertEquals(0, $doc['body']['score']); + } + + /** + * Test individual increment/decrement endpoints with transactions for Legacy Collections API + * This test ensures that: + * 1. Transaction logs store the correct attribute key ('attribute' for Collections API) + * 2. Mock responses return the correct ID keys ('$collectionId' not '$tableId') + */ + public function testIncrementDecrementEndpointsWithTransaction(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'IncrDecrEndpointTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'AccountsCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add balance attribute + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'balance', + 'required' => false, + 'default' => 0, + ]); + + sleep(2); + + // Create initial documents + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => 'joe', + 'data' => ['balance' => 100] + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => 'jane', + 'data' => ['balance' => 50] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test: Decrement using individual endpoint - should store 'attribute' not 'column' in transaction log + $decrementResponse = $this->client->call( + Client::METHOD_PATCH, + "/databases/{$databaseId}/collections/{$collectionId}/documents/joe/balance/decrement", + array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), + [ + 'transactionId' => $transactionId, + 'value' => 50, + 'min' => 0, + ] + ); + + // Test: Response should return '$collectionId' not '$tableId' for Collections API + $this->assertEquals(200, $decrementResponse['headers']['status-code']); + $this->assertArrayHasKey('$collectionId', $decrementResponse['body'], 'Response should contain $collectionId for Collections API'); + $this->assertArrayNotHasKey('$tableId', $decrementResponse['body'], 'Response should not contain $tableId for Collections API'); + $this->assertEquals($collectionId, $decrementResponse['body']['$collectionId']); + + // Test increment endpoint + $incrementResponse = $this->client->call( + Client::METHOD_PATCH, + "/databases/{$databaseId}/collections/{$collectionId}/documents/jane/balance/increment", + array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), + [ + 'transactionId' => $transactionId, + 'value' => 50, + ] + ); + + $this->assertEquals(200, $incrementResponse['headers']['status-code']); + $this->assertArrayHasKey('$collectionId', $incrementResponse['body'], 'Response should contain $collectionId for Collections API'); + $this->assertArrayNotHasKey('$tableId', $incrementResponse['body'], 'Response should not contain $tableId for Collections API'); + $this->assertEquals($collectionId, $incrementResponse['body']['$collectionId']); + + // Commit transaction - this will fail if transaction log has 'column' instead of 'attribute' + $commitResponse = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'commit' => true + ]); + + $this->assertEquals(200, $commitResponse['headers']['status-code'], 'Transaction commit should succeed'); + + // Verify final values + $joe = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/joe", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $jane = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents/jane", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $joe['headers']['status-code']); + $this->assertEquals(50, $joe['body']['balance'], 'Joe should have 100 - 50 = 50'); + + $this->assertEquals(200, $jane['headers']['status-code']); + $this->assertEquals(100, $jane['body']['balance'], 'Jane should have 50 + 50 = 100'); + } + + /** + * Test bulk update operations in transaction + */ + public function testBulkUpdateOperations(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'BulkUpdateCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 50, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 50, + 'required' => false, + ]); + + sleep(2); + + // Create initial documents + for ($i = 1; $i <= 5; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => "doc_{$i}", + 'data' => [ + 'status' => 'pending', + 'category' => $i % 2 === 0 ? 'even' : 'odd' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk update operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkUpdate', + 'data' => [ + 'queries' => [ + Query::equal('category', ['even'])->toString() + ], + 'data' => [ + 'status' => 'approved' + ] + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkUpdate', + 'data' => [ + 'queries' => [ + Query::equal('category', ['odd'])->toString() + ], + 'data' => [ + 'status' => 'rejected' + ] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify updates + $docs = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + foreach ($docs['body']['documents'] as $doc) { + if ($doc['category'] === 'even') { + $this->assertEquals('approved', $doc['status']); + } else { + $this->assertEquals('rejected', $doc['status']); + } + } + } + + /** + * Test bulk upsert operations in transaction + */ + public function testBulkUpsertOperations(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpsertTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'BulkUpsertCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 100, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'value', + 'required' => false, + ]); + + sleep(2); + + // Create some initial documents + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => 'existing_1', + 'data' => [ + 'name' => 'Existing Document 1', + 'value' => 10 + ] + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => 'existing_2', + 'data' => [ + 'name' => 'Existing Document 2', + 'value' => 20 + ] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk upsert operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkUpsert', + 'data' => [ + [ + '$id' => 'existing_1', + 'name' => 'Updated Document 1', + 'value' => 100 + ], + [ + '$id' => 'new_1', + 'name' => 'New Document 1', + 'value' => 30 + ], + [ + '$id' => 'new_2', + 'name' => 'New Document 2', + 'value' => 40 + ] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify results + $docs = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(4, $docs['body']['total']); + + $docMap = []; + foreach ($docs['body']['documents'] as $doc) { + $docMap[$doc['$id']] = $doc; + } + + // Verify updated document + $this->assertEquals('Updated Document 1', $docMap['existing_1']['name']); + $this->assertEquals(100, $docMap['existing_1']['value']); + + // Verify unchanged document + $this->assertEquals('Existing Document 2', $docMap['existing_2']['name']); + $this->assertEquals(20, $docMap['existing_2']['value']); + + // Verify new documents + $this->assertEquals('New Document 1', $docMap['new_1']['name']); + $this->assertEquals(30, $docMap['new_1']['value']); + $this->assertEquals('New Document 2', $docMap['new_2']['name']); + $this->assertEquals(40, $docMap['new_2']['value']); + } + + /** + * Test bulk delete operations in transaction + */ + public function testBulkDeleteOperations(): void + { + // Create database and collection + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'BulkDeleteCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $collectionId = $collection['body']['$id']; + + // Add attributes + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'type', + 'size' => 50, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/attributes/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'priority', + 'required' => false, + ]); + + sleep(2); + + // Create initial documents + for ($i = 1; $i <= 10; $i++) { + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => "doc_{$i}", + 'data' => [ + 'type' => $i <= 5 ? 'temp' : 'permanent', + 'priority' => $i + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk delete operations + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => [ + Query::equal('type', ['temp'])->toString() + ] + ] + ], + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => [ + Query::greaterThan('priority', 8)->toString() + ] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify deletions + $docs = $this->client->call(Client::METHOD_GET, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Should have deleted docs 1-5 (temp) and docs 9-10 (priority > 8) + // Remaining should be docs 6-8 + $this->assertEquals(3, $docs['body']['total']); + + $remainingIds = array_map(fn ($doc) => $doc['$id'], $docs['body']['documents']); + sort($remainingIds); + $this->assertEquals(['doc_6', 'doc_7', 'doc_8'], $remainingIds); + } + + /** + * Test validation for invalid operation inputs + */ + public function testCreateOperationsValidation(): void + { + // Create database and collection for testing + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ValidationTestDatabase' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'ValidationTest', + 'documentSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + $collectionId = $collection['body']['$id']; + + // Add required attribute + $attribute = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + + // Wait for attribute to be ready + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test 1: Invalid action type + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'invalidAction', + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'documentId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 2: Missing required action field + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'documentId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 3: Missing required databaseId field + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'collectionId' => $collectionId, + 'documentId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 4: Missing documentId for create operation + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 5: Missing data for create operation + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'documentId' => ID::unique() + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 6: BulkCreate with non-array data + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'bulkCreate', + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'data' => 'not an array' + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 7: BulkUpdate with missing queries + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'bulkUpdate', + 'databaseId' => $databaseId, + 'collectionId' => $collectionId, + 'data' => [ + 'data' => ['name' => 'Updated'] + ] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 8: Empty operations array + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 9: Operations not an array + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => 'not an array' + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test validation for committing/rolling back transactions + */ + public function testCommitRollbackValidation(): void + { + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test 1: Missing both commit and rollback + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), []); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 2: Both commit and rollback set to true + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true, + 'rollback' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 3: Invalid transaction ID + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/invalid_id", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Test 4: Attempt to commit already committed transaction + $response = $this->client->call(Client::METHOD_PATCH, "/databases/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test validation for non-existent resources + */ + public function testNonExistentResources(): void + { + // Create database and transaction + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ResourceTestDatabase' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + $transaction = $this->client->call(Client::METHOD_POST, '/databases/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test 1: Non-existent database + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => 'nonExistentDatabase', + 'collectionId' => 'someCollection', + 'documentId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Test 2: Non-existent collection + $response = $this->client->call(Client::METHOD_POST, "/databases/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => $databaseId, + 'collectionId' => 'nonExistentCollection', + 'documentId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + } +} diff --git a/tests/e2e/Services/Databases/Legacy/Transactions/TransactionsConsoleClientTest.php b/tests/e2e/Services/Databases/Legacy/Transactions/TransactionsConsoleClientTest.php new file mode 100644 index 0000000000..ef6e9d15d0 --- /dev/null +++ b/tests/e2e/Services/Databases/Legacy/Transactions/TransactionsConsoleClientTest.php @@ -0,0 +1,14 @@ +assertEquals(400, $fulltextReleaseYear['headers']['status-code']); - $this->assertEquals($fulltextReleaseYear['body']['message'], 'Attribute "releaseYear" cannot be part of a FULLTEXT index, must be of type string'); + $this->assertEquals($fulltextReleaseYear['body']['message'], 'Attribute "releaseYear" cannot be part of a fulltext index, must be of type string'); $noAttributes = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $data['moviesId'] . '/indexes', array_merge([ 'content-type' => 'application/json', @@ -4638,12 +4638,16 @@ trait DatabasesBase 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ 'queries' => [ + Query::select(['library.*'])->toString(), Query::equal('library.libraryName', ['Library 1'])->toString(), ], ]); - $this->assertEquals(400, $rows['headers']['status-code']); - $this->assertEquals('Invalid query: Cannot query nested attribute on: library', $rows['body']['message']); + $this->assertEquals(200, $rows['headers']['status-code']); + $this->assertEquals(1, $rows['body']['total']); + $this->assertCount(1, $rows['body']['rows']); + $this->assertEquals('Library 1', $rows['body']['rows'][0]['library']['libraryName']); + $this->assertEquals($person1['body']['$id'], $rows['body']['rows'][0]['$id']); $response = $this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $person['body']['$id'] . '/columns/library', array_merge([ 'content-type' => 'application/json', diff --git a/tests/e2e/Services/Databases/TablesDB/DatabasesPermissionsGuestTest.php b/tests/e2e/Services/Databases/TablesDB/Permissions/DatabasesPermissionsGuestTest.php similarity index 99% rename from tests/e2e/Services/Databases/TablesDB/DatabasesPermissionsGuestTest.php rename to tests/e2e/Services/Databases/TablesDB/Permissions/DatabasesPermissionsGuestTest.php index 71d033c89e..2f69c037d0 100644 --- a/tests/e2e/Services/Databases/TablesDB/DatabasesPermissionsGuestTest.php +++ b/tests/e2e/Services/Databases/TablesDB/Permissions/DatabasesPermissionsGuestTest.php @@ -1,6 +1,6 @@ client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'AtomicityTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create table with unique constraint + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'AtomicityTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add unique column + $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'email', + 'size' => 256, + 'required' => true, + ]); + + // Add unique index + $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/indexes', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'unique_email', + 'type' => Database::INDEX_UNIQUE, + 'columns' => ['email'] + ]); + + sleep(3); + + // Create first row outside transaction + $doc1 = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => ID::unique(), + 'data' => [ + 'email' => 'existing@example.com' + ] + ]); + + $this->assertEquals(201, $doc1['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction['headers']['status-code'], 'Transaction creation should succeed. Response: ' . json_encode($transaction)); + $this->assertArrayHasKey('$id', $transaction['body'], 'Transaction response should have $id. Response body: ' . json_encode($transaction['body'])); + $transactionId = $transaction['body']['$id']; + + // Add operations - second one will fail due to unique constraint + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => [ + 'email' => 'newuser@example.com' // This should succeed + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => [ + 'email' => 'existing@example.com' // This will fail - duplicate + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => [ + 'email' => 'anotheruser@example.com' // This should not be created due to atomicity + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code'], 'Add operations failed. Response: ' . json_encode($response['body'])); + + // Attempt to commit - should fail due to unique constraint violation + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + if ($response['headers']['status-code'] === 200) { + // If transaction succeeded, all rows should be created + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Should have 4 rows total (1 original + 3 from transaction) + // But since we have a unique constraint violation, this might fail + $this->assertGreaterThanOrEqual(1, $rows['body']['total']); + } else { + $this->assertEquals(409, $response['headers']['status-code']); // Conflict error + + // Verify NO new rows were created (atomicity) + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(1, $rows['body']['total']); // Only the original row + $this->assertEquals('existing@example.com', $rows['body']['rows'][0]['email']); + } + } + + /** + * Test consistency - schema validation and constraints + */ + public function testConsistency(): void + { + // Create database + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ConsistencyTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create table with required fields and constraints + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'ConsistencyTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add required string column + $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'required_field', + 'size' => 256, + 'required' => true, + ]); + + // Add integer column with min/max constraints + $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/integer', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'age', + 'required' => true, + 'min' => 18, + 'max' => 100 + ]); + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $transactionId = $transaction['body']['$id']; + + // Add operations with both valid and invalid data + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => [ + 'required_field' => 'Valid User', + 'age' => 25 // Valid age + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => [ + 'required_field' => 'Too Young User', + 'age' => 10 // Below minimum - will fail constraint + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => [ + 'required_field' => 'Another Valid User', + 'age' => 30 // Valid but should not be created due to transaction failure + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Attempt to commit - should fail due to constraint violation + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertContains($response['headers']['status-code'], [400, 500], 'Transaction commit should fail due to validation. Response: ' . json_encode($response['body'])); + + // Verify no rows were created + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(0, $rows['body']['total']); + } + + /** + * Test isolation - concurrent transactions on same data + */ + public function testIsolation(): void + { + // Create database + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'IsolationTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create table + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'IsolationTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add counter column + $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/integer', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => true, + 'min' => 0, + 'max' => 1000000 + ]); + + sleep(2); + + // Create initial row with counter + $doc = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'shared_counter', + 'data' => [ + 'counter' => 0 + ] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create first transaction + $transaction1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction1['headers']['status-code'], 'Transaction 1 creation should succeed'); + $this->assertArrayHasKey('$id', $transaction1['body'], 'Transaction 1 response should have $id'); + $transactionId1 = $transaction1['body']['$id']; + + // Create second transaction + $transaction2 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction2['headers']['status-code'], 'Transaction 2 creation should succeed'); + $this->assertArrayHasKey('$id', $transaction2['body'], 'Transaction 2 response should have $id'); + $transactionId2 = $transaction2['body']['$id']; + + // Transaction 1: Increment counter by 10 + $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId1}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => 'shared_counter', + 'action' => 'increment', + 'data' => [ + 'column' => 'counter', + 'value' => 10 + ] + ] + ] + ]); + + // Transaction 2: Increment counter by 5 + $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId2}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => 'shared_counter', + 'action' => 'increment', + 'data' => [ + 'column' => 'counter', + 'value' => 5 + ] + ] + ] + ]); + + // Commit first transaction + $response1 = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId1}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response1['headers']['status-code']); + + // Commit second transaction + $response2 = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response2['headers']['status-code']); + + // Check final value - both increments should be applied + $row = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/shared_counter", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Both increments should be applied: 0 + 10 + 5 = 15 + $this->assertEquals(15, $row['body']['counter']); + } + + /** + * Test durability - committed data persists + */ + public function testDurability(): void + { + // Create database + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DurabilityTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create table + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'DurabilityTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add column + $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create and commit transaction with multiple operations + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(201, $transaction['headers']['status-code'], 'Transaction creation should succeed'); + $this->assertArrayHasKey('$id', $transaction['body'], 'Transaction response should have $id'); + $transactionId = $transaction['body']['$id']; + + // Add multiple operations + $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'durable_doc_1', + 'data' => [ + 'data' => 'Important data 1' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'durable_doc_2', + 'data' => [ + 'data' => 'Important data 2' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'durable_doc_1', + 'data' => [ + 'data' => 'Updated important data 1' + ] + ] + ] + ]); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code'], 'Commit should succeed. Response: ' . json_encode($response['body'])); + $this->assertEquals('committed', $response['body']['status']); + + // List all rows to see what was created + $allDocs = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertGreaterThan(0, $allDocs['body']['total'], 'Should have created rows. Found: ' . json_encode($allDocs['body'])); + + // Verify rows exist and have correct data + $row1 = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/durable_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $row1['headers']['status-code']); + $this->assertEquals('Updated important data 1', $row1['body']['data']); + + $row2 = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/durable_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $row2['headers']['status-code']); + $this->assertEquals('Important data 2', $row2['body']['data']); + + // Further update outside transaction to ensure persistence + $update = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/durable_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'data' => [ + 'data' => 'Modified outside transaction' + ] + ]); + + $this->assertEquals(200, $update['headers']['status-code']); + + // Verify the update persisted + $row1 = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/durable_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Modified outside transaction', $row1['body']['data']); + + // List all rows to verify total count + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(2, $rows['body']['total']); + } +} diff --git a/tests/e2e/Services/Databases/TablesDB/Transactions/PermissionsBase.php b/tests/e2e/Services/Databases/TablesDB/Transactions/PermissionsBase.php new file mode 100644 index 0000000000..a1082256ee --- /dev/null +++ b/tests/e2e/Services/Databases/TablesDB/Transactions/PermissionsBase.php @@ -0,0 +1,1216 @@ +client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'PermissionsTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $this->permissionsDatabase = $database['body']['$id']; + } + + /** + * Test collection-level create permission check on staging + */ + public function testCollectionCreatePermissionDenied(): void + { + // Create a collection with no create permission for current user + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest1', + 'name' => 'Permission Test 1', + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => false, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Try to stage a create operation without permission, should fail + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'create', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'testDoc1', + 'data' => ['title' => 'Test Document'], + ]] + ]); + + // This should fail with 401 Unauthorized + if ($staged['headers']['status-code'] !== 401) { + echo "\nDEBUG - Actual response code: " . $staged['headers']['status-code'] . "\n"; + echo "DEBUG - Response body: " . json_encode($staged['body'], JSON_PRETTY_PRINT) . "\n"; + } + $this->assertEquals(401, $staged['headers']['status-code']); + } + + /** + * Test collection-level update permission check on staging + */ + public function testCollectionUpdatePermissionDenied(): void + { + // Create a collection with create but no update permission + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest2', + 'name' => 'Permission Test 2', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => false, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create a document first with API key + $doc = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/rows', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'testDoc2', + 'data' => ['title' => 'Original Title'], + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Try to stage an update operation without permission, should fail + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'update', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'testDoc2', + 'data' => ['title' => 'Updated Title'], + ]] + ]); + + // This should fail with 401 Unauthorized + $this->assertEquals(401, $staged['headers']['status-code']); + } + + /** + * Test collection-level delete permission check on staging + */ + public function testCollectionDeletePermissionDenied(): void + { + // Create a collection with create, read but no delete permission + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest3', + 'name' => 'Permission Test 3', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + 'rowSecurity' => false, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + $doc = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/rows', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'testDoc3', + 'data' => ['title' => 'To Be Deleted'], + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Try to stage a delete operation without permission, should fail + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'delete', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'testDoc3', + 'data' => [], + ]] + ]); + + // This should fail with 401 Unauthorized + $this->assertEquals(401, $staged['headers']['status-code']); + } + + /** + * Test document-level update permission grants access when rowSecurity is enabled + * Collection has no update permission, but document does, should succeed + */ + public function testDocumentLevelUpdatePermissionGranted(): void + { + // Create collection with rowSecurity enabled but no update permission at collection level + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest4', + 'name' => 'Permission Test 4', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + ], + 'rowSecurity' => true, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create a document with update permission at document level + $doc = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/rows', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'testDoc4', + 'data' => ['title' => 'Protected Document'], + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Stage an update, should succeed because document has update permission + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'update', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'testDoc4', + 'data' => ['title' => 'Trying to Update'], + ]] + ]); + + // This should succeed with 201 because document has update permission + $this->assertEquals(201, $staged['headers']['status-code']); + } + + /** + * Test document-level delete permission grants access when rowSecurity is enabled + * Collection has no delete permission, but document does, should succeed + */ + public function testDocumentLevelDeletePermissionGranted(): void + { + // Create collection with rowSecurity enabled but no delete permission at collection level + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest5', + 'name' => 'Permission Test 5', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + 'rowSecurity' => true, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create a document with delete permission at document level + $doc = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/rows', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'testDoc5', + 'data' => ['title' => 'Can Delete Me'], + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Stage a delete should succeed because document has delete permission + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'delete', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'testDoc5', + 'data' => [], + ]] + ]); + + // This should succeed with 201 because document has DELETE permission + $this->assertEquals(201, $staged['headers']['status-code']); + } + + /** + * Test that users cannot set permissions for roles they don't have + */ + public function testCannotSetUnauthorizedRolePermissions(): void + { + // Create a collection + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest6', + 'name' => 'Permission Test 6', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => true, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + // Add attribute + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Try to stage a create with team permissions, current user is not in team + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'create', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'testDoc6', + 'data' => [ + 'title' => 'Admin Only Doc', + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::team('adminTeam')), + ], + ], + ]] + ]); + + // This should fail with 401 Unauthorized, cannot set permissions for roles you don't have + $this->assertEquals(401, $staged['headers']['status-code']); + $this->assertStringContainsString('Permissions must be one of', $staged['body']['message']); + } + + /** + * Test successful staging when user has the required permissions + */ + public function testSuccessfulStagingWithProperPermissions(): void + { + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest7', + 'name' => 'Permission Test 7', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => true, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Stage a create with permissions for current user's roles, should succeed + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'create', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'testDoc7', + 'data' => [ + 'title' => 'Valid Document', + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::user($this->getUser()['$id'])), + ], + ], + ]] + ]); + + // This should succeed + $this->assertEquals(201, $staged['headers']['status-code']); + $this->assertEquals(1, $staged['body']['operations']); + } + + /** + * Test that non-existent documents cannot be updated in transactions + */ + public function testCannotUpdateNonExistentDocument(): void + { + // Create a collection + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest8', + 'name' => 'Permission Test 8', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => false, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Try to update a document that doesn't exist - should fail + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'update', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'nonExistentDoc', + 'data' => ['title' => 'Trying to Update'], + ]] + ]); + + // This should fail with 404 Not Found + $this->assertEquals(404, $staged['headers']['status-code']); + } + + /** + * Test that non-existent documents cannot be deleted in transactions + */ + public function testCannotDeleteNonExistentDocument(): void + { + // Create a collection + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest9', + 'name' => 'Permission Test 9', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => false, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Try to delete a document that doesn't exist, should fail + $staged = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'delete', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'nonExistentDoc', + 'data' => [], + ]] + ]); + + // This should fail with 404 Not Found + $this->assertEquals(404, $staged['headers']['status-code']); + } + + /** + * Test that a document created in one batch can be updated in a subsequent batch within the same transaction + * This validates the transactionState->getDocument() fix for cross-batch dependencies + */ + public function testCanUpdateDocumentCreatedInPreviousBatch(): void + { + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest10', + 'name' => 'Permission Test 10', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => false, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + + // Batch 1: Create a document + $batch1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'create', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'crossBatchDoc', + 'data' => [ + 'title' => 'Initial Title', + ], + ]] + ]); + + $this->assertEquals(201, $batch1['headers']['status-code']); + $this->assertEquals(1, $batch1['body']['operations']); + + // Batch 2: Update the document created in batch 1 + $batch2 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'update', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'crossBatchDoc', + 'data' => [ + 'title' => 'Updated Title', + ], + ]] + ]); + + // This should succeed with 201 because transactionState finds the staged document from batch 1 + $this->assertEquals(201, $batch2['headers']['status-code']); + $this->assertEquals(2, $batch2['body']['operations']); + + // Batch 3: Delete the same document + $batch3 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transaction['body']['$id'] . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [[ + 'action' => 'delete', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'crossBatchDoc', + 'data' => [], + ]] + ]); + + // This should also succeed with 201 + $this->assertEquals(201, $batch3['headers']['status-code']); + $this->assertEquals(3, $batch3['body']['operations']); + + // Rollback to clean up + $rollback = $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transaction['body']['$id'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rollback' => true, + ]); + + $this->assertEquals(200, $rollback['headers']['status-code']); + } + + /** + * Test that one user cannot read another user's transaction + */ + public function testUserCannotReadAnotherUsersTransaction(): void + { + // Create user 1 (fresh) and their transaction + $user1 = $this->getUser(true); + $user1Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user1['session'], + ]; + + $transaction1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(201, $transaction1['headers']['status-code']); + $transactionId1 = $transaction1['body']['$id']; + + // Create user 2 (fresh) + $user2 = $this->getUser(true); // Fresh user + $user2Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user2['session'], + ]; + + // User 2 tries to read User 1's transaction - should fail + $readAttempt = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user2Headers)); + + // This should fail with 404 Not Found (transaction doesn't exist for this user) + $this->assertEquals(404, $readAttempt['headers']['status-code']); + + // Verify User 1 can still read their own transaction + $readOwn = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(200, $readOwn['headers']['status-code']); + $this->assertEquals($transactionId1, $readOwn['body']['$id']); + } + + /** + * Test that one user cannot list another user's transactions + */ + public function testUserCannotListAnotherUsersTransactions(): void + { + // Create user 1 (fresh) with transactions + $user1 = $this->getUser(true); + $user1Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user1['session'], + ]; + + $transaction1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(201, $transaction1['headers']['status-code']); + + $transaction2 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(201, $transaction2['headers']['status-code']); + + // Create user 2 (fresh) with their own transaction + $user2 = $this->getUser(true); // Fresh user + $user2Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user2['session'], + ]; + + $transaction3 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user2Headers)); + + $this->assertEquals(201, $transaction3['headers']['status-code']); + + // User 2 lists transactions - should only see their own + $listUser2 = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user2Headers)); + + $this->assertEquals(200, $listUser2['headers']['status-code']); + $this->assertEquals(1, $listUser2['body']['total']); + $this->assertEquals($transaction3['body']['$id'], $listUser2['body']['transactions'][0]['$id']); + + // User 1 lists transactions - should only see their own (2 transactions) + $listUser1 = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(200, $listUser1['headers']['status-code']); + $this->assertEquals(2, $listUser1['body']['total']); + + // Verify neither of user1's transactions appear in user2's list + $user2TransactionIds = array_column($listUser2['body']['transactions'], '$id'); + $this->assertNotContains($transaction1['body']['$id'], $user2TransactionIds); + $this->assertNotContains($transaction2['body']['$id'], $user2TransactionIds); + } + + /** + * Test that one user cannot update another user's transaction + */ + public function testUserCannotUpdateAnotherUsersTransaction(): void + { + // Create user 1 (fresh) and their transaction + $user1 = $this->getUser(true); + $user1Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user1['session'], + ]; + + $transaction1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(201, $transaction1['headers']['status-code']); + $transactionId1 = $transaction1['body']['$id']; + + // Create user 2 (fresh) + $user2 = $this->getUser(true); // Fresh user + $user2Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user2['session'], + ]; + + // User 2 tries to commit User 1's transaction - should fail + $commitAttempt = $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user2Headers), [ + 'commit' => true, + ]); + + // This should fail with 404 Not Found + $this->assertEquals(404, $commitAttempt['headers']['status-code']); + + // User 2 tries to rollback User 1's transaction - should also fail + $rollbackAttempt = $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user2Headers), [ + 'rollback' => true, + ]); + + // This should also fail with 404 Not Found + $this->assertEquals(404, $rollbackAttempt['headers']['status-code']); + + // Verify User 1 can still commit their own transaction + $commitOwn = $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers), [ + 'commit' => true, + ]); + + $this->assertEquals(200, $commitOwn['headers']['status-code']); + } + + /** + * Test that one user cannot delete another user's transaction + */ + public function testUserCannotDeleteAnotherUsersTransaction(): void + { + // Create user 1 (fresh) and their transaction + $user1 = $this->getUser(true); + $user1Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user1['session'], + ]; + + $transaction1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(201, $transaction1['headers']['status-code']); + $transactionId1 = $transaction1['body']['$id']; + + // Create user 2 (fresh) + $user2 = $this->getUser(true); // Fresh user + $user2Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user2['session'], + ]; + + // User 2 tries to delete User 1's transaction - should fail + $deleteAttempt = $this->client->call(Client::METHOD_DELETE, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user2Headers)); + + // This should fail with 404 Not Found + $this->assertEquals(404, $deleteAttempt['headers']['status-code']); + + // Verify User 1 can still access their transaction + $readOwn = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(200, $readOwn['headers']['status-code']); + + // User 1 can delete their own transaction + $deleteOwn = $this->client->call(Client::METHOD_DELETE, '/tablesdb/transactions/' . $transactionId1, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(204, $deleteOwn['headers']['status-code']); + } + + /** + * Test that one user cannot add operations to another user's transaction + */ + public function testUserCannotAddOperationsToAnotherUsersTransaction(): void + { + // Create a collection for testing + $collection = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => 'permTest11', + 'name' => 'Permission Test 11', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'rowSecurity' => false, + ]); + + $this->assertEquals(201, $collection['headers']['status-code']); + + $attribute = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $this->permissionsDatabase . '/tables/' . $collection['body']['$id'] . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'title', + 'size' => 255, + 'required' => true, + ]); + + $this->assertEquals(202, $attribute['headers']['status-code']); + sleep(2); + + // Create user 1 (fresh) and their transaction + $user1 = $this->getUser(true); + $user1Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user1['session'], + ]; + + $transaction1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers)); + + $this->assertEquals(201, $transaction1['headers']['status-code']); + $transactionId1 = $transaction1['body']['$id']; + + // Create user 2 (fresh) + $user2 = $this->getUser(true); // Fresh user + $user2Headers = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user2['session'], + ]; + + // User 2 tries to add operations to User 1's transaction - should fail + $operationAttempt = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transactionId1 . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user2Headers), [ + 'operations' => [[ + 'action' => 'create', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'maliciousDoc', + 'data' => ['title' => 'Malicious Document'], + ]] + ]); + + // This should fail with 404 Not Found + $this->assertEquals(404, $operationAttempt['headers']['status-code']); + + // Verify User 1 can still add operations to their own transaction + $operationOwn = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transactionId1 . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $user1Headers), [ + 'operations' => [[ + 'action' => 'create', + 'databaseId' => $this->permissionsDatabase, + 'tableId' => $collection['body']['$id'], + 'rowId' => 'legitimateDoc', + 'data' => ['title' => 'Legitimate Document'], + ]] + ]); + + $this->assertEquals(201, $operationOwn['headers']['status-code']); + $this->assertEquals(1, $operationOwn['body']['operations']); + } + + /** + * Test that an authenticated user can successfully list their own transactions + */ + public function testAuthenticatedUserCanListTheirOwnTransactions(): void + { + // Create an authenticated user + $user = $this->getUser(); + $userHeaders = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user['session'], + ]; + + // Create multiple transactions for this user + $transactionIds = []; + for ($i = 0; $i < 3; $i++) { + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $this->assertNotEmpty($transaction['body']['$id']); + $transactionIds[] = $transaction['body']['$id']; + } + + // List transactions + $list = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(200, $list['headers']['status-code']); + $this->assertGreaterThanOrEqual(3, $list['body']['total']); + $this->assertIsArray($list['body']['transactions']); + $this->assertGreaterThanOrEqual(3, count($list['body']['transactions'])); + + // Verify all created transactions are in the list + $listedIds = array_column($list['body']['transactions'], '$id'); + foreach ($transactionIds as $transactionId) { + $this->assertContains($transactionId, $listedIds); + } + + // Verify transaction structure + foreach ($list['body']['transactions'] as $transaction) { + $this->assertArrayHasKey('$id', $transaction); + $this->assertArrayHasKey('$createdAt', $transaction); + $this->assertArrayHasKey('$updatedAt', $transaction); + $this->assertArrayHasKey('status', $transaction); + $this->assertArrayHasKey('operations', $transaction); + } + } + + /** + * Test that an authenticated user can successfully delete their own transaction + */ + public function testAuthenticatedUserCanDeleteTheirOwnTransaction(): void + { + // Create an authenticated user + $user = $this->getUser(); + $userHeaders = [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $user['session'], + ]; + + // Create a transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Verify transaction exists by reading it + $read = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(200, $read['headers']['status-code']); + $this->assertEquals($transactionId, $read['body']['$id']); + + // Delete the transaction + $delete = $this->client->call(Client::METHOD_DELETE, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(204, $delete['headers']['status-code']); + + // Verify transaction is deleted by trying to read it again + $readAfterDelete = $this->client->call(Client::METHOD_GET, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(404, $readAfterDelete['headers']['status-code']); + + // Create another transaction and verify it can also be deleted + $transaction2 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(201, $transaction2['headers']['status-code']); + $transactionId2 = $transaction2['body']['$id']; + + $delete2 = $this->client->call(Client::METHOD_DELETE, '/tablesdb/transactions/' . $transactionId2, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $userHeaders)); + + $this->assertEquals(204, $delete2['headers']['status-code']); + } +} diff --git a/tests/e2e/Services/Databases/TablesDB/Transactions/PermissionsCustomClientTest.php b/tests/e2e/Services/Databases/TablesDB/Transactions/PermissionsCustomClientTest.php new file mode 100644 index 0000000000..fa33aea7b6 --- /dev/null +++ b/tests/e2e/Services/Databases/TablesDB/Transactions/PermissionsCustomClientTest.php @@ -0,0 +1,14 @@ +client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionTestDatabase' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Test creating a transaction with default TTL + $response = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertArrayHasKey('$id', $response['body']); + $this->assertArrayHasKey('status', $response['body']); + $this->assertArrayHasKey('operations', $response['body']); + $this->assertArrayHasKey('expiresAt', $response['body']); + $this->assertEquals('pending', $response['body']['status']); + $this->assertEquals(0, $response['body']['operations']); + + $transactionId1 = $response['body']['$id']; + + // Test creating a transaction with custom TTL + $response = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 900 + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals('pending', $response['body']['status']); + + $expiresAt = new \DateTime($response['body']['expiresAt']); + $now = new \DateTime(); + $diff = $expiresAt->getTimestamp() - $now->getTimestamp(); + $this->assertGreaterThan(800, $diff); + $this->assertLessThan(1000, $diff); + + $transactionId2 = $response['body']['$id']; + + // Test invalid TTL values + $response = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 30 // Below minimum + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 4000 // Above maximum + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test adding operations to a transaction + */ + public function testCreateOperations(): void + { + // Create database first + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionOperationsTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Create a table for testing + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TransactionOperationsTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $table['headers']['status-code']); + $tableId = $table['body']['$id']; + + // Add columns + $column = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->assertEquals(202, $column['headers']['status-code']); + + // Wait for column to be created + sleep(2); + + // Add valid operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc1', + 'data' => [ + 'name' => 'Test Document 1' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc2', + 'data' => [ + 'name' => 'Test Document 2' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(2, $response['body']['operations']); + + // Test adding more operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'doc1', + 'data' => [ + 'name' => 'Updated Document 1' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(3, $response['body']['operations']); + + // Test invalid database ID + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => 'invalid_database', + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code'], 'Invalid database should return 404. Got: ' . json_encode($response['body'])); + + // Test invalid table ID + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => 'invalid_table', + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + } + + /** + * Test committing a transaction + */ + public function testCommit(): void + { + // Create database first + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionCommitTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create table + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TransactionCommitTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $table['headers']['status-code']); + $tableId = $table['body']['$id']; + + // Add columns + $column = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->assertEquals(202, $column['headers']['status-code']); + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Add operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc1', + 'data' => [ + 'name' => 'Test Document 1' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc2', + 'data' => [ + 'name' => 'Test Document 2' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'doc1', + 'data' => [ + 'name' => 'Updated Document 1' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(3, $response['body']['operations']); + + // Commit the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('committed', $response['body']['status']); + + // Verify rows were created + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $rows['headers']['status-code']); + $this->assertEquals(2, $rows['body']['total']); + + // Verify the update was applied + $doc1Found = false; + foreach ($rows['body']['rows'] as $doc) { + if ($doc['$id'] === 'doc1') { + $this->assertEquals('Updated Document 1', $doc['name']); + $doc1Found = true; + } + } + $this->assertTrue($doc1Found, 'Document doc1 should exist with updated name'); + + // Test committing already committed transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test rolling back a transaction + */ + public function testRollback(): void + { + // Create database first + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'TransactionRollbackTestDB' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Create a table for rollback test + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TransactionRollbackTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add column + $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'value', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Add operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'rollback_doc', + 'data' => [ + 'value' => 'Should not exist' + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Rollback the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rollback' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('failed', $response['body']['status']); + + // Verify no rows were created + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $rows['headers']['status-code']); + $this->assertEquals(0, $rows['body']['total']); + } + + /** + * Test transaction expiration + */ + public function testTransactionExpiration(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ExpirationTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create transaction with minimum TTL (60 seconds) + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 60 + ]); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Add operation + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['data' => 'Should expire'] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Verify transaction was created with correct expiration + $txnDetails = $this->client->call(Client::METHOD_GET, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(200, $txnDetails['headers']['status-code']); + $this->assertEquals('pending', $txnDetails['body']['status']); + + // Verify expiration time is approximately 60 seconds from now + $expiresAt = new \DateTime($txnDetails['body']['expiresAt']); + $now = new \DateTime(); + $diff = $expiresAt->getTimestamp() - $now->getTimestamp(); + $this->assertGreaterThan(55, $diff); + $this->assertLessThan(65, $diff); + } + + /** + * Test maximum operations per transaction + */ + public function testTransactionSizeLimit(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'SizeLimitTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [Permission::create(Role::any())], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'value', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Try to add operations exceeding the limit (assuming limit is 100) + // We'll add 50 operations twice to test incremental limit + $operations = []; + for ($i = 0; $i < 50; $i++) { + $operations[] = [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc_' . $i, + 'data' => ['value' => 'Test ' . $i] + ]; + } + + // First batch should succeed + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => $operations + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(50, $response['body']['operations']); + + // Second batch of 50 more operations + $operations = []; + for ($i = 50; $i < 100; $i++) { + $operations[] = [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => 'doc_' . $i, + 'action' => 'create', + 'data' => ['value' => 'Test ' . $i] + ]; + } + + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => $operations + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(100, $response['body']['operations']); + + // Try to add one more operation - should fail + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc_overflow', + 'data' => ['value' => 'This should fail'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test concurrent transactions with conflicting operations + */ + public function testConcurrentTransactionConflicts(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ConflictTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => true, + 'min' => 0, + 'max' => 1000000, + ]); + + sleep(2); + + // Create initial row + $doc = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'shared_doc', + 'data' => ['counter' => 100] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create two transactions + $txn1 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $txn2 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId1 = $txn1['body']['$id']; + $transactionId2 = $txn2['body']['$id']; + + // Both transactions try to update the same row + $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId1}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'shared_doc', + 'data' => ['counter' => 200] + ] + ] + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId2}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'shared_doc', + 'data' => ['counter' => 300] + ] + ] + ]); + + // Commit first transaction + $response1 = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId1}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response1['headers']['status-code']); + + // Commit second transaction - should fail with conflict + $response2 = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(409, $response2['headers']['status-code']); // Conflict + + // Verify the row has the value from first transaction + $doc = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/shared_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $doc['body']['counter']); + } + + /** + * Test deleting a row that's being updated in a transaction + */ + public function testDeleteDocumentDuringTransaction(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DeleteConflictDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create row + $doc = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'target_doc', + 'data' => ['data' => 'Original'] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add update operation to transaction + $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'target_doc', + 'data' => ['data' => 'Updated in transaction'] + ] + ] + ]); + + // Delete the row outside of transaction + $response = $this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/target_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(204, $response['headers']['status-code']); + + // Try to commit transaction - should fail because row no longer exists + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + } + + /** + * Test bulk operations in transactions + */ + public function testBulkOperations(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkOpsDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); + + // Create some initial rows + for ($i = 1; $i <= 5; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'existing_' . $i, + 'data' => [ + 'name' => 'Existing ' . $i, + 'category' => 'old' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + // Bulk create + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkCreate', + 'data' => [ + ['$id' => 'bulk_1', 'name' => 'Bulk 1', 'category' => 'new'], + ['$id' => 'bulk_2', 'name' => 'Bulk 2', 'category' => 'new'], + ['$id' => 'bulk_3', 'name' => 'Bulk 3', 'category' => 'new'], + ] + ], + // Bulk update + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkUpdate', + 'data' => [ + 'queries' => [Query::equal('category', ['old'])->toString()], + 'data' => ['category' => 'updated'] + ] + ], + // Bulk delete + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => [Query::equal('name', ['Existing 5'])->toString()] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify results + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Should have 7 rows (5 existing - 1 deleted + 3 new) + $this->assertEquals(7, $rows['body']['total']); + + // Check categories were updated + $oldCategoryCount = 0; + $updatedCategoryCount = 0; + $newCategoryCount = 0; + + foreach ($rows['body']['rows'] as $doc) { + switch ($doc['category']) { + case 'old': + $oldCategoryCount++; + break; + case 'updated': + $updatedCategoryCount++; + break; + case 'new': + $newCategoryCount++; + break; + } + } + + $this->assertEquals(0, $oldCategoryCount); + $this->assertEquals(4, $updatedCategoryCount); // 4 existing docs updated + $this->assertEquals(3, $newCategoryCount); // 3 new docs + } + + /** + * Test transaction with mixed success and failure operations + */ + public function testPartialFailureRollback(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'PartialFailureDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns with constraints + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'email', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create unique index on email + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/indexes", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'unique_email', + 'type' => 'unique', + 'columns' => ['email'], + ]); + + sleep(2); + + // Create an existing row + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => ID::unique(), + 'data' => ['email' => 'existing@example.com'] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add operations - mix of valid and invalid + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['email' => 'valid1@example.com'] // Valid + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['email' => 'valid2@example.com'] // Valid + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['email' => 'existing@example.com'] // Will fail - duplicate + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['email' => 'valid3@example.com'] // Would be valid but should rollback + ], + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Try to commit - should fail and rollback all operations + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(409, $response['headers']['status-code']); // Conflict due to duplicate + + // Verify NO new rows were created (atomicity) + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(1, $rows['body']['total']); // Only the original row + $this->assertEquals('existing@example.com', $rows['body']['rows'][0]['email']); + } + + /** + * Test double commit/rollback attempts + */ + public function testDoubleCommitRollback(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DoubleCommitDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [Permission::create(Role::any())], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Test double commit + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add operation + $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => ID::unique(), + 'data' => ['data' => 'Test'] + ] + ] + ]); + + // First commit + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Second commit attempt - should fail + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); // Bad request - already committed + + // Test double rollback + $transaction2 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId2 = $transaction2['body']['$id']; + + // First rollback + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rollback' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Second rollback attempt - should fail + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId2}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rollback' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); // Bad request - already rolled back + } + + /** + * Test operations on non-existent rows + */ + public function testOperationsOnNonExistentDocuments(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'NonExistentDocDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'data', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Try to update non-existent row - should fail at staging time with early validation + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'non_existent_doc', + 'data' => ['data' => 'Should fail'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); // Document not found at staging time + + // Test delete non-existent row - should also fail at staging time with early validation + $transaction2 = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId2 = $transaction2['body']['$id']; + + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId2}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'delete', + 'rowId' => 'non_existent_doc', + 'data' => [] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); // Document not found at staging time + } + + /** + * Test createDocument with transactionId via normal route + */ + public function testCreateDocument(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'WriteRoutesTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $columns = [ + ['key' => 'name', 'type' => 'string', 'size' => 256, 'required' => true], + ['key' => 'counter', 'type' => 'integer', 'required' => false, 'min' => 0, 'max' => 10000], + ['key' => 'category', 'type' => 'string', 'size' => 256, 'required' => false], + ['key' => 'data', 'type' => 'string', 'size' => 256, 'required' => false], + ]; + + foreach ($columns as $attr) { + $type = $attr['type']; + unset($attr['type']); + + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/{$type}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), $attr); + + $this->assertEquals(202, $response['headers']['status-code']); + } + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Create row via normal route with transactionId + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'doc_from_route', + 'data' => [ + 'name' => 'Created via normal route', + 'counter' => 100, + 'category' => 'test' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Document should not exist outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_from_route", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should now exist + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_from_route", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Created via normal route', $response['body']['name']); + } + + /** + * Test updateDocument with transactionId via normal route + */ + public function testUpdateDocument(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'UpdateRouteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'min' => 0, + 'max' => 10000, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create row outside transaction + $doc = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'doc_to_update', + 'data' => [ + 'name' => 'Original name', + 'counter' => 50, + 'category' => 'original' + ] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Update row via normal route with transactionId + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_to_update", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'name' => 'Updated via normal route', + 'counter' => 150, + 'category' => 'updated' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should still have original values outside transaction + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_to_update", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Original name', $response['body']['name']); + $this->assertEquals(50, $response['body']['counter']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should now have updated values + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_to_update", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Updated via normal route', $response['body']['name']); + $this->assertEquals(150, $response['body']['counter']); + } + + /** + * Test upsertDocument with transactionId via normal route + */ + public function testUpsertDocument(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'UpsertRouteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'min' => 0, + 'max' => 10000, + ]); + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Upsert row (create) via normal route with transactionId + $response = $this->client->call(Client::METHOD_PUT, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'doc_upsert', + 'data' => [ + 'name' => 'Created by upsert', + 'counter' => 25 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Document should not exist outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Upsert same row (update) in same transaction + $response = $this->client->call(Client::METHOD_PUT, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'doc_upsert', + 'data' => [ + 'name' => 'Updated by upsert', + 'counter' => 75 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); // Upsert in transaction returns 201 + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should now exist with updated values + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_upsert", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Updated by upsert', $response['body']['name']); + $this->assertEquals(75, $response['body']['counter']); + } + + /** + * Test deleteDocument with transactionId via normal route + */ + public function testDeleteDocument(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'DeleteRouteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create row outside transaction + $doc = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'doc_to_delete', + 'data' => ['name' => 'Will be deleted'] + ]); + + $this->assertEquals(201, $doc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Delete row via normal route with transactionId + $response = $this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_to_delete", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'transactionId' => $transactionId + ]); + + $this->assertEquals(204, $response['headers']['status-code']); + + // Document should still exist outside transaction + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_to_delete", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Document should no longer exist + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_to_delete", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + } + + /** + * Test bulkCreate with transactionId via normal route + */ + public function testBulkCreate(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkCreateTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk create via normal route with transactionId + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rows' => [ + [ + '$id' => 'bulk_create_1', + 'name' => 'Bulk created 1', + 'category' => 'bulk_created' + ], + [ + '$id' => 'bulk_create_2', + 'name' => 'Bulk created 2', + 'category' => 'bulk_created' + ], + [ + '$id' => 'bulk_create_3', + 'name' => 'Bulk created 3', + 'category' => 'bulk_created' + ] + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); // Bulk operations return 200 + + // Documents should not exist outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_created'])->toString()] + ]); + + $this->assertEquals(0, $response['body']['total']); + + // Individual row check + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/bulk_create_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should now exist + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_created'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + + // Verify individual rows + for ($i = 1; $i <= 3; $i++) { + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/bulk_create_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals("Bulk created {$i}", $response['body']['name']); + $this->assertEquals('bulk_created', $response['body']['category']); + } + } + + /** + * Test bulkUpdate with transactionId via normal route + */ + public function testBulkUpdate(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create rows for bulk testing + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'bulk_update_' . $i, + 'data' => [ + 'name' => 'Bulk doc ' . $i, + 'category' => 'bulk_test' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk update via normal route with transactionId + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('category', ['bulk_test'])->toString()], + 'data' => ['category' => 'bulk_updated'], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should still have original category outside transaction + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_test'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should now have updated category + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_updated'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + } + + /** + * Test bulkUpsert with transactionId via normal route + */ + public function testBulkUpsert(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpsertTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'min' => 0, + 'max' => 10000, + ]); + + sleep(3); + + // Create one row outside transaction + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'bulk_upsert_existing', + 'data' => [ + 'name' => 'Existing doc', + 'counter' => 10 + ] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk upsert via normal route with transactionId (updates existing, creates new) + $response = $this->client->call(Client::METHOD_PUT, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rows' => [ + [ + '$id' => 'bulk_upsert_existing', + 'name' => 'Updated existing', + 'counter' => 20 + ], + [ + '$id' => 'bulk_upsert_new', + 'name' => 'New doc', + 'counter' => 30 + ] + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Original row should be unchanged, new row shouldn't exist outside transaction + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/bulk_upsert_existing", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Existing doc', $response['body']['name']); + $this->assertEquals(10, $response['body']['counter']); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/bulk_upsert_new", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Check both rows exist with updated values + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/bulk_upsert_existing", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('Updated existing', $response['body']['name']); + $this->assertEquals(20, $response['body']['counter']); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/bulk_upsert_new", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('New doc', $response['body']['name']); + $this->assertEquals(30, $response['body']['counter']); + } + + /** + * Test bulkDelete with transactionId via normal route + */ + public function testBulkDelete(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + // Create rows for bulk testing + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'bulk_delete_' . $i, + 'data' => [ + 'name' => 'Delete doc ' . $i, + 'category' => 'bulk_delete_test' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Bulk delete via normal route with transactionId + $response = $this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('category', ['bulk_delete_test'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); // Bulk delete with transaction returns 200 + + // Documents should still exist outside transaction + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_delete_test'])->toString()] + ]); + + $this->assertEquals(3, $response['body']['total']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Documents should now be deleted + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => [Query::equal('category', ['bulk_delete_test'])->toString()] + ]); + + $this->assertEquals(0, $response['body']['total']); + } + + /** + * Test multiple single route operations in one transaction + */ + public function testMixedSingleOperations(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'MultipleSingleRoutesDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 256, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'priority', + 'required' => false, + 'min' => 1, + 'max' => 10, + ]); + + sleep(3); + + // Create an existing row outside transaction for testing + $existingDoc = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'existing_doc', + 'data' => [ + 'name' => 'Existing Document', + 'status' => 'active', + 'priority' => 5 + ] + ]); + + $this->assertEquals(201, $existingDoc['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + $this->assertEquals(201, $transaction['headers']['status-code']); + + // 1. Create new row via normal route with transactionId + $response1 = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'new_doc_1', + 'data' => [ + 'name' => 'New Document 1', + 'status' => 'pending', + 'priority' => 1 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response1['headers']['status-code']); + + // 2. Create another row via normal route with transactionId + $response2 = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'new_doc_2', + 'data' => [ + 'name' => 'New Document 2', + 'status' => 'pending', + 'priority' => 2 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response2['headers']['status-code']); + + // 3. Update existing row via normal route with transactionId + $response3 = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/existing_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'updated', + 'priority' => 10 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response3['headers']['status-code']); + + // 4. Update the first new row (created in same transaction) + $response4 = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/new_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'active', + 'priority' => 8 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response4['headers']['status-code']); + + // 5. Delete the second new row (created in same transaction) + $response5 = $this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/new_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'transactionId' => $transactionId + ]); + + $this->assertEquals(204, $response5['headers']['status-code']); + + // 6. Upsert a new row via normal route with transactionId + $response6 = $this->client->call(Client::METHOD_PUT, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/upserted_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'upserted_doc', + 'data' => [ + 'name' => 'Upserted Document', + 'status' => 'new', + 'priority' => 3 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response6['headers']['status-code']); + + // Check transaction has correct number of operations + $txnDetails = $this->client->call(Client::METHOD_GET, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(200, $txnDetails['headers']['status-code']); + $this->assertEquals(6, $txnDetails['body']['operations']); // 6 operations total + + // Verify nothing exists outside transaction yet + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/new_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/upserted_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Existing doc should still have original values + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/existing_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('active', $response['body']['status']); + $this->assertEquals(5, $response['body']['priority']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('committed', $response['body']['status']); + + // Verify final state after commit + // new_doc_1 should exist with updated values + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/new_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('New Document 1', $response['body']['name']); + $this->assertEquals('active', $response['body']['status']); + $this->assertEquals(8, $response['body']['priority']); + + // new_doc_2 should not exist (was deleted in transaction) + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/new_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // existing_doc should have updated values + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/existing_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals('updated', $response['body']['status']); + $this->assertEquals(10, $response['body']['priority']); + + // upserted_doc should exist + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/upserted_doc", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Upserted Document', $response['body']['name']); + $this->assertEquals('new', $response['body']['status']); + $this->assertEquals(3, $response['body']['priority']); + + // Verify total row count + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(3, $rows['body']['total']); // existing_doc, new_doc_1, upserted_doc + } + + /** + * Test mixed operations with transactions + */ + public function testMixedOperations(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'MixedOpsTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add operation via Operations\Add endpoint + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'mixed_doc1', + 'data' => ['name' => 'Via Operations Add'] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $this->assertEquals(1, $response['body']['operations']); + + // Add operation via normal route with transactionId + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'mixed_doc2', + 'data' => ['name' => 'Via normal route'], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Check transaction now has 2 operations + $txnDetails = $this->client->call(Client::METHOD_GET, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ])); + + $this->assertEquals(2, $txnDetails['body']['operations']); + + // Both rows shouldn't exist yet + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/mixed_doc1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/mixed_doc2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Both rows should now exist + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/mixed_doc1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Via Operations Add', $response['body']['name']); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/mixed_doc2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Via normal route', $response['body']['name']); + } + + /** + * Test bulk update with queries that should match rows created in the same transaction + */ + public function testBulkUpdateWithTransactionAwareQueries(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkTxnAwareDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'age', + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for columns to be created + + // Create some existing rows + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'existing_' . $i, + 'data' => [ + 'name' => 'Existing ' . $i, + 'age' => 20 + $i, + 'status' => 'inactive' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Create new rows with age > 25 in transaction + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'txn_doc_1', + 'data' => [ + 'name' => 'Transaction Doc 1', + 'age' => 30, + 'status' => 'inactive' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'txn_doc_2', + 'data' => [ + 'name' => 'Transaction Doc 2', + 'age' => 35, + 'status' => 'inactive' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Step 2: Bulk update all rows with age > 25 to have status 'active' + // This should match both existing_3 (age=23 doesn't match, age=24 doesn't match, but existing rows have age 21,22,23) + // Wait, let me fix the ages - existing docs have ages 21, 22, 23, so only txn docs should match + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'active' + ], + 'queries' => [Query::greaterThan('age', 25)->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify that rows created in the transaction were updated by the bulk update + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/txn_doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('active', $response['body']['status'], 'Document created in transaction should be updated by bulk update query'); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/txn_doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('active', $response['body']['status'], 'Document created in transaction should be updated by bulk update query'); + + // Verify existing rows were not affected + for ($i = 1; $i <= 3; $i++) { + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/existing_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('inactive', $response['body']['status'], "Existing row {$i} should remain inactive (age <= 25)"); + } + } + + /** + * Test bulk update with queries that should match rows updated in the same transaction + */ + public function testBulkUpdateMatchingUpdatedDocuments(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateTxnDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'priority', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for columns to be created + + // Create existing rows + for ($i = 1; $i <= 4; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'doc_' . $i, + 'data' => [ + 'name' => 'Document ' . $i, + 'category' => 'normal', + 'priority' => 'low' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Update some rows to have category 'special' in transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'category' => 'special' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'category' => 'special' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Step 2: Bulk update all rows with category 'special' to have priority 'high' + // This should match the rows we just updated in the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'priority' => 'high' + ], + 'queries' => [Query::equal('category', ['special'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify that the updated rows were matched by bulk update + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('special', $response['body']['category']); + $this->assertEquals('high', $response['body']['priority'], 'Document updated in transaction should be matched by bulk update query'); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('special', $response['body']['category']); + $this->assertEquals('high', $response['body']['priority'], 'Document updated in transaction should be matched by bulk update query'); + + // Verify other rows were not affected + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_3", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('normal', $response['body']['category']); + $this->assertEquals('low', $response['body']['priority']); + } + + /** + * Test bulk delete with queries that should match rows created in the same transaction + */ + public function testBulkDeleteMatchingCreatedDocuments(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteTxnDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'type', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for columns to be created + + // Create existing rows + for ($i = 1; $i <= 3; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'existing_' . $i, + 'data' => [ + 'name' => 'Existing ' . $i, + 'type' => 'permanent' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Create temporary rows in transaction + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'temp_1', + 'data' => [ + 'name' => 'Temporary 1', + 'type' => 'temporary' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'temp_2', + 'data' => [ + 'name' => 'Temporary 2', + 'type' => 'temporary' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Step 2: Bulk delete all rows with type 'temporary' + // This should delete the rows we just created in the transaction + $response = $this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('type', ['temporary'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify temporary rows were deleted (should not exist) + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/temp_1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Temporary row created and deleted in transaction should not exist'); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/temp_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Temporary row created and deleted in transaction should not exist'); + + // Verify existing rows were not affected + for ($i = 1; $i <= 3; $i++) { + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/existing_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code'], "Permanent row {$i} should still exist"); + $this->assertEquals('permanent', $response['body']['type']); + } + } + + /** + * Test bulk delete with queries that should match rows updated in the same transaction + */ + public function testBulkDeleteMatchingUpdatedDocuments(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteUpdateTxnDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 256, + 'required' => true, + ]); + + sleep(3); // Wait for columns to be created + + // Create existing rows + for ($i = 1; $i <= 5; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'doc_' . $i, + 'data' => [ + 'name' => 'Document ' . $i, + 'status' => 'active' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Step 1: Mark some rows for deletion by updating their status + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'marked_for_deletion' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_4", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'status' => 'marked_for_deletion' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Step 2: Bulk delete all rows with status 'marked_for_deletion' + // This should delete the rows we just updated in the transaction + $response = $this->client->call(Client::METHOD_DELETE, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'queries' => [Query::equal('status', ['marked_for_deletion'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify marked rows were deleted + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_2", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Document marked for deletion should have been deleted'); + + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_4", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(404, $response['headers']['status-code'], 'Document marked for deletion should have been deleted'); + + // Verify other rows still exist + foreach ([1, 3, 5] as $i) { + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc_{$i}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code'], "Document {$i} should still exist"); + $this->assertEquals('active', $response['body']['status']); + } + } + + /** + * Test increment and decrement operations in transaction + */ + public function testIncrementDecrementOperations(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'IncrementDecrementTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'CounterTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add integer columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'default' => 0, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'score', + 'required' => false, + 'default' => 100, + ]); + + sleep(2); + + // Create initial row + $row = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'counter_row', + 'data' => [ + 'counter' => 10, + 'score' => 50 + ] + ]); + + $this->assertEquals(201, $row['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add increment and decrement operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'increment', + 'rowId' => 'counter_row', + 'data' => [ + 'column' => 'counter', + 'value' => 5, + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'decrement', + 'rowId' => 'counter_row', + 'data' => [ + 'column' => 'score', + 'value' => 20, + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'increment', + 'rowId' => 'counter_row', + 'data' => [ + 'column' => 'counter', + 'value' => 3, + 'max' => 20 + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'decrement', + 'rowId' => 'counter_row', + 'data' => [ + 'column' => 'score', + 'value' => 30, + 'min' => 0 + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify final values + $row = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/counter_row", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $row['headers']['status-code']); + // counter: 10 + 5 + 3 = 18 (capped at 20 max) + $this->assertEquals(18, $row['body']['counter']); + // score: 50 - 20 - 100 = -70, but min is 0 + $this->assertEquals(0, $row['body']['score']); + } + + /** + * Test increment followed by update (read-your-writes) + * This test ensures that after an increment operation, subsequent operations + * in the same transaction can see the incremented value in the transaction state. + */ + public function testIncrementThenUpdate(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'IncrementUpdateTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'CounterTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'default' => 0, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 50, + 'required' => false, + ]); + + sleep(2); + + // Create initial row + $row = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'test_row', + 'data' => [ + 'counter' => 10, + 'status' => 'initial' + ] + ]); + + $this->assertEquals(201, $row['headers']['status-code']); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add operations: increment then update + // The update operation needs to see the document in transaction state + // to properly merge the changes + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'increment', + 'rowId' => 'test_row', + 'data' => [ + 'column' => 'counter', + 'value' => 5, + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'update', + 'rowId' => 'test_row', + 'data' => [ + 'status' => 'updated' + ] + ], + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify final values - both increment and update should be applied + $row = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/test_row", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $row['headers']['status-code']); + $this->assertEquals(15, $row['body']['counter'], 'Counter should be incremented: 10 + 5 = 15'); + $this->assertEquals('updated', $row['body']['status'], 'Status should be updated'); + } + + /** + * Test individual increment/decrement endpoints with transactions + * This test ensures that: + * 1. Transaction logs store the correct attribute key ('column' for TablesDB) + * 2. Mock responses return the correct ID keys ('$tableId' not '$collectionId') + */ + public function testIncrementDecrementEndpointsWithTransaction(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'IncrDecrEndpointTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'AccountsTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add balance column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'balance', + 'required' => false, + 'default' => 0, + ]); + + sleep(2); + + // Create initial rows + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'joe', + 'data' => ['balance' => 100] + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'jane', + 'data' => ['balance' => 50] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test Bug 1: Decrement using individual endpoint - should store 'column' not 'attribute' in transaction log + $decrementResponse = $this->client->call( + Client::METHOD_PATCH, + "/tablesdb/{$databaseId}/tables/{$tableId}/rows/joe/balance/decrement", + array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), + [ + 'transactionId' => $transactionId, + 'value' => 50, + 'min' => 0, + ] + ); + + // Test Bug 2: Response should return '$tableId' not '$collectionId' + $this->assertEquals(200, $decrementResponse['headers']['status-code']); + $this->assertArrayHasKey('$tableId', $decrementResponse['body'], 'Response should contain $tableId for TablesDB API'); + $this->assertArrayNotHasKey('$collectionId', $decrementResponse['body'], 'Response should not contain $collectionId for TablesDB API'); + $this->assertEquals($tableId, $decrementResponse['body']['$tableId']); + + // Test increment endpoint + $incrementResponse = $this->client->call( + Client::METHOD_PATCH, + "/tablesdb/{$databaseId}/tables/{$tableId}/rows/jane/balance/increment", + array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), + [ + 'transactionId' => $transactionId, + 'value' => 50, + ] + ); + + $this->assertEquals(200, $incrementResponse['headers']['status-code']); + $this->assertArrayHasKey('$tableId', $incrementResponse['body'], 'Response should contain $tableId for TablesDB API'); + $this->assertArrayNotHasKey('$collectionId', $incrementResponse['body'], 'Response should not contain $collectionId for TablesDB API'); + $this->assertEquals($tableId, $incrementResponse['body']['$tableId']); + + // Commit transaction - this will fail if transaction log has 'attribute' instead of 'column' + $commitResponse = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'commit' => true + ]); + + $this->assertEquals(200, $commitResponse['headers']['status-code'], 'Transaction commit should succeed'); + + // Verify final values + $joe = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/joe", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $jane = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/jane", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $joe['headers']['status-code']); + $this->assertEquals(50, $joe['body']['balance'], 'Joe should have 100 - 50 = 50'); + + $this->assertEquals(200, $jane['headers']['status-code']); + $this->assertEquals(100, $jane['body']['balance'], 'Jane should have 50 + 50 = 100'); + } + + /** + * Test cross-API compatibility: stage operations via TablesDB, commit via Collections API + * This ensures fallback logic works when APIs are mixed + */ + public function testCrossAPIIncrementDecrement(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'CrossAPITestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'CrossAPITable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add balance column + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'balance', + 'required' => false, + 'default' => 0, + ]); + + sleep(2); + + // Create initial row + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'test', + 'data' => ['balance' => 100] + ]); + + // Create transaction using TablesDB API + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Stage operations using TablesDB API (will store 'column' key) + $this->client->call( + Client::METHOD_PATCH, + "/tablesdb/{$databaseId}/tables/{$tableId}/rows/test/balance/decrement", + array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), + [ + 'transactionId' => $transactionId, + 'value' => 30, + ] + ); + + // Commit using Collections API (expects 'attribute' key but should fallback to 'column') + $commitResponse = $this->client->call( + Client::METHOD_PATCH, + "/databases/transactions/{$transactionId}", + array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), + [ + 'commit' => true + ] + ); + + $this->assertEquals(200, $commitResponse['headers']['status-code'], 'Cross-API commit should succeed'); + + // Verify final value + $row = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/test", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $row['headers']['status-code']); + $this->assertEquals(70, $row['body']['balance'], 'Balance should be 100 - 30 = 70'); + } + + public function testBulkUpdateWithDependentDocuments(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateDependentDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 50, + 'required' => false, + ]); + + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Create a document, then bulk update it - this triggers the state structure bug + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc1', + 'data' => [ + 'status' => 'pending' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkUpdate', + 'data' => [ + 'queries' => [], + 'data' => [ + 'status' => 'approved' + ] + ] + ], + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code'], 'Bulk update should succeed on dependent documents'); + + // Verify the document was updated + $row = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $row['headers']['status-code']); + $this->assertEquals('approved', $row['body']['status']); + } + + /** + * Test bulk delete with dependent documents (Bug #2 regression test) + */ + public function testBulkDeleteWithDependentDocuments(): void + { + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteDependentDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 50, + 'required' => false, + ]); + + sleep(2); + + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Create then bulk delete + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc1', + 'data' => [ + 'name' => 'Test' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => [], + ] + ], + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code'], 'Bulk delete should succeed on dependent documents'); + + // Verify document was deleted + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(0, $rows['body']['total']); + } + + /** + * Test bulk upsert with dependent documents (Bug #3 regression test) + */ + public function testBulkUpsertWithDependentDocuments(): void + { + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpsertDependentDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 50, + 'required' => false, + ]); + + sleep(2); + + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Create then bulk upsert same document + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'create', + 'rowId' => 'doc1', + 'data' => [ + 'status' => 'pending' + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkUpsert', + 'data' => [ + [ + '$id' => 'doc1', + 'status' => 'approved' + ] + ] + ], + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code'], 'Bulk upsert should succeed on dependent documents'); + + $row = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/doc1", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $row['headers']['status-code']); + $this->assertEquals('approved', $row['body']['status']); + } + + /** + * Test bulk update operations in transaction + */ + public function testBulkUpdateOperations(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'BulkUpdateTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 50, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'category', + 'size' => 50, + 'required' => false, + ]); + + sleep(2); + + // Create initial rows + for ($i = 1; $i <= 5; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => "row_{$i}", + 'data' => [ + 'status' => 'pending', + 'category' => $i % 2 === 0 ? 'even' : 'odd' + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk update operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkUpdate', + 'data' => [ + 'queries' => [ + Query::equal('category', ['even'])->toString() + ], + 'data' => [ + 'status' => 'approved' + ] + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkUpdate', + 'data' => [ + 'queries' => [ + Query::equal('category', ['odd'])->toString() + ], + 'data' => [ + 'status' => 'rejected' + ] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify updates + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + foreach ($rows['body']['rows'] as $row) { + if ($row['category'] === 'even') { + $this->assertEquals('approved', $row['status']); + } else { + $this->assertEquals('rejected', $row['status']); + } + } + } + + /** + * Test bulk upsert operations in transaction + */ + public function testBulkUpsertOperations(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpsertTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'BulkUpsertTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 100, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'value', + 'required' => false, + ]); + + sleep(2); + + // Create some initial rows + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'existing_1', + 'data' => [ + 'name' => 'Existing Row 1', + 'value' => 10 + ] + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => 'existing_2', + 'data' => [ + 'name' => 'Existing Row 2', + 'value' => 20 + ] + ]); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk upsert operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkUpsert', + 'data' => [ + [ + '$id' => 'existing_1', + 'name' => 'Updated Row 1', + 'value' => 100 + ], + [ + '$id' => 'new_1', + 'name' => 'New Row 1', + 'value' => 30 + ], + [ + '$id' => 'new_2', + 'name' => 'New Row 2', + 'value' => 40 + ] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify results + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(4, $rows['body']['total']); + + $rowMap = []; + foreach ($rows['body']['rows'] as $row) { + $rowMap[$row['$id']] = $row; + } + + // Verify updated row + $this->assertEquals('Updated Row 1', $rowMap['existing_1']['name']); + $this->assertEquals(100, $rowMap['existing_1']['value']); + + // Verify unchanged row + $this->assertEquals('Existing Row 2', $rowMap['existing_2']['name']); + $this->assertEquals(20, $rowMap['existing_2']['value']); + + // Verify new rows + $this->assertEquals('New Row 1', $rowMap['new_1']['name']); + $this->assertEquals(30, $rowMap['new_1']['value']); + $this->assertEquals('New Row 2', $rowMap['new_2']['name']); + $this->assertEquals(40, $rowMap['new_2']['value']); + } + + /** + * Test bulk delete operations in transaction + */ + public function testBulkDeleteOperations(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkDeleteTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'BulkDeleteTable', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Add columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'type', + 'size' => 50, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'priority', + 'required' => false, + ]); + + sleep(2); + + // Create initial rows + for ($i = 1; $i <= 10; $i++) { + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rowId' => "row_{$i}", + 'data' => [ + 'type' => $i <= 5 ? 'temp' : 'permanent', + 'priority' => $i + ] + ]); + } + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Add bulk delete operations + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => [ + Query::equal('type', ['temp'])->toString() + ] + ] + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'action' => 'bulkDelete', + 'data' => [ + 'queries' => [ + Query::greaterThan('priority', 8)->toString() + ] + ] + ] + ] + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify deletions + $rows = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + // Should have deleted rows 1-5 (temp) and rows 9-10 (priority > 8) + // Remaining should be rows 6-8 + $this->assertEquals(3, $rows['body']['total']); + + $remainingIds = array_map(fn ($row) => $row['$id'], $rows['body']['rows']); + sort($remainingIds); + $this->assertEquals(['row_6', 'row_7', 'row_8'], $remainingIds); + } + + /** + * Test validation for invalid operation inputs + */ + public function testCreateOperationsValidation(): void + { + // Create database and table for testing + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ValidationTestDatabase' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'ValidationTest', + 'rowSecurity' => false, + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $this->assertEquals(201, $table['headers']['status-code']); + $tableId = $table['body']['$id']; + + // Add required column + $column = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->assertEquals(202, $column['headers']['status-code']); + + // Wait for column to be ready + sleep(2); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test 1: Invalid action type + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'invalidAction', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 2: Missing required action field + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 3: Missing required databaseId field + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'tableId' => $tableId, + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 4: Missing required tableId field + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => $databaseId, + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 5: Missing rowId for create operation + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 6: Missing data for create operation + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => ID::unique() + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 7: BulkCreate with non-array data + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'bulkCreate', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'data' => 'not an array' + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 8: BulkUpdate with missing queries + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'bulkUpdate', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'data' => [ + 'data' => ['name' => 'Updated'] + ] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 9: BulkUpdate with invalid query format + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'bulkUpdate', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'data' => [ + 'queries' => 'not an array', + 'data' => ['name' => 'Updated'] + ] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 10: BulkDelete with missing queries + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'bulkDelete', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'data' => [] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 11: Increment with missing attribute + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'increment', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => ID::unique(), + 'data' => ['value' => 1] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 12: Decrement with invalid value type + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'decrement', + 'databaseId' => $databaseId, + 'tableId' => $tableId, + 'rowId' => ID::unique(), + 'data' => [ + 'attribute' => 'counter', + 'value' => 'not a number' + ] + ] + ] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 13: Empty operations array + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [] + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 14: Operations not an array + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => 'not an array' + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test validation for committing/rolling back transactions + */ + public function testCommitRollbackValidation(): void + { + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test 1: Missing both commit and rollback + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), []); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 2: Both commit and rollback set to true + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true, + 'rollback' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + // Test 3: Invalid transaction ID + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/invalid_id", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Commit the transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Test 4: Attempt to commit already committed transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + } + + /** + * Test validation for non-existent resources + */ + public function testNonExistentResources(): void + { + // Create database and transaction + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'ResourceTestDatabase' + ]); + + $this->assertEquals(201, $database['headers']['status-code']); + $databaseId = $database['body']['$id']; + + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(201, $transaction['headers']['status-code']); + $transactionId = $transaction['body']['$id']; + + // Test 1: Non-existent database + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => 'nonExistentDatabase', + 'tableId' => 'someTable', + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + + // Test 2: Non-existent table + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/transactions/{$transactionId}/operations", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'operations' => [ + [ + 'action' => 'create', + 'databaseId' => $databaseId, + 'tableId' => 'nonExistentTable', + 'rowId' => ID::unique(), + 'data' => ['name' => 'Test'] + ] + ] + ]); + + $this->assertEquals(404, $response['headers']['status-code']); + } + + /** + * Test that bulkUpdate can match documents created in the same transaction + * This tests the fix for the bug where applyBulkUpdateToState was treating + * state entries as Documents instead of arrays with 'document' keys + */ + public function testBulkUpdateMatchesCreatedDocsInSameTransaction(): void + { + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'BulkUpdateStateDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestTable', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'status', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'flag', + 'size' => 256, + 'required' => false, + ]); + + sleep(3); + + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // Create 3 documents with status='pending' in transaction + $docIds = []; + for ($i = 1; $i <= 3; $i++) { + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => 'test_' . $i, + 'data' => [ + 'status' => 'pending' + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $docIds[] = $response['body']['$id']; + } + + // Bulk update all documents with status='pending' to add flag='processed' + // This should match all 3 documents created above in the same transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'flag' => 'processed' + ], + 'queries' => [Query::equal('status', ['pending'])->toString()], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify all 3 documents have the flag set + foreach ($docIds as $docId) { + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/{$docId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('pending', $response['body']['status']); + $this->assertEquals('processed', $response['body']['flag'], 'Bulk update should have matched document created in same transaction'); + } + } + + /** + * Test upsert with auto-generated ID followed by update + * This tests that the transaction state properly stores the document under its actual ID, + * not under null when the ID is auto-generated + */ + public function testUpsertAutoIdThenUpdate(): void + { + // Create database and table + $database = $this->client->call(Client::METHOD_POST, '/tablesdb', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'UpsertAutoIDTestDB' + ]); + + $databaseId = $database['body']['$id']; + + $table = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'tableId' => ID::unique(), + 'name' => 'TestCollection', + 'permissions' => [ + Permission::create(Role::any()), + Permission::read(Role::any()), + Permission::update(Role::any()), + ], + ]); + + $tableId = $table['body']['$id']; + + // Create columns + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/columns/integer", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'counter', + 'required' => false, + 'min' => 0, + 'max' => 10000, + ]); + + sleep(3); + + // Create transaction + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $transactionId = $transaction['body']['$id']; + + // First create a document in the transaction + $response = $this->client->call(Client::METHOD_POST, "/tablesdb/{$databaseId}/tables/{$tableId}/rows", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'rowId' => ID::unique(), + 'data' => [ + 'name' => 'Initial document', + 'counter' => 5 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $docId = $response['body']['$id']; + + // Now upsert the same document using ID::unique() in the path + // The database will recognize it exists and update it, generating a new auto ID if needed + // This tests that handleUpsertOperation properly captures the actual document ID + $response = $this->client->call(Client::METHOD_PUT, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/{$docId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'name' => 'Upserted in transaction', + 'counter' => 10 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Now try to update the same document again in the same transaction + // This verifies that the upsert properly stored the document under its actual ID in state + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/{$docId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'name' => 'Updated after upsert', + 'counter' => 20 + ], + 'transactionId' => $transactionId + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Commit transaction + $response = $this->client->call(Client::METHOD_PATCH, "/tablesdb/transactions/{$transactionId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'commit' => true + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + + // Verify the document has the final updated values + $response = $this->client->call(Client::METHOD_GET, "/tablesdb/{$databaseId}/tables/{$tableId}/rows/{$docId}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals('Updated after upsert', $response['body']['name']); + $this->assertEquals(20, $response['body']['counter']); + } +} diff --git a/tests/e2e/Services/Databases/TablesDB/Transactions/TransactionsConsoleClientTest.php b/tests/e2e/Services/Databases/TablesDB/Transactions/TransactionsConsoleClientTest.php new file mode 100644 index 0000000000..2159390fa2 --- /dev/null +++ b/tests/e2e/Services/Databases/TablesDB/Transactions/TransactionsConsoleClientTest.php @@ -0,0 +1,14 @@ + 10, ]); $this->assertEquals(401, $function['headers']['status-code']); + + + /** + * Test for DUPLICATE functionId + */ + $functionId = $this->setupFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'execute' => [Role::user($this->getUser()['$id'])->toString()], + 'runtime' => 'node-22', + 'entrypoint' => 'index.js', + 'events' => [ + 'users.*.create', + 'users.*.delete', + ], + 'timeout' => 10, + ]); + + $response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), [ + 'functionId' => $functionId, + 'name' => 'Test', + 'execute' => [Role::user($this->getUser()['$id'])->toString()], + 'runtime' => 'node-22', + 'entrypoint' => 'index.js', + 'events' => [ + 'users.*.create', + 'users.*.delete', + ], + 'timeout' => 10, + ]); + $this->assertEquals(409, $response['headers']['status-code']); } public function testCreateExecution() diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index e297757225..4e479344d3 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -113,13 +113,33 @@ class ProjectsConsoleClientTest extends Scope ]; } - /** - * @depends testCreateProject - */ - public function testCreateDuplicateProject($data) + public function testCreateDuplicateProject(): void { - $teamId = $data['teamId'] ?? ''; - $projectId = $data['projectId'] ?? ''; + // Create a team + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Duplicate Test Team', + ]); + + $this->assertEquals(201, $team['headers']['status-code']); + $teamId = $team['body']['$id']; + + // Create a project + $projectId = ID::unique(); + $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'projectId' => $projectId, + 'name' => 'Original Project', + 'teamId' => $teamId, + 'region' => System::getEnv('_APP_REGION', 'default') + ]); + + $this->assertEquals(201, $response['headers']['status-code']); /** * Test for FAILURE @@ -417,12 +437,32 @@ class ProjectsConsoleClientTest extends Scope return $data; } - /** - * @depends testCreateProject - */ - public function testGetProject($data): array + public function testGetProject(): void { - $id = $data['projectId'] ?? ''; + // Create a team + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Get Project Test Team', + ]); + + $this->assertEquals(201, $team['headers']['status-code']); + + // Create a project + $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Project Test', + 'teamId' => $team['body']['$id'], + 'region' => System::getEnv('_APP_REGION', 'default') + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $id = $response['body']['$id']; /** * Test for SUCCESS @@ -440,7 +480,6 @@ class ProjectsConsoleClientTest extends Scope /** * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_GET, '/projects/empty', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -454,8 +493,6 @@ class ProjectsConsoleClientTest extends Scope ], $this->getHeaders())); $this->assertEquals(400, $response['headers']['status-code']); - - return $data; } /** @@ -513,12 +550,33 @@ class ProjectsConsoleClientTest extends Scope return $data; } - /** - * @depends testCreateProject - */ - public function testUpdateProject($data): array + public function testUpdateProject(): void { - $id = $data['projectId'] ?? ''; + // Create a team + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Update Project Test Team', + ]); + + $this->assertEquals(201, $team['headers']['status-code']); + $teamId = $team['body']['$id']; + + // Create a project + $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Project Test', + 'teamId' => $teamId, + 'region' => System::getEnv('_APP_REGION', 'default') + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $id = $response['body']['$id']; /** * Test for SUCCESS @@ -543,7 +601,6 @@ class ProjectsConsoleClientTest extends Scope /** * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -553,8 +610,6 @@ class ProjectsConsoleClientTest extends Scope ]); $this->assertEquals(401, $response['headers']['status-code']); - - return ['projectId' => $projectId]; } /** @@ -608,11 +663,35 @@ class ProjectsConsoleClientTest extends Scope /** * @group smtpAndTemplates - * @depends testCreateProject */ - public function testCreateProjectSMTPTests($data): array + public function testCreateProjectSMTPTests(): void { - $id = $data['projectId']; + // Create a team + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Create Project SMTP Tests Test Team', + ]); + + $this->assertEquals(201, $team['headers']['status-code']); + $teamId = $team['body']['$id']; + + // Create a project + $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Project Test', + 'teamId' => $teamId, + 'region' => System::getEnv('_APP_REGION', 'default') + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $id = $response['body']['$id']; + $response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/smtp/tests', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -681,8 +760,6 @@ class ProjectsConsoleClientTest extends Scope ]); $this->assertEquals(400, $response['headers']['status-code']); - - return $data; } /** @@ -794,7 +871,6 @@ class ProjectsConsoleClientTest extends Scope /** * Test for SUCCESS */ - $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/duration', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -951,10 +1027,32 @@ class ProjectsConsoleClientTest extends Scope return ['projectId' => $projectId]; } - /** @depends testCreateProject */ - public function testUpdateProjectInvalidateSessions($data): array + public function testUpdateProjectInvalidateSessions(): void { - $id = $data['projectId']; + // Create a team for the test project + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Session Invalidation Test Team', + ]); + + $this->assertEquals(201, $team['headers']['status-code']); + + // Create a test project + $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Session Invalidation Test Project', + 'teamId' => $team['body']['$id'], + 'region' => System::getEnv('_APP_REGION', 'default') + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $id = $response['body']['$id']; // Check defaults $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([ @@ -996,22 +1094,41 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertTrue($response['body']['authInvalidateSessions']); - - return $data; } - /** - * @depends testCreateProject - */ - public function testUpdateProjectOAuth($data): array + public function testUpdateProjectOAuth(): void { - $id = $data['projectId'] ?? ''; + // Create a team + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Update Project OAuth Test Team', + ]); + + $this->assertEquals(201, $team['headers']['status-code']); + $teamId = $team['body']['$id']; + + // Create a project + $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Project Test', + 'teamId' => $teamId, + 'region' => System::getEnv('_APP_REGION', 'default') + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $id = $response['body']['$id']; + $providers = require(__DIR__ . '/../../../../app/config/oAuthProviders.php'); /** * Test for SUCCESS */ - foreach ($providers as $key => $provider) { $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([ 'content-type' => 'application/json', @@ -1096,7 +1213,6 @@ class ProjectsConsoleClientTest extends Scope /** * Test for FAILURE */ - $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/oauth2', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], @@ -1107,18 +1223,37 @@ class ProjectsConsoleClientTest extends Scope ]); $this->assertEquals(400, $response['headers']['status-code']); - - return $data; } - /** - * @depends testCreateProject - */ - public function testUpdateProjectAuthStatus($data): array + public function testUpdateProjectAuthStatus(): void { - $id = $data['projectId'] ?? ''; - $auth = require(__DIR__ . '/../../../../app/config/auth.php'); + // Create a team + $team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'teamId' => ID::unique(), + 'name' => 'Update Project Auth Status Test Team', + ]); + $this->assertEquals(201, $team['headers']['status-code']); + $teamId = $team['body']['$id']; + + // Create a project + $response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'projectId' => ID::unique(), + 'name' => 'Project Test', + 'teamId' => $teamId, + 'region' => System::getEnv('_APP_REGION', 'default') + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + $id = $response['body']['$id']; + + $auth = require(__DIR__ . '/../../../../app/config/auth.php'); $originalEmail = uniqid() . 'user@localhost.test'; $originalPassword = 'password'; $originalName = 'User Name'; @@ -1252,8 +1387,6 @@ class ProjectsConsoleClientTest extends Scope 'status' => true, ]); } - - return $data; } /** @@ -1458,9 +1591,6 @@ class ProjectsConsoleClientTest extends Scope $sessionCookie = $response['headers']['set-cookie']; $sessionId2 = $response['body']['$id']; - // request was called in parallel and test failed - sleep(5); - /** * List sessions */ @@ -3358,15 +3488,15 @@ class ProjectsConsoleClientTest extends Scope { $id = $data['projectId'] ?? ''; - sleep(1); + $this->assertEventually(function () use ($id) { + $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), []); - $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/platforms', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(8, $response['body']['total']); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(8, $response['body']['total']); + }); /** * Test for FAILURE @@ -4016,16 +4146,16 @@ class ProjectsConsoleClientTest extends Scope $this->assertEquals(204, $project1['headers']['status-code']); - \sleep(3); - // Ensure project 2 user is still there - $user2 = $this->client->call(Client::METHOD_GET, '/users/' . $user2['body']['$id'], [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $project2Id, - 'x-appwrite-key' => $key2['body']['secret'], - ]); + $this->assertEventually(function () use ($user2, $project2Id, $key2) { + $response = $this->client->call(Client::METHOD_GET, '/users/' . $user2['body']['$id'], [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $project2Id, + 'x-appwrite-key' => $key2['body']['secret'], + ]); - $this->assertEquals(200, $user2['headers']['status-code']); + $this->assertEquals(200, $response['headers']['status-code']); + }); // Create another user in project 2 in case read hits stale cache $user3 = $this->client->call(Client::METHOD_POST, '/users', [ diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 3e57c5e9bc..c6a1686864 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -28,7 +28,7 @@ class RealtimeCustomClientTest extends Scope $userId = $user['$id'] ?? ''; $session = $user['session'] ?? ''; - $headers = [ + $headers = [ 'origin' => 'http://localhost', 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session ]; @@ -787,6 +787,8 @@ class RealtimeCustomClientTest extends Scope $this->assertContains('documents', $response['data']['channels']); $this->assertContains('databases.' . $databaseId . '.collections.' . $actorsId . '.documents.' . $documentId, $response['data']['channels']); $this->assertContains('databases.' . $databaseId . '.collections.' . $actorsId . '.documents', $response['data']['channels']); + $this->assertContains('databases.' . $databaseId . '.tables.' . $actorsId . '.rows.' . $documentId, $response['data']['channels']); + $this->assertContains('databases.' . $databaseId . '.tables.' . $actorsId . '.rows', $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}.create", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.*.create", $response['data']['events']); @@ -831,6 +833,8 @@ class RealtimeCustomClientTest extends Scope $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}.update", $response['data']['events']); + $this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows", $response['data']['channels']); + $this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows.{$documentId}.update", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.*.update", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.*", $response['data']['events']); @@ -884,6 +888,8 @@ class RealtimeCustomClientTest extends Scope $this->assertContains('documents', $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents", $response['data']['channels']); + $this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows.{$documentId}", $response['data']['channels']); + $this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows", $response['data']['channels']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}.delete", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.{$documentId}", $response['data']['events']); $this->assertContains("databases.{$databaseId}.collections.{$actorsId}.documents.*.delete", $response['data']['events']); @@ -2507,4 +2513,613 @@ class RealtimeCustomClientTest extends Scope $client->close(); } + + public function testChannelDatabaseTransaction() + { + $user = $this->getUser(); + $session = $user['session'] ?? ''; + $projectId = $this->getProject()['$id']; + + $client = $this->getWebsocket(['documents'], [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $projectId . '=' . $session + ]); + + $response = json_decode($client->receive(), true); + + $this->assertArrayHasKey('type', $response); + $this->assertEquals('connected', $response['type']); + + /** + * Setup Database and Collection + */ + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'Transactions DB', + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'Test Collection', + 'permissions' => [ + Permission::create(Role::user($this->getUser()['$id'])), + ], + 'documentSecurity' => true, + ]); + + $collectionId = $collection['body']['$id']; + + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + /** + * Test Transaction Create with Single Document + */ + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 3600 // 1 hour + ]); + + $this->assertEquals(201, $transaction['headers']['status-code'], 'Failed to create transaction: ' . json_encode($transaction['body'])); + $this->assertNotEmpty($transaction['body']['$id']); + + $transactionId = $transaction['body']['$id']; + $documentId = ID::unique(); + + $operationsResponse = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transactionId . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $collectionId, + 'rowId' => $documentId, + 'action' => 'create', + 'data' => [ + 'name' => 'Transaction Document', + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ], + ] + ] + ]); + + $this->assertEquals(201, $operationsResponse['headers']['status-code'], 'Failed to add operations: ' . json_encode($operationsResponse['body'])); + + // Commit transaction + $commitResponse = $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'commit' => true + ]); + + $this->assertEquals(200, $commitResponse['headers']['status-code'], 'Failed to commit transaction: ' . json_encode($commitResponse['body'])); + + $response = json_decode($client->receive(), true); + + $this->assertArrayHasKey('type', $response); + $this->assertArrayHasKey('data', $response); + $this->assertEquals('event', $response['type']); + $this->assertNotEmpty($response['data']); + $this->assertArrayHasKey('timestamp', $response['data']); + $this->assertContains('documents', $response['data']['channels']); + $this->assertContains("databases.{$databaseId}.tables.{$collectionId}.rows.{$documentId}.create", $response['data']['events']); + $this->assertNotEmpty($response['data']['payload']); + $this->assertEquals('Transaction Document', $response['data']['payload']['name']); + + /** + * Test Transaction Update + */ + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 3600 + ]); + + $transactionId = $transaction['body']['$id']; + + $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transactionId . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $collectionId, + 'rowId' => $documentId, + 'action' => 'update', + 'data' => [ + 'name' => 'Updated Transaction Document', + ], + ] + ] + ]); + + $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'commit' => true + ]); + + $response = json_decode($client->receive(), true); + + $this->assertArrayHasKey('type', $response); + $this->assertEquals('event', $response['type']); + $this->assertContains("databases.{$databaseId}.tables.{$collectionId}.rows.{$documentId}.update", $response['data']['events']); + $this->assertEquals('Updated Transaction Document', $response['data']['payload']['name']); + + /** + * Test Transaction Delete + */ + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 3600 + ]); + + $transactionId = $transaction['body']['$id']; + + $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transactionId . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $collectionId, + 'rowId' => $documentId, + 'action' => 'delete', + ] + ] + ]); + + $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'commit' => true + ]); + + $response = json_decode($client->receive(), true); + + $this->assertArrayHasKey('type', $response); + $this->assertEquals('event', $response['type']); + $this->assertContains("databases.{$databaseId}.tables.{$collectionId}.rows.{$documentId}.delete", $response['data']['events']); + + $client->close(); + } + + public function testChannelDatabaseTransactionMultipleOperations() + { + $user = $this->getUser(); + $session = $user['session'] ?? ''; + $projectId = $this->getProject()['$id']; + + $client = $this->getWebsocket(['documents'], [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $projectId . '=' . $session + ]); + + $response = json_decode($client->receive(), true); + $this->assertEquals('connected', $response['type']); + + /** + * Setup Database and Collection + */ + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'Multi-Op DB', + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'Test Collection', + 'permissions' => [ + Permission::create(Role::user($this->getUser()['$id'])), + ], + 'documentSecurity' => true, + ]); + + $collectionId = $collection['body']['$id']; + + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + /** + * Test Multiple Operations in Single Transaction + */ + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 3600 + ]); + + $transactionId = $transaction['body']['$id']; + $documentId1 = ID::unique(); + $documentId2 = ID::unique(); + $documentId3 = ID::unique(); + + $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transactionId . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $collectionId, + 'rowId' => $documentId1, + 'action' => 'create', + 'data' => [ + 'name' => 'Doc 1', + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ], + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $collectionId, + 'rowId' => $documentId2, + 'action' => 'create', + 'data' => [ + 'name' => 'Doc 2', + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ], + ], + [ + 'databaseId' => $databaseId, + 'tableId' => $collectionId, + 'rowId' => $documentId3, + 'action' => 'create', + 'data' => [ + 'name' => 'Doc 3', + '$permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ], + ] + ] + ]); + + $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'commit' => true + ]); + + // Should receive 3 events, one for each document + $response1 = json_decode($client->receive(), true); + $response2 = json_decode($client->receive(), true); + $response3 = json_decode($client->receive(), true); + + $this->assertEquals('event', $response1['type']); + $this->assertEquals('event', $response2['type']); + $this->assertEquals('event', $response3['type']); + + $receivedDocIds = [ + $response1['data']['payload']['$id'], + $response2['data']['payload']['$id'], + $response3['data']['payload']['$id'], + ]; + + $this->assertContains($documentId1, $receivedDocIds); + $this->assertContains($documentId2, $receivedDocIds); + $this->assertContains($documentId3, $receivedDocIds); + + $client->close(); + } + + public function testChannelDatabaseTransactionRollback() + { + $user = $this->getUser(); + $session = $user['session'] ?? ''; + $projectId = $this->getProject()['$id']; + + $client = $this->getWebsocket(['documents'], [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $projectId . '=' . $session + ]); + + $response = json_decode($client->receive(), true); + $this->assertEquals('connected', $response['type']); + + /** + * Setup Database and Collection + */ + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'Rollback DB', + ]); + + $databaseId = $database['body']['$id']; + + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'Test Collection', + 'permissions' => [ + Permission::create(Role::user($this->getUser()['$id'])), + ], + 'documentSecurity' => true, + ]); + + $collectionId = $collection['body']['$id']; + + $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => true, + ]); + + sleep(2); + + /** + * Test Transaction Rollback - Should NOT trigger realtime events + */ + $transaction = $this->client->call(Client::METHOD_POST, '/tablesdb/transactions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'ttl' => 3600 + ]); + + $transactionId = $transaction['body']['$id']; + $documentId = ID::unique(); + + $this->client->call(Client::METHOD_POST, '/tablesdb/transactions/' . $transactionId . '/operations', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'operations' => [ + [ + 'databaseId' => $databaseId, + 'tableId' => $collectionId, + 'rowId' => $documentId, + 'action' => 'create', + 'data' => ['name' => 'Rollback Document'], + ] + ] + ]); + + // Rollback transaction + $this->client->call(Client::METHOD_PATCH, '/tablesdb/transactions/' . $transactionId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'rollback' => true + ]); + + // Wait a bit to ensure no event is received + sleep(1); + + try { + $client->receive(1); // 1 second timeout + $this->fail('Should not receive any event after rollback'); + } catch (TimeoutException $e) { + // Expected - no event should be triggered + $this->assertTrue(true); + } + + $client->close(); + } + + public function testRelationshipPayloadHidesRelatedDoc() + { + $user = $this->getUser(); + $session = $user['session'] ?? ''; + $projectId = $this->getProject()['$id']; + + $client = $this->getWebsocket(['documents'], [ + 'origin' => 'http://localhost', + 'cookie' => 'a_session_' . $projectId . '=' . $session + ]); + + $response = json_decode($client->receive(), true); + $this->assertArrayHasKey('type', $response); + $this->assertEquals('connected', $response['type']); + + // Create database + $database = $this->client->call(Client::METHOD_POST, '/databases', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'databaseId' => ID::unique(), + 'name' => 'db-rel' + ]); + $databaseId = $database['body']['$id']; + + $level1 = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'level1', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'documentSecurity' => true, + ]); + $level1Id = $level1['body']['$id']; + + $level2 = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'collectionId' => ID::unique(), + 'name' => 'level2', + 'permissions' => [ + Permission::read(Role::any()), + Permission::create(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + 'documentSecurity' => true, + ]); + $level2Id = $level2['body']['$id']; + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$level1Id}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => false, + ]); + + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$level2Id}/attributes/string", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'key' => 'name', + 'size' => 256, + 'required' => false, + ]); + + sleep(2); + + // two-way one-to-one relationship from level1 to level2 + $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$level1Id}/attributes/relationship", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'relatedCollectionId' => $level2Id, + 'type' => 'oneToOne', + 'twoWay' => true, + 'key' => 'level2Ref', + 'onDelete' => 'cascade', + ]); + + sleep(2); + + $doc2 = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$level2Id}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + ], $this->getHeaders()), [ + 'documentId' => ID::unique(), + 'data' => ['name' => 'L2'], + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + $doc2Id = $doc2['body']['$id']; + + $doc1 = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$level1Id}/documents", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + ], $this->getHeaders()), [ + 'documentId' => ID::unique(), + 'data' => ['name' => 'L1'], + 'permissions' => [ + Permission::read(Role::any()), + Permission::update(Role::any()), + Permission::delete(Role::any()), + ], + ]); + $doc1Id = $doc1['body']['$id']; + + json_decode($client->receive(), true); + + $this->client->call(Client::METHOD_PATCH, "/databases/{$databaseId}/collections/{$level1Id}/documents/{$doc1Id}", array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]), [ + 'data' => [ + 'level2Ref' => $doc2Id, + ], + ]); + + // payload should not contain the relationship attribute 'level2Ref' + $event = json_decode($client->receive(), true); + $this->assertArrayHasKey('type', $event); + $this->assertEquals('event', $event['type']); + $this->assertArrayHasKey('data', $event); + $this->assertNotEmpty($event['data']); + $this->assertArrayHasKey('payload', $event['data']); + $this->assertArrayHasKey('$id', $event['data']['payload']); + $this->assertEquals($doc1Id, $event['data']['payload']['$id']); + $this->assertArrayNotHasKey('level2Ref', $event['data']['payload']); + + $client->close(); + } } diff --git a/tests/e2e/Services/Webhooks/WebhooksBase.php b/tests/e2e/Services/Webhooks/WebhooksBase.php index 41f6c03c35..3d53a4a2ad 100644 --- a/tests/e2e/Services/Webhooks/WebhooksBase.php +++ b/tests/e2e/Services/Webhooks/WebhooksBase.php @@ -147,25 +147,25 @@ trait WebhooksBase $this->assertEquals($extra['body']['key'], 'extra'); // wait for database worker to kick in - sleep(10); - - $webhook = $this->getLastRequest(); - $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - - $this->assertEquals($webhook['method'], 'POST'); - $this->assertEquals($webhook['headers']['Content-Type'], 'application/json'); - $this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io'); - $this->assertStringContainsString('databases.' . $databaseId . '.collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.attributes.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.attributes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.attributes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); - $this->assertNotEmpty($webhook['data']['key']); - $this->assertEquals($webhook['data']['key'], 'extra'); + $this->assertEventually(function () use ($databaseId, $actorsId) { + $webhook = $this->getLastRequest(); + $this->assertNotEmpty($webhook); + $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); + $this->assertEquals($webhook['method'], 'POST'); + $this->assertEquals($webhook['headers']['Content-Type'], 'application/json'); + $this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io'); + $this->assertStringContainsString('databases.' . $databaseId . '.collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.attributes.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.attributes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.attributes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + $this->assertNotEmpty($webhook['data']['key']); + $this->assertEquals($webhook['data']['key'], 'extra'); + }, 15000, 500); $removed = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $data['actorsId'] . '/attributes/' . $extra['body']['key'], array_merge([ 'content-type' => 'application/json', @@ -498,25 +498,25 @@ trait WebhooksBase $this->assertEquals($extra['body']['key'], 'extra'); // wait for database worker to kick in - sleep(10); - - $webhook = $this->getLastRequest(); - $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - - $this->assertEquals($webhook['method'], 'POST'); - $this->assertEquals($webhook['headers']['Content-Type'], 'application/json'); - $this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io'); - $this->assertStringContainsString('databases.' . $databaseId . '.tables.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.columns.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.columns.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.columns.*", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.columns.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); - $this->assertNotEmpty($webhook['data']['key']); - $this->assertEquals($webhook['data']['key'], 'extra'); + $this->assertEventually(function () use ($databaseId, $actorsId) { + $webhook = $this->getLastRequest(); + $this->assertNotEmpty($webhook); + $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); + $this->assertEquals($webhook['method'], 'POST'); + $this->assertEquals($webhook['headers']['Content-Type'], 'application/json'); + $this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io'); + $this->assertStringContainsString('databases.' . $databaseId . '.tables.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.columns.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.columns.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.columns.*", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.columns.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + $this->assertNotEmpty($webhook['data']['key']); + $this->assertEquals($webhook['data']['key'], 'extra'); + }, 15000, 500); $removed = $this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $data['actorsId'] . '/columns/' . $extra['body']['key'], array_merge([ 'content-type' => 'application/json', @@ -1487,17 +1487,17 @@ trait WebhooksBase $this->assertNotEmpty($newCollection['body']['$id']); } - sleep(10); + $this->assertEventually(function () use ($projectId, $webhookId) { + $webhook = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/webhooks/' . $webhookId, array_merge([ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + 'x-appwrite-project' => 'console', + ])); - $webhook = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId . '/webhooks/' . $webhookId, array_merge([ - 'origin' => 'http://localhost', - 'content-type' => 'application/json', - 'cookie' => 'a_session_console=' . $this->getRoot()['session'], - 'x-appwrite-project' => 'console', - ])); - - // assert that the webhook is now disabled after 10 consecutive failures - $this->assertEquals($webhook['body']['enabled'], false); - $this->assertEquals($webhook['body']['attempts'], 10); + // assert that the webhook is now disabled after 10 consecutive failures + $this->assertEquals($webhook['body']['enabled'], false); + $this->assertEquals($webhook['body']['attempts'], 10); + }, 15000, 500); } } diff --git a/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php b/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php index 1df6dfe9ae..d1f1106247 100644 --- a/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php +++ b/tests/e2e/Services/Webhooks/WebhooksCustomServerTest.php @@ -2,6 +2,7 @@ namespace Tests\E2E\Services\Webhooks; +use Appwrite\Tests\Async; use CURLFile; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; @@ -15,6 +16,7 @@ use Utopia\Database\Validator\Datetime as DatetimeValidator; class WebhooksCustomServerTest extends Scope { + use Async; use WebhooksBase; use ProjectCustom; use SideServer; @@ -89,24 +91,24 @@ class WebhooksCustomServerTest extends Scope $this->assertEquals('fullname', $index['body']['key']); // wait for database worker to create index - sleep(5); + $this->assertEventually(function () use ($databaseId, $actorsId) { + $webhook = $this->getLastRequest(); + $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - $webhook = $this->getLastRequest(); - $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - - $this->assertEquals('POST', $webhook['method']); - $this->assertEquals('application/json', $webhook['headers']['Content-Type']); - $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); - $this->assertStringContainsString('databases.' . $databaseId . '.collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.indexes.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.indexes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.indexes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); - $this->assertTrue(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? '')); + $this->assertEquals('POST', $webhook['method']); + $this->assertEquals('application/json', $webhook['headers']['Content-Type']); + $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); + $this->assertStringContainsString('databases.' . $databaseId . '.collections.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.indexes.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.collections.*.indexes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.collections.{$actorsId}.indexes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + $this->assertTrue(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? '')); + }, 10000, 500); // Remove index $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $data['actorsId'] . '/indexes/' . $index['body']['key'], array_merge([ @@ -275,24 +277,24 @@ class WebhooksCustomServerTest extends Scope $this->assertEquals('fullname', $index['body']['key']); // wait for database worker to create index - sleep(5); + $this->assertEventually(function () use ($databaseId, $actorsId) { + $webhook = $this->getLastRequest(); + $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - $webhook = $this->getLastRequest(); - $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - - $this->assertEquals('POST', $webhook['method']); - $this->assertEquals('application/json', $webhook['headers']['Content-Type']); - $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); - $this->assertStringContainsString('databases.' . $databaseId . '.tables.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.indexes.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.indexes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.indexes.*", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.indexes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); - $this->assertTrue(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? '')); + $this->assertEquals('POST', $webhook['method']); + $this->assertEquals('application/json', $webhook['headers']['Content-Type']); + $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); + $this->assertStringContainsString('databases.' . $databaseId . '.tables.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.indexes.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString('databases.' . $databaseId . '.tables.*.indexes.*.create', $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.indexes.*", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertStringContainsString("databases.{$databaseId}.tables.{$actorsId}.indexes.*.create", $webhook['headers']['X-Appwrite-Webhook-Events']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + $this->assertTrue(empty($webhook['headers']['X-Appwrite-Webhook-User-Id'] ?? '')); + }, 10000, 500); // Remove index $this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $data['actorsId'] . '/indexes/' . $index['body']['key'], array_merge([ @@ -735,27 +737,27 @@ class WebhooksCustomServerTest extends Scope $this->assertNotEmpty($response['body']['$id']); // Wait for deployment to be built. - sleep(5); + $this->assertEventually(function () use ($deploymentId, $id) { + $webhook = $this->getLastRequest(); + $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - $webhook = $this->getLastRequest(); - $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - - $this->assertEquals('POST', $webhook['method']); - $this->assertEquals('application/json', $webhook['headers']['Content-Type']); - $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); - // $this->assertStringContainsString('functions.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString('functions.*.deployments.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString('functions.*.deployments.*.update', $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.*.deployments.{$deploymentId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.*.deployments.{$deploymentId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.deployments.*", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.deployments.*.update", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.deployments.{$deploymentId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.deployments.{$deploymentId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); TODO @christyjacob4 : enable test once we allow functions.* events - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + $this->assertEquals('POST', $webhook['method']); + $this->assertEquals('application/json', $webhook['headers']['Content-Type']); + $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); + // $this->assertStringContainsString('functions.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString('functions.*.deployments.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString('functions.*.deployments.*.update', $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.*.deployments.{$deploymentId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.*.deployments.{$deploymentId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.deployments.*", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.deployments.*.update", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.deployments.{$deploymentId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.deployments.{$deploymentId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); TODO @christyjacob4 : enable test once we allow functions.* events + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + }, 10000, 500); /** * Test for FAILURE @@ -806,27 +808,27 @@ class WebhooksCustomServerTest extends Scope $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); // wait for timeout function to complete - sleep(20); + $this->assertEventually(function () use ($executionId, $id) { + $webhook = $this->getLastRequest(); + $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - $webhook = $this->getLastRequest(); - $signatureExpected = self::getWebhookSignature($webhook, $this->getProject()['signatureKey']); - - $this->assertEquals('POST', $webhook['method']); - $this->assertEquals('application/json', $webhook['headers']['Content-Type']); - $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); - // $this->assertStringContainsString('functions.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString('functions.*.executions.*', $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString('functions.*.executions.*.update', $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.*.executions.{$executionId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.*.executions.{$executionId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.executions.*", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.executions.*.update", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.executions.{$executionId}", $webhook['headers']['X-Appwrite-Webhook-Events']); - // $this->assertStringContainsString("functions.{$id}.executions.{$executionId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); TODO @christyjacob4 : enable test once we allow functions.* events - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); - $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + $this->assertEquals('POST', $webhook['method']); + $this->assertEquals('application/json', $webhook['headers']['Content-Type']); + $this->assertEquals('Appwrite-Server vdev. Please report abuse at security@appwrite.io', $webhook['headers']['User-Agent']); + // $this->assertStringContainsString('functions.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString('functions.*.executions.*', $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString('functions.*.executions.*.update', $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.*.executions.{$executionId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.*.executions.{$executionId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.executions.*", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.executions.*.update", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.executions.{$executionId}", $webhook['headers']['X-Appwrite-Webhook-Events']); + // $this->assertStringContainsString("functions.{$id}.executions.{$executionId}.update", $webhook['headers']['X-Appwrite-Webhook-Events']); TODO @christyjacob4 : enable test once we allow functions.* events + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], $signatureExpected); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']); + $this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']); + }, 30000, 1000); /** * Test for FAILURE diff --git a/tests/resources/functions/log-error-truncation/index.js b/tests/resources/functions/log-error-truncation/index.js index 7e94fa5028..35747095f5 100644 --- a/tests/resources/functions/log-error-truncation/index.js +++ b/tests/resources/functions/log-error-truncation/index.js @@ -2,8 +2,21 @@ module.exports = async(context) => { // Create a string that is 1000001 characters long (exceeds the 1000000 limit) const longString = 'z' + 'a'.repeat(1000000); - context.log(longString); - context.error(longString); + // Split the string into chunks of 8000 characters (max limit for each log and error) + const chunkSize = 8000; + const chunks = []; + + for (let i = 0; i < longString.length; i += chunkSize) { + chunks.push(longString.slice(i, i + chunkSize)); + } + + chunks.forEach((chunk, index) => { + context.log(chunk); + }); + + chunks.forEach((chunk, index) => { + context.error(chunk); + }); return context.res.json({ motto: 'Build like a team of hundreds_',