diff --git a/app/cli.php b/app/cli.php index 7493d10ab3..4b85ba35c6 100644 --- a/app/cli.php +++ b/app/cli.php @@ -78,6 +78,7 @@ CLI::setResource('dbForPlatform', function ($pools, $cache, $authorization) { $dbForPlatform = new Database($adapter, $cache); $dbForPlatform + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setNamespace('_console') ->setMetadata('host', \gethostname()) @@ -168,6 +169,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform } $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setMetadata('host', \gethostname()) ->setMetadata('project', $project->getId()); @@ -189,6 +191,7 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizatio $database = new Database($adapter, $cache); $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setSharedTables(true) ->setNamespace('logsV1') diff --git a/app/config/sdks.php b/app/config/sdks.php index 5d7755e38f..41dee55080 100644 --- a/app/config/sdks.php +++ b/app/config/sdks.php @@ -227,7 +227,7 @@ return [ [ 'key' => 'cli', 'name' => 'Command Line', - 'version' => '12.0.1', + 'version' => '13.0.0', 'url' => 'https://github.com/appwrite/sdk-for-cli', 'package' => 'https://www.npmjs.com/package/appwrite-cli', 'enabled' => true, diff --git a/app/config/specs/open-api3-latest-client.json b/app/config/specs/open-api3-latest-client.json index 942e83c234..6aef25072a 100644 --- a/app/config/specs/open-api3-latest-client.json +++ b/app/config/specs/open-api3-latest-client.json @@ -13454,6 +13454,16 @@ "description": "Total number of chunks uploaded", "x-example": 17890, "format": "int32" + }, + "encryption": { + "type": "boolean", + "description": "Whether file contents are encrypted at rest.", + "x-example": true + }, + "compression": { + "type": "string", + "description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).", + "x-example": "gzip" } }, "required": [ @@ -13467,7 +13477,9 @@ "mimeType", "sizeOriginal", "chunksTotal", - "chunksUploaded" + "chunksUploaded", + "encryption", + "compression" ], "example": { "$id": "5e5ea5c16897e", @@ -13482,7 +13494,9 @@ "mimeType": "image\/png", "sizeOriginal": 17890, "chunksTotal": 17890, - "chunksUploaded": 17890 + "chunksUploaded": 17890, + "encryption": true, + "compression": "gzip" } }, "team": { diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index f7cbca76a5..96c074b8ee 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -55191,6 +55191,16 @@ "description": "Total number of chunks uploaded", "x-example": 17890, "format": "int32" + }, + "encryption": { + "type": "boolean", + "description": "Whether file contents are encrypted at rest.", + "x-example": true + }, + "compression": { + "type": "string", + "description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).", + "x-example": "gzip" } }, "required": [ @@ -55204,7 +55214,9 @@ "mimeType", "sizeOriginal", "chunksTotal", - "chunksUploaded" + "chunksUploaded", + "encryption", + "compression" ], "example": { "$id": "5e5ea5c16897e", @@ -55219,7 +55231,9 @@ "mimeType": "image\/png", "sizeOriginal": 17890, "chunksTotal": 17890, - "chunksUploaded": 17890 + "chunksUploaded": 17890, + "encryption": true, + "compression": "gzip" } }, "bucket": { diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index 76e3a2a45c..d86aa78f99 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -43244,6 +43244,16 @@ "description": "Total number of chunks uploaded", "x-example": 17890, "format": "int32" + }, + "encryption": { + "type": "boolean", + "description": "Whether file contents are encrypted at rest.", + "x-example": true + }, + "compression": { + "type": "string", + "description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).", + "x-example": "gzip" } }, "required": [ @@ -43257,7 +43267,9 @@ "mimeType", "sizeOriginal", "chunksTotal", - "chunksUploaded" + "chunksUploaded", + "encryption", + "compression" ], "example": { "$id": "5e5ea5c16897e", @@ -43272,7 +43284,9 @@ "mimeType": "image\/png", "sizeOriginal": 17890, "chunksTotal": 17890, - "chunksUploaded": 17890 + "chunksUploaded": 17890, + "encryption": true, + "compression": "gzip" } }, "bucket": { diff --git a/app/config/specs/swagger2-latest-client.json b/app/config/specs/swagger2-latest-client.json index 1d02df124a..0df8d6f382 100644 --- a/app/config/specs/swagger2-latest-client.json +++ b/app/config/specs/swagger2-latest-client.json @@ -13393,6 +13393,16 @@ "description": "Total number of chunks uploaded", "x-example": 17890, "format": "int32" + }, + "encryption": { + "type": "boolean", + "description": "Whether file contents are encrypted at rest.", + "x-example": true + }, + "compression": { + "type": "string", + "description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).", + "x-example": "gzip" } }, "required": [ @@ -13406,7 +13416,9 @@ "mimeType", "sizeOriginal", "chunksTotal", - "chunksUploaded" + "chunksUploaded", + "encryption", + "compression" ], "example": { "$id": "5e5ea5c16897e", @@ -13421,7 +13433,9 @@ "mimeType": "image\/png", "sizeOriginal": 17890, "chunksTotal": 17890, - "chunksUploaded": 17890 + "chunksUploaded": 17890, + "encryption": true, + "compression": "gzip" } }, "team": { diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 17064287be..3f2b3d4447 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -55019,6 +55019,16 @@ "description": "Total number of chunks uploaded", "x-example": 17890, "format": "int32" + }, + "encryption": { + "type": "boolean", + "description": "Whether file contents are encrypted at rest.", + "x-example": true + }, + "compression": { + "type": "string", + "description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).", + "x-example": "gzip" } }, "required": [ @@ -55032,7 +55042,9 @@ "mimeType", "sizeOriginal", "chunksTotal", - "chunksUploaded" + "chunksUploaded", + "encryption", + "compression" ], "example": { "$id": "5e5ea5c16897e", @@ -55047,7 +55059,9 @@ "mimeType": "image\/png", "sizeOriginal": 17890, "chunksTotal": 17890, - "chunksUploaded": 17890 + "chunksUploaded": 17890, + "encryption": true, + "compression": "gzip" } }, "bucket": { diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index 6ad3eb4bce..2a452b8658 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -43169,6 +43169,16 @@ "description": "Total number of chunks uploaded", "x-example": 17890, "format": "int32" + }, + "encryption": { + "type": "boolean", + "description": "Whether file contents are encrypted at rest.", + "x-example": true + }, + "compression": { + "type": "string", + "description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).", + "x-example": "gzip" } }, "required": [ @@ -43182,7 +43192,9 @@ "mimeType", "sizeOriginal", "chunksTotal", - "chunksUploaded" + "chunksUploaded", + "encryption", + "compression" ], "example": { "$id": "5e5ea5c16897e", @@ -43197,7 +43209,9 @@ "mimeType": "image\/png", "sizeOriginal": 17890, "chunksTotal": 17890, - "chunksUploaded": 17890 + "chunksUploaded": 17890, + "encryption": true, + "compression": "gzip" } }, "bucket": { diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 74f734a856..b0493ff38f 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -227,6 +227,7 @@ App::post('/v1/projects') if (!$sharedTablesV2) { $adapter = new DatabasePool($pools->get($dsn->getHost())); $dbForProject = new Database($adapter, $cache); + $dbForProject->setDatabase(APP_DATABASE); if ($sharedTables) { $dbForProject diff --git a/app/init/constants.php b/app/init/constants.php index 0c95c4543b..d51cb6b7af 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -161,6 +161,9 @@ const ACTIVITY_TYPE_GUEST = 'guest'; const MFA_RECENT_DURATION = 1800; // 30 mins +// Database name +const APP_DATABASE = 'appwrite'; + // Database Reconnect const DATABASE_RECONNECT_SLEEP = 2; const DATABASE_RECONNECT_MAX_ATTEMPTS = 10; diff --git a/app/init/registers.php b/app/init/registers.php index 1b58c85aa4..9799c56914 100644 --- a/app/init/registers.php +++ b/app/init/registers.php @@ -324,6 +324,12 @@ $register->set('pools', function () { Config::setParam('pools-' . $key, $config); } + $reconnectAttempts = (int) System::getEnv('_APP_CONNECTIONS_RECONNECT_ATTEMPTS', 5); + $reconnectSleep = (int) System::getEnv('_APP_CONNECTIONS_RECONNECT_SLEEP', 2); + + $group->setReconnectAttempts($reconnectAttempts); + $group->setReconnectSleep($reconnectSleep); + return $group; }); diff --git a/app/init/resources.php b/app/init/resources.php index 371609da97..a9d46a17be 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -533,6 +533,7 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform $database = new Database($adapter, $cache); $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setMetadata('host', \gethostname()) ->setMetadata('project', $project->getId()) @@ -563,6 +564,7 @@ App::setResource('dbForPlatform', function (Group $pools, Cache $cache, Authoriz $database = new Database($adapter, $cache); $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setNamespace('_console') ->setMetadata('host', \gethostname()) @@ -592,6 +594,7 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform $configure = (function (Database $database) use ($project, $dsn, $authorization) { $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setMetadata('host', \gethostname()) ->setMetadata('project', $project->getId()) @@ -643,6 +646,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizatio $database = new Database($adapter, $cache); $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setSharedTables(true) ->setNamespace('logsV1') diff --git a/app/realtime.php b/app/realtime.php index 31e6015d92..fcc5329982 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -66,6 +66,7 @@ if (!function_exists('getConsoleDB')) { $adapter = new DatabasePool($pools->get('console')); $database = new Database($adapter, getCache()); $database + ->setDatabase(APP_DATABASE) ->setNamespace('_console') ->setMetadata('host', \gethostname()) ->setMetadata('project', '_console'); @@ -122,6 +123,7 @@ if (!function_exists('getProjectDB')) { } $database + ->setDatabase(APP_DATABASE) ->setMetadata('host', \gethostname()) ->setMetadata('project', $project->getId()); diff --git a/app/worker.php b/app/worker.php index d31e63fc8b..ba8bf98568 100644 --- a/app/worker.php +++ b/app/worker.php @@ -65,6 +65,7 @@ Server::setResource('dbForPlatform', function (Cache $cache, Registry $register, $dbForPlatform = new Database($adapter, $cache); $dbForPlatform + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setNamespace('_console') ->setDocumentType('users', User::class) @@ -118,6 +119,7 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register, } $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER); @@ -179,6 +181,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf } $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER); @@ -198,6 +201,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authoriza $database = new Database($adapter, $cache); $database + ->setDatabase(APP_DATABASE) ->setAuthorization($authorization) ->setSharedTables(true) ->setNamespace('logsV1') diff --git a/composer.lock b/composer.lock index d909b43d59..5519d4cf93 100644 --- a/composer.lock +++ b/composer.lock @@ -3455,24 +3455,25 @@ }, { "name": "utopia-php/abuse", - "version": "1.0.2", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "611fa66a97e87c0dbbc133a717d970da7a5ca828" + "reference": "15cd5dbefa4453e8a2d90649a7078e242966ac3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/611fa66a97e87c0dbbc133a717d970da7a5ca828", - "reference": "611fa66a97e87c0dbbc133a717d970da7a5ca828", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/15cd5dbefa4453e8a2d90649a7078e242966ac3f", + "reference": "15cd5dbefa4453e8a2d90649a7078e242966ac3f", "shasum": "" }, "require": { + "appwrite/appwrite": "19.*", "ext-curl": "*", "ext-pdo": "*", "ext-redis": "*", "php": ">=8.0", - "utopia-php/database": "*" + "utopia-php/database": "4.*" }, "require-dev": { "laravel/pint": "1.*", @@ -3500,9 +3501,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/1.0.2" + "source": "https://github.com/utopia-php/abuse/tree/1.2.1" }, - "time": "2025-10-20T07:18:33+00:00" + "time": "2026-01-15T02:09:49+00:00" }, { "name": "utopia-php/analytics", @@ -3898,16 +3899,16 @@ }, { "name": "utopia-php/database", - "version": "4.5.1", + "version": "4.5.2", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "7b935bb09aeae8aeff5a28f6f2485cef1cc4d898" + "reference": "8e6a033d4da09a2f2ac1f79fd85fcfa2da018d23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/7b935bb09aeae8aeff5a28f6f2485cef1cc4d898", - "reference": "7b935bb09aeae8aeff5a28f6f2485cef1cc4d898", + "url": "https://api.github.com/repos/utopia-php/database/zipball/8e6a033d4da09a2f2ac1f79fd85fcfa2da018d23", + "reference": "8e6a033d4da09a2f2ac1f79fd85fcfa2da018d23", "shasum": "" }, "require": { @@ -3950,9 +3951,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/4.5.1" + "source": "https://github.com/utopia-php/database/tree/4.5.2" }, - "time": "2026-01-14T12:07:24+00:00" + "time": "2026-01-15T04:23:30+00:00" }, { "name": "utopia-php/detector", @@ -5481,16 +5482,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "1.8.15", + "version": "1.8.16", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "a43e8ba5d539e48f0717df284dbd5dc1fb659d6b" + "reference": "e2963002b39f3aa24bd6bf61a78492e182397174" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/a43e8ba5d539e48f0717df284dbd5dc1fb659d6b", - "reference": "a43e8ba5d539e48f0717df284dbd5dc1fb659d6b", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/e2963002b39f3aa24bd6bf61a78492e182397174", + "reference": "e2963002b39f3aa24bd6bf61a78492e182397174", "shasum": "" }, "require": { @@ -5526,9 +5527,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.8.15" + "source": "https://github.com/appwrite/sdk-generator/tree/1.8.16" }, - "time": "2026-01-14T10:42:32+00:00" + "time": "2026-01-15T08:16:15+00:00" }, { "name": "brianium/paratest", @@ -9197,5 +9198,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } diff --git a/docs/sdks/cli/CHANGELOG.md b/docs/sdks/cli/CHANGELOG.md index 9f1f02bbd0..b8dfc56dc5 100644 --- a/docs/sdks/cli/CHANGELOG.md +++ b/docs/sdks/cli/CHANGELOG.md @@ -1,5 +1,34 @@ # Change Log +## 13.0.0 + +- Mark release as stable +- Feat: add pull sync on destruction of remote resources (+ confirmation) +- Fix: refine zod schema to check string size +- Validate using zod schema during push cli command +- Maintain order of keys in local config + +## 13.0.0-rc.5 + +- Fix push all command not working correctly + +## 13.0.0-rc.4 + +- Fix CLI ES module import issues + +## 13.0.0-rc.3 + +- Add `Schema` class for programmatically pushing and pulling appwrite config +- Add client side db generation using `schema.db.generate()` command + +## 13.0.0-rc.2 + +- Fixes a lot of typescript errors throughout the codebase + +## 13.0.0-rc.1 + +- Migrates codebase from JavaScript to TypeScript + ## 12.0.1 Fix type generation for `point`, `lineString` and `polygon` columns diff --git a/src/Appwrite/Platform/Tasks/SDKs.php b/src/Appwrite/Platform/Tasks/SDKs.php index c3a67d7fbb..8a3eef2d34 100644 --- a/src/Appwrite/Platform/Tasks/SDKs.php +++ b/src/Appwrite/Platform/Tasks/SDKs.php @@ -399,7 +399,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ->setDefaultHeaders([ 'X-Appwrite-Response-Format' => '1.8.0', ]) - ->setExclude($language['exclude'] ?? []); + ->setExclude($language['exclude'] ?? []) + ->setTest(false); // Make sure we have a clean slate. // Otherwise, all files in this dir will be pushed, diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index d047d0925e..e053efa021 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -8,6 +8,7 @@ use Appwrite\Event\Func; use Appwrite\Event\Realtime; use Appwrite\Event\StatsUsage; use Appwrite\Event\Webhook; +use Appwrite\Extend\Exception as AppwriteException; use Appwrite\Utopia\Response\Model\Execution; use Exception; use Executor\Executor; @@ -661,7 +662,11 @@ class Functions extends Action ->trigger(); if (!empty($error)) { - throw new Exception($error, $errorCode); + throw new AppwriteException( + AppwriteException::GENERAL_SERVER_ERROR, + $error ?: 'Function execution failed with no error message', + $errorCode + ); } } } diff --git a/src/Appwrite/SDK/Specification/Format.php b/src/Appwrite/SDK/Specification/Format.php index ed77e568f4..7cb03c8e1b 100644 --- a/src/Appwrite/SDK/Specification/Format.php +++ b/src/Appwrite/SDK/Specification/Format.php @@ -666,171 +666,16 @@ abstract class Format 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; + if ($param !== 'status') { + return null; } - return null; + + return match (true) { + $model === 'healthStatus' => 'HealthCheckStatus', + str_starts_with($model, 'attribute') => 'AttributeStatus', + str_starts_with($model, 'column') => 'ColumnStatus', + default => null, + }; } protected function getNestedModels(Model $model, array &$usedModels): void @@ -852,4 +697,31 @@ abstract class Format } } } + + protected function parseDescription(string $description, array $excludedValues): string + { + if (empty($excludedValues)) { + return $description; + } + + foreach ($excludedValues as $excludedValue) { + // remove from comma-separated list + $description = preg_replace( + '/,\s*' . preg_quote($excludedValue, '/') . '(?=\s*[,.]|$)/', + '', + $description + ); + $description = preg_replace( + '/(?<=:\s|,\s)' . preg_quote($excludedValue, '/') . '\s*,\s*/', + '', + $description + ); + } + + // clean up double commas and extra spaces + $description = preg_replace('/,\s*,/', ',', $description); + $description = preg_replace('/\s+/', ' ', $description); + + return trim($description); + } } diff --git a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php index 27dcf92923..8171a45db4 100644 --- a/src/Appwrite/SDK/Specification/Format/OpenAPI3.php +++ b/src/Appwrite/SDK/Specification/Format/OpenAPI3.php @@ -623,6 +623,10 @@ class OpenAPI3 extends Format $node['schema']['items']['enum'] = $enumValues; $node['schema']['items']['x-enum-name'] = $this->getRequestEnumName($sdk->getNamespace() ?? '', $methodName, $name); $node['schema']['items']['x-enum-keys'] = $enumKeys; + + if (!empty($excludeKeys)) { + $node['description'] = $this->parseDescription($node['description'], $excludeKeys); + } } if ($validator->getType() === 'integer') { $node['schema']['items']['format'] = $validator->getFormat() ?? 'int32'; @@ -673,6 +677,10 @@ class OpenAPI3 extends Format $node['schema']['enum'] = $enumValues; $node['schema']['x-enum-name'] = $this->getRequestEnumName($sdk->getNamespace() ?? '', $methodName, $name); $node['schema']['x-enum-keys'] = $enumKeys; + + if (!empty($excludeKeys)) { + $node['description'] = $this->parseDescription($node['description'], $excludeKeys); + } } if ($validator->getType() === 'integer') { $node['schema']['format'] = $validator->getFormat() ?? 'int32'; diff --git a/src/Appwrite/SDK/Specification/Format/Swagger2.php b/src/Appwrite/SDK/Specification/Format/Swagger2.php index de25a57ccc..990c456851 100644 --- a/src/Appwrite/SDK/Specification/Format/Swagger2.php +++ b/src/Appwrite/SDK/Specification/Format/Swagger2.php @@ -607,6 +607,10 @@ class Swagger2 extends Format $node['items']['enum'] = $enumValues; $node['items']['x-enum-name'] = $this->getRequestEnumName($namespace, $methodName, $name); $node['items']['x-enum-keys'] = $enumKeys; + + if (!empty($excludeKeys)) { + $node['description'] = $this->parseDescription($node['description'], $excludeKeys); + } } if ($validator->getType() === 'integer') { $node['items']['format'] = $validator->getFormat() ?? 'int32'; @@ -651,6 +655,10 @@ class Swagger2 extends Format $node['enum'] = $enumValues; $node['x-enum-name'] = $this->getRequestEnumName($namespace, $methodName, $name); $node['x-enum-keys'] = $enumKeys; + + if (!empty($excludeKeys)) { + $node['description'] = $this->parseDescription($node['description'], $excludeKeys); + } } if ($validator->getType() === 'integer') { $node['format'] = $validator->getFormat() ?? 'int32';