From aee3280a9c252e95e603a0b55c1d169d201e0fd0 Mon Sep 17 00:00:00 2001 From: Khushboo Verma Date: Wed, 4 Jun 2025 13:50:36 +0530 Subject: [PATCH 01/11] Use static code instead of astro in tests --- .../Services/Sites/SitesCustomServerTest.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php index 8459e46c6f..b3ea045430 100644 --- a/tests/e2e/Services/Sites/SitesCustomServerTest.php +++ b/tests/e2e/Services/Sites/SitesCustomServerTest.php @@ -477,7 +477,7 @@ class SitesCustomServerTest extends Scope $this->assertNotEmpty($domain); $deploymentId = $this->setupDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'true' ]); $this->assertNotEmpty($deploymentId); @@ -856,7 +856,7 @@ class SitesCustomServerTest extends Scope $deployment = $this->createDeployment($siteId, [ 'siteId' => $siteId, - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => true, ]); @@ -874,7 +874,7 @@ class SitesCustomServerTest extends Scope }, 50000, 500); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'false' ]); @@ -917,7 +917,7 @@ class SitesCustomServerTest extends Scope $this->assertNotNull($siteId); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'false' ]); @@ -969,7 +969,7 @@ class SitesCustomServerTest extends Scope $this->assertNotNull($siteId); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'false' ]); @@ -1014,7 +1014,7 @@ class SitesCustomServerTest extends Scope $this->assertNotNull($siteId); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'false' ]); @@ -1022,7 +1022,7 @@ class SitesCustomServerTest extends Scope $this->assertEquals(202, $deployment['headers']['status-code']); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'false' ]); @@ -1193,7 +1193,7 @@ class SitesCustomServerTest extends Scope $this->assertNotNull($siteId); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'false' ]); @@ -1318,7 +1318,7 @@ class SitesCustomServerTest extends Scope $this->assertNotNull($siteId); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'false' ]); @@ -1818,7 +1818,7 @@ class SitesCustomServerTest extends Scope ]); $deploymentId = $this->setupDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => true ]); @@ -2435,7 +2435,7 @@ class SitesCustomServerTest extends Scope $this->assertNotEmpty($siteId); $deploymentId = $this->setupDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'true' ]); @@ -2477,7 +2477,7 @@ class SitesCustomServerTest extends Scope // test canceled deployment error page $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'true' ]); $deploymentId = $deployment['body']['$id'] ?? ''; @@ -2517,7 +2517,7 @@ class SitesCustomServerTest extends Scope $this->assertStringContainsString('View deployments', $response['body']); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('astro'), + 'code' => $this->packageSite('static-single-file'), 'activate' => 'true' ]); @@ -2606,7 +2606,7 @@ class SitesCustomServerTest extends Scope $this->assertNotEmpty($siteId); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => true ]); $this->assertEquals(202, $deployment['headers']['status-code']); @@ -2635,7 +2635,7 @@ class SitesCustomServerTest extends Scope $this->assertNotEmpty($siteId); $deployment = $this->createDeployment($siteId, [ - 'code' => $this->packageSite('static'), + 'code' => $this->packageSite('static-single-file'), 'activate' => true ]); $this->assertEquals(202, $deployment['headers']['status-code']); From 72090248e54b4798a03d378027ebd09b15b56208 Mon Sep 17 00:00:00 2001 From: Khushboo Verma Date: Tue, 10 Jun 2025 20:37:37 +0530 Subject: [PATCH 02/11] Add ref param to vcs list contents --- app/controllers/api/vcs.php | 5 +++-- composer.lock | 24 ++++++++++++------------ docker-compose.yml | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index c8a0a36a85..c63d39057a 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -605,11 +605,12 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro ->param('installationId', '', new Text(256), 'Installation Id') ->param('providerRepositoryId', '', new Text(256), 'Repository Id') ->param('providerRootDirectory', '', new Text(256, 0), 'Path to get contents of nested directory', true) + ->param('providerRef', '', new Text(256, 0), 'Git reference (branch, tag, commit) to get contents from', true) ->inject('gitHub') ->inject('response') ->inject('project') ->inject('dbForPlatform') - ->action(function (string $installationId, string $providerRepositoryId, string $providerRootDirectory, GitHub $github, Response $response, Document $project, Database $dbForPlatform) { + ->action(function (string $installationId, string $providerRepositoryId, string $providerRootDirectory, string $providerRef, GitHub $github, Response $response, Document $project, Database $dbForPlatform) { $installation = $dbForPlatform->getDocument('installations', $installationId); if ($installation->isEmpty()) { @@ -631,7 +632,7 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } - $contents = $github->listRepositoryContents($owner, $repositoryName, $providerRootDirectory); + $contents = $github->listRepositoryContents($owner, $repositoryName, $providerRootDirectory, $providerRef); $vcsContents = []; foreach ($contents as $content) { diff --git a/composer.lock b/composer.lock index d7b9f22722..fdde3f2750 100644 --- a/composer.lock +++ b/composer.lock @@ -4584,16 +4584,16 @@ }, { "name": "utopia-php/vcs", - "version": "0.10.4", + "version": "0.10.5", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "f635b368909eb3c3fe57344fe43525e74e8fdc03" + "reference": "b358439dc387f6097019eb83ebb9fc258fe9da05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/f635b368909eb3c3fe57344fe43525e74e8fdc03", - "reference": "f635b368909eb3c3fe57344fe43525e74e8fdc03", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/b358439dc387f6097019eb83ebb9fc258fe9da05", + "reference": "b358439dc387f6097019eb83ebb9fc258fe9da05", "shasum": "" }, "require": { @@ -4627,9 +4627,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.10.4" + "source": "https://github.com/utopia-php/vcs/tree/0.10.5" }, - "time": "2025-06-02T09:18:36+00:00" + "time": "2025-06-10T15:01:16+00:00" }, { "name": "utopia-php/websocket", @@ -4807,16 +4807,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.41.1", + "version": "0.41.4", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "6d9318abf4542a757c87abf056557d6afa1dc06b" + "reference": "07804269131f411576aac60c795a5ebc3afaa48a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/6d9318abf4542a757c87abf056557d6afa1dc06b", - "reference": "6d9318abf4542a757c87abf056557d6afa1dc06b", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/07804269131f411576aac60c795a5ebc3afaa48a", + "reference": "07804269131f411576aac60c795a5ebc3afaa48a", "shasum": "" }, "require": { @@ -4852,9 +4852,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/0.41.1" + "source": "https://github.com/appwrite/sdk-generator/tree/0.41.4" }, - "time": "2025-06-01T04:20:04+00:00" + "time": "2025-06-10T08:28:11+00:00" }, { "name": "doctrine/annotations", diff --git a/docker-compose.yml b/docker-compose.yml index 29a43aca91..c042d36cd5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -213,7 +213,7 @@ services: appwrite-console: <<: *x-logging container_name: appwrite-console - image: appwrite/console:6.0.32 + image: appwrite/console:6.0.41 restart: unless-stopped networks: - appwrite From fc0e1b607d47fe0cddb20042216ae173dad56909 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Thu, 12 Jun 2025 14:57:12 -0400 Subject: [PATCH 03/11] Update database --- composer.lock | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/composer.lock b/composer.lock index 6372df41ba..1d32907bcb 100644 --- a/composer.lock +++ b/composer.lock @@ -3490,16 +3490,16 @@ }, { "name": "utopia-php/database", - "version": "0.71.4", + "version": "0.71.5", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "308cbeb65780f954f9f3abfff2ef17c5941ae00e" + "reference": "4df05773144e166a217c6359621feb38653ca4be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/308cbeb65780f954f9f3abfff2ef17c5941ae00e", - "reference": "308cbeb65780f954f9f3abfff2ef17c5941ae00e", + "url": "https://api.github.com/repos/utopia-php/database/zipball/4df05773144e166a217c6359621feb38653ca4be", + "reference": "4df05773144e166a217c6359621feb38653ca4be", "shasum": "" }, "require": { @@ -3540,9 +3540,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.71.4" + "source": "https://github.com/utopia-php/database/tree/0.71.5" }, - "time": "2025-06-10T15:47:50+00:00" + "time": "2025-06-12T18:55:07+00:00" }, { "name": "utopia-php/detector", @@ -4807,16 +4807,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.41.4", + "version": "0.41.6", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "07804269131f411576aac60c795a5ebc3afaa48a" + "reference": "bfcebb968c527e17fdf18d40b8986c83d9c18c93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/07804269131f411576aac60c795a5ebc3afaa48a", - "reference": "07804269131f411576aac60c795a5ebc3afaa48a", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/bfcebb968c527e17fdf18d40b8986c83d9c18c93", + "reference": "bfcebb968c527e17fdf18d40b8986c83d9c18c93", "shasum": "" }, "require": { @@ -4852,9 +4852,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/0.41.4" + "source": "https://github.com/appwrite/sdk-generator/tree/0.41.6" }, - "time": "2025-06-10T08:28:11+00:00" + "time": "2025-06-12T03:27:26+00:00" }, { "name": "doctrine/annotations", @@ -5147,16 +5147,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.73", + "version": "1.3.74", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a" + "reference": "a2593286a4135d03c6a6a9e9aeded5d41e931ce4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/cb7a9297b4ab070909cefade30ee95054d4ae87a", - "reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a2593286a4135d03c6a6a9e9aeded5d41e931ce4", + "reference": "a2593286a4135d03c6a6a9e9aeded5d41e931ce4", "shasum": "" }, "require": { @@ -5167,8 +5167,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": ">=2.0", "matthiasmullie/scrapbook": ">=1.3", - "phpunit/phpunit": ">=4.8", - "squizlabs/php_codesniffer": ">=3.0" + "phpunit/phpunit": ">=4.8" }, "suggest": { "psr/cache-implementation": "Cache implementation to use with Minify::cache" @@ -5206,7 +5205,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.73" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.74" }, "funding": [ { @@ -5214,7 +5213,7 @@ "type": "github" } ], - "time": "2024-03-15T10:27:10+00:00" + "time": "2025-06-12T08:06:04+00:00" }, { "name": "matthiasmullie/path-converter", From 221f15313ce8bebaf0251b67e5330b6901dd7920 Mon Sep 17 00:00:00 2001 From: Khushboo Verma Date: Fri, 13 Jun 2025 15:55:02 +0530 Subject: [PATCH 04/11] Update var name and generate specs --- app/config/specs/open-api3-latest-client.json | 26 +++++++++++++++- .../specs/open-api3-latest-console.json | 30 +++++++++++++++---- app/config/specs/open-api3-latest-server.json | 19 ++++++++---- app/config/specs/swagger2-latest-client.json | 26 +++++++++++++++- app/config/specs/swagger2-latest-console.json | 28 +++++++++++++---- app/config/specs/swagger2-latest-server.json | 19 ++++++++---- app/controllers/api/vcs.php | 6 ++-- 7 files changed, 129 insertions(+), 25 deletions(-) diff --git a/app/config/specs/open-api3-latest-client.json b/app/config/specs/open-api3-latest-client.json index bbb78c6c66..807903b764 100644 --- a/app/config/specs/open-api3-latest-client.json +++ b/app/config/specs/open-api3-latest-client.json @@ -4490,6 +4490,29 @@ } ], "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console." + }, + { + "name": "createDocuments", + "auth": { + "Key": [] + }, + "parameters": [ + "databaseId", + "collectionId", + "documents" + ], + "required": [ + "databaseId", + "collectionId", + "documents" + ], + "responses": [ + { + "code": 201, + "model": "#\/components\/schemas\/documentList" + } + ], + "description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console." } ], "auth": { @@ -6595,7 +6618,8 @@ "png", "webp", "heic", - "avif" + "avif", + "gif" ], "x-enum-name": "ImageFormat", "x-enum-keys": [], diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 187281716f..cc4753dd4a 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -9767,6 +9767,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -9792,7 +9793,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -10395,6 +10397,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -10420,7 +10423,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -25957,6 +25961,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -25982,7 +25987,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -26601,6 +26607,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -26626,7 +26633,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -29385,7 +29393,8 @@ "png", "webp", "heic", - "avif" + "avif", + "gif" ], "x-enum-name": "ImageFormat", "x-enum-keys": [], @@ -34867,6 +34876,17 @@ "default": "" }, "in": "query" + }, + { + "name": "providerReference", + "description": "Git reference (branch, tag, commit) to get contents from", + "required": false, + "schema": { + "type": "string", + "x-example": "", + "default": "" + }, + "in": "query" } ] } diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index 1ae9328864..cc0abd241d 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -8844,6 +8844,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -8869,7 +8870,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -9244,6 +9246,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -9269,7 +9272,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -17490,6 +17494,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -17515,7 +17520,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -17906,6 +17912,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -17931,7 +17938,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -20646,7 +20654,8 @@ "png", "webp", "heic", - "avif" + "avif", + "gif" ], "x-enum-name": "ImageFormat", "x-enum-keys": [], diff --git a/app/config/specs/swagger2-latest-client.json b/app/config/specs/swagger2-latest-client.json index 92132151b4..b3f41e101c 100644 --- a/app/config/specs/swagger2-latest-client.json +++ b/app/config/specs/swagger2-latest-client.json @@ -4636,6 +4636,29 @@ } ], "description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console." + }, + { + "name": "createDocuments", + "auth": { + "Key": [] + }, + "parameters": [ + "databaseId", + "collectionId", + "documents" + ], + "required": [ + "databaseId", + "collectionId", + "documents" + ], + "responses": [ + { + "code": 201, + "model": "#\/definitions\/documentList" + } + ], + "description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console." } ], "auth": { @@ -6729,7 +6752,8 @@ "png", "webp", "heic", - "avif" + "avif", + "gif" ], "x-enum-name": "ImageFormat", "x-enum-keys": [], diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 06a33c9a3d..4e60716c4b 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -9835,6 +9835,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -9860,7 +9861,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -10466,6 +10468,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -10491,7 +10494,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -26226,6 +26230,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -26251,7 +26256,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -26873,6 +26879,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -26898,7 +26905,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -29627,7 +29635,8 @@ "png", "webp", "heic", - "avif" + "avif", + "gif" ], "x-enum-name": "ImageFormat", "x-enum-keys": [], @@ -35086,6 +35095,15 @@ "x-example": "", "default": "", "in": "query" + }, + { + "name": "providerReference", + "description": "Git reference (branch, tag, commit) to get contents from", + "required": false, + "type": "string", + "x-example": "", + "default": "", + "in": "query" } ] } diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index 083290bcc0..4c7c193858 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -8927,6 +8927,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -8952,7 +8953,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -9340,6 +9342,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -9365,7 +9368,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -17792,6 +17796,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -17817,7 +17822,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -18221,6 +18227,7 @@ "dart-3.1", "dart-3.3", "dart-3.5", + "dart-3.8", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", @@ -18246,7 +18253,8 @@ "static-1", "flutter-3.24", "flutter-3.27", - "flutter-3.29" + "flutter-3.29", + "flutter-3.32" ], "x-enum-name": null, "x-enum-keys": [] @@ -20935,7 +20943,8 @@ "png", "webp", "heic", - "avif" + "avif", + "gif" ], "x-enum-name": "ImageFormat", "x-enum-keys": [], diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index c63d39057a..7fb8713e25 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -605,12 +605,12 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro ->param('installationId', '', new Text(256), 'Installation Id') ->param('providerRepositoryId', '', new Text(256), 'Repository Id') ->param('providerRootDirectory', '', new Text(256, 0), 'Path to get contents of nested directory', true) - ->param('providerRef', '', new Text(256, 0), 'Git reference (branch, tag, commit) to get contents from', true) + ->param('providerReference', '', new Text(256, 0), 'Git reference (branch, tag, commit) to get contents from', true) ->inject('gitHub') ->inject('response') ->inject('project') ->inject('dbForPlatform') - ->action(function (string $installationId, string $providerRepositoryId, string $providerRootDirectory, string $providerRef, GitHub $github, Response $response, Document $project, Database $dbForPlatform) { + ->action(function (string $installationId, string $providerRepositoryId, string $providerRootDirectory, string $providerReference, GitHub $github, Response $response, Document $project, Database $dbForPlatform) { $installation = $dbForPlatform->getDocument('installations', $installationId); if ($installation->isEmpty()) { @@ -632,7 +632,7 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } - $contents = $github->listRepositoryContents($owner, $repositoryName, $providerRootDirectory, $providerRef); + $contents = $github->listRepositoryContents($owner, $repositoryName, $providerRootDirectory, $providerReference); $vcsContents = []; foreach ($contents as $content) { From c510af0a90072b1d7873b547b2fc98361af5b8b4 Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Fri, 13 Jun 2025 20:21:03 +0530 Subject: [PATCH 05/11] Update appwrite-assistant image version to 0.8.3 --- app/views/install/compose.phtml | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 2d8f2b35ab..e3699662a4 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -841,7 +841,7 @@ $image = $this->getParam('image', ''); - _APP_DB_PASS appwrite-assistant: - image: appwrite/assistant:0.4.0 + image: appwrite/assistant:0.8.3 container_name: appwrite-assistant <<: *x-logging restart: unless-stopped diff --git a/docker-compose.yml b/docker-compose.yml index c042d36cd5..0b653af8c2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -934,7 +934,7 @@ services: appwrite-assistant: container_name: appwrite-assistant - image: appwrite/assistant:0.7.0 + image: appwrite/assistant:0.8.3 networks: - appwrite environment: From 160c937dc2614078030982c233ac5b8251c9ad3f Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Fri, 13 Jun 2025 09:01:38 -0700 Subject: [PATCH 06/11] fix: prevent 'Attribute "factors" must be an array' error Because array_unique() preserves keys, the $factors can go from: [ 0 => 'password', 1 => 'totp', 2 => 'totp', 3 => 'email' ] to: [ 0 => 'password', 1 => 'totp', 3 => 'email' ] and because this is not an array list, the validation fails. Using array_values() after array_unique() will reset the keys to be sequential, resulting in: [ 0 => 'password', 1 => 'totp', 2 => 'email' ] --- app/controllers/api/account.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index ac01476314..a7ff7c099d 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -3880,7 +3880,7 @@ App::patch('/v1/account/mfa') if ($user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false)) { $factors[] = Type::PHONE; } - $factors = \array_unique($factors); + $factors = \array_values(\array_unique($factors)); $session->setAttribute('factors', $factors); $dbForProject->updateDocument('sessions', $session->getId(), $session); @@ -4065,7 +4065,7 @@ App::put('/v1/account/mfa/authenticators/:type') $factors = $session->getAttribute('factors', []); $factors[] = $type; - $factors = \array_unique($factors); + $factors = \array_values(\array_unique($factors)); $session->setAttribute('factors', $factors); $dbForProject->updateDocument('sessions', $session->getId(), $session); @@ -4549,7 +4549,7 @@ App::put('/v1/account/mfa/challenge') $factors = $session->getAttribute('factors', []); $factors[] = $type; - $factors = \array_unique($factors); + $factors = \array_values(\array_unique($factors)); $session ->setAttribute('factors', $factors) From 089a80e9a3a5afdee531885568e7350e17fda92a Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 14 Jun 2025 11:57:21 +0530 Subject: [PATCH 07/11] chore: update coderabbit config file --- .coderabbit.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index ec2953a161..23428a6b48 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -8,4 +8,9 @@ reviews: base_branches: - main - 1.6.x - - 1.7.x \ No newline at end of file + - 1.7.x + high_level_summary: false + poem: false + sequence_diagrams: false + collapse_walkthrough: true + changed_files_summary: false \ No newline at end of file From c8854e01de4833ab347013988b026f67980408dd Mon Sep 17 00:00:00 2001 From: Chirag Aggarwal Date: Sat, 14 Jun 2025 12:05:40 +0530 Subject: [PATCH 08/11] chore: formatting --- .coderabbit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 23428a6b48..32f53aea02 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -13,4 +13,4 @@ reviews: poem: false sequence_diagrams: false collapse_walkthrough: true - changed_files_summary: false \ No newline at end of file + changed_files_summary: false From 9196ae7908c5b902f67a638749f99c6a079895cd Mon Sep 17 00:00:00 2001 From: loks0n <22452787+loks0n@users.noreply.github.com> Date: Fri, 13 Jun 2025 11:15:32 +0100 Subject: [PATCH 09/11] feat: tar support --- app/controllers/general.php | 21 +++++++++---------- .../Functions/Http/Executions/Create.php | 6 ++++-- src/Appwrite/Platform/Workers/Functions.php | 6 ++++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 5beac9e1e8..d30c70be42 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -511,28 +511,27 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw 'function' => $deployment->getAttribute('entrypoint', ''), 'site' => '', }; + $source = $deployment->getAttribute('buildPath', ''); + $extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz'; - if ($type === 'function') { - $runtimeEntrypoint = match ($version) { - 'v2' => '', - default => 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $runtime['startCommand'] . '"' - }; - } elseif ($type === 'site') { + $startCommand = $runtime['startCommand']; + if ($type === 'site') { $frameworks = Config::getParam('frameworks', []); $framework = $frameworks[$resource->getAttribute('framework', '')] ?? null; - $startCommand = $runtime['startCommand']; - if (!is_null($framework)) { $adapter = ($framework['adapters'] ?? [])[$deployment->getAttribute('adapter', '')] ?? null; if (!is_null($adapter) && isset($adapter['startCommand'])) { $startCommand = $adapter['startCommand']; } } - - $runtimeEntrypoint = 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $startCommand . '"'; } + $runtimeEntrypoint = match ($version) { + 'v2' => '', + default => "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$startCommand\"", + }; + $entrypoint = match ($type) { 'function' => $deployment->getAttribute('entrypoint', ''), 'site' => '', @@ -545,7 +544,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw variables: $vars, timeout: $resource->getAttribute('timeout', 30), image: $runtime['image'], - source: $deployment->getAttribute('buildPath', ''), + source: $source, entrypoint: $entrypoint, version: $version, path: $path, diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php index fd1b2076a8..71ff730b98 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php @@ -386,7 +386,9 @@ class Create extends Base try { $version = $function->getAttribute('version', 'v2'); $command = $runtime['startCommand']; - $command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"'; + $source = $deployment->getAttribute('buildPath', ''); + $extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz'; + $command = $version === 'v2' ? '' : "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$command\""; $executionResponse = $executor->createExecution( projectId: $project->getId(), deploymentId: $deployment->getId(), @@ -394,7 +396,7 @@ class Create extends Base variables: $vars, timeout: $function->getAttribute('timeout', 0), image: $runtime['image'], - source: $deployment->getAttribute('buildPath', ''), + source: $source, entrypoint: $deployment->getAttribute('entrypoint', ''), version: $version, path: $path, diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index c8c68a58ba..843cb4a5b9 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -519,7 +519,9 @@ class Functions extends Action try { $version = $function->getAttribute('version', 'v2'); $command = $runtime['startCommand']; - $command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"'; + $source = $deployment->getAttribute('buildPath', ''); + $extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz'; + $command = $version === 'v2' ? '' : "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$command\""; $executionResponse = $executor->createExecution( projectId: $project->getId(), deploymentId: $deploymentId, @@ -527,7 +529,7 @@ class Functions extends Action variables: $vars, timeout: $function->getAttribute('timeout', 0), image: $runtime['image'], - source: $deployment->getAttribute('buildPath', ''), + source: $source, entrypoint: $deployment->getAttribute('entrypoint', ''), version: $version, path: $path, From 384b42312948b8a3318194bf39a134d228cc37b8 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 16 Jun 2025 17:46:23 +0300 Subject: [PATCH 10/11] update deleteProject scope --- src/Appwrite/Platform/Workers/Deletes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 43bc55583d..4e7fa1885a 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -495,7 +495,7 @@ class Deletes extends Action * @throws Authorization * @throws DatabaseException */ - private function deleteProject(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForSites, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, Document $document): void + protected function deleteProject(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForSites, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, Document $document): void { $projectInternalId = $document->getInternalId(); $projectId = $document->getId(); From e704e96290822db12744bda75b0a003bb2f9e5c3 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Mon, 16 Jun 2025 11:48:27 -0400 Subject: [PATCH 11/11] Revert "Feat: Lazy-load relationships" --- .github/workflows/tests.yml | 6 +- app/controllers/api/databases.php | 72 ++++------ app/controllers/general.php | 9 -- src/Appwrite/Utopia/Request/Filter.php | 41 ------ src/Appwrite/Utopia/Request/Filters/V19.php | 2 +- src/Appwrite/Utopia/Request/Filters/V20.php | 124 ------------------ src/Appwrite/Utopia/Response/Filters/V20.php | 14 -- .../e2e/Services/Databases/DatabasesBase.php | 37 +----- .../Databases/DatabasesCustomServerTest.php | 52 +------- 9 files changed, 38 insertions(+), 319 deletions(-) delete mode 100644 src/Appwrite/Utopia/Request/Filters/V20.php delete mode 100644 src/Appwrite/Utopia/Response/Filters/V20.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ff548f3447..97f3696e67 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -122,7 +122,7 @@ jobs: docker load --input /tmp/${{ env.IMAGE }}.tar docker compose up -d sleep 10 - + - name: Wait for Open Runtimes timeout-minutes: 3 run: | @@ -273,7 +273,7 @@ jobs: export _APP_DATABASE_SHARED_TABLES=database_db_main export _APP_DATABASE_SHARED_TABLES_V1= fi - + docker compose exec -T \ -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ @@ -359,4 +359,4 @@ jobs: docker compose exec -T \ -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ - appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys \ No newline at end of file + appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 31ab002df2..0e85171772 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -3649,20 +3649,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') $cursor->setValue($cursorDocument); } - - $selectQueries = []; - try { - $selectQueries = Query::groupByType($queries)['selections'] ?? []; - - if (! empty($selectQueries)) { - // has selects, allow relationship on documents! - $documents = $dbForProject->find('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries); - } else { - // has no selects, disable relationship looping on documents! - $documents = $dbForProject->skipRelationships(fn () => $dbForProject->find('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries)); - } - + $documents = $dbForProject->find('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries); $total = $dbForProject->count('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries, APP_LIMIT_COUNT); } catch (OrderException $e) { throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null."); @@ -3735,41 +3723,29 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents') ->addMetric(METRIC_DATABASES_OPERATIONS_READS, \max(1, $operations)) ->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS), \max(1, $operations)); + $select = \array_reduce($queries, function ($result, $query) { + return $result || ($query->getMethod() === Query::TYPE_SELECT); + }, false); + // Check if the SELECT query includes $databaseId and $collectionId - $hasWildcard = false; $hasDatabaseId = false; $hasCollectionId = false; - $hasSelectQueries = !empty($selectQueries); + if ($select) { + $hasDatabaseId = \array_reduce($queries, function ($result, $query) { + return $result || ($query->getMethod() === Query::TYPE_SELECT && \in_array('$databaseId', $query->getValues())); + }, false); + $hasCollectionId = \array_reduce($queries, function ($result, $query) { + return $result || ($query->getMethod() === Query::TYPE_SELECT && \in_array('$collectionId', $query->getValues())); + }, false); + } - if ($hasSelectQueries) { - foreach ($selectQueries as $query) { - if ($query->getMethod() !== Query::TYPE_SELECT) { - continue; + if ($select) { + foreach ($documents as $document) { + if (!$hasDatabaseId) { + $document->removeAttribute('$databaseId'); } - - $values = $query->getValues(); - if (\in_array('*', $values, true)) { - $hasWildcard = true; - break; - } - - if (\in_array('$databaseId', $values, true)) { - $hasDatabaseId = true; - } - - if (\in_array('$collectionId', $values, true)) { - $hasCollectionId = true; - } - } - - if (!$hasWildcard) { - foreach ($documents as $document) { - if (!$hasDatabaseId) { - $document->removeAttribute('$databaseId'); - } - if (!$hasCollectionId) { - $document->removeAttribute('$collectionId'); - } + if (!$hasCollectionId) { + $document->removeAttribute('$collectionId'); } } } @@ -3827,14 +3803,10 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } - $selects = Query::groupByType($queries)['selections'] ?? []; - - if (! empty($selects)) { - // has selects, allow relationship on documents! + try { $document = $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $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)); + } catch (QueryException $e) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); } if ($document->isEmpty()) { diff --git a/app/controllers/general.php b/app/controllers/general.php index c979f8f1b5..ba5b409a2b 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -22,13 +22,11 @@ use Appwrite\Utopia\Request\Filters\V16 as RequestV16; use Appwrite\Utopia\Request\Filters\V17 as RequestV17; use Appwrite\Utopia\Request\Filters\V18 as RequestV18; use Appwrite\Utopia\Request\Filters\V19 as RequestV19; -use Appwrite\Utopia\Request\Filters\V20 as RequestV20; use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Filters\V16 as ResponseV16; use Appwrite\Utopia\Response\Filters\V17 as ResponseV17; use Appwrite\Utopia\Response\Filters\V18 as ResponseV18; use Appwrite\Utopia\Response\Filters\V19 as ResponseV19; -use Appwrite\Utopia\Response\Filters\V20 as ResponseV20; use Appwrite\Utopia\View; use Executor\Executor; use MaxMind\Db\Reader; @@ -844,10 +842,6 @@ App::init() if (version_compare($requestFormat, '1.7.0', '<')) { $request->addFilter(new RequestV19()); } - if (version_compare($requestFormat, '1.8.0', '<')) { - $dbForProject = $getProjectDB($project); - $request->addFilter(new RequestV20($dbForProject, $route)); - } } $domain = $request->getHostname(); @@ -1017,9 +1011,6 @@ App::init() if (version_compare($responseFormat, '1.7.0', '<')) { $response->addFilter(new ResponseV19()); } - if (version_compare($responseFormat, '1.8.0', '<')) { - $response->addFilter(new ResponseV20()); - } if (version_compare($responseFormat, APP_VERSION_STABLE, '>')) { $response->addHeader('X-Appwrite-Warning', "The current SDK is built for Appwrite " . $responseFormat . ". However, the current Appwrite server version is " . APP_VERSION_STABLE . ". Please downgrade your SDK to match the Appwrite version: https://appwrite.io/docs/sdks"); } diff --git a/src/Appwrite/Utopia/Request/Filter.php b/src/Appwrite/Utopia/Request/Filter.php index 2a5fe4d394..59346c7e17 100644 --- a/src/Appwrite/Utopia/Request/Filter.php +++ b/src/Appwrite/Utopia/Request/Filter.php @@ -2,20 +2,8 @@ namespace Appwrite\Utopia\Request; -use Utopia\Database\Database; -use Utopia\Route; - abstract class Filter { - private ?Route $route; - private ?Database $dbForProject; - - public function __construct(Database $dbForProject = null, Route $route = null) - { - $this->route = $route; - $this->dbForProject = $dbForProject; - } - /** * Parse params to another format. * @@ -25,33 +13,4 @@ abstract class Filter * @return array */ abstract public function parse(array $content, string $model): array; - - /** - * Get the database for the current project. - * - * @return null|Database - */ - public function getDbForProject(): ?Database - { - return $this->dbForProject; - } - - /** - * Returns the value of the given route param key, or a default if not found or on error. - * - * @param string $key - * @param mixed $default - * - * @return mixed - */ - public function getParamValue(string $key, mixed $default = ''): mixed - { - try { - $value = $this->route?->getParamValue($key) ?? $default; - } catch (\Exception $e) { - $value = $default; - } - - return $value; - } } diff --git a/src/Appwrite/Utopia/Request/Filters/V19.php b/src/Appwrite/Utopia/Request/Filters/V19.php index e7789ac0f7..8680cd642c 100644 --- a/src/Appwrite/Utopia/Request/Filters/V19.php +++ b/src/Appwrite/Utopia/Request/Filters/V19.php @@ -39,7 +39,7 @@ class V19 extends Filter return $content; } - public function convertQueryAttribute(array $content, string $old, string $new): array + public function convertQueryAttribute(array $content, string $old, string $new) { if (isset($content['queries']) && is_array($content['queries'])) { foreach ($content['queries'] as $index => $query) { diff --git a/src/Appwrite/Utopia/Request/Filters/V20.php b/src/Appwrite/Utopia/Request/Filters/V20.php deleted file mode 100644 index 8719cf7325..0000000000 --- a/src/Appwrite/Utopia/Request/Filters/V20.php +++ /dev/null @@ -1,124 +0,0 @@ -manageSelectQueries($content, $model); - break; - } - return $content; - } - - /** - * From 1.8.x onward, related documents are no longer returned by default to improve performance. - * - * Use `Query::select(['related.*'])` for full documents or `Query::select(['related.key'])` for specific fields. - * - * This filter preserves 1.7.x behavior by including all related documents for backward compatibility with - * `listDocuments` and `getDocument` calls. - */ - protected function manageSelectQueries(array $content, string $model): array - { - $hasWildcard = false; - if (! isset($content['queries'])) { - $hasWildcard = true; - // only query, make it json encoded! - $content['queries'] = [Query::select(['*'])->toString()]; - } - - try { - $parsed = Query::parseQueries($content['queries']); - } catch (QueryException) { - // don't crash! - return $content; - } - - $selections = Query::groupByType($parsed)['selections'] ?? []; - - if (! $hasWildcard) { - // check if any select includes a wildcard as we added one above - foreach ($selections as $select) { - if (\in_array('*', $select->getValues(), true)) { - $hasWildcard = true; - break; - } - } - } - - if ($hasWildcard && $model === 'databases.listDocuments') { - $relatedKeys = $this->getRelatedCollectionKeys(); - - if (! empty($relatedKeys)) { - $selects = \array_values(\array_unique(\array_merge(['*'], $relatedKeys))); - - // remove previous select queries - $parsed = \array_filter( - $parsed, - fn ($query) => $query->getMethod() !== Query::TYPE_SELECT - ); - - // add wildcard + relationship(s) selects - $parsed[] = Query::select($selects); - } - } - - $resolvedQueries = []; - foreach ($parsed as $query) { - // make em json encoded! - $resolvedQueries[] = $query->toString(); - } - - $content['queries'] = $resolvedQueries; - - return $content; - } - - /** - * Returns all relationship attribute keys in `key.*` format for use with `Query::select`. - */ - private function getRelatedCollectionKeys(): array - { - $dbForProject = $this->getDbForProject(); - - if ($dbForProject === null) { - return []; - } - - $databaseId = $this->getParamValue('databaseId'); - $collectionId = $this->getParamValue('collectionId'); - - if (empty($databaseId) || empty($collectionId)) { - return []; - } - - $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - - $collection = $dbForProject->getDocument( - 'database_' . $database->getSequence(), - $collectionId - ); - - $attributes = $collection->getAttribute('attributes', []); - - return \array_values(\array_map( - fn ($attr) => $attr['key'] . '.*', - \array_filter( - $attributes, - fn ($attr) => ($attr['type'] ?? null) === Database::VAR_RELATIONSHIP - ) - )); - } -} diff --git a/src/Appwrite/Utopia/Response/Filters/V20.php b/src/Appwrite/Utopia/Response/Filters/V20.php deleted file mode 100644 index c0ed8297cc..0000000000 --- a/src/Appwrite/Utopia/Response/Filters/V20.php +++ /dev/null @@ -1,14 +0,0 @@ -client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $personCollection . '/documents/' . $person2['body']['$id'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::select(['*', 'libraries.*'])->toString() - ] - ]); + ], $this->getHeaders())); $this->assertEquals(200, $response['headers']['status-code']); $this->assertArrayNotHasKey('$collection', $response['body']); @@ -4568,11 +4564,7 @@ trait DatabasesBase $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $libraryCollection . '/documents/library11', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::select(['person_one_to_many.$id'])->toString() - ] - ]); + ], $this->getHeaders())); $this->assertEquals(200, $response['headers']['status-code']); $this->assertArrayHasKey('person_one_to_many', $response['body']); @@ -4722,11 +4714,7 @@ trait DatabasesBase $album = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $albums['body']['$id'] . '/documents/album1', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::select(['*', 'artist.name', 'artist.$permissions'])->toString() - ] - ]); + ], $this->getHeaders())); $this->assertEquals(200, $album['headers']['status-code']); $this->assertEquals('album1', $album['body']['$id']); @@ -4738,11 +4726,7 @@ trait DatabasesBase $artist = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $artists['body']['$id'] . '/documents/' . $album['body']['artist']['$id'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::select(['*', 'albums.$id', 'albums.name', 'albums.$permissions'])->toString() - ] - ]); + ], $this->getHeaders())); $this->assertEquals(200, $artist['headers']['status-code']); $this->assertEquals('Artist 1', $artist['body']['name']); @@ -4883,11 +4867,7 @@ trait DatabasesBase $sport = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $sports['body']['$id'] . '/documents/sport1', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::select(['*', 'players.name', 'players.$permissions'])->toString() - ] - ]); + ], $this->getHeaders())); $this->assertEquals(200, $sport['headers']['status-code']); $this->assertEquals('sport1', $sport['body']['$id']); @@ -4901,11 +4881,7 @@ trait DatabasesBase $player = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $players['body']['$id'] . '/documents/' . $sport['body']['players'][0]['$id'], array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'queries' => [ - Query::select(['*', 'sports.$id', 'sports.name', 'sports.$permissions'])->toString() - ] - ]); + ], $this->getHeaders())); $this->assertEquals(200, $player['headers']['status-code']); $this->assertEquals('Player 1', $player['body']['name']); @@ -4933,7 +4909,6 @@ trait DatabasesBase ], $this->getHeaders()), [ 'queries' => [ Query::isNotNull('$id')->toString(), - Query::select(['*', 'libraries.*'])->toString(), Query::startsWith('fullName', 'Stevie')->toString(), Query::endsWith('fullName', 'Wonder')->toString(), Query::between('$createdAt', '1975-12-06', '2050-12-01')->toString(), diff --git a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php index 752690cc10..e84c760c86 100644 --- a/tests/e2e/Services/Databases/DatabasesCustomServerTest.php +++ b/tests/e2e/Services/Databases/DatabasesCustomServerTest.php @@ -3779,11 +3779,7 @@ class DatabasesCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), [ - 'queries' => [ - Query::select(['new_level_2.*'])->toString() - ] - ]); + ])); $this->assertArrayHasKey('new_level_2', $newDocument['body']); $this->assertEquals(1, count($newDocument['body']['new_level_2'])); @@ -3893,11 +3889,7 @@ class DatabasesCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), [ - 'queries' => [ - Query::select(['new_level_2.*'])->toString() - ] - ]); + ])); $this->assertArrayHasKey('new_level_2', $newDocument['body']); $this->assertNotEmpty($newDocument['body']['new_level_2']); @@ -4007,11 +3999,7 @@ class DatabasesCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), [ - 'queries' => [ - Query::select(['new_level_2.*'])->toString() - ] - ]); + ])); $this->assertArrayHasKey('new_level_2', $newDocument['body']); $this->assertNotEmpty($newDocument['body']['new_level_2']); @@ -4022,11 +4010,7 @@ class DatabasesCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), [ - 'queries' => [ - Query::select(['*', 'level1.*'])->toString() - ] - ]); + ])); $this->assertArrayHasKey('level1', $level2Document['body']); $this->assertNotEmpty($level2Document['body']['level1']); @@ -4125,11 +4109,7 @@ class DatabasesCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), [ - 'queries' => [ - Query::select(['new_level_2.*'])->toString() - ] - ]); + ])); $this->assertArrayHasKey('new_level_2', $newDocument['body']); $this->assertNotEmpty($newDocument['body']['new_level_2']); @@ -4140,11 +4120,7 @@ class DatabasesCustomServerTest extends Scope 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'] - ]), [ - 'queries' => [ - Query::select(['*', 'level1.*'])->toString() - ] - ]); + ])); $this->assertArrayHasKey('level1', $level2Document['body']); $this->assertNotEmpty($level2Document['body']['level1']); @@ -4489,14 +4465,6 @@ class DatabasesCustomServerTest extends Scope $createBulkDocuments(); - /** - * Wait for database to purge cache... - * - * This test specifically failed on 1.6.x response format, - * could be due to the slow or overworked machine, but being safe here! - */ - sleep(5); - // TEST: Update all documents $response = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([ 'content-type' => 'application/json', @@ -4515,14 +4483,6 @@ class DatabasesCustomServerTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertCount(10, $response['body']['documents']); - /** - * Wait for database to purge cache... - * - * This test specifically failed on 1.6.x response format, - * could be due to the slow or overworked machine, but being safe here! - */ - sleep(5); - $documents = $this->client->call(Client::METHOD_GET, '/databases/' . $data['databaseId'] . '/collections/' . $data['$id'] . '/documents', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'],