Merge branch '1.8.x' of https://github.com/appwrite/appwrite into migration-endpoint

# Conflicts:
#	.env
This commit is contained in:
fogelito 2026-01-29 17:15:05 +02:00
commit 1b82d32436
69 changed files with 14691 additions and 963 deletions

1
.env
View file

@ -130,4 +130,5 @@ _APP_PROJECT_REGIONS=default
_APP_FUNCTIONS_CREATION_ABUSE_LIMIT=5000
_APP_STATS_USAGE_DUAL_WRITING_DBS=database_db_main
_APP_TRUSTED_HEADERS=x-forwarded-for
_APP_POOL_ADAPTER=stack
_APP_MIGRATION_ENDPOINT=http://appwrite.test/v1

View file

@ -12,7 +12,7 @@ RUN composer install --ignore-platform-reqs --optimize-autoloader \
--no-plugins --no-scripts --prefer-dist \
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
FROM appwrite/base:0.10.6 AS base
FROM appwrite/base:0.11.5 AS base
LABEL maintainer="team@appwrite.io"

View file

@ -5888,7 +5888,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 338,
"weight": 346,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@ -5955,7 +5955,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 334,
"weight": 342,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@ -6026,7 +6026,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 335,
"weight": 343,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@ -6090,7 +6090,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 336,
"weight": 344,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@ -6168,7 +6168,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 337,
"weight": 345,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@ -6234,7 +6234,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 339,
"weight": 347,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@ -7335,7 +7335,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 431,
"weight": 447,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@ -7422,7 +7422,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 429,
"weight": 445,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@ -7540,7 +7540,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 430,
"weight": 446,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@ -8315,7 +8315,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 527,
"weight": 543,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@ -8414,7 +8414,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 525,
"weight": 541,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@ -8516,7 +8516,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 526,
"weight": 542,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@ -8590,7 +8590,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 528,
"weight": 544,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@ -8682,7 +8682,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 529,
"weight": 545,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@ -8751,7 +8751,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 531,
"weight": 547,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@ -8831,7 +8831,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 530,
"weight": 546,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@ -9061,7 +9061,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 532,
"weight": 548,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@ -9148,7 +9148,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 403,
"weight": 419,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@ -9218,7 +9218,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 399,
"weight": 415,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@ -9292,7 +9292,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 400,
"weight": 416,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@ -9359,7 +9359,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 401,
"weight": 417,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@ -9440,7 +9440,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 402,
"weight": 418,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@ -9509,7 +9509,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 404,
"weight": 420,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@ -9597,7 +9597,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 395,
"weight": 411,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@ -9708,7 +9708,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 387,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@ -9864,7 +9864,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 388,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@ -9974,7 +9974,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 391,
"weight": 407,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@ -10124,7 +10124,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 389,
"weight": 405,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@ -10235,7 +10235,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 393,
"weight": 409,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@ -10341,7 +10341,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 398,
"weight": 414,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@ -10469,7 +10469,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 397,
"weight": 413,
"cookies": false,
"type": "",
"demo": "tablesdb\/increment-row-column.md",

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5994,7 +5994,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 338,
"weight": 346,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@ -6061,7 +6061,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 334,
"weight": 342,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@ -6132,7 +6132,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 335,
"weight": 343,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@ -6195,7 +6195,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 336,
"weight": 344,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@ -6274,7 +6274,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 337,
"weight": 345,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@ -6339,7 +6339,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 339,
"weight": 347,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@ -7392,7 +7392,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 431,
"weight": 447,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@ -7475,7 +7475,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 429,
"weight": 445,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@ -7594,7 +7594,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 430,
"weight": 446,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@ -8396,7 +8396,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 527,
"weight": 543,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@ -8489,7 +8489,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 525,
"weight": 541,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@ -8580,7 +8580,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 526,
"weight": 542,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@ -8651,7 +8651,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 528,
"weight": 544,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@ -8742,7 +8742,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 529,
"weight": 545,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@ -8813,7 +8813,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 531,
"weight": 547,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@ -8893,7 +8893,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 530,
"weight": 546,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@ -9101,7 +9101,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 532,
"weight": 548,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@ -9181,7 +9181,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 403,
"weight": 419,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@ -9251,7 +9251,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 399,
"weight": 415,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@ -9325,7 +9325,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 400,
"weight": 416,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@ -9391,7 +9391,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 401,
"weight": 417,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@ -9473,7 +9473,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 402,
"weight": 418,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@ -9541,7 +9541,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 404,
"weight": 420,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@ -9625,7 +9625,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 395,
"weight": 411,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@ -9728,7 +9728,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 387,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@ -9882,7 +9882,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 388,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@ -9984,7 +9984,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 391,
"weight": 407,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@ -10130,7 +10130,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 389,
"weight": 405,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@ -10239,7 +10239,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 393,
"weight": 409,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@ -10339,7 +10339,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 398,
"weight": 414,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@ -10461,7 +10461,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 397,
"weight": 413,
"cookies": false,
"type": "",
"demo": "tablesdb\/increment-row-column.md",

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,34 @@ function getRuntimes($runtimes, $commands, $entrypoint, $providerRootDirectory,
}));
}
class FunctionUseCases
{
public const STARTER = 'starter';
public const DATABASES = 'databases';
public const AI = 'ai';
public const MESSAGING = 'messaging';
public const UTILITIES = 'utilities';
public const DEV_TOOLS = 'dev-tools';
public const AUTH = 'auth';
/**
* @var array<string>
*/
public static function getAll(): array
{
return [
self::STARTER,
self::DATABASES,
self::AI,
self::MESSAGING,
self::UTILITIES,
self::DEV_TOOLS,
self::AUTH,
];
}
}
return [
[
'icon' => 'icon-lightning-bolt',
@ -32,7 +60,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['starter'],
'useCases' => [FunctionUseCases::STARTER],
'runtimes' => [
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/starter', $allowList),
...getRuntimes(
@ -73,7 +101,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['databases'],
'useCases' => [FunctionUseCases::DATABASES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -119,7 +147,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['databases'],
'useCases' => [FunctionUseCases::DATABASES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -164,7 +192,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['databases'],
'useCases' => [FunctionUseCases::DATABASES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -218,7 +246,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['databases'],
'useCases' => [FunctionUseCases::DATABASES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -257,7 +285,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['databases'],
'useCases' => [FunctionUseCases::DATABASES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -326,7 +354,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -392,7 +420,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['messaging'],
'useCases' => [FunctionUseCases::MESSAGING],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -459,7 +487,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -497,7 +525,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -548,7 +576,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['utilities'],
'useCases' => [FunctionUseCases::UTILITIES],
'runtimes' => [
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/generate-pdf', $allowList)
],
@ -571,7 +599,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['dev-tools'],
'useCases' => [FunctionUseCases::DEV_TOOLS],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -616,7 +644,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['utilities'],
'useCases' => [FunctionUseCases::UTILITIES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -669,7 +697,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['databases'],
'useCases' => [FunctionUseCases::DATABASES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -754,7 +782,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['databases'],
'useCases' => [FunctionUseCases::DATABASES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -853,7 +881,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['messaging'],
'useCases' => [FunctionUseCases::MESSAGING],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -946,7 +974,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['messaging'],
'useCases' => [FunctionUseCases::MESSAGING],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1004,7 +1032,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['utilities'],
'useCases' => [FunctionUseCases::UTILITIES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1091,7 +1119,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['utilities'],
'useCases' => [FunctionUseCases::UTILITIES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1134,7 +1162,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['utilities'],
'useCases' => [FunctionUseCases::UTILITIES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1193,7 +1221,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1229,7 +1257,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1265,7 +1293,7 @@ return [
'events' => ['buckets.*.files.*.create'],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1325,7 +1353,7 @@ return [
'events' => ['buckets.*.files.*.create'],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1385,7 +1413,7 @@ return [
'events' => ['buckets.*.files.*.create'],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1448,7 +1476,7 @@ return [
],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1508,7 +1536,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1545,7 +1573,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1589,7 +1617,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1632,7 +1660,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1669,7 +1697,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1734,7 +1762,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1799,7 +1827,7 @@ return [
'cron' => '',
'events' => [],
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1856,7 +1884,7 @@ return [
'cron' => '',
'events' => [],
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1899,7 +1927,7 @@ return [
'cron' => '',
'events' => [],
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1942,7 +1970,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -1986,7 +2014,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => ['ai'],
'useCases' => [FunctionUseCases::AI],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -2023,7 +2051,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['utilities'],
'useCases' => [FunctionUseCases::UTILITIES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -2080,7 +2108,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['utilities'],
'useCases' => [FunctionUseCases::UTILITIES],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@ -2153,7 +2181,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['auth'],
'useCases' => [FunctionUseCases::AUTH],
'runtimes' => [
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/sign_in_with_apple', $allowList)
],

View file

@ -13,7 +13,7 @@ $hostname = $platform['consoleHostname'] ?? '';
$url = $protocol . '://' . $hostname;
class UseCases
class SiteUseCases
{
public const PORTFOLIO = 'portfolio';
public const STARTER = 'starter';
@ -21,9 +21,27 @@ class UseCases
public const ECOMMERCE = 'ecommerce';
public const DOCUMENTATION = 'documentation';
public const BLOG = 'blog';
public const AI = 'artificial intelligence';
public const AI = 'ai';
public const FORMS = 'forms';
public const DASHBOARD = 'dashboard';
/**
* @var array<string>
*/
public static function getAll(): array
{
return [
self::PORTFOLIO,
self::STARTER,
self::EVENTS,
self::ECOMMERCE,
self::DOCUMENTATION,
self::BLOG,
self::AI,
self::FORMS,
self::DASHBOARD,
];
}
}
const TEMPLATE_FRAMEWORKS = [
@ -188,7 +206,7 @@ return [
'name' => 'Documentation template',
'tagline' => 'Modern site to store your knowledge with a clean design, full-text search, dark mode, and more.',
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::DOCUMENTATION],
'useCases' => [SiteUseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/template-for-documentation-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-documentation-light.png',
'frameworks' => [
@ -209,7 +227,7 @@ return [
// When we add Lynx with Appwrite SDK, use following tagline for it:
// 'tagline' => 'Sample application built with Lynx, a cross-platform framework focused on performance.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-lynx-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-lynx-light.png',
'frameworks' => [
@ -220,7 +238,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -228,7 +246,7 @@ return [
'name' => 'Vitepress',
'tagline' => 'Platform for documentation and knowledge sharing powered by Vite.',
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::DOCUMENTATION],
'useCases' => [SiteUseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/vitepress-dark.png',
'screenshotLight' => $url . '/images/sites/templates/vitepress-light.png',
'frameworks' => [
@ -243,7 +261,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -251,7 +269,7 @@ return [
'name' => 'Vuepress',
'tagline' => 'Platform for documentation and knowledge sharing powered by Vue.',
'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::DOCUMENTATION],
'useCases' => [SiteUseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/vuepress-dark.png',
'screenshotLight' => $url . '/images/sites/templates/vuepress-light.png',
'frameworks' => [
@ -266,7 +284,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -274,7 +292,7 @@ return [
'name' => 'Docusaurus',
'tagline' => 'Platform for documentation and knowledge sharing powered by React.',
'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::DOCUMENTATION],
'useCases' => [SiteUseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/docusaurus-dark.png',
'screenshotLight' => $url . '/images/sites/templates/docusaurus-light.png',
'frameworks' => [
@ -289,7 +307,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -297,7 +315,7 @@ return [
'name' => 'Nxt Lnk',
'tagline' => 'Personal website for creators to merge all URLs to social profiles.',
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::PORTFOLIO],
'useCases' => [SiteUseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/nxt-lnk-dark.png',
'screenshotLight' => $url . '/images/sites/templates/nxt-lnk-light.png',
'frameworks' => [
@ -308,7 +326,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -316,7 +334,7 @@ return [
'name' => 'Magic Portfolio',
'tagline' => 'Complex personal website to showcase your projects, articles, and more.',
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::PORTFOLIO],
'useCases' => [SiteUseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/magic-portfolio-dark.png',
'screenshotLight' => $url . '/images/sites/templates/magic-portfolio-light.png',
'frameworks' => [
@ -327,7 +345,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -335,7 +353,7 @@ return [
'name' => 'LittleLink',
'tagline' => 'Personal website for creators to merge all URLs to social profiles.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::PORTFOLIO],
'useCases' => [SiteUseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/littlelink-dark.png',
'screenshotLight' => $url . '/images/sites/templates/littlelink-light.png',
'frameworks' => [
@ -346,7 +364,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -354,7 +372,7 @@ return [
'name' => 'Logspot',
'tagline' => 'Website to publish changelogs of your application.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::BLOG],
'useCases' => [SiteUseCases::BLOG],
'screenshotDark' => $url . '/images/sites/templates/logspot-dark.png',
'screenshotLight' => $url . '/images/sites/templates/logspot-light.png',
'frameworks' => [
@ -368,7 +386,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -376,7 +394,7 @@ return [
'name' => 'Astro Nano',
'tagline' => 'Minimal personal website to showcase your projects, articles, and more.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::PORTFOLIO],
'useCases' => [SiteUseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/astro-nano-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-nano-light.png',
'frameworks' => [
@ -389,7 +407,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -397,7 +415,7 @@ return [
'name' => 'Astro Starlight',
'tagline' => 'Platform for documentation and knowledge sharing powered by Astro.',
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::DOCUMENTATION],
'useCases' => [SiteUseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/astro-starlight-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-starlight-light.png',
'frameworks' => [
@ -410,7 +428,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -418,7 +436,7 @@ return [
'name' => 'Astro Sphere',
'tagline' => 'Modern personal website to showcase your projects, articles, and more.',
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::PORTFOLIO],
'useCases' => [SiteUseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/astro-sphere-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-sphere-light.png',
'frameworks' => [
@ -431,7 +449,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -439,7 +457,7 @@ return [
'name' => 'Astro Starlog',
'tagline' => 'Platform for publishing written content and media powered by Astro.',
'score' => 5, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::BLOG],
'useCases' => [SiteUseCases::BLOG],
'screenshotDark' => $url . '/images/sites/templates/astro-starlog-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-starlog-light.png',
'frameworks' => [
@ -452,7 +470,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -460,7 +478,7 @@ return [
'name' => 'Onelink',
'tagline' => 'Personal website for creators to merge all URLs to social profiles.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::PORTFOLIO],
'useCases' => [SiteUseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/onelink-dark.png',
'screenshotLight' => $url . '/images/sites/templates/onelink-light.png',
'frameworks' => [
@ -474,13 +492,13 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
'key' => 'starter-for-flutter',
'name' => 'Flutter starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Flutter application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-flutter-dark.png',
@ -525,7 +543,7 @@ return [
[
'key' => 'starter-for-js',
'name' => 'JavaScript starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple JavaScript application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-js-dark.png',
@ -569,7 +587,7 @@ return [
[
'key' => 'starter-for-angular',
'name' => 'Angular starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Angular application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-angular-dark.png',
@ -615,7 +633,7 @@ return [
[
'key' => 'starter-for-astro',
'name' => 'Astro starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Astro application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-astro-dark.png',
@ -660,7 +678,7 @@ return [
[
'key' => 'starter-for-analog',
'name' => 'Analog starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Analog application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-analog-dark.png',
@ -704,7 +722,7 @@ return [
[
'key' => 'starter-for-remix',
'name' => 'Remix starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Remix application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-remix-dark.png',
@ -748,7 +766,7 @@ return [
[
'key' => 'starter-for-svelte',
'name' => 'Svelte starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Svelte application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-svelte-dark.png',
@ -792,7 +810,7 @@ return [
[
'key' => 'starter-for-react',
'name' => 'React starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple React application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-dark.png',
@ -836,7 +854,7 @@ return [
[
'key' => 'starter-for-vue',
'name' => 'Vue starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Vue application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-vue-dark.png',
@ -880,7 +898,7 @@ return [
[
'key' => 'starter-for-react-native',
'name' => 'React Native starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple React Native application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-native-dark.png',
@ -924,7 +942,7 @@ return [
[
'key' => 'starter-for-nextjs',
'name' => 'Next.js starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Next.js application integrated with Appwrite SDK.',
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-nextjs-dark.png',
@ -968,7 +986,7 @@ return [
[
'key' => 'starter-for-tanstack-start',
'name' => 'TanStack Start starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple TanStack Start application integrated with Appwrite SDK.',
'score' => 9, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-tanstack-start-dark.png',
@ -1012,7 +1030,7 @@ return [
[
'key' => 'starter-for-nuxt',
'name' => 'Nuxt starter',
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'tagline' => 'Simple Nuxt application integrated with Appwrite SDK.',
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'screenshotDark' => $url . '/images/sites/templates/starter-for-nuxt-dark.png',
@ -1058,7 +1076,7 @@ return [
'name' => 'Event template',
'tagline' => 'Hackathon landing page with support for project submissions.',
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::EVENTS],
'useCases' => [SiteUseCases::EVENTS],
'screenshotDark' => $url . '/images/sites/templates/template-for-event-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-event-light.png',
'frameworks' => [
@ -1096,7 +1114,7 @@ return [
'name' => 'Portfolio template',
'tagline' => 'Simple personal website to showcase your projects, articles, and more.',
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::PORTFOLIO],
'useCases' => [SiteUseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/template-for-portfolio-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-portfolio-light.png',
'frameworks' => [
@ -1115,7 +1133,7 @@ return [
'name' => 'Store template',
'tagline' => 'E-commerce platform for selling products with Stripe integration.',
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::ECOMMERCE],
'useCases' => [SiteUseCases::ECOMMERCE],
'screenshotDark' => $url . '/images/sites/templates/template-for-store-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-store-light.png',
'frameworks' => [
@ -1159,7 +1177,7 @@ return [
'name' => 'Blog template',
'tagline' => 'Platform for publishing written content and media.',
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::BLOG],
'useCases' => [SiteUseCases::BLOG],
'screenshotDark' => $url . '/images/sites/templates/template-for-blog-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-blog-light.png',
'frameworks' => [
@ -1178,7 +1196,7 @@ return [
'name' => 'Astro playground',
'tagline' => 'A basic Astro website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-astro-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-astro-light.png',
'frameworks' => [
@ -1189,7 +1207,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1197,7 +1215,7 @@ return [
'name' => 'Remix playground',
'tagline' => 'A basic Remix website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-remix-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-remix-light.png',
'frameworks' => [
@ -1208,7 +1226,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1216,7 +1234,7 @@ return [
'name' => 'Next.js playground',
'tagline' => 'A basic Next.js website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-nextjs-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-nextjs-light.png',
'frameworks' => [
@ -1227,7 +1245,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1235,7 +1253,7 @@ return [
'name' => 'Flutter playground',
'tagline' => 'A basic Flutter website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-flutter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-flutter-light.png',
'frameworks' => [
@ -1246,7 +1264,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1254,7 +1272,7 @@ return [
'name' => 'Vite playground',
'tagline' => 'A basic Vite website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-vite-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-vite-light.png',
'frameworks' => [
@ -1265,7 +1283,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1273,7 +1291,7 @@ return [
'name' => 'Angular playground',
'tagline' => 'A basic Angular website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-angular-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-angular-light.png',
'frameworks' => [
@ -1285,7 +1303,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1293,7 +1311,7 @@ return [
'name' => 'Analog playground',
'tagline' => 'A basic Analog website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-analog-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-analog-light.png',
'frameworks' => [
@ -1304,7 +1322,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1312,7 +1330,7 @@ return [
'name' => 'Svelte playground',
'tagline' => 'A basic Svelte website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-svelte-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-svelte-light.png',
'frameworks' => [
@ -1323,7 +1341,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
@ -1332,7 +1350,7 @@ return [
'name' => 'React playground',
'tagline' => 'A basic React website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-react-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-react-light.png',
'frameworks' => [
@ -1344,7 +1362,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
@ -1353,7 +1371,7 @@ return [
'name' => 'Vue playground',
'tagline' => 'A basic Vue website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-vue-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-vue-light.png',
'frameworks' => [
@ -1364,7 +1382,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1372,7 +1390,7 @@ return [
'name' => 'Nuxt playground',
'tagline' => 'A basic Nuxt website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-nuxt-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-nuxt-light.png',
'frameworks' => [
@ -1383,7 +1401,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1391,7 +1409,7 @@ return [
'name' => 'TanStack Start playground',
'tagline' => 'A basic TanStack Start website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-tanstack-start-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-tanstack-start-light.png',
'frameworks' => [
@ -1402,7 +1420,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.5.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1410,7 +1428,7 @@ return [
'name' => 'React Native playground',
'tagline' => 'A basic React Native website without Appwrite SDK integration.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-react-native-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-react-native-light.png',
'frameworks' => [
@ -1421,7 +1439,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => [],
],
[
@ -1429,7 +1447,7 @@ return [
'name' => 'Lynx gallery',
'tagline' => 'A Lynx website showcasing gallery with smooth animations.',
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::STARTER],
'useCases' => [SiteUseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/gallery-for-lynx-dark.png',
'screenshotLight' => $url . '/images/sites/templates/gallery-for-lynx-light.png',
'frameworks' => [
@ -1440,7 +1458,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.3.*',
'providerVersion' => '0.7.*',
'variables' => []
],
[
@ -1448,7 +1466,7 @@ return [
'name' => 'Text-to-speech with ElevenLabs',
'tagline' => 'Next.js app that transforms text into natural, human-like speech using ElevenLabs',
'score' => 10, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::AI],
'useCases' => [SiteUseCases::AI],
'screenshotDark' => $url . '/images/sites/templates/text-to-speech-dark.png',
'screenshotLight' => $url . '/images/sites/templates/text-to-speech-light.png',
'frameworks' => [
@ -1459,7 +1477,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.6.*',
'providerVersion' => '0.7.*',
'variables' => [
[
'name' => 'ELEVENLABS_API_KEY',
@ -1476,7 +1494,7 @@ return [
'name' => 'CRM dashboard with React Admin',
'tagline' => 'A React-based admin dashboard template with CRM features.',
'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::DASHBOARD],
'useCases' => [SiteUseCases::DASHBOARD],
'screenshotDark' => $url . '/images/sites/templates/crm-dashboard-react-admin-dark.png',
'screenshotLight' => $url . '/images/sites/templates/crm-dashboard-react-admin-light.png',
'frameworks' => [
@ -1579,7 +1597,7 @@ return [
'name' => 'Job applications form with Formspree',
'tagline' => 'A simple form submission template using Formspree.',
'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
'useCases' => [UseCases::FORMS],
'useCases' => [SiteUseCases::FORMS],
'screenshotDark' => $url . '/images/sites/templates/job-applications-formspree-dark.png',
'screenshotLight' => $url . '/images/sites/templates/job-applications-formspree-light.png',
'frameworks' => [

View file

@ -20,11 +20,15 @@ use Appwrite\Utopia\Response\Model\AttributeInteger;
use Appwrite\Utopia\Response\Model\AttributeIP;
use Appwrite\Utopia\Response\Model\AttributeLine;
use Appwrite\Utopia\Response\Model\AttributeList;
use Appwrite\Utopia\Response\Model\AttributeLongtext;
use Appwrite\Utopia\Response\Model\AttributeMediumtext;
use Appwrite\Utopia\Response\Model\AttributePoint;
use Appwrite\Utopia\Response\Model\AttributePolygon;
use Appwrite\Utopia\Response\Model\AttributeRelationship;
use Appwrite\Utopia\Response\Model\AttributeString;
use Appwrite\Utopia\Response\Model\AttributeText;
use Appwrite\Utopia\Response\Model\AttributeURL;
use Appwrite\Utopia\Response\Model\AttributeVarchar;
use Appwrite\Utopia\Response\Model\AuthProvider;
use Appwrite\Utopia\Response\Model\BaseList;
use Appwrite\Utopia\Response\Model\Branch;
@ -41,11 +45,15 @@ use Appwrite\Utopia\Response\Model\ColumnInteger;
use Appwrite\Utopia\Response\Model\ColumnIP;
use Appwrite\Utopia\Response\Model\ColumnLine;
use Appwrite\Utopia\Response\Model\ColumnList;
use Appwrite\Utopia\Response\Model\ColumnLongtext;
use Appwrite\Utopia\Response\Model\ColumnMediumtext;
use Appwrite\Utopia\Response\Model\ColumnPoint;
use Appwrite\Utopia\Response\Model\ColumnPolygon;
use Appwrite\Utopia\Response\Model\ColumnRelationship;
use Appwrite\Utopia\Response\Model\ColumnString;
use Appwrite\Utopia\Response\Model\ColumnText;
use Appwrite\Utopia\Response\Model\ColumnURL;
use Appwrite\Utopia\Response\Model\ColumnVarchar;
use Appwrite\Utopia\Response\Model\ConsoleVariables;
use Appwrite\Utopia\Response\Model\Continent;
use Appwrite\Utopia\Response\Model\Country;
@ -222,6 +230,10 @@ Response::setModel(new AttributeRelationship());
Response::setModel(new AttributePoint());
Response::setModel(new AttributeLine());
Response::setModel(new AttributePolygon());
Response::setModel(new AttributeVarchar());
Response::setModel(new AttributeText());
Response::setModel(new AttributeMediumtext());
Response::setModel(new AttributeLongtext());
// Table API Models
Response::setModel(new Table());
@ -240,6 +252,10 @@ Response::setModel(new ColumnRelationship());
Response::setModel(new ColumnPoint());
Response::setModel(new ColumnLine());
Response::setModel(new ColumnPolygon());
Response::setModel(new ColumnVarchar());
Response::setModel(new ColumnText());
Response::setModel(new ColumnMediumtext());
Response::setModel(new ColumnLongtext());
Response::setModel(new Index());
Response::setModel(new ColumnIndex());
Response::setModel(new Row());

View file

@ -23,6 +23,8 @@ use Utopia\Logger\Adapter\LogOwl;
use Utopia\Logger\Adapter\Raygun;
use Utopia\Logger\Adapter\Sentry;
use Utopia\Logger\Logger;
use Utopia\Pools\Adapter\Stack as StackPool;
use Utopia\Pools\Adapter\Swoole as SwoolePool;
use Utopia\Pools\Group;
use Utopia\Pools\Pool;
use Utopia\Queue;
@ -285,7 +287,9 @@ $register->set('pools', function () {
default => throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Invalid scheme'),
};
$pool = new Pool($name, $poolSize, function () use ($type, $resource, $dsn) {
$poolAdapter = System::getEnv('_APP_POOL_ADAPTER', default: 'stack') === 'swoole' ? new SwoolePool() : new StackPool();
$pool = new Pool($poolAdapter, $name, $poolSize, function () use ($type, $resource, $dsn) {
// Get Adapter
switch ($type) {
case 'database':

View file

@ -38,7 +38,7 @@
"ext-yaml": "*",
"ext-dom": "*",
"ext-redis": "*",
"ext-swoole": "*",
"ext-swoole": "6.*",
"ext-pdo": "*",
"ext-openssl": "*",
"ext-zlib": "*",
@ -67,7 +67,7 @@
"utopia-php/migration": "1.*",
"utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.7.*",
"utopia-php/pools": "0.8.*",
"utopia-php/pools": "1.*",
"utopia-php/preloader": "0.2.*",
"utopia-php/queue": "0.15.*",
"utopia-php/registry": "0.5.*",
@ -91,7 +91,7 @@
"ext-fileinfo": "*",
"appwrite/sdk-generator": "*",
"phpunit/phpunit": "9.*",
"swoole/ide-helper": "5.1.2",
"swoole/ide-helper": "6.*",
"phpstan/phpstan": "1.8.*",
"textalk/websocket": "1.5.*",
"laravel/pint": "1.*",

73
composer.lock generated
View file

@ -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": "33da844fdf5648d1d1a027dfb6ae42bc",
"content-hash": "2aca1c8eeaa9fa338e389e3527cb6bd6",
"packages": [
{
"name": "adhocore/jwt",
@ -3719,16 +3719,16 @@
},
{
"name": "utopia-php/cache",
"version": "0.13.2",
"version": "0.13.3",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/cache.git",
"reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6"
"reference": "355707ab2c0090435059216165db86976b68a126"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/cache/zipball/5768498c9f451482f0bf3eede4d6452ddcd4a0f6",
"reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6",
"url": "https://api.github.com/repos/utopia-php/cache/zipball/355707ab2c0090435059216165db86976b68a126",
"reference": "355707ab2c0090435059216165db86976b68a126",
"shasum": ""
},
"require": {
@ -3736,7 +3736,7 @@
"ext-memcached": "*",
"ext-redis": "*",
"php": ">=8.0",
"utopia-php/pools": "0.8.*",
"utopia-php/pools": "1.*",
"utopia-php/telemetry": "*"
},
"require-dev": {
@ -3765,9 +3765,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/cache/issues",
"source": "https://github.com/utopia-php/cache/tree/0.13.2"
"source": "https://github.com/utopia-php/cache/tree/0.13.3"
},
"time": "2025-12-17T08:55:43+00:00"
"time": "2026-01-16T07:54:34+00:00"
},
{
"name": "utopia-php/cli",
@ -3961,16 +3961,16 @@
},
{
"name": "utopia-php/database",
"version": "4.6.2",
"version": "4.6.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "53394759c44067e9db4660635765e2056f83788c"
"reference": "8795a7f5bf8828955299ae44e5946f93a2b1bde5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/53394759c44067e9db4660635765e2056f83788c",
"reference": "53394759c44067e9db4660635765e2056f83788c",
"url": "https://api.github.com/repos/utopia-php/database/zipball/8795a7f5bf8828955299ae44e5946f93a2b1bde5",
"reference": "8795a7f5bf8828955299ae44e5946f93a2b1bde5",
"shasum": ""
},
"require": {
@ -3981,7 +3981,7 @@
"utopia-php/cache": "0.13.*",
"utopia-php/framework": "0.33.*",
"utopia-php/mongo": "0.11.*",
"utopia-php/pools": "0.8.*"
"utopia-php/pools": "1.*"
},
"require-dev": {
"fakerphp/faker": "1.23.*",
@ -4013,9 +4013,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/4.6.2"
"source": "https://github.com/utopia-php/database/tree/4.6.1"
},
"time": "2026-01-22T07:14:12+00:00"
"time": "2026-01-21T09:37:22+00:00"
},
{
"name": "utopia-php/detector",
@ -4796,16 +4796,16 @@
},
{
"name": "utopia-php/pools",
"version": "0.8.3",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/pools.git",
"reference": "ad7d6ba946376e81c603204285ce9a674b6502b8"
"reference": "b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/pools/zipball/ad7d6ba946376e81c603204285ce9a674b6502b8",
"reference": "ad7d6ba946376e81c603204285ce9a674b6502b8",
"url": "https://api.github.com/repos/utopia-php/pools/zipball/b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1",
"reference": "b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1",
"shasum": ""
},
"require": {
@ -4815,7 +4815,8 @@
"require-dev": {
"laravel/pint": "1.*",
"phpstan/phpstan": "1.*",
"phpunit/phpunit": "11.*"
"phpunit/phpunit": "11.*",
"swoole/ide-helper": "6.*"
},
"type": "library",
"autoload": {
@ -4842,9 +4843,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/pools/issues",
"source": "https://github.com/utopia-php/pools/tree/0.8.3"
"source": "https://github.com/utopia-php/pools/tree/1.0.2"
},
"time": "2025-12-17T09:35:18+00:00"
"time": "2026-01-28T13:12:36+00:00"
},
{
"name": "utopia-php/preloader",
@ -4901,16 +4902,16 @@
},
{
"name": "utopia-php/queue",
"version": "0.15.0",
"version": "0.15.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/queue.git",
"reference": "6abb268ba7ec00dea4e5201b007776ea1bce9242"
"reference": "e551606385990ec7901d222017c4cfc2749a518c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/queue/zipball/6abb268ba7ec00dea4e5201b007776ea1bce9242",
"reference": "6abb268ba7ec00dea4e5201b007776ea1bce9242",
"url": "https://api.github.com/repos/utopia-php/queue/zipball/e551606385990ec7901d222017c4cfc2749a518c",
"reference": "e551606385990ec7901d222017c4cfc2749a518c",
"shasum": ""
},
"require": {
@ -4919,7 +4920,7 @@
"utopia-php/console": "0.0.*",
"utopia-php/fetch": "0.5.*",
"utopia-php/framework": "0.33.*",
"utopia-php/pools": "0.8.*",
"utopia-php/pools": "1.*",
"utopia-php/telemetry": "*"
},
"require-dev": {
@ -4961,9 +4962,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/queue/issues",
"source": "https://github.com/utopia-php/queue/tree/0.15.0"
"source": "https://github.com/utopia-php/queue/tree/0.15.1"
},
"time": "2026-01-06T12:41:51+00:00"
"time": "2026-01-16T07:54:54+00:00"
},
{
"name": "utopia-php/registry",
@ -8007,16 +8008,16 @@
},
{
"name": "swoole/ide-helper",
"version": "5.1.2",
"version": "6.0.2",
"source": {
"type": "git",
"url": "https://github.com/swoole/ide-helper.git",
"reference": "33ec7af9111b76d06a70dd31191cc74793551112"
"reference": "6f12243dce071714c5febe059578d909698f9a52"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/33ec7af9111b76d06a70dd31191cc74793551112",
"reference": "33ec7af9111b76d06a70dd31191cc74793551112",
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/6f12243dce071714c5febe059578d909698f9a52",
"reference": "6f12243dce071714c5febe059578d909698f9a52",
"shasum": ""
},
"type": "library",
@ -8033,9 +8034,9 @@
"description": "IDE help files for Swoole.",
"support": {
"issues": "https://github.com/swoole/ide-helper/issues",
"source": "https://github.com/swoole/ide-helper/tree/5.1.2"
"source": "https://github.com/swoole/ide-helper/tree/6.0.2"
},
"time": "2024-02-01T22:28:11+00:00"
"time": "2025-03-23T07:31:41+00:00"
},
{
"name": "symfony/console",
@ -9063,7 +9064,7 @@
"ext-yaml": "*",
"ext-dom": "*",
"ext-redis": "*",
"ext-swoole": "*",
"ext-swoole": "6.*",
"ext-pdo": "*",
"ext-openssl": "*",
"ext-zlib": "*",

View file

@ -112,6 +112,7 @@ services:
- _APP_ENV
- _APP_EDITION
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_LOCALE
- _APP_COMPRESSION_ENABLED
- _APP_COMPRESSION_MIN_SIZE_BYTES
@ -302,6 +303,7 @@ services:
- _APP_LOGGING_CONFIG
- _APP_LOGGING_CONFIG_REALTIME
- _APP_DATABASE_SHARED_TABLES
- _APP_POOL_ADAPTER=swoole
appwrite-worker-audits:
entrypoint: worker-audits
@ -319,6 +321,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@ -350,6 +353,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_EMAIL_SECURITY
- _APP_DB_HOST
@ -387,6 +391,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@ -444,6 +449,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@ -478,6 +484,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
@ -551,6 +558,7 @@ services:
# Basic
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_LOGGING_CONFIG
# Database
- _APP_OPENSSL_KEY_V1
@ -608,6 +616,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
@ -650,6 +659,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_OPTIONS_FORCE_HTTPS
@ -693,6 +703,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
@ -727,6 +738,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@ -784,6 +796,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
@ -824,6 +837,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
- _APP_DOMAIN_TARGET_AAAA
@ -868,6 +882,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
- _APP_DOMAIN_TARGET_AAAA
@ -906,6 +921,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@ -937,6 +953,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@ -968,6 +985,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@ -999,6 +1017,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@ -1027,6 +1046,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@ -1054,6 +1074,7 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT

View file

@ -0,0 +1 @@
Create a longtext attribute.

View file

@ -0,0 +1 @@
Create a mediumtext attribute.

View file

@ -0,0 +1 @@
Create a text attribute.

View file

@ -0,0 +1 @@
Create a varchar attribute.

View file

@ -0,0 +1 @@
Update a longtext attribute. Changing the `default` value will not update already existing documents.

View file

@ -0,0 +1 @@
Update a mediumtext attribute. Changing the `default` value will not update already existing documents.

View file

@ -0,0 +1 @@
Update a text attribute. Changing the `default` value will not update already existing documents.

View file

@ -0,0 +1 @@
Update a varchar attribute. Changing the `default` value will not update already existing documents.

View file

@ -0,0 +1 @@
Create a longtext column.

View file

@ -0,0 +1 @@
Create a mediumtext column.

View file

@ -0,0 +1 @@
Create a text column.

View file

@ -0,0 +1 @@
Create a varchar column.

View file

@ -0,0 +1 @@
Update a longtext column. Changing the `default` value will not update already existing rows.

View file

@ -0,0 +1 @@
Update a mediumtext column. Changing the `default` value will not update already existing rows.

View file

@ -0,0 +1 @@
Update a text column. Changing the `default` value will not update already existing rows.

View file

@ -0,0 +1 @@
Update a varchar column. Changing the `default` value will not update already existing rows.

View file

@ -265,6 +265,22 @@ abstract class Action extends UtopiaAction
? UtopiaResponse::MODEL_ATTRIBUTE_POLYGON
: UtopiaResponse::MODEL_COLUMN_POLYGON,
Database::VAR_VARCHAR => $isCollections
? UtopiaResponse::MODEL_ATTRIBUTE_VARCHAR
: UtopiaResponse::MODEL_COLUMN_VARCHAR,
Database::VAR_TEXT => $isCollections
? UtopiaResponse::MODEL_ATTRIBUTE_TEXT
: UtopiaResponse::MODEL_COLUMN_TEXT,
Database::VAR_MEDIUMTEXT => $isCollections
? UtopiaResponse::MODEL_ATTRIBUTE_MEDIUMTEXT
: UtopiaResponse::MODEL_COLUMN_MEDIUMTEXT,
Database::VAR_LONGTEXT => $isCollections
? UtopiaResponse::MODEL_ATTRIBUTE_LONGTEXT
: UtopiaResponse::MODEL_COLUMN_LONGTEXT,
Database::VAR_STRING => match ($format) {
APP_DATABASE_ATTRIBUTE_EMAIL => $isCollections
? UtopiaResponse::MODEL_ATTRIBUTE_EMAIL

View file

@ -0,0 +1,108 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Longtext;
use Appwrite\Event\Database as EventDatabase;
use Appwrite\Event\Event;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
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\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Create extends Action
{
public static function getName(): string
{
return 'createLongtextAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_LONGTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/longtext')
->desc('Create longtext attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
->label('audits.event', 'attribute.create')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/create-longtext-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
],
))
->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('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?bool $required,
?string $default,
bool $array,
UtopiaResponse $response,
Database $dbForProject,
EventDatabase $queueForDatabase,
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->createAttribute(
$databaseId,
$collectionId,
new Document([
'key' => $key,
'type' => Database::VAR_LONGTEXT,
'size' => 2147483647,
'required' => $required,
'default' => $default,
'array' => $array,
]),
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents,
$authorization
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,101 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Longtext;
use Appwrite\Event\Event;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Update extends Action
{
public static function getName(): string
{
return 'updateLongtextAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_LONGTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/longtext/:key')
->desc('Update longtext attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
->label('audits.event', 'attribute.update')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/update-longtext-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
contentType: ContentType::JSON,
))
->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('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
->param('newKey', null, new Nullable(new Key()), 'New Attribute Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?bool $required,
?string $default,
?string $newKey,
UtopiaResponse $response,
Database $dbForProject,
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->updateAttribute(
databaseId: $databaseId,
collectionId: $collectionId,
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_LONGTEXT,
default: $default,
required: $required,
newKey: $newKey
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,108 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Mediumtext;
use Appwrite\Event\Database as EventDatabase;
use Appwrite\Event\Event;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
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\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Create extends Action
{
public static function getName(): string
{
return 'createMediumtextAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_MEDIUMTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/mediumtext')
->desc('Create mediumtext attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
->label('audits.event', 'attribute.create')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/create-mediumtext-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
],
))
->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('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?bool $required,
?string $default,
bool $array,
UtopiaResponse $response,
Database $dbForProject,
EventDatabase $queueForDatabase,
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->createAttribute(
$databaseId,
$collectionId,
new Document([
'key' => $key,
'type' => Database::VAR_MEDIUMTEXT,
'size' => 16777215,
'required' => $required,
'default' => $default,
'array' => $array,
]),
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents,
$authorization
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,101 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Mediumtext;
use Appwrite\Event\Event;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Update extends Action
{
public static function getName(): string
{
return 'updateMediumtextAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_MEDIUMTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/mediumtext/:key')
->desc('Update mediumtext attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
->label('audits.event', 'attribute.update')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/update-mediumtext-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
contentType: ContentType::JSON,
))
->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('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
->param('newKey', null, new Nullable(new Key()), 'New Attribute Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?bool $required,
?string $default,
?string $newKey,
UtopiaResponse $response,
Database $dbForProject,
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->updateAttribute(
databaseId: $databaseId,
collectionId: $collectionId,
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_MEDIUMTEXT,
default: $default,
required: $required,
newKey: $newKey
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,108 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Text;
use Appwrite\Event\Database as EventDatabase;
use Appwrite\Event\Event;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
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\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Create extends Action
{
public static function getName(): string
{
return 'createTextAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_TEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/text')
->desc('Create text attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
->label('audits.event', 'attribute.create')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/create-text-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
],
))
->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('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?bool $required,
?string $default,
bool $array,
UtopiaResponse $response,
Database $dbForProject,
EventDatabase $queueForDatabase,
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->createAttribute(
$databaseId,
$collectionId,
new Document([
'key' => $key,
'type' => Database::VAR_TEXT,
'size' => 65535,
'required' => $required,
'default' => $default,
'array' => $array,
]),
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents,
$authorization
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,101 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Text;
use Appwrite\Event\Event;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Update extends Action
{
public static function getName(): string
{
return 'updateTextAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_TEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/text/:key')
->desc('Update text attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
->label('audits.event', 'attribute.update')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/update-text-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
contentType: ContentType::JSON,
))
->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('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
->param('newKey', null, new Nullable(new Key()), 'New Attribute Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?bool $required,
?string $default,
?string $newKey,
UtopiaResponse $response,
Database $dbForProject,
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->updateAttribute(
databaseId: $databaseId,
collectionId: $collectionId,
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_TEXT,
default: $default,
required: $required,
newKey: $newKey
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,119 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Varchar;
use Appwrite\Event\Database as EventDatabase;
use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
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\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
class Create extends Action
{
public static function getName(): string
{
return 'createVarcharAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_VARCHAR;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/varchar')
->desc('Create varchar attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
->label('audits.event', 'attribute.create')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/create-varchar-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
],
))
->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('key', '', new Key(), 'Attribute Key.')
->param('size', null, new Range(1, 16381, Validator::TYPE_INTEGER), 'Attribute size for varchar attributes, in number of characters. Maximum size is 16381.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?int $size,
?bool $required,
?string $default,
bool $array,
UtopiaResponse $response,
Database $dbForProject,
EventDatabase $queueForDatabase,
Event $queueForEvents,
Authorization $authorization
): void {
// Ensure default fits in the given size
$validator = new Text($size, 0);
if (!is_null($default) && !$validator->isValid($default)) {
throw new Exception($this->getInvalidValueException(), $validator->getDescription());
}
$attribute = $this->createAttribute(
$databaseId,
$collectionId,
new Document([
'key' => $key,
'type' => Database::VAR_VARCHAR,
'size' => $size,
'required' => $required,
'default' => $default,
'array' => $array,
]),
$response,
$dbForProject,
$queueForDatabase,
$queueForEvents,
$authorization
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,106 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Varchar;
use Appwrite\Event\Event;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
class Update extends Action
{
public static function getName(): string
{
return 'updateVarcharAttribute';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_ATTRIBUTE_VARCHAR;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/varchar/:key')
->desc('Update varchar attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
->label('audits.event', 'attribute.update')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/databases/update-varchar-attribute.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
contentType: ContentType::JSON,
))
->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('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Nullable(new Text(0, 0)), 'Default value for attribute when not provided. Cannot be set when attribute is required.')
->param('size', null, new Nullable(new Range(1, 16381, Validator::TYPE_INTEGER)), 'Maximum size of the varchar attribute.', true)
->param('newKey', null, new Nullable(new Key()), 'New Attribute Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
public function action(
string $databaseId,
string $collectionId,
string $key,
?bool $required,
?string $default,
?int $size,
?string $newKey,
UtopiaResponse $response,
Database $dbForProject,
Event $queueForEvents,
Authorization $authorization
): void {
$attribute = $this->updateAttribute(
databaseId: $databaseId,
collectionId: $collectionId,
key: $key,
dbForProject: $dbForProject,
queueForEvents: $queueForEvents,
authorization: $authorization,
type: Database::VAR_VARCHAR,
size: $size,
default: $default,
required: $required,
newKey: $newKey
);
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($attribute, $this->getResponseModel());
}
}

View file

@ -0,0 +1,67 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Longtext;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Longtext\Create as LongtextCreate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Create extends LongtextCreate
{
public static function getName(): string
{
return 'createLongtextColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_LONGTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/longtext')
->desc('Create longtext column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
->label('audits.event', 'column.create')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/create-longtext-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
]
))
->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/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.', true)
->param('array', false, new Boolean(), 'Is column an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -0,0 +1,68 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Longtext;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Longtext\Update as LongtextUpdate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Update extends LongtextUpdate
{
public static function getName(): string
{
return 'updateLongtextColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_LONGTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/longtext/:key')
->desc('Update longtext column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
->label('audits.event', 'column.update')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/update-longtext-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
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/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.')
->param('newKey', null, new Nullable(new Key()), 'New Column Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -0,0 +1,67 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Mediumtext;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Mediumtext\Create as MediumtextCreate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Create extends MediumtextCreate
{
public static function getName(): string
{
return 'createMediumtextColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_MEDIUMTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/mediumtext')
->desc('Create mediumtext column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
->label('audits.event', 'column.create')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/create-mediumtext-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
]
))
->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/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.', true)
->param('array', false, new Boolean(), 'Is column an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -0,0 +1,68 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Mediumtext;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Mediumtext\Update as MediumtextUpdate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Update extends MediumtextUpdate
{
public static function getName(): string
{
return 'updateMediumtextColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_MEDIUMTEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/mediumtext/:key')
->desc('Update mediumtext column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
->label('audits.event', 'column.update')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/update-mediumtext-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
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/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.')
->param('newKey', null, new Nullable(new Key()), 'New Column Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -4,6 +4,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Strin
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\String\Create as StringCreate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Deprecated;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
@ -51,7 +52,11 @@ class Create extends StringCreate
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
]
],
deprecated: new Deprecated(
since: '1.9.0',
replaceWith: 'tablesDB.createTextColumn',
),
))
->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/references/cloud/server-dart/tablesDB#createTable).')

View file

@ -4,7 +4,7 @@ namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Strin
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\String\Update as StringUpdate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Deprecated;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
@ -53,7 +53,10 @@ class Update extends StringUpdate
model: $this->getResponseModel(),
)
],
contentType: ContentType::JSON
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'tablesDB.updateTextColumn',
)
))
->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/references/cloud/server-dart/tablesDB#createTable).')

View file

@ -0,0 +1,67 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Text;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Text\Create as TextCreate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Create extends TextCreate
{
public static function getName(): string
{
return 'createTextColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_TEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/text')
->desc('Create text column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
->label('audits.event', 'column.create')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/create-text-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
]
))
->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/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.', true)
->param('array', false, new Boolean(), 'Is column an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -0,0 +1,68 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Text;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Text\Update as TextUpdate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Text;
class Update extends TextUpdate
{
public static function getName(): string
{
return 'updateTextColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_TEXT;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/text/:key')
->desc('Update text column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
->label('audits.event', 'column.update')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/update-text-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
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/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.')
->param('newKey', null, new Nullable(new Key()), 'New Column Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -0,0 +1,70 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Varchar;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Varchar\Create as VarcharCreate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
class Create extends VarcharCreate
{
public static function getName(): string
{
return 'createVarcharColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_VARCHAR;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/varchar')
->desc('Create varchar column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
->label('audits.event', 'column.create')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/create-varchar-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: $this->getResponseModel()
)
]
))
->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/references/cloud/server-dart/tablesDB#createTable).')
->param('key', '', new Key(), 'Column Key.')
->param('size', null, new Range(1, 16381, Validator::TYPE_INTEGER), 'Column size for varchar columns, in number of characters. Maximum size is 16381.')
->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.', true)
->param('array', false, new Boolean(), 'Is column an array?', true)
->inject('response')
->inject('dbForProject')
->inject('queueForDatabase')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -0,0 +1,71 @@
<?php
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Varchar;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Varchar\Update as VarcharUpdate;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Validator\Key;
use Utopia\Database\Validator\UID;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator;
use Utopia\Validator\Boolean;
use Utopia\Validator\Nullable;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
class Update extends VarcharUpdate
{
public static function getName(): string
{
return 'updateVarcharColumn';
}
protected function getResponseModel(): string|array
{
return UtopiaResponse::MODEL_COLUMN_VARCHAR;
}
public function __construct()
{
$this
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/varchar/:key')
->desc('Update varchar column')
->groups(['api', 'database', 'schema'])
->label('scope', ['tables.write', 'collections.write'])
->label('resourceType', RESOURCE_TYPE_DATABASES)
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
->label('audits.event', 'column.update')
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
->label('sdk', new Method(
namespace: $this->getSDKNamespace(),
group: $this->getSDKGroup(),
name: self::getName(),
description: '/docs/references/tablesdb/update-varchar-column.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: $this->getResponseModel(),
)
],
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/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.')
->param('size', null, new Nullable(new Range(1, 16381, Validator::TYPE_INTEGER)), 'Maximum size of the varchar column.', true)
->param('newKey', null, new Nullable(new Key()), 'New Column Key.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->inject('authorization')
->callback($this->action(...));
}
}

View file

@ -20,6 +20,10 @@ use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\IP
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\IP\Update as UpdateIPAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line\Create as CreateLineAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Line\Update as UpdateLineAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Longtext\Create as CreateLongtextAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Longtext\Update as UpdateLongtextAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Mediumtext\Create as CreateMediumtextAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Mediumtext\Update as UpdateMediumtextAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point\Create as CreatePointAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Point\Update as UpdatePointAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Polygon\Create as CreatePolygonAttribute;
@ -28,8 +32,12 @@ use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Re
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Relationship\Update as UpdateRelationshipAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\String\Create as CreateStringAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\String\Update as UpdateStringAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Text\Create as CreateTextAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Text\Update as UpdateTextAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\URL\Create as CreateURLAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\URL\Update as UpdateURLAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Varchar\Create as CreateVarcharAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Varchar\Update as UpdateVarcharAttribute;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\XList as ListAttributes;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Create as CreateCollection;
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Delete as DeleteCollection;
@ -190,6 +198,22 @@ class Legacy extends Base
// Attribute: URL
$service->addAction(CreateURLAttribute::getName(), new CreateURLAttribute());
$service->addAction(UpdateURLAttribute::getName(), new UpdateURLAttribute());
// Attribute: Varchar
$service->addAction(CreateVarcharAttribute::getName(), new CreateVarcharAttribute());
$service->addAction(UpdateVarcharAttribute::getName(), new UpdateVarcharAttribute());
// Attribute: Text
$service->addAction(CreateTextAttribute::getName(), new CreateTextAttribute());
$service->addAction(UpdateTextAttribute::getName(), new UpdateTextAttribute());
// Attribute: Mediumtext
$service->addAction(CreateMediumtextAttribute::getName(), new CreateMediumtextAttribute());
$service->addAction(UpdateMediumtextAttribute::getName(), new UpdateMediumtextAttribute());
// Attribute: Longtext
$service->addAction(CreateLongtextAttribute::getName(), new CreateLongtextAttribute());
$service->addAction(UpdateLongtextAttribute::getName(), new UpdateLongtextAttribute());
}
private function registerIndexActions(Service $service): void

View file

@ -23,6 +23,10 @@ use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\IP\Create a
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\IP\Update as UpdateIP;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Line\Create as CreateLine;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Line\Update as UpdateLine;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Longtext\Create as CreateLongtext;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Longtext\Update as UpdateLongtext;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Mediumtext\Create as CreateMediumtext;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Mediumtext\Update as UpdateMediumtext;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Point\Create as CreatePoint;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Point\Update as UpdatePoint;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Polygon\Create as CreatePolygon;
@ -31,8 +35,12 @@ use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Relationshi
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Relationship\Update as UpdateRelationship;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\String\Create as CreateString;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\String\Update as UpdateString;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Text\Create as CreateText;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Text\Update as UpdateText;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\URL\Create as CreateURL;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\URL\Update as UpdateURL;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Varchar\Create as CreateVarchar;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Varchar\Update as UpdateVarchar;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\XList as ListColumns;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Create as CreateTable;
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Delete as DeleteTable;
@ -170,6 +178,22 @@ class TablesDB extends Base
// Column: URL
$service->addAction(CreateURL::getName(), new CreateURL());
$service->addAction(UpdateURL::getName(), new UpdateURL());
// Column: Varchar
$service->addAction(CreateVarchar::getName(), new CreateVarchar());
$service->addAction(UpdateVarchar::getName(), new UpdateVarchar());
// Column: Text
$service->addAction(CreateText::getName(), new CreateText());
$service->addAction(UpdateText::getName(), new UpdateText());
// Column: Mediumtext
$service->addAction(CreateMediumtext::getName(), new CreateMediumtext());
$service->addAction(UpdateMediumtext::getName(), new UpdateMediumtext());
// Column: Longtext
$service->addAction(CreateLongtext::getName(), new CreateLongtext());
$service->addAction(UpdateLongtext::getName(), new UpdateLongtext());
}
private function registerIndexActions(Service $service): void

View file

@ -7,6 +7,7 @@ use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use FunctionUseCases;
use Utopia\Config\Config;
use Utopia\Database\Document;
use Utopia\Platform\Action;
@ -50,7 +51,7 @@ class XList extends Base
]
))
->param('runtimes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('runtimes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of runtimes allowed for filtering function templates. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' runtimes are allowed.', true)
->param('useCases', [], new ArrayList(new WhiteList(['dev-tools','starter','databases','ai','messaging','utilities']), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of use cases allowed for filtering function templates. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' use cases are allowed.', true)
->param('useCases', [], new ArrayList(new WhiteList(FunctionUseCases::getAll()), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of use cases allowed for filtering function templates. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' use cases are allowed.', true)
->param('limit', 25, new Range(1, 5000), 'Limit the number of templates returned in the response. Default limit is 25, and maximum limit is 5000.', true)
->param('offset', 0, new Range(0, 5000), 'Offset the list of returned templates. Maximum offset is 5000.', true)
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)

View file

@ -7,6 +7,7 @@ use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use SiteUseCases;
use Utopia\Config\Config;
use Utopia\Database\Document;
use Utopia\Platform\Action;
@ -49,7 +50,7 @@ class XList extends Base
]
))
->param('frameworks', [], new ArrayList(new WhiteList(\array_keys(Config::getParam('frameworks')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of frameworks allowed for filtering site templates. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' frameworks are allowed.', true)
->param('useCases', [], new ArrayList(new WhiteList(['dev-tools', 'starter', 'databases', 'ai', 'messaging', 'utilities']), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of use cases allowed for filtering site templates. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' use cases are allowed.', true)
->param('useCases', [], new ArrayList(new WhiteList(SiteUseCases::getAll()), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of use cases allowed for filtering site templates. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' use cases are allowed.', true)
->param('limit', 25, new Range(1, 5000), 'Limit the number of templates returned in the response. Default limit is 25, and maximum limit is 5000.', true)
->param('offset', 0, new Range(0, 5000), 'Offset the list of returned templates. Maximum offset is 5000.', true)
->inject('response')

View file

@ -26,7 +26,7 @@ class Screenshot extends Action
$this
->desc('Create Site template screenshot')
->param('templateId', '', new Text(128), 'Template ID.')
->param('variables', '', new Text(16384), 'JSON of env variables to use when setting up the site.')
->param('variables', '', new Text(16384), 'JSON of env variables to use when setting up the site.', true)
->callback($this->action(...));
}

View file

@ -75,6 +75,10 @@ class Response extends SwooleResponse
public const MODEL_ATTRIBUTE_POINT = 'attributePoint';
public const MODEL_ATTRIBUTE_LINE = 'attributeLine';
public const MODEL_ATTRIBUTE_POLYGON = 'attributePolygon';
public const MODEL_ATTRIBUTE_VARCHAR = 'attributeVarchar';
public const MODEL_ATTRIBUTE_TEXT = 'attributeText';
public const MODEL_ATTRIBUTE_MEDIUMTEXT = 'attributeMediumtext';
public const MODEL_ATTRIBUTE_LONGTEXT = 'attributeLongtext';
// Database Columns
public const MODEL_COLUMN = 'column';
@ -92,6 +96,10 @@ class Response extends SwooleResponse
public const MODEL_COLUMN_POINT = 'columnPoint';
public const MODEL_COLUMN_LINE = 'columnLine';
public const MODEL_COLUMN_POLYGON = 'columnPolygon';
public const MODEL_COLUMN_VARCHAR = 'columnVarchar';
public const MODEL_COLUMN_TEXT = 'columnText';
public const MODEL_COLUMN_MEDIUMTEXT = 'columnMediumtext';
public const MODEL_COLUMN_LONGTEXT = 'columnLongtext';
// Transactions
public const MODEL_TRANSACTION = 'transaction';

View file

@ -0,0 +1,47 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class AttributeLongtext extends Attribute
{
public function __construct()
{
parent::__construct();
$this
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'longtext',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'AttributeLongtext';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_ATTRIBUTE_LONGTEXT;
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class AttributeMediumtext extends Attribute
{
public function __construct()
{
parent::__construct();
$this
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'mediumtext',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'AttributeMediumtext';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_ATTRIBUTE_MEDIUMTEXT;
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class AttributeText extends Attribute
{
public function __construct()
{
parent::__construct();
$this
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'text',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'AttributeText';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_ATTRIBUTE_TEXT;
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class AttributeVarchar extends Attribute
{
public function __construct()
{
parent::__construct();
$this
->addRule('size', [
'type' => self::TYPE_INTEGER,
'description' => 'Attribute size.',
'default' => 0,
'example' => 128,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'varchar',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'AttributeVarchar';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_ATTRIBUTE_VARCHAR;
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnLongtext extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'longtext',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnLongtext';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_LONGTEXT;
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnMediumtext extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'mediumtext',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnMediumtext';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_MEDIUMTEXT;
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnText extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'text',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnText';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_TEXT;
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnVarchar extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('size', [
'type' => self::TYPE_INTEGER,
'description' => 'Column size.',
'default' => 0,
'example' => 128,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => 'varchar',
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnVarchar';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_VARCHAR;
}
}

View file

@ -0,0 +1,786 @@
<?php
namespace Tests\E2E\Services\Databases\Legacy;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
class DatabasesStringTypesTest extends Scope
{
use ProjectCustom;
use SideServer;
private static string $databaseId;
private static string $collectionId;
public function testCreateDatabase(): array
{
$database = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'String Types Test Database'
]);
$this->assertEquals(201, $database['headers']['status-code']);
self::$databaseId = $database['body']['$id'];
return ['databaseId' => $database['body']['$id']];
}
/**
* @depends testCreateDatabase
*/
public function testCreateCollection(array $data): array
{
$collection = $this->client->call(Client::METHOD_POST, '/databases/' . $data['databaseId'] . '/collections', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'collectionId' => ID::unique(),
'name' => 'String Types Collection',
'documentSecurity' => true,
'permissions' => [
Permission::create(Role::any()),
Permission::read(Role::any()),
],
]);
$this->assertEquals(201, $collection['headers']['status-code']);
self::$collectionId = $collection['body']['$id'];
return [
'databaseId' => $data['databaseId'],
'collectionId' => $collection['body']['$id'],
];
}
/**
* @depends testCreateCollection
*/
public function testCreateVarcharAttribute(array $data): array
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Create varchar attribute with valid size
$varchar = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_field',
'size' => 255,
'required' => false,
]);
$this->assertEquals(202, $varchar['headers']['status-code']);
$this->assertEquals('varchar_field', $varchar['body']['key']);
$this->assertEquals('varchar', $varchar['body']['type']);
$this->assertEquals(255, $varchar['body']['size']);
$this->assertEquals(false, $varchar['body']['required']);
$this->assertNull($varchar['body']['default']);
// Test SUCCESS: Create varchar with default value
$varcharWithDefault = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_with_default',
'size' => 100,
'required' => false,
'default' => 'hello world',
]);
$this->assertEquals(202, $varcharWithDefault['headers']['status-code']);
$this->assertEquals('hello world', $varcharWithDefault['body']['default']);
// Test SUCCESS: Create required varchar
$varcharRequired = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_required',
'size' => 50,
'required' => true,
]);
$this->assertEquals(202, $varcharRequired['headers']['status-code']);
$this->assertEquals(true, $varcharRequired['body']['required']);
// Test SUCCESS: Create varchar array
$varcharArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_array',
'size' => 64,
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $varcharArray['headers']['status-code']);
$this->assertEquals(true, $varcharArray['body']['array']);
// Test SUCCESS: Minimum varchar size (1)
$varcharMin = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_min',
'size' => 1,
'required' => false,
]);
$this->assertEquals(202, $varcharMin['headers']['status-code']);
$this->assertEquals(1, $varcharMin['body']['size']);
return $data;
}
/**
* @depends testCreateCollection
*/
public function testCreateVarcharAttributeFailures(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test FAILURE: Size 0
$varcharZero = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_zero',
'size' => 0,
'required' => false,
]);
$this->assertEquals(400, $varcharZero['headers']['status-code']);
// Test FAILURE: Negative size
$varcharNegative = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_negative',
'size' => -10,
'required' => false,
]);
$this->assertEquals(400, $varcharNegative['headers']['status-code']);
// Test FAILURE: Size exceeds maximum (16382)
$varcharTooLarge = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_too_large',
'size' => 16382,
'required' => false,
]);
$this->assertEquals(400, $varcharTooLarge['headers']['status-code']);
// Test FAILURE: Missing size parameter
$varcharNoSize = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_no_size',
'required' => false,
]);
$this->assertEquals(400, $varcharNoSize['headers']['status-code']);
// Test FAILURE: Default value exceeds size
$varcharDefaultTooLong = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_default_too_long',
'size' => 5,
'required' => false,
'default' => 'this is way too long for the size',
]);
$this->assertEquals(400, $varcharDefaultTooLong['headers']['status-code']);
// Test FAILURE: Duplicate key
$varcharDuplicate = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_field', // Already exists
'size' => 100,
'required' => false,
]);
$this->assertEquals(409, $varcharDuplicate['headers']['status-code']);
}
/**
* @depends testCreateCollection
*/
public function testCreateTextAttribute(array $data): array
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Create text attribute
$text = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_field',
'required' => false,
]);
$this->assertEquals(202, $text['headers']['status-code']);
$this->assertEquals('text_field', $text['body']['key']);
$this->assertEquals('text', $text['body']['type']);
$this->assertEquals(false, $text['body']['required']);
// Test SUCCESS: Create text with default value
$textWithDefault = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_with_default',
'required' => false,
'default' => 'This is a longer default text value that can contain more content.',
]);
$this->assertEquals(202, $textWithDefault['headers']['status-code']);
$this->assertEquals('This is a longer default text value that can contain more content.', $textWithDefault['body']['default']);
// Test SUCCESS: Create required text
$textRequired = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_required',
'required' => true,
]);
$this->assertEquals(202, $textRequired['headers']['status-code']);
$this->assertEquals(true, $textRequired['body']['required']);
// Test SUCCESS: Create text array
$textArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_array',
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $textArray['headers']['status-code']);
$this->assertEquals(true, $textArray['body']['array']);
return $data;
}
/**
* @depends testCreateCollection
*/
public function testCreateMediumtextAttribute(array $data): array
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Create mediumtext attribute
$mediumtext = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_field',
'required' => false,
]);
$this->assertEquals(202, $mediumtext['headers']['status-code']);
$this->assertEquals('mediumtext_field', $mediumtext['body']['key']);
$this->assertEquals('mediumtext', $mediumtext['body']['type']);
$this->assertEquals(false, $mediumtext['body']['required']);
// Test SUCCESS: Create mediumtext with default
$mediumtextWithDefault = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_with_default',
'required' => false,
'default' => 'Default mediumtext content',
]);
$this->assertEquals(202, $mediumtextWithDefault['headers']['status-code']);
// Test SUCCESS: Create required mediumtext
$mediumtextRequired = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_required',
'required' => true,
]);
$this->assertEquals(202, $mediumtextRequired['headers']['status-code']);
$this->assertEquals(true, $mediumtextRequired['body']['required']);
// Test SUCCESS: Create mediumtext array
$mediumtextArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_array',
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $mediumtextArray['headers']['status-code']);
$this->assertEquals(true, $mediumtextArray['body']['array']);
return $data;
}
/**
* @depends testCreateCollection
*/
public function testCreateLongtextAttribute(array $data): array
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Create longtext attribute
$longtext = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_field',
'required' => false,
]);
$this->assertEquals(202, $longtext['headers']['status-code']);
$this->assertEquals('longtext_field', $longtext['body']['key']);
$this->assertEquals('longtext', $longtext['body']['type']);
$this->assertEquals(false, $longtext['body']['required']);
// Test SUCCESS: Create longtext with default
$longtextWithDefault = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_with_default',
'required' => false,
'default' => 'Default longtext content for very large text storage',
]);
$this->assertEquals(202, $longtextWithDefault['headers']['status-code']);
// Test SUCCESS: Create required longtext
$longtextRequired = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_required',
'required' => true,
]);
$this->assertEquals(202, $longtextRequired['headers']['status-code']);
$this->assertEquals(true, $longtextRequired['body']['required']);
// Test SUCCESS: Create longtext array
$longtextArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_array',
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $longtextArray['headers']['status-code']);
$this->assertEquals(true, $longtextArray['body']['array']);
return $data;
}
/**
* @depends testCreateLongtextAttribute
*/
public function testUpdateVarcharAttribute(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports VARCHAR type');
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Wait for attributes to be created
sleep(3);
// Test SUCCESS: Update varchar default value
$update = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar/varchar_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'updated default',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('updated default', $update['body']['default']);
// Test SUCCESS: Update varchar to make it required (no default)
$updateRequired = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar/varchar_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => true,
'default' => null,
]);
$this->assertEquals(200, $updateRequired['headers']['status-code']);
$this->assertEquals(true, $updateRequired['body']['required']);
// Test SUCCESS: Update varchar key (rename)
$updateKey = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar/varchar_min', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => null,
'newKey' => 'varchar_renamed',
]);
$this->assertEquals(200, $updateKey['headers']['status-code']);
$this->assertEquals('varchar_renamed', $updateKey['body']['key']);
return $data;
}
/**
* @depends testUpdateVarcharAttribute
*/
public function testUpdateTextAttribute(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports TEXT type');
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Update text default value
$update = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/text/text_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'Updated text default value',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('Updated text default value', $update['body']['default']);
return $data;
}
/**
* @depends testUpdateTextAttribute
*/
public function testUpdateMediumtextAttribute(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports MEDIUMTEXT type');
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Update mediumtext default value
$update = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/mediumtext/mediumtext_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'Updated mediumtext default',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('Updated mediumtext default', $update['body']['default']);
return $data;
}
/**
* @depends testUpdateMediumtextAttribute
*/
public function testUpdateLongtextAttribute(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports LONGTEXT type');
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Update longtext default value
$update = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/longtext/longtext_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'Updated longtext default',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('Updated longtext default', $update['body']['default']);
return $data;
}
/**
* @depends testUpdateLongtextAttribute
*/
public function testCreateDocumentWithStringTypes(array $data): array
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Wait for all attributes to be available
sleep(2);
// Test SUCCESS: Create document with all string types
$document = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'documentId' => ID::unique(),
'data' => [
'varchar_field' => 'Test varchar value',
'varchar_required' => 'Required value',
'text_field' => 'This is a text field with more content.',
'text_required' => 'Required text',
'mediumtext_field' => 'Medium text content here',
'mediumtext_required' => 'Required mediumtext',
'longtext_field' => 'Long text content for storing large amounts of data',
'longtext_required' => 'Required longtext',
'varchar_array' => ['item1', 'item2', 'item3'],
'text_array' => ['text item 1', 'text item 2'],
'mediumtext_array' => ['mediumtext item 1'],
'longtext_array' => ['longtext item 1', 'longtext item 2'],
],
'permissions' => [
Permission::read(Role::any()),
],
]);
$this->assertEquals(201, $document['headers']['status-code']);
$this->assertEquals('Test varchar value', $document['body']['varchar_field']);
$this->assertEquals('Required value', $document['body']['varchar_required']);
$this->assertEquals('This is a text field with more content.', $document['body']['text_field']);
$this->assertEquals('Required text', $document['body']['text_required']);
$this->assertEquals('Medium text content here', $document['body']['mediumtext_field']);
$this->assertEquals('Long text content for storing large amounts of data', $document['body']['longtext_field']);
$this->assertCount(3, $document['body']['varchar_array']);
$this->assertCount(2, $document['body']['text_array']);
return array_merge($data, ['documentId' => $document['body']['$id']]);
}
/**
* @depends testCreateDocumentWithStringTypes
*/
public function testCreateDocumentWithDefaultValues(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Create document using default values
$document = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'documentId' => ID::unique(),
'data' => [
'varchar_field' => 'Value',
'varchar_required' => 'Required',
'text_required' => 'Required text',
'mediumtext_required' => 'Required mediumtext',
'longtext_required' => 'Required longtext',
],
'permissions' => [
Permission::read(Role::any()),
],
]);
$this->assertEquals(201, $document['headers']['status-code']);
// Check that default values are applied
$this->assertEquals('updated default', $document['body']['varchar_with_default']);
$this->assertEquals('Updated text default value', $document['body']['text_with_default']);
}
/**
* @depends testCreateDocumentWithStringTypes
*/
public function testCreateDocumentFailures(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test FAILURE: Missing required field
$docMissingRequired = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'documentId' => ID::unique(),
'data' => [
'varchar_field' => 'Value',
// Missing varchar_required, text_required, etc.
],
'permissions' => [
Permission::read(Role::any()),
],
]);
$this->assertEquals(400, $docMissingRequired['headers']['status-code']);
}
/**
* @depends testCreateDocumentWithStringTypes
*/
public function testGetVarcharAttribute(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$attribute = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $attribute['headers']['status-code']);
$this->assertEquals('varchar_with_default', $attribute['body']['key']);
$this->assertEquals('varchar', $attribute['body']['type']);
$this->assertEquals(100, $attribute['body']['size']);
}
/**
* @depends testCreateDocumentWithStringTypes
*/
public function testGetTextAttribute(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$attribute = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/text_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $attribute['headers']['status-code']);
$this->assertEquals('text_field', $attribute['body']['key']);
$this->assertEquals('text', $attribute['body']['type']);
}
/**
* @depends testCreateDocumentWithStringTypes
*/
public function testGetMediumtextAttribute(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$attribute = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/mediumtext_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $attribute['headers']['status-code']);
$this->assertEquals('mediumtext_field', $attribute['body']['key']);
$this->assertEquals('mediumtext', $attribute['body']['type']);
}
/**
* @depends testCreateDocumentWithStringTypes
*/
public function testGetLongtextAttribute(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$attribute = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/longtext_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $attribute['headers']['status-code']);
$this->assertEquals('longtext_field', $attribute['body']['key']);
$this->assertEquals('longtext', $attribute['body']['type']);
}
/**
* @depends testGetLongtextAttribute
*/
public function testDeleteStringTypeAttributes(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
// Test SUCCESS: Delete varchar attribute
$deleteVarchar = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar_max', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(204, $deleteVarchar['headers']['status-code']);
// Verify deletion
$getDeleted = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/varchar_max', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(404, $getDeleted['headers']['status-code']);
}
}

View file

@ -0,0 +1,786 @@
<?php
namespace Tests\E2E\Services\Databases\TablesDB;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
class DatabasesStringTypesTest extends Scope
{
use ProjectCustom;
use SideServer;
private static string $databaseId;
private static string $tableId;
public function testCreateDatabase(): array
{
$database = $this->client->call(Client::METHOD_POST, '/tablesdb', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'String Types Test Database'
]);
$this->assertEquals(201, $database['headers']['status-code']);
self::$databaseId = $database['body']['$id'];
return ['databaseId' => $database['body']['$id']];
}
/**
* @depends testCreateDatabase
*/
public function testCreateTable(array $data): array
{
$table = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $data['databaseId'] . '/tables', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'tableId' => ID::unique(),
'name' => 'String Types Table',
'rowSecurity' => true,
'permissions' => [
Permission::create(Role::any()),
Permission::read(Role::any()),
],
]);
$this->assertEquals(201, $table['headers']['status-code']);
self::$tableId = $table['body']['$id'];
return [
'databaseId' => $data['databaseId'],
'tableId' => $table['body']['$id'],
];
}
/**
* @depends testCreateTable
*/
public function testCreateVarcharColumn(array $data): array
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Create varchar column with valid size
$varchar = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_field',
'size' => 255,
'required' => false,
]);
$this->assertEquals(202, $varchar['headers']['status-code']);
$this->assertEquals('varchar_field', $varchar['body']['key']);
$this->assertEquals('varchar', $varchar['body']['type']);
$this->assertEquals(255, $varchar['body']['size']);
$this->assertEquals(false, $varchar['body']['required']);
$this->assertNull($varchar['body']['default']);
// Test SUCCESS: Create varchar with default value
$varcharWithDefault = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_with_default',
'size' => 100,
'required' => false,
'default' => 'hello world',
]);
$this->assertEquals(202, $varcharWithDefault['headers']['status-code']);
$this->assertEquals('hello world', $varcharWithDefault['body']['default']);
// Test SUCCESS: Create required varchar
$varcharRequired = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_required',
'size' => 50,
'required' => true,
]);
$this->assertEquals(202, $varcharRequired['headers']['status-code']);
$this->assertEquals(true, $varcharRequired['body']['required']);
// Test SUCCESS: Create varchar array
$varcharArray = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_array',
'size' => 64,
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $varcharArray['headers']['status-code']);
$this->assertEquals(true, $varcharArray['body']['array']);
// Test SUCCESS: Minimum varchar size (1)
$varcharMin = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_min',
'size' => 1,
'required' => false,
]);
$this->assertEquals(202, $varcharMin['headers']['status-code']);
$this->assertEquals(1, $varcharMin['body']['size']);
return $data;
}
/**
* @depends testCreateTable
*/
public function testCreateVarcharColumnFailures(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test FAILURE: Size 0
$varcharZero = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_zero',
'size' => 0,
'required' => false,
]);
$this->assertEquals(400, $varcharZero['headers']['status-code']);
// Test FAILURE: Negative size
$varcharNegative = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_negative',
'size' => -10,
'required' => false,
]);
$this->assertEquals(400, $varcharNegative['headers']['status-code']);
// Test FAILURE: Size exceeds maximum (16382)
$varcharTooLarge = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_too_large',
'size' => 16382,
'required' => false,
]);
$this->assertEquals(400, $varcharTooLarge['headers']['status-code']);
// Test FAILURE: Missing size parameter
$varcharNoSize = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_no_size',
'required' => false,
]);
$this->assertEquals(400, $varcharNoSize['headers']['status-code']);
// Test FAILURE: Default value exceeds size
$varcharDefaultTooLong = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_default_too_long',
'size' => 5,
'required' => false,
'default' => 'this is way too long for the size',
]);
$this->assertEquals(400, $varcharDefaultTooLong['headers']['status-code']);
// Test FAILURE: Duplicate key
$varcharDuplicate = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'varchar_field', // Already exists
'size' => 100,
'required' => false,
]);
$this->assertEquals(409, $varcharDuplicate['headers']['status-code']);
}
/**
* @depends testCreateTable
*/
public function testCreateTextColumn(array $data): array
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Create text column
$text = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_field',
'required' => false,
]);
$this->assertEquals(202, $text['headers']['status-code']);
$this->assertEquals('text_field', $text['body']['key']);
$this->assertEquals('text', $text['body']['type']);
$this->assertEquals(false, $text['body']['required']);
// Test SUCCESS: Create text with default value
$textWithDefault = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_with_default',
'required' => false,
'default' => 'This is a longer default text value that can contain more content.',
]);
$this->assertEquals(202, $textWithDefault['headers']['status-code']);
$this->assertEquals('This is a longer default text value that can contain more content.', $textWithDefault['body']['default']);
// Test SUCCESS: Create required text
$textRequired = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_required',
'required' => true,
]);
$this->assertEquals(202, $textRequired['headers']['status-code']);
$this->assertEquals(true, $textRequired['body']['required']);
// Test SUCCESS: Create text array
$textArray = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/text', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'text_array',
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $textArray['headers']['status-code']);
$this->assertEquals(true, $textArray['body']['array']);
return $data;
}
/**
* @depends testCreateTable
*/
public function testCreateMediumtextColumn(array $data): array
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Create mediumtext column
$mediumtext = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_field',
'required' => false,
]);
$this->assertEquals(202, $mediumtext['headers']['status-code']);
$this->assertEquals('mediumtext_field', $mediumtext['body']['key']);
$this->assertEquals('mediumtext', $mediumtext['body']['type']);
$this->assertEquals(false, $mediumtext['body']['required']);
// Test SUCCESS: Create mediumtext with default
$mediumtextWithDefault = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_with_default',
'required' => false,
'default' => 'Default mediumtext content',
]);
$this->assertEquals(202, $mediumtextWithDefault['headers']['status-code']);
// Test SUCCESS: Create required mediumtext
$mediumtextRequired = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_required',
'required' => true,
]);
$this->assertEquals(202, $mediumtextRequired['headers']['status-code']);
$this->assertEquals(true, $mediumtextRequired['body']['required']);
// Test SUCCESS: Create mediumtext array
$mediumtextArray = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/mediumtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'mediumtext_array',
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $mediumtextArray['headers']['status-code']);
$this->assertEquals(true, $mediumtextArray['body']['array']);
return $data;
}
/**
* @depends testCreateTable
*/
public function testCreateLongtextColumn(array $data): array
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Create longtext column
$longtext = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_field',
'required' => false,
]);
$this->assertEquals(202, $longtext['headers']['status-code']);
$this->assertEquals('longtext_field', $longtext['body']['key']);
$this->assertEquals('longtext', $longtext['body']['type']);
$this->assertEquals(false, $longtext['body']['required']);
// Test SUCCESS: Create longtext with default
$longtextWithDefault = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_with_default',
'required' => false,
'default' => 'Default longtext content for very large text storage',
]);
$this->assertEquals(202, $longtextWithDefault['headers']['status-code']);
// Test SUCCESS: Create required longtext
$longtextRequired = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_required',
'required' => true,
]);
$this->assertEquals(202, $longtextRequired['headers']['status-code']);
$this->assertEquals(true, $longtextRequired['body']['required']);
// Test SUCCESS: Create longtext array
$longtextArray = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/longtext', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'longtext_array',
'required' => false,
'array' => true,
]);
$this->assertEquals(202, $longtextArray['headers']['status-code']);
$this->assertEquals(true, $longtextArray['body']['array']);
return $data;
}
/**
* @depends testCreateLongtextColumn
*/
public function testUpdateVarcharColumn(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports VARCHAR type');
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Wait for columns to be created
sleep(3);
// Test SUCCESS: Update varchar default value
$update = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar/varchar_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'updated default',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('updated default', $update['body']['default']);
// Test SUCCESS: Update varchar to make it required (no default)
$updateRequired = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar/varchar_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => true,
'default' => null,
]);
$this->assertEquals(200, $updateRequired['headers']['status-code']);
$this->assertEquals(true, $updateRequired['body']['required']);
// Test SUCCESS: Update varchar key (rename)
$updateKey = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar/varchar_min', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => null,
'newKey' => 'varchar_renamed',
]);
$this->assertEquals(200, $updateKey['headers']['status-code']);
$this->assertEquals('varchar_renamed', $updateKey['body']['key']);
return $data;
}
/**
* @depends testUpdateVarcharColumn
*/
public function testUpdateTextColumn(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports TEXT type');
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Update text default value
$update = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/text/text_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'Updated text default value',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('Updated text default value', $update['body']['default']);
return $data;
}
/**
* @depends testUpdateTextColumn
*/
public function testUpdateMediumtextColumn(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports MEDIUMTEXT type');
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Update mediumtext default value
$update = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/mediumtext/mediumtext_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'Updated mediumtext default',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('Updated mediumtext default', $update['body']['default']);
return $data;
}
/**
* @depends testUpdateMediumtextColumn
*/
public function testUpdateLongtextColumn(array $data): array
{
$this->markTestSkipped('Skipped until utopia-php/database updateAttribute supports LONGTEXT type');
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Update longtext default value
$update = $this->client->call(Client::METHOD_PATCH, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/longtext/longtext_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'required' => false,
'default' => 'Updated longtext default',
]);
$this->assertEquals(200, $update['headers']['status-code']);
$this->assertEquals('Updated longtext default', $update['body']['default']);
return $data;
}
/**
* @depends testUpdateLongtextColumn
*/
public function testCreateRowWithStringTypes(array $data): array
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Wait for all columns to be available
sleep(2);
// Test SUCCESS: Create row with all string types
$row = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'rowId' => ID::unique(),
'data' => [
'varchar_field' => 'Test varchar value',
'varchar_required' => 'Required value',
'text_field' => 'This is a text field with more content.',
'text_required' => 'Required text',
'mediumtext_field' => 'Medium text content here',
'mediumtext_required' => 'Required mediumtext',
'longtext_field' => 'Long text content for storing large amounts of data',
'longtext_required' => 'Required longtext',
'varchar_array' => ['item1', 'item2', 'item3'],
'text_array' => ['text item 1', 'text item 2'],
'mediumtext_array' => ['mediumtext item 1'],
'longtext_array' => ['longtext item 1', 'longtext item 2'],
],
'permissions' => [
Permission::read(Role::any()),
],
]);
$this->assertEquals(201, $row['headers']['status-code']);
$this->assertEquals('Test varchar value', $row['body']['varchar_field']);
$this->assertEquals('Required value', $row['body']['varchar_required']);
$this->assertEquals('This is a text field with more content.', $row['body']['text_field']);
$this->assertEquals('Required text', $row['body']['text_required']);
$this->assertEquals('Medium text content here', $row['body']['mediumtext_field']);
$this->assertEquals('Long text content for storing large amounts of data', $row['body']['longtext_field']);
$this->assertCount(3, $row['body']['varchar_array']);
$this->assertCount(2, $row['body']['text_array']);
return array_merge($data, ['rowId' => $row['body']['$id']]);
}
/**
* @depends testCreateRowWithStringTypes
*/
public function testCreateRowWithDefaultValues(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Create row using default values
$row = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'rowId' => ID::unique(),
'data' => [
'varchar_field' => 'Value',
'varchar_required' => 'Required',
'text_required' => 'Required text',
'mediumtext_required' => 'Required mediumtext',
'longtext_required' => 'Required longtext',
],
'permissions' => [
Permission::read(Role::any()),
],
]);
$this->assertEquals(201, $row['headers']['status-code']);
// Check that default values are applied
$this->assertEquals('updated default', $row['body']['varchar_with_default']);
$this->assertEquals('Updated text default value', $row['body']['text_with_default']);
}
/**
* @depends testCreateRowWithStringTypes
*/
public function testCreateRowFailures(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test FAILURE: Missing required field
$rowMissingRequired = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/rows', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'rowId' => ID::unique(),
'data' => [
'varchar_field' => 'Value',
// Missing varchar_required, text_required, etc.
],
'permissions' => [
Permission::read(Role::any()),
],
]);
$this->assertEquals(400, $rowMissingRequired['headers']['status-code']);
}
/**
* @depends testCreateRowWithStringTypes
*/
public function testGetVarcharColumn(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
$column = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar_with_default', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $column['headers']['status-code']);
$this->assertEquals('varchar_with_default', $column['body']['key']);
$this->assertEquals('varchar', $column['body']['type']);
$this->assertEquals(100, $column['body']['size']);
}
/**
* @depends testCreateRowWithStringTypes
*/
public function testGetTextColumn(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
$column = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/text_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $column['headers']['status-code']);
$this->assertEquals('text_field', $column['body']['key']);
$this->assertEquals('text', $column['body']['type']);
}
/**
* @depends testCreateRowWithStringTypes
*/
public function testGetMediumtextColumn(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
$column = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/mediumtext_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $column['headers']['status-code']);
$this->assertEquals('mediumtext_field', $column['body']['key']);
$this->assertEquals('mediumtext', $column['body']['type']);
}
/**
* @depends testCreateRowWithStringTypes
*/
public function testGetLongtextColumn(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
$column = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/longtext_field', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $column['headers']['status-code']);
$this->assertEquals('longtext_field', $column['body']['key']);
$this->assertEquals('longtext', $column['body']['type']);
}
/**
* @depends testGetLongtextColumn
*/
public function testDeleteStringTypeColumns(array $data): void
{
$databaseId = $data['databaseId'];
$tableId = $data['tableId'];
// Test SUCCESS: Delete varchar column
$deleteVarchar = $this->client->call(Client::METHOD_DELETE, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar_max', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(204, $deleteVarchar['headers']['status-code']);
// Verify deletion
$getDeleted = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/varchar_max', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(404, $getDeleted['headers']['status-code']);
}
}

View file

@ -1870,7 +1870,7 @@ class ProjectsConsoleClientTest extends Scope
$this->assertEquals(1, count($sessions));
$this->assertEquals($sessionId2, $sessions[0]['$id']);
});
}, 120_000, 300);
/**
* Reset Limit

View file

@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Realtime;
use CURLFile;
use Exception;
use Swoole\Coroutine;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope;
@ -3122,4 +3123,153 @@ class RealtimeCustomClientTest extends Scope
$client->close();
}
/**
* Simulate concurrent realtime traffic using Swoole coroutines.
* Opens multiple websocket clients concurrently, then performs create/update/delete ops.
*/
public function testConcurrentRealtimeTrafficCoroutines()
{
if (!class_exists(\Swoole\Coroutine::class)) {
$this->markTestSkipped('Swoole Coroutine not available in this environment.');
}
$user = $this->getUser();
$session = $user['session'] ?? '';
$projectId = $this->getProject()['$id'];
Coroutine\run(function () use ($session, $projectId) {
$headers = [
'origin' => 'http://localhost',
'cookie' => 'a_session_' . $projectId . '=' . $session
];
$clientCount = 5;
$clients = [];
for ($i = 0; $i < $clientCount; $i++) {
$clients[] = $this->getWebsocket(['documents', 'collections'], $headers);
}
foreach ($clients as $client) {
$response = json_decode($client->receive(), true);
$this->assertEquals('connected', $response['type']);
}
// Setup DB/collection/attribute
$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' => 'Concurrent DB',
]);
$databaseId = $database['body']['$id'];
$collection = $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' => 'Concurrent 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' => $projectId,
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'name',
'size' => 64,
'required' => true,
]);
Coroutine::sleep(1);
$creates = [
['name' => 'Doc A'],
['name' => 'Doc B'],
['name' => 'Doc C'],
['name' => 'Doc D'],
['name' => 'Doc E'],
['name' => 'Doc F'],
];
$expectedEvents = count($creates);
// Per-client receipts
$receivedEvents = array_fill(0, $clientCount, []);
// Launch receiver coroutines (one per client)
foreach ($clients as $idx => $client) {
Coroutine::create(function () use ($client, &$receivedEvents, $expectedEvents, $idx) {
$local = [];
for ($i = 0; $i < $expectedEvents; $i++) {
$event = json_decode($client->receive(), true);
$local[] = $event;
}
$receivedEvents[$idx] = $local;
});
}
// Create docs
foreach ($creates as $payload) {
$this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/documents", array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'documentId' => ID::unique(),
'data' => $payload,
'permissions' => [
Permission::read(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
]);
}
// Wait for receivers to collect; timeout ~10s
$deadline = microtime(true) + 10;
while (microtime(true) < $deadline) {
$done = true;
foreach ($receivedEvents as $events) {
if (count($events) < $expectedEvents) {
$done = false;
break;
}
}
if ($done) {
break;
}
Coroutine::sleep(0.1);
}
$expectedNames = array_column($creates, 'name');
for ($c = 0; $c < $clientCount; $c++) {
$events = $receivedEvents[$c];
$this->assertCount($expectedEvents, $events, 'Unexpected event count on client '.$c);
$seen = [];
foreach ($events as $event) {
$this->assertEquals('event', $event['type']);
$this->assertArrayHasKey('payload', $event['data']);
$seen[] = $event['data']['payload']['name'] ?? '';
}
foreach ($expectedNames as $name) {
$this->assertContains($name, $seen);
}
}
foreach ($clients as $client) {
$client->close();
}
});
}
}

View file

@ -2409,7 +2409,8 @@ class SitesCustomServerTest extends Scope
$this->assertEquals(301, $response['headers']['status-code']);
$this->assertArrayHasKey('set-cookie', $response['headers']);
$this->assertStringContainsString('a_jwt_console=', $response['headers']['set-cookie']);
$this->assertStringContainsString('httponly', $response['headers']['set-cookie']);
// due to swoole update; no more httponly
$this->assertStringContainsString('HttpOnly', $response['headers']['set-cookie']);
$this->assertStringContainsString('domain=' . $domain, $response['headers']['set-cookie']);
$this->assertStringContainsString('path=/', $response['headers']['set-cookie']);
$this->assertNotEmpty($response['cookies']['a_jwt_console']);