Compare commits

..
Author SHA1 Message Date
Hemachandar 3133572d7c Reset scope 2026-01-26 00:22:29 +05:30
Hemachandar f28975117d feedback + tests fix 2026-01-26 00:00:31 +05:30
Hemachandar e7d711e8c8 teams test 2026-01-25 21:59:33 +05:30
Hemachandar 9f5cf5f384 Implement project-specific permissions 2026-01-25 21:55:32 +05:30
124 changed files with 2050 additions and 16314 deletions
-1
View File
@@ -130,4 +130,3 @@ _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
+1 -1
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.11.5 AS base
FROM appwrite/base:0.10.6 AS base
LABEL maintainer="team@appwrite.io"
+2 -2
View File
@@ -26,8 +26,8 @@ unset($common['files']);
$collections = [
'buckets' => $buckets,
'databases' => $databases,
'projects' => array_merge_recursive($projects, $common),
'console' => array_merge_recursive($platform, $common),
'projects' => array_merge($projects, $common),
'console' => array_merge($platform, $common),
'logs' => $logs,
];
+37 -8
View File
@@ -633,7 +633,29 @@ $platformCollections = [
'name' => 'keys',
'attributes' => [
[
'$id' => ID::custom('resourceType'),
'$id' => ID::custom('projectInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => true,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('projectId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => 0,
'array' => false,
'filters' => [],
],
[
'$id' => 'resourceType',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
@@ -644,7 +666,7 @@ $platformCollections = [
'filters' => [],
],
[
'$id' => ID::custom('resourceId'),
'$id' => 'resourceId',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
@@ -655,7 +677,7 @@ $platformCollections = [
'filters' => [],
],
[
'$id' => ID::custom('resourceInternalId'),
'$id' => 'resourceInternalId',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
@@ -734,14 +756,21 @@ $platformCollections = [
],
'indexes' => [
[
'$id' => ID::custom('_key_resource'),
'$id' => ID::custom('_key_project'),
'type' => Database::INDEX_KEY,
'attributes' => ['resourceType', 'resourceInternalId'],
'lengths' => [],
'orders' => [],
'attributes' => ['projectInternalId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_accessedAt'),
'$id' => '_key_resource',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceType', 'resourceInternalId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_accessedAt',
'type' => Database::INDEX_KEY,
'attributes' => ['accessedAt'],
'lengths' => [],
-25
View File
@@ -357,11 +357,6 @@ return [
'description' => 'API key and session used in the same request. Use either `setSession` or `setKey`. Learn about which authentication method to use in the SSR docs: https://appwrite.io/docs/products/auth/server-side-rendering',
'code' => 403,
],
Exception::USER_JWT_AND_COOKIE_SET => [
'name' => Exception::USER_JWT_AND_COOKIE_SET,
'description' => 'JWT and cookie used in the same request. Use either `setJWT` or `setCookie`. Learn about which authentication method to use in the SSR docs: https://appwrite.io/docs/products/auth/server-side-rendering',
'code' => 403,
],
Exception::API_KEY_EXPIRED => [
'name' => Exception::API_KEY_EXPIRED,
'description' => 'The dynamic API key has expired. Please don\'t use dynamic API keys for more than duration of the execution.',
@@ -1079,11 +1074,6 @@ return [
'description' => 'The project key has expired. Please generate a new key using the Appwrite console.',
'code' => 401,
],
Exception::ACCOUNT_KEY_EXPIRED => [
'name' => Exception::ACCOUNT_KEY_EXPIRED,
'description' => 'The account API key has expired. Please generate a new key using the Appwrite console.',
'code' => 401,
],
Exception::ROUTER_HOST_NOT_FOUND => [
'name' => Exception::ROUTER_HOST_NOT_FOUND,
'description' => 'Host is not trusted. This could occur because you have not configured a custom domain. Add a custom domain to your project first and try again.',
@@ -1338,19 +1328,4 @@ return [
'description' => 'Target has an invalid provider type.',
'code' => 400,
],
Exception::USER_ID_MISSING => [
'name' => Exception::USER_ID_MISSING,
'description' => 'When using account API key, make sure to pass x-appwrite-user header with your user ID.',
'code' => 403,
],
Exception::ORGANIZATION_ID_MISSING => [
'name' => Exception::ORGANIZATION_ID_MISSING,
'description' => 'When using organization API key, make sure to pass x-appwrite-organization header with your organization ID.',
'code' => 403,
],
Exception::PROJECT_ID_MISSING => [
'name' => Exception::PROJECT_ID_MISSING,
'description' => 'When using project API key, make sure to pass x-appwrite-project header with your project ID.',
'code' => 403,
],
];
+38 -21
View File
@@ -50,12 +50,17 @@
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Poppins';
src: url('https://assets.appwrite.io/fonts/poppins/poppins-v23-latin-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
</style>
<style>
.main {
max-width: 650px;
margin: 0 auto;
margin-top: 32px;
body {
padding: 32px;
line-height: 1.5;
color: #616b7c;
@@ -63,12 +68,15 @@
font-weight: 400;
font-family: "Inter", sans-serif;
background-color: #ffffff;
margin: 0;
padding: 0;
line-height: 150%;
}
.main a {
a {
color: currentColor;
word-break: break-all;
}
.main a.button {
a.button {
box-sizing: border-box;
display: inline-block;
text-align: center;
@@ -79,8 +87,8 @@
border: 1px solid #414146;
border-radius: 8px;
}
.main a.button:hover,
.main a.button:focus {
a.button:hover,
a.button:focus {
opacity: 0.8;
}
table {
@@ -94,6 +102,11 @@
td {
vertical-align: top;
}
.main {
max-width: 650px;
margin: 0 auto;
margin-top: 32px;
}
h1 {
font-size: 22px;
margin-bottom: 0px;
@@ -125,6 +138,9 @@
border: none;
border-top: 1px solid #e8e9f0;
}
h* {
font-family: 'Poppins', sans-serif;
}
p {
margin-bottom: 10px;
}
@@ -139,20 +155,21 @@
<body style="direction: {{direction}}">
<div style="display: none; overflow: hidden; max-height: 0; max-width: 0; opacity: 0; line-height: 1px;">
{{preview}}
<div>{{previewWhitespace}}</div>
</div>
<div style="display: none; overflow: hidden; max-height: 0; max-width: 0; opacity: 0; line-height: 1px;">
{{preview}}
<div>{{previewWhitespace}}</div>
</div>
<div class="main" style="max-width:650px; word-wrap: break-word; overflow-wrap: break-word; word-break: normal; margin:0 auto;">
<table style="margin-top: 32px">
<tr>
<td>
{{body}}
</td>
</tr>
</table>
</div>
<div style="max-width:650px; word-wrap: break-word; overflow-wrap: break-word;
word-break: normal; margin:0 auto;">
<table style="margin-top: 32px">
<tr>
<td>
{{body}}
</td>
</tr>
</table>
</div>
</body>
</html>
-1
View File
@@ -23,5 +23,4 @@ return [
'privacyUrl' => APP_EMAIL_PRIVACY_URL,
'websiteUrl' => 'https://' . APP_DOMAIN,
'emailSenderName' => APP_EMAIL_PLATFORM_NAME,
'sitePreviewDomain' => System::getEnv('_APP_DOMAIN_SITES', ''),
];
-15
View File
@@ -1,15 +0,0 @@
<?php
// List of scopes for Account API keys (Tokens)
return [
"account" => [
"description" => 'Access to manage account, its organizations, sessions, tokens, and billing.',
],
"teams.read" => [
"description" => 'Access to read account\'s organizations.',
],
"teams.write" => [
"description" => 'Access to create, update and delete account\'s organizations and its memberships.',
],
];
-42
View File
@@ -1,42 +0,0 @@
<?php
// List of scopes for organization (teams) API keys
return [
"platforms.read" => [
"description" => 'Access to read project\'s platforms',
],
"platforms.write" => [
"description" =>
'Access to create, update, and delete project\'s platforms',
],
"projects.read" => [
"description" => 'Access to read organization\'s projects',
],
"projects.write" => [
"description" =>
"Access to create, update, and delete projects in organization",
],
"keys.read" => [
"description" => 'Access to read project\'s API keys',
],
"keys.write" => [
"description" =>
"Access to create, update, and delete project\'s API keys",
],
"devKeys.read" => [
"description" => 'Access to read project\'s development keys',
],
"devKeys.write" => [
"description" =>
"Access to create, update, and delete project\'s development keys",
],
"webhooks.read" => [
"description" =>
"Access to read project\'s webhooks",
],
"webhooks.write" => [
"description" =>
"Access to create, update, and delete project\'s webhooks",
],
];
+1 -21
View File
@@ -227,7 +227,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '13.1.0',
'version' => '13.0.1',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://www.npmjs.com/package/appwrite-cli',
'enabled' => true,
@@ -250,26 +250,6 @@ return [
],
],
],
[
'key' => 'markdown',
'name' => 'Markdown',
'version' => '0.1.0',
'url' => 'https://github.com/appwrite/sdk-for-md.git',
'package' => 'https://www.npmjs.com/package/@appwrite.io/docs',
'enabled' => true,
'beta' => false,
'dev' => false,
'hidden' => false,
'family' => APP_SDK_PLATFORM_CONSOLE,
'prism' => 'markdown',
'source' => \realpath(__DIR__ . '/../sdks/console-md'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-md.git',
'gitRepoName' => 'sdk-for-md',
'gitUserName' => 'appwrite',
'gitBranch' => 'dev',
'repoBranch' => 'main',
'changelog' => \realpath(__DIR__ . '/../../docs/sdks/md/CHANGELOG.md'),
],
],
],
+31 -31
View File
@@ -5888,7 +5888,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 346,
"weight": 338,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@@ -5955,7 +5955,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 342,
"weight": 334,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@@ -6026,7 +6026,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 343,
"weight": 335,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@@ -6090,7 +6090,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 344,
"weight": 336,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@@ -6168,7 +6168,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 345,
"weight": 337,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@@ -6234,7 +6234,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 347,
"weight": 339,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@@ -7335,7 +7335,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 447,
"weight": 431,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@@ -7422,7 +7422,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 445,
"weight": 429,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@@ -7540,7 +7540,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 446,
"weight": 430,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@@ -8315,7 +8315,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 543,
"weight": 527,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@@ -8414,7 +8414,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 541,
"weight": 525,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@@ -8516,7 +8516,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 542,
"weight": 526,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@@ -8590,7 +8590,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 544,
"weight": 528,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@@ -8682,7 +8682,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 545,
"weight": 529,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@@ -8751,7 +8751,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 547,
"weight": 531,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@@ -8831,7 +8831,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 546,
"weight": 530,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@@ -9061,7 +9061,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 548,
"weight": 532,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@@ -9148,7 +9148,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 419,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@@ -9218,7 +9218,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 415,
"weight": 399,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@@ -9292,7 +9292,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 416,
"weight": 400,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@@ -9359,7 +9359,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 417,
"weight": 401,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@@ -9440,7 +9440,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 418,
"weight": 402,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@@ -9509,7 +9509,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 420,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@@ -9597,7 +9597,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 411,
"weight": 395,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@@ -9708,7 +9708,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 403,
"weight": 387,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@@ -9864,7 +9864,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 404,
"weight": 388,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@@ -9974,7 +9974,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 407,
"weight": 391,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@@ -10124,7 +10124,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 405,
"weight": 389,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@@ -10235,7 +10235,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 409,
"weight": 393,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@@ -10341,7 +10341,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 414,
"weight": 398,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@@ -10469,7 +10469,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 413,
"weight": 397,
"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
+31 -31
View File
@@ -5994,7 +5994,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 346,
"weight": 338,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@@ -6061,7 +6061,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 342,
"weight": 334,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@@ -6132,7 +6132,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 343,
"weight": 335,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@@ -6195,7 +6195,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 344,
"weight": 336,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@@ -6274,7 +6274,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 345,
"weight": 337,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@@ -6339,7 +6339,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 347,
"weight": 339,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@@ -7392,7 +7392,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 447,
"weight": 431,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@@ -7475,7 +7475,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 445,
"weight": 429,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@@ -7594,7 +7594,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 446,
"weight": 430,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@@ -8396,7 +8396,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 543,
"weight": 527,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@@ -8489,7 +8489,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 541,
"weight": 525,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@@ -8580,7 +8580,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 542,
"weight": 526,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@@ -8651,7 +8651,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 544,
"weight": 528,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@@ -8742,7 +8742,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 545,
"weight": 529,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@@ -8813,7 +8813,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 547,
"weight": 531,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@@ -8893,7 +8893,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 546,
"weight": 530,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@@ -9101,7 +9101,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 548,
"weight": 532,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@@ -9181,7 +9181,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 419,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@@ -9251,7 +9251,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 415,
"weight": 399,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@@ -9325,7 +9325,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 416,
"weight": 400,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@@ -9391,7 +9391,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 417,
"weight": 401,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@@ -9473,7 +9473,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 418,
"weight": 402,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@@ -9541,7 +9541,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 420,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@@ -9625,7 +9625,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 411,
"weight": 395,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@@ -9728,7 +9728,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 403,
"weight": 387,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@@ -9882,7 +9882,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 404,
"weight": 388,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@@ -9984,7 +9984,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 407,
"weight": 391,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@@ -10130,7 +10130,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 405,
"weight": 389,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@@ -10239,7 +10239,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 409,
"weight": 393,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@@ -10339,7 +10339,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 414,
"weight": 398,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@@ -10461,7 +10461,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 413,
"weight": 397,
"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
+40 -68
View File
@@ -20,34 +20,6 @@ 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',
@@ -60,7 +32,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::STARTER],
'useCases' => ['starter'],
'runtimes' => [
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/starter', $allowList),
...getRuntimes(
@@ -101,7 +73,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DATABASES],
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -147,7 +119,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DATABASES],
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -192,7 +164,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DATABASES],
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -246,7 +218,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DATABASES],
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -285,7 +257,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DATABASES],
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -354,7 +326,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -420,7 +392,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::MESSAGING],
'useCases' => ['messaging'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -487,7 +459,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -525,7 +497,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -576,7 +548,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::UTILITIES],
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/generate-pdf', $allowList)
],
@@ -599,7 +571,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DEV_TOOLS],
'useCases' => ['dev-tools'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -644,7 +616,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::UTILITIES],
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -697,7 +669,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DATABASES],
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -782,7 +754,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::DATABASES],
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -881,7 +853,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::MESSAGING],
'useCases' => ['messaging'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -974,7 +946,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::MESSAGING],
'useCases' => ['messaging'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1032,7 +1004,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::UTILITIES],
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1119,7 +1091,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::UTILITIES],
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1162,7 +1134,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::UTILITIES],
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1221,7 +1193,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1257,7 +1229,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1293,7 +1265,7 @@ return [
'events' => ['buckets.*.files.*.create'],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1353,7 +1325,7 @@ return [
'events' => ['buckets.*.files.*.create'],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1413,7 +1385,7 @@ return [
'events' => ['buckets.*.files.*.create'],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1476,7 +1448,7 @@ return [
],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1536,7 +1508,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1573,7 +1545,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1617,7 +1589,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1660,7 +1632,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1697,7 +1669,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1762,7 +1734,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 30,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1827,7 +1799,7 @@ return [
'cron' => '',
'events' => [],
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1884,7 +1856,7 @@ return [
'cron' => '',
'events' => [],
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1927,7 +1899,7 @@ return [
'cron' => '',
'events' => [],
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -1970,7 +1942,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -2014,7 +1986,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 300,
'useCases' => [FunctionUseCases::AI],
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -2051,7 +2023,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::UTILITIES],
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -2108,7 +2080,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::UTILITIES],
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
$templateRuntimes['NODE'],
@@ -2181,7 +2153,7 @@ return [
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => [FunctionUseCases::AUTH],
'useCases' => ['auth'],
'runtimes' => [
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/sign_in_with_apple', $allowList)
],
+78 -96
View File
@@ -13,7 +13,7 @@ $hostname = $platform['consoleHostname'] ?? '';
$url = $protocol . '://' . $hostname;
class SiteUseCases
class UseCases
{
public const PORTFOLIO = 'portfolio';
public const STARTER = 'starter';
@@ -21,27 +21,9 @@ class SiteUseCases
public const ECOMMERCE = 'ecommerce';
public const DOCUMENTATION = 'documentation';
public const BLOG = 'blog';
public const AI = 'ai';
public const AI = 'artificial intelligence';
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 = [
@@ -206,7 +188,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' => [SiteUseCases::DOCUMENTATION],
'useCases' => [UseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/template-for-documentation-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-documentation-light.png',
'frameworks' => [
@@ -227,7 +209,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-lynx-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-lynx-light.png',
'frameworks' => [
@@ -238,7 +220,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -246,7 +228,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' => [SiteUseCases::DOCUMENTATION],
'useCases' => [UseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/vitepress-dark.png',
'screenshotLight' => $url . '/images/sites/templates/vitepress-light.png',
'frameworks' => [
@@ -261,7 +243,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -269,7 +251,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' => [SiteUseCases::DOCUMENTATION],
'useCases' => [UseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/vuepress-dark.png',
'screenshotLight' => $url . '/images/sites/templates/vuepress-light.png',
'frameworks' => [
@@ -284,7 +266,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -292,7 +274,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' => [SiteUseCases::DOCUMENTATION],
'useCases' => [UseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/docusaurus-dark.png',
'screenshotLight' => $url . '/images/sites/templates/docusaurus-light.png',
'frameworks' => [
@@ -307,7 +289,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -315,7 +297,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' => [SiteUseCases::PORTFOLIO],
'useCases' => [UseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/nxt-lnk-dark.png',
'screenshotLight' => $url . '/images/sites/templates/nxt-lnk-light.png',
'frameworks' => [
@@ -326,7 +308,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -334,7 +316,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' => [SiteUseCases::PORTFOLIO],
'useCases' => [UseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/magic-portfolio-dark.png',
'screenshotLight' => $url . '/images/sites/templates/magic-portfolio-light.png',
'frameworks' => [
@@ -345,7 +327,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -353,7 +335,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' => [SiteUseCases::PORTFOLIO],
'useCases' => [UseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/littlelink-dark.png',
'screenshotLight' => $url . '/images/sites/templates/littlelink-light.png',
'frameworks' => [
@@ -364,7 +346,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -372,7 +354,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' => [SiteUseCases::BLOG],
'useCases' => [UseCases::BLOG],
'screenshotDark' => $url . '/images/sites/templates/logspot-dark.png',
'screenshotLight' => $url . '/images/sites/templates/logspot-light.png',
'frameworks' => [
@@ -386,7 +368,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -394,7 +376,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' => [SiteUseCases::PORTFOLIO],
'useCases' => [UseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/astro-nano-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-nano-light.png',
'frameworks' => [
@@ -407,7 +389,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -415,7 +397,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' => [SiteUseCases::DOCUMENTATION],
'useCases' => [UseCases::DOCUMENTATION],
'screenshotDark' => $url . '/images/sites/templates/astro-starlight-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-starlight-light.png',
'frameworks' => [
@@ -428,7 +410,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -436,7 +418,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' => [SiteUseCases::PORTFOLIO],
'useCases' => [UseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/astro-sphere-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-sphere-light.png',
'frameworks' => [
@@ -449,7 +431,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -457,7 +439,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' => [SiteUseCases::BLOG],
'useCases' => [UseCases::BLOG],
'screenshotDark' => $url . '/images/sites/templates/astro-starlog-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-starlog-light.png',
'frameworks' => [
@@ -470,7 +452,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -478,7 +460,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' => [SiteUseCases::PORTFOLIO],
'useCases' => [UseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/onelink-dark.png',
'screenshotLight' => $url . '/images/sites/templates/onelink-light.png',
'frameworks' => [
@@ -492,13 +474,13 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
'key' => 'starter-for-flutter',
'name' => 'Flutter starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -543,7 +525,7 @@ return [
[
'key' => 'starter-for-js',
'name' => 'JavaScript starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -587,7 +569,7 @@ return [
[
'key' => 'starter-for-angular',
'name' => 'Angular starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -633,7 +615,7 @@ return [
[
'key' => 'starter-for-astro',
'name' => 'Astro starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -678,7 +660,7 @@ return [
[
'key' => 'starter-for-analog',
'name' => 'Analog starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -722,7 +704,7 @@ return [
[
'key' => 'starter-for-remix',
'name' => 'Remix starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -766,7 +748,7 @@ return [
[
'key' => 'starter-for-svelte',
'name' => 'Svelte starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -810,7 +792,7 @@ return [
[
'key' => 'starter-for-react',
'name' => 'React starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -854,7 +836,7 @@ return [
[
'key' => 'starter-for-vue',
'name' => 'Vue starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -898,7 +880,7 @@ return [
[
'key' => 'starter-for-react-native',
'name' => 'React Native starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -942,7 +924,7 @@ return [
[
'key' => 'starter-for-nextjs',
'name' => 'Next.js starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -986,7 +968,7 @@ return [
[
'key' => 'starter-for-tanstack-start',
'name' => 'TanStack Start starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -1030,7 +1012,7 @@ return [
[
'key' => 'starter-for-nuxt',
'name' => 'Nuxt starter',
'useCases' => [SiteUseCases::STARTER],
'useCases' => [UseCases::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',
@@ -1076,7 +1058,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' => [SiteUseCases::EVENTS],
'useCases' => [UseCases::EVENTS],
'screenshotDark' => $url . '/images/sites/templates/template-for-event-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-event-light.png',
'frameworks' => [
@@ -1114,7 +1096,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' => [SiteUseCases::PORTFOLIO],
'useCases' => [UseCases::PORTFOLIO],
'screenshotDark' => $url . '/images/sites/templates/template-for-portfolio-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-portfolio-light.png',
'frameworks' => [
@@ -1133,7 +1115,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' => [SiteUseCases::ECOMMERCE],
'useCases' => [UseCases::ECOMMERCE],
'screenshotDark' => $url . '/images/sites/templates/template-for-store-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-store-light.png',
'frameworks' => [
@@ -1177,7 +1159,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' => [SiteUseCases::BLOG],
'useCases' => [UseCases::BLOG],
'screenshotDark' => $url . '/images/sites/templates/template-for-blog-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-blog-light.png',
'frameworks' => [
@@ -1196,7 +1178,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-astro-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-astro-light.png',
'frameworks' => [
@@ -1207,7 +1189,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1215,7 +1197,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-remix-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-remix-light.png',
'frameworks' => [
@@ -1226,7 +1208,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1234,7 +1216,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-nextjs-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-nextjs-light.png',
'frameworks' => [
@@ -1245,7 +1227,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1253,7 +1235,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-flutter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-flutter-light.png',
'frameworks' => [
@@ -1264,7 +1246,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1272,7 +1254,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-vite-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-vite-light.png',
'frameworks' => [
@@ -1283,7 +1265,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1291,7 +1273,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-angular-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-angular-light.png',
'frameworks' => [
@@ -1303,7 +1285,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1311,7 +1293,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-analog-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-analog-light.png',
'frameworks' => [
@@ -1322,7 +1304,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1330,7 +1312,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-svelte-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-svelte-light.png',
'frameworks' => [
@@ -1341,7 +1323,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
@@ -1350,7 +1332,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-react-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-react-light.png',
'frameworks' => [
@@ -1362,7 +1344,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
@@ -1371,7 +1353,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-vue-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-vue-light.png',
'frameworks' => [
@@ -1382,7 +1364,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1390,7 +1372,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-nuxt-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-nuxt-light.png',
'frameworks' => [
@@ -1401,7 +1383,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1409,7 +1391,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-tanstack-start-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-tanstack-start-light.png',
'frameworks' => [
@@ -1420,7 +1402,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.5.*',
'variables' => [],
],
[
@@ -1428,7 +1410,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/playground-for-react-native-dark.png',
'screenshotLight' => $url . '/images/sites/templates/playground-for-react-native-light.png',
'frameworks' => [
@@ -1439,7 +1421,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => [],
],
[
@@ -1447,7 +1429,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' => [SiteUseCases::STARTER],
'useCases' => [UseCases::STARTER],
'screenshotDark' => $url . '/images/sites/templates/gallery-for-lynx-dark.png',
'screenshotLight' => $url . '/images/sites/templates/gallery-for-lynx-light.png',
'frameworks' => [
@@ -1458,7 +1440,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.3.*',
'variables' => []
],
[
@@ -1466,7 +1448,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' => [SiteUseCases::AI],
'useCases' => [UseCases::AI],
'screenshotDark' => $url . '/images/sites/templates/text-to-speech-dark.png',
'screenshotLight' => $url . '/images/sites/templates/text-to-speech-light.png',
'frameworks' => [
@@ -1477,7 +1459,7 @@ return [
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.7.*',
'providerVersion' => '0.6.*',
'variables' => [
[
'name' => 'ELEVENLABS_API_KEY',
@@ -1494,7 +1476,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' => [SiteUseCases::DASHBOARD],
'useCases' => [UseCases::DASHBOARD],
'screenshotDark' => $url . '/images/sites/templates/crm-dashboard-react-admin-dark.png',
'screenshotLight' => $url . '/images/sites/templates/crm-dashboard-react-admin-light.png',
'frameworks' => [
@@ -1597,7 +1579,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' => [SiteUseCases::FORMS],
'useCases' => [UseCases::FORMS],
'screenshotDark' => $url . '/images/sites/templates/job-applications-formspree-dark.png',
'screenshotLight' => $url . '/images/sites/templates/job-applications-formspree-light.png',
'frameworks' => [
+5 -5
View File
@@ -195,7 +195,7 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, arr
->setPreview($preview)
->setBody($body)
->setBodyTemplate($bodyTemplate)
->appendVariables($emailVariables)
->setVariables($emailVariables)
->setRecipient($email);
// since this is console project, set email sender name!
@@ -2301,7 +2301,7 @@ App::post('/v1/account/tokens/magic-url')
->setSubject($subject)
->setPreview($preview)
->setBody($body)
->appendVariables($emailVariables)
->setVariables($emailVariables)
->setRecipient($email);
if ($project->getId() === 'console') {
@@ -2602,7 +2602,7 @@ App::post('/v1/account/tokens/email')
->setPreview($preview)
->setBody($body)
->setBodyTemplate($bodyTemplate)
->appendVariables($emailVariables)
->setVariables($emailVariables)
->setRecipient($email);
// since this is console project, set email sender name!
@@ -3678,7 +3678,7 @@ App::post('/v1/account/recovery')
->setRecipient($profile->getAttribute('email', ''))
->setName($profile->getAttribute('name', ''))
->setBody($body)
->appendVariables($emailVariables)
->setVariables($emailVariables)
->setSubject($subject)
->setPreview($preview);
@@ -4009,7 +4009,7 @@ App::post('/v1/account/verifications/email')
->setPreview($preview)
->setBody($body)
->setBodyTemplate($bodyTemplate)
->appendVariables($emailVariables)
->setVariables($emailVariables)
->setRecipient($user->getAttribute('email'))
->setName($user->getAttribute('name') ?? '');
+20 -3
View File
@@ -175,11 +175,18 @@ App::post('/v1/projects')
$project = $dbForPlatform->createDocument('projects', new Document([
'$id' => $projectId,
'$permissions' => [
// Team-wide permissions
Permission::read(Role::team(ID::custom($teamId))),
Permission::update(Role::team(ID::custom($teamId), 'owner')),
Permission::update(Role::team(ID::custom($teamId), 'developer')),
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
// Project-specific permissions
Permission::read(Role::team(ID::custom($teamId), "project-$projectId")),
Permission::update(Role::team(ID::custom($teamId), "project-$projectId-owner")),
Permission::update(Role::team(ID::custom($teamId), "project-$projectId-developer")),
Permission::delete(Role::team(ID::custom($teamId), "project-$projectId-owner")),
Permission::delete(Role::team(ID::custom($teamId), "project-$projectId-developer")),
],
'name' => $name,
'teamInternalId' => $team->getSequence(),
@@ -428,11 +435,18 @@ App::patch('/v1/projects/:projectId/team')
}
$permissions = [
// Team-wide permissions
Permission::read(Role::team(ID::custom($teamId))),
Permission::update(Role::team(ID::custom($teamId), 'owner')),
Permission::update(Role::team(ID::custom($teamId), 'developer')),
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
// Project-specific permissions
Permission::read(Role::team(ID::custom($teamId), "project-$projectId")),
Permission::update(Role::team(ID::custom($teamId), "project-$projectId-owner")),
Permission::update(Role::team(ID::custom($teamId), "project-$projectId-developer")),
Permission::delete(Role::team(ID::custom($teamId), "project-$projectId-owner")),
Permission::delete(Role::team(ID::custom($teamId), "project-$projectId-developer")),
];
$project
@@ -1483,7 +1497,7 @@ App::post('/v1/projects/:projectId/keys')
))
->param('projectId', '', new UID(), 'Project unique ID.')
->param('name', null, new Text(128), 'Key name. Max length: 128 chars.')
->param('scopes', null, new Nullable(new ArrayList(new WhiteList(array_keys(Config::getParam('projectScopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE)), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.')
->param('scopes', null, new Nullable(new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE)), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.')
->param('expire', null, new Nullable(new DatetimeValidator()), 'Expiration time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Use null for unlimited expiration.', true)
->inject('response')
->inject('dbForPlatform')
@@ -1502,6 +1516,9 @@ App::post('/v1/projects/:projectId/keys')
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
// TODO: @hmacr Remove `projectInternalId` and `projectId` column writes before deleting the column.
'projectInternalId' => $project->getSequence(),
'projectId' => $project->getId(),
'resourceInternalId' => $project->getSequence(),
'resourceId' => $project->getId(),
'resourceType' => 'projects',
@@ -1625,7 +1642,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
->param('projectId', '', new UID(), 'Project unique ID.')
->param('keyId', '', new UID(), 'Key unique ID.')
->param('name', null, new Text(128), 'Key name. Max length: 128 chars.')
->param('scopes', null, new Nullable(new ArrayList(new WhiteList(array_keys(Config::getParam('projectScopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE)), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.')
->param('scopes', null, new Nullable(new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE)), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.')
->param('expire', null, new Nullable(new DatetimeValidator()), 'Expiration time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Use null for unlimited expiration.', true)
->inject('response')
->inject('dbForPlatform')
@@ -1726,7 +1743,7 @@ App::post('/v1/projects/:projectId/jwts')
]
))
->param('projectId', '', new UID(), 'Project unique ID.')
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('projectScopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for JWT key. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.')
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for JWT key. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.')
->param('duration', 900, new Range(0, 3600), 'Time in seconds before JWT expires. Default duration is 900 seconds, and maximum is 3600 seconds.', true)
->inject('response')
->inject('dbForPlatform')
+5 -12
View File
@@ -2,6 +2,7 @@
use Appwrite\Auth\MFA\Type\TOTP;
use Appwrite\Auth\Validator\Phone;
use Appwrite\Auth\Validator\Role as RoleValidator;
use Appwrite\Detector\Detector;
use Appwrite\Event\Delete;
use Appwrite\Event\Event;
@@ -58,7 +59,6 @@ use Utopia\Validator\ArrayList;
use Utopia\Validator\Assoc;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
App::post('/v1/teams')
->desc('Create team')
@@ -433,22 +433,15 @@ App::delete('/v1/teams/:teamId')
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove team from DB');
}
// Sync delete
$deletes = new Deletes();
$deletes->deleteMemberships($getProjectDB, $team, $project);
// Async delete
if ($project->getId() === 'console') {
$queueForDeletes
->setType(DELETE_TYPE_TEAM_PROJECTS)
->setDocument($team)
->trigger();
->setDocument($team);
}
$queueForDeletes
->setType(DELETE_TYPE_DOCUMENT)
->setDocument($team);
$queueForEvents
->setParam('teamId', $team->getId())
->setPayload($response->output($team, Response::MODEL_TEAM))
@@ -490,7 +483,7 @@ App::post('/v1/teams/:teamId/memberships')
$roles = array_filter($roles, function ($role) {
return !in_array($role, [User::ROLE_APPS, User::ROLE_GUESTS, User::ROLE_USERS]);
});
return new ArrayList(new WhiteList($roles), APP_LIMIT_ARRAY_PARAMS_SIZE);
return new ArrayList(new RoleValidator($roles), APP_LIMIT_ARRAY_PARAMS_SIZE);
}
return new ArrayList(new Key(), APP_LIMIT_ARRAY_PARAMS_SIZE);
}, 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 32 characters long.', false, ['project'])
@@ -779,7 +772,7 @@ App::post('/v1/teams/:teamId/memberships')
->setPreview($preview)
->setRecipient($invitee->getAttribute('email'))
->setName($invitee->getAttribute('name', ''))
->appendVariables($emailVariables)
->setVariables($emailVariables)
->trigger();
} elseif (!empty($phone)) {
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
@@ -1101,7 +1094,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
$roles = array_filter($roles, function ($role) {
return !in_array($role, [User::ROLE_APPS, User::ROLE_GUESTS, User::ROLE_USERS]);
});
return new ArrayList(new WhiteList($roles), APP_LIMIT_ARRAY_PARAMS_SIZE);
return new ArrayList(new RoleValidator($roles), APP_LIMIT_ARRAY_PARAMS_SIZE);
}
return new ArrayList(new Key(), APP_LIMIT_ARRAY_PARAMS_SIZE);
}, 'An array of strings. Use this param to set the user\'s roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 32 characters long.', false, ['project'])
+1 -1
View File
@@ -341,7 +341,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
$projectId = $project->getId();
// Deployment preview
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
$ruleId = md5($domain);
$previewRuleId = $ruleId;
+4 -4
View File
@@ -1228,7 +1228,7 @@ App::error()
}
switch ($class) {
case Utopia\Exception::class:
case 'Utopia\Exception':
$error = new AppwriteException(AppwriteException::GENERAL_UNKNOWN, $message, $code, $error);
switch ($code) {
case 400:
@@ -1239,10 +1239,10 @@ App::error()
break;
}
break;
case Utopia\Database\Exception\Authorization::class:
case 'Utopia\Database\Exception\Authorization':
$error = new AppwriteException(AppwriteException::USER_UNAUTHORIZED);
break;
case Utopia\Database\Exception\Timeout::class:
case 'Utopia\Database\Exception\Timeout':
$error = new AppwriteException(AppwriteException::DATABASE_TIMEOUT, previous: $error);
break;
}
@@ -1503,7 +1503,7 @@ App::error()
$template = $error->getView() ?? (($route) ? $route->getLabel('error', null) : null);
// TODO: Ideally use group 'api' here, but all wildcard routes seem to have 'api' at the moment
if (empty($route) || !\str_starts_with($route->getPath(), '/v1')) {
if (!\str_starts_with($route->getPath(), '/v1')) {
$template = __DIR__ . '/../views/general/error.phtml';
}
+4 -1
View File
@@ -191,7 +191,7 @@ App::post('/v1/mock/api-key-unprefixed')
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$scopes = array_keys(Config::getParam('projectScopes'));
$scopes = array_keys(Config::getParam('scopes'));
$key = new Document([
'$id' => ID::unique(),
@@ -200,6 +200,9 @@ App::post('/v1/mock/api-key-unprefixed')
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
// TODO: @hmacr Remove `projectInternalId` and `projectId` column writes before deleting the column.
'projectInternalId' => $project->getSequence(),
'projectId' => $project->getId(),
'resourceInternalId' => $project->getSequence(),
'resourceId' => $project->getId(),
'resourceType' => 'projects',
+44 -41
View File
@@ -91,6 +91,7 @@ App::init()
->inject('authorization')
->action(function (App $utopia, Request $request, Database $dbForPlatform, Database $dbForProject, Audit $queueForAudits, Document $project, Document $user, ?Document $session, array $servers, string $mode, Document $team, ?Key $apiKey, Authorization $authorization) {
$route = $utopia->getRoute();
$path = $route->getPath();
/**
* Handle user authentication and session validation.
@@ -157,6 +158,10 @@ App::init()
// Step 5: API Key Authentication
if (!empty($apiKey)) {
// Verify no user session exists simultaneously
if (!$user->isEmpty()) {
throw new Exception(Exception::USER_API_KEY_AND_SESSION_SET);
}
// Check if key is expired
if ($apiKey->isExpired()) {
throw new Exception(Exception::PROJECT_KEY_EXPIRED);
@@ -185,38 +190,23 @@ App::init()
}
// For standard keys, update last accessed time
if (\in_array($apiKey->getType(), [API_KEY_STANDARD, API_KEY_ORGANIZATION, API_KEY_ACCOUNT])) {
$dbKey = null;
if (!empty($apiKey->getProjectId())) {
$dbKey = $project->find(
key: 'secret',
find: $request->getHeader('x-appwrite-key', ''),
subject: 'keys'
);
} elseif (!empty($apiKey->getUserId())) {
$dbKey = $user->find(
key: 'secret',
find: $request->getHeader('x-appwrite-key', ''),
subject: 'keys'
);
} elseif (!empty($apiKey->getTeamId())) {
$dbKey = $team->find(
key: 'secret',
find: $request->getHeader('x-appwrite-key', ''),
subject: 'keys'
);
}
if ($apiKey->getType() === API_KEY_STANDARD) {
$dbKey = $project->find(
key: 'secret',
find: $request->getHeader('x-appwrite-key', ''),
subject: 'keys'
);
if (!$dbKey) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
$updates = new Document();
$accessedAt = $dbKey->getAttribute('accessedAt', 0);
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_KEY_ACCESS)) > $accessedAt) {
$updates->setAttribute('accessedAt', DateTime::now());
$dbKey->setAttribute('accessedAt', DateTime::now());
$dbForPlatform->updateDocument('keys', $dbKey->getId(), $dbKey);
$dbForPlatform->purgeCachedDocument('projects', $project->getId());
}
$sdkValidator = new WhiteList($servers, true);
@@ -227,21 +217,12 @@ App::init()
if (!in_array($sdk, $sdks)) {
$sdks[] = $sdk;
$dbKey->setAttribute('sdks', $sdks);
$updates->setAttribute('sdks', $sdks);
$updates->setAttribute('accessedAt', Datetime::now());
}
}
if (!$updates->isEmpty()) {
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->updateDocument('keys', $dbKey->getId(), $updates));
if (!empty($apiKey->getProjectId())) {
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->purgeCachedDocument('projects', $project->getId()));
} elseif (!empty($apiKey->getUserId())) {
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->purgeCachedDocument('users', $user->getId()));
} elseif (!empty($apiKey->getTeamId())) {
$dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->purgeCachedDocument('teams', $team->getId()));
/** Update access time as well */
$dbKey->setAttribute('accessedAt', Datetime::now());
$dbForPlatform->updateDocument('keys', $dbKey->getId(), $dbKey);
$dbForPlatform->purgeCachedDocument('projects', $project->getId());
}
}
@@ -264,8 +245,30 @@ App::init()
}
$scopes = []; // Reset scope if admin
foreach ($adminRoles as $role) {
$scopes = \array_merge($scopes, $roles[$role]['scopes']);
$teamWideRoles = \array_filter($adminRoles, fn ($role) => !str_starts_with($role, "project-"));
foreach ($teamWideRoles as $teamRole) {
$scopes = \array_merge($scopes, $roles[$teamRole]['scopes']);
$authorization->addRole($teamRole);
}
$projectId = $project->getId();
if ($projectId === 'console') {
// Find the true project-id
if (str_starts_with($path, "/v1/projects/:projectId")) {
$uri = $request->getURI();
$projectId = explode('/', $uri)[3];
}
}
$projectSpecificRoles = \array_filter($adminRoles, fn ($role) => str_starts_with($role, "project-$projectId"));
foreach ($projectSpecificRoles as $projectRole) {
$actualRole = \substr($projectRole, \strlen("project-$projectId-"));
if ($actualRole === '' || !isset($roles[$actualRole])) {
continue;
}
$scopes = \array_merge($scopes, $roles[$actualRole]['scopes']);
$authorization->addRole($actualRole);
}
$authorization->setDefaultStatus(false); // Cancel security segmentation for admin users.
@@ -274,7 +277,7 @@ App::init()
$scopes = \array_unique($scopes);
$authorization->addRole($role);
foreach ($user->getRoles($authorization) as $authRole) {
foreach ($user->getRoles($authorization, $project->getId(), $path) as $authRole) {
$authorization->addRole($authRole);
}
+1 -3
View File
@@ -22,9 +22,7 @@ Config::load('collections', __DIR__ . '/../config/collections.php', $configAdapt
Config::load('frameworks', __DIR__ . '/../config/frameworks.php', $configAdapter);
Config::load('usage', __DIR__ . '/../config/usage.php', $configAdapter);
Config::load('roles', __DIR__ . '/../config/roles.php', $configAdapter); // User roles and scopes
Config::load('projectScopes', __DIR__ . '/../config/scopes/project.php', $configAdapter);
Config::load('organizationScopes', __DIR__ . '/../config/scopes/organization.php', $configAdapter);
Config::load('accountScopes', __DIR__ . '/../config/scopes/account.php', $configAdapter);
Config::load('scopes', __DIR__ . '/../config/scopes.php', $configAdapter); // User roles and scopes
Config::load('services', __DIR__ . '/../config/services.php', $configAdapter); // List of services
Config::load('variables', __DIR__ . '/../config/variables.php', $configAdapter); // List of env variables
Config::load('regions', __DIR__ . '/../config/regions.php', $configAdapter); // List of available regions
-3
View File
@@ -194,7 +194,6 @@ const DELETE_TYPE_SITES = 'sites';
const DELETE_TYPE_FUNCTIONS = 'functions';
const DELETE_TYPE_DEPLOYMENTS = 'deployments';
const DELETE_TYPE_USERS = 'users';
const DELETE_TYPE_TEAMS = 'teams';
const DELETE_TYPE_TEAM_PROJECTS = 'teams_projects';
const DELETE_TYPE_EXECUTIONS = 'executions';
const DELETE_TYPE_EXECUTIONS_LIMIT = 'executionsLimit';
@@ -250,8 +249,6 @@ const MESSAGE_TYPE_PUSH = 'push';
// API key types
const API_KEY_STANDARD = 'standard';
const API_KEY_DYNAMIC = 'dynamic';
const API_KEY_ORGANIZATION = 'organization';
const API_KEY_ACCOUNT = 'account';
// Usage metrics
const METRIC_TEAMS = 'teams';
const METRIC_USERS = 'users';
-31
View File
@@ -433,34 +433,3 @@ Database::addFilter(
return $value;
}
);
Database::addFilter(
'subQueryOrganizationKeys',
function (mixed $value) {
return;
},
function (mixed $value, Document $document, Database $database) {
return $database->getAuthorization()->skip(fn () => $database
->find('keys', [
Query::equal('resourceType', ['teams']),
Query::equal('resourceInternalId', [$document->getSequence()]),
Query::limit(APP_LIMIT_SUBQUERY),
]));
}
);
Database::addFilter(
'subQueryAccountKeys',
function (mixed $value) {
return;
},
function (mixed $value, Document $document, Database $database) {
return $database->getAuthorization()->skip(fn () => $database
->find('keys', [
Query::equal('resourceType', ['users']),
Query::equal('resourceInternalId', [$document->getSequence()]),
Query::limit(APP_LIMIT_SUBQUERY),
]));
}
);
+1 -17
View File
@@ -20,15 +20,11 @@ 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;
@@ -45,15 +41,11 @@ 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;
@@ -185,7 +177,7 @@ Response::setModel(new BaseList('Deployments List', Response::MODEL_DEPLOYMENT_L
Response::setModel(new BaseList('Executions List', Response::MODEL_EXECUTION_LIST, 'executions', Response::MODEL_EXECUTION));
Response::setModel(new BaseList('Projects List', Response::MODEL_PROJECT_LIST, 'projects', Response::MODEL_PROJECT, true, false));
Response::setModel(new BaseList('Webhooks List', Response::MODEL_WEBHOOK_LIST, 'webhooks', Response::MODEL_WEBHOOK, true, false));
Response::setModel(new BaseList('API Keys List', Response::MODEL_KEY_LIST, 'keys', Response::MODEL_KEY, true, true));
Response::setModel(new BaseList('API Keys List', Response::MODEL_KEY_LIST, 'keys', Response::MODEL_KEY, true, false));
Response::setModel(new BaseList('Dev Keys List', Response::MODEL_DEV_KEY_LIST, 'devKeys', Response::MODEL_DEV_KEY, true, false));
Response::setModel(new BaseList('Auth Providers List', Response::MODEL_AUTH_PROVIDER_LIST, 'platforms', Response::MODEL_AUTH_PROVIDER, true, false));
Response::setModel(new BaseList('Platforms List', Response::MODEL_PLATFORM_LIST, 'platforms', Response::MODEL_PLATFORM, true, false));
@@ -230,10 +222,6 @@ 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());
@@ -252,10 +240,6 @@ 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());
+1 -5
View File
@@ -23,8 +23,6 @@ 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;
@@ -287,9 +285,7 @@ $register->set('pools', function () {
default => throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Invalid scheme'),
};
$poolAdapter = System::getEnv('_APP_POOL_ADAPTER', default: 'stack') === 'swoole' ? new SwoolePool() : new StackPool();
$pool = new Pool($poolAdapter, $name, $poolSize, function () use ($type, $resource, $dsn) {
$pool = new Pool($name, $poolSize, function () use ($type, $resource, $dsn) {
// Get Adapter
switch ($type) {
case 'database':
+4 -62
View File
@@ -343,7 +343,6 @@ App::setResource('user', function (string $mode, Document $project, Document $co
* 5. Regardless of the results from steps 1-4, attempts to fetch the JWT token.
* 6. If the JWT user has a valid session ID, updates the user variable with the user from `projectDB`,
* overwriting the previous value.
* 7. If account API key is passed, use user of the account API key as long as user ID header matches too
*/
$authorization->setDefaultStatus(true);
@@ -420,17 +419,12 @@ App::setResource('user', function (string $mode, Document $project, Document $co
// }
$authJWT = $request->getHeader('x-appwrite-jwt', '');
if (!empty($authJWT) && !$project->isEmpty()) { // JWT authentication
if (!$user->isEmpty()) {
throw new Exception(Exception::USER_JWT_AND_COOKIE_SET);
}
$jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 3600, 0);
try {
$payload = $jwt->decode($authJWT);
} catch (JWTException $error) {
throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage());
}
$jwtUserId = $payload['userId'] ?? '';
if (!empty($jwtUserId)) {
if ($mode === APP_MODE_ADMIN) {
@@ -446,34 +440,6 @@ App::setResource('user', function (string $mode, Document $project, Document $co
}
}
}
// Account based on account API key
$accountKey = $request->getHeader('x-appwrite-key', '');
$accountKeyUserId = $request->getHeader('x-appwrite-user', '');
if (!empty($accountKeyUserId) && !empty($accountKey)) {
if (!$user->isEmpty()) {
throw new Exception(Exception::USER_API_KEY_AND_SESSION_SET);
}
$accountKeyUser = $dbForPlatform->getAuthorization()->skip(fn () => $dbForPlatform->getDocument('users', $accountKeyUserId));
if (!$accountKeyUser->isEmpty()) {
$key = $accountKeyUser->find(
key: 'secret',
find: $accountKey,
subject: 'keys'
);
if (!empty($key)) {
$expire = $key->getAttribute('expire');
if (!empty($expire) && $expire < DatabaseDateTime::formatTz(DatabaseDateTime::now())) {
throw new Exception(Exception::ACCOUNT_KEY_EXPIRED);
}
$user = $accountKeyUser;
}
}
}
$dbForProject->setMetadata('user', $user->getId());
$dbForPlatform->setMetadata('user', $user->getId());
@@ -1261,7 +1227,7 @@ App::setResource('team', function (Document $project, Database $dbForPlatform, A
$teamInternalId = $project->getAttribute('teamInternalId', '');
} else {
$route = $utopia->match($request);
$path = !empty($route) ? $route->getPath() : $request->getURI();
$path = $route->getPath();
if (str_starts_with($path, '/v1/projects/:projectId')) {
$uri = $request->getURI();
$pid = explode('/', $uri)[3];
@@ -1316,39 +1282,15 @@ App::setResource('previewHostname', function (Request $request, ?Key $apiKey) {
return '';
}, ['request', 'apiKey']);
App::setResource('apiKey', function (Request $request, Document $project, Document $team, Document $user): ?Key {
App::setResource('apiKey', function (Request $request, Document $project): ?Key {
$key = $request->getHeader('x-appwrite-key');
if (empty($key)) {
return null;
}
$key = Key::decode($project, $team, $user, $key);
$userHeader = $request->getHeader('x-appwrite-user');
$organizationHeader = $request->getHeader('x-appwrite-organization');
$projectHeader = $request->getHeader('x-appwrite-project');
if (!empty($key->getProjectId())) {
if (empty($projectHeader) || $projectHeader !== $key->getProjectId()) {
throw new Exception(Exception::PROJECT_ID_MISSING);
}
}
if (!empty($key->getUserId())) {
if (empty($userHeader) || $userHeader !== $key->getUserId()) {
throw new Exception(Exception::USER_ID_MISSING);
}
}
if (!empty($key->getTeamId())) {
if (empty($organizationHeader) || $organizationHeader !== $key->getTeamId()) {
throw new Exception(Exception::ORGANIZATION_ID_MISSING);
}
}
return $key;
}, ['request', 'project', 'team', 'user']);
return Key::decode($project, $key);
}, ['request', 'project']);
App::setResource('executor', fn () => new Executor());
+11 -5
View File
@@ -38,7 +38,7 @@
"ext-yaml": "*",
"ext-dom": "*",
"ext-redis": "*",
"ext-swoole": "6.*",
"ext-swoole": "*",
"ext-pdo": "*",
"ext-openssl": "*",
"ext-zlib": "*",
@@ -52,7 +52,7 @@
"utopia-php/cache": "0.13.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "1.*",
"utopia-php/database": "4.*",
"utopia-php/database": "dev-ser-541-tag-4.5.2 as 4.0.99",
"utopia-php/detector": "0.2.*",
"utopia-php/domains": "0.11.*",
"utopia-php/emails": "0.6.*",
@@ -67,7 +67,7 @@
"utopia-php/migration": "1.*",
"utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.7.*",
"utopia-php/pools": "1.*",
"utopia-php/pools": "0.8.*",
"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": "6.*",
"swoole/ide-helper": "5.1.2",
"phpstan/phpstan": "1.8.*",
"textalk/websocket": "1.5.*",
"laravel/pint": "1.*",
@@ -108,5 +108,11 @@
"php-http/discovery": true,
"tbachert/spi": true
}
}
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/utopia-php/database"
}
]
}
Generated
+175 -199
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": "2aca1c8eeaa9fa338e389e3527cb6bd6",
"content-hash": "6df869889de657693cbd12e2cf4cf781",
"packages": [
{
"name": "adhocore/jwt",
@@ -798,68 +798,6 @@
},
"time": "2026-01-12T17:58:43+00:00"
},
{
"name": "halaxa/json-machine",
"version": "1.2.6",
"source": {
"type": "git",
"url": "https://github.com/halaxa/json-machine.git",
"reference": "8bf0b0ff6ff60ab480778eaa5ad7d505b442c2d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/halaxa/json-machine/zipball/8bf0b0ff6ff60ab480778eaa5ad7d505b442c2d4",
"reference": "8bf0b0ff6ff60ab480778eaa5ad7d505b442c2d4",
"shasum": ""
},
"require": {
"php": "7.2 - 8.5"
},
"require-dev": {
"ext-json": "*",
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^8.0"
},
"suggest": {
"ext-json": "To run JSON Machine out of the box without custom decoders.",
"guzzlehttp/guzzle": "To run example with GuzzleHttp"
},
"type": "library",
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"JsonMachine\\": "src/"
},
"exclude-from-classmap": [
"src/autoloader.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Filip Halaxa",
"email": "filip@halaxa.cz"
}
],
"description": "Efficient, easy-to-use and fast JSON pull parser",
"support": {
"issues": "https://github.com/halaxa/json-machine/issues",
"source": "https://github.com/halaxa/json-machine/tree/1.2.6"
},
"funding": [
{
"url": "https://ko-fi.com/G2G57KTE4",
"type": "other"
}
],
"time": "2025-12-05T14:53:09+00:00"
},
{
"name": "league/csv",
"version": "9.24.1",
@@ -1298,16 +1236,16 @@
},
{
"name": "open-telemetry/api",
"version": "1.8.0",
"version": "1.7.1",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/api.git",
"reference": "df5197c6fd0ddd8e9883b87de042d9341300e2ad"
"reference": "45bda7efa8fcdd9bdb0daa2f26c8e31f062f49d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/api/zipball/df5197c6fd0ddd8e9883b87de042d9341300e2ad",
"reference": "df5197c6fd0ddd8e9883b87de042d9341300e2ad",
"url": "https://api.github.com/repos/opentelemetry-php/api/zipball/45bda7efa8fcdd9bdb0daa2f26c8e31f062f49d4",
"reference": "45bda7efa8fcdd9bdb0daa2f26c8e31f062f49d4",
"shasum": ""
},
"require": {
@@ -1317,7 +1255,7 @@
"symfony/polyfill-php82": "^1.26"
},
"conflict": {
"open-telemetry/sdk": "<=1.11"
"open-telemetry/sdk": "<=1.0.8"
},
"type": "library",
"extra": {
@@ -1364,7 +1302,7 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2026-01-21T04:14:03+00:00"
"time": "2025-10-19T10:49:48+00:00"
},
{
"name": "open-telemetry/context",
@@ -1554,16 +1492,16 @@
},
{
"name": "open-telemetry/sdk",
"version": "1.12.0",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/sdk.git",
"reference": "7f1bd524465c1ca42755a9ef1143ba09913f5be0"
"reference": "d91f21addcdb42da9a451c002777f8318432461a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/7f1bd524465c1ca42755a9ef1143ba09913f5be0",
"reference": "7f1bd524465c1ca42755a9ef1143ba09913f5be0",
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/d91f21addcdb42da9a451c002777f8318432461a",
"reference": "d91f21addcdb42da9a451c002777f8318432461a",
"shasum": ""
},
"require": {
@@ -1604,7 +1542,7 @@
]
},
"branch-alias": {
"dev-main": "1.12.x-dev"
"dev-main": "1.9.x-dev"
}
},
"autoload": {
@@ -1647,20 +1585,20 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2026-01-21T04:14:03+00:00"
"time": "2026-01-15T11:21:03+00:00"
},
{
"name": "open-telemetry/sem-conv",
"version": "1.38.0",
"version": "1.37.0",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/sem-conv.git",
"reference": "e613bc640a407def4991b8a936a9b27edd9a3240"
"reference": "8da7ec497c881e39afa6657d72586e27efbd29a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/e613bc640a407def4991b8a936a9b27edd9a3240",
"reference": "e613bc640a407def4991b8a936a9b27edd9a3240",
"url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/8da7ec497c881e39afa6657d72586e27efbd29a1",
"reference": "8da7ec497c881e39afa6657d72586e27efbd29a1",
"shasum": ""
},
"require": {
@@ -1700,11 +1638,11 @@
],
"support": {
"chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V",
"docs": "https://opentelemetry.io/docs/languages/php",
"docs": "https://opentelemetry.io/docs/php",
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2026-01-21T04:14:03+00:00"
"time": "2025-09-03T12:08:10+00:00"
},
{
"name": "paragonie/constant_time_encoding",
@@ -2066,16 +2004,16 @@
},
{
"name": "phpseclib/phpseclib",
"version": "3.0.49",
"version": "3.0.48",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "6233a1e12584754e6b5daa69fe1289b47775c1b9"
"reference": "64065a5679c50acb886e82c07aa139b0f757bb89"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/6233a1e12584754e6b5daa69fe1289b47775c1b9",
"reference": "6233a1e12584754e6b5daa69fe1289b47775c1b9",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/64065a5679c50acb886e82c07aa139b0f757bb89",
"reference": "64065a5679c50acb886e82c07aa139b0f757bb89",
"shasum": ""
},
"require": {
@@ -2156,7 +2094,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.49"
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.48"
},
"funding": [
{
@@ -2172,7 +2110,7 @@
"type": "tidelift"
}
],
"time": "2026-01-27T09:17:28+00:00"
"time": "2025-12-15T11:51:42+00:00"
},
{
"name": "psr/container",
@@ -2735,16 +2673,16 @@
},
{
"name": "symfony/http-client",
"version": "v7.4.5",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
"reference": "84bb634857a893cc146cceb467e31b3f02c5fe9f"
"reference": "d01dfac1e0dc99f18da48b18101c23ce57929616"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/84bb634857a893cc146cceb467e31b3f02c5fe9f",
"reference": "84bb634857a893cc146cceb467e31b3f02c5fe9f",
"url": "https://api.github.com/repos/symfony/http-client/zipball/d01dfac1e0dc99f18da48b18101c23ce57929616",
"reference": "d01dfac1e0dc99f18da48b18101c23ce57929616",
"shasum": ""
},
"require": {
@@ -2812,7 +2750,7 @@
"http"
],
"support": {
"source": "https://github.com/symfony/http-client/tree/v7.4.5"
"source": "https://github.com/symfony/http-client/tree/v7.4.3"
},
"funding": [
{
@@ -2832,7 +2770,7 @@
"type": "tidelift"
}
],
"time": "2026-01-27T16:16:02+00:00"
"time": "2025-12-23T14:50:43+00:00"
},
{
"name": "symfony/http-client-contracts",
@@ -3615,16 +3553,16 @@
},
{
"name": "utopia-php/audit",
"version": "2.1.0",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/audit.git",
"reference": "8e0540aa939968418ee3ad2b2c305992a771e142"
"reference": "1301ab2607667b9f86456f86895f3e26f8c0c9a7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/8e0540aa939968418ee3ad2b2c305992a771e142",
"reference": "8e0540aa939968418ee3ad2b2c305992a771e142",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/1301ab2607667b9f86456f86895f3e26f8c0c9a7",
"reference": "1301ab2607667b9f86456f86895f3e26f8c0c9a7",
"shasum": ""
},
"require": {
@@ -3658,9 +3596,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/audit/issues",
"source": "https://github.com/utopia-php/audit/tree/2.1.0"
"source": "https://github.com/utopia-php/audit/tree/2.0.4"
},
"time": "2026-01-22T12:40:48+00:00"
"time": "2026-01-14T07:22:46+00:00"
},
{
"name": "utopia-php/auth",
@@ -3719,16 +3657,16 @@
},
{
"name": "utopia-php/cache",
"version": "0.13.3",
"version": "0.13.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/cache.git",
"reference": "355707ab2c0090435059216165db86976b68a126"
"reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/cache/zipball/355707ab2c0090435059216165db86976b68a126",
"reference": "355707ab2c0090435059216165db86976b68a126",
"url": "https://api.github.com/repos/utopia-php/cache/zipball/5768498c9f451482f0bf3eede4d6452ddcd4a0f6",
"reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6",
"shasum": ""
},
"require": {
@@ -3736,7 +3674,7 @@
"ext-memcached": "*",
"ext-redis": "*",
"php": ">=8.0",
"utopia-php/pools": "1.*",
"utopia-php/pools": "0.8.*",
"utopia-php/telemetry": "*"
},
"require-dev": {
@@ -3765,9 +3703,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/cache/issues",
"source": "https://github.com/utopia-php/cache/tree/0.13.3"
"source": "https://github.com/utopia-php/cache/tree/0.13.2"
},
"time": "2026-01-16T07:54:34+00:00"
"time": "2025-12-17T08:55:43+00:00"
},
{
"name": "utopia-php/cli",
@@ -3961,16 +3899,16 @@
},
{
"name": "utopia-php/database",
"version": "4.6.1",
"version": "dev-ser-541-tag-4.5.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "8795a7f5bf8828955299ae44e5946f93a2b1bde5"
"reference": "71c0b9c44f7b4d47b3d7517f592374743eb604d6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/8795a7f5bf8828955299ae44e5946f93a2b1bde5",
"reference": "8795a7f5bf8828955299ae44e5946f93a2b1bde5",
"url": "https://api.github.com/repos/utopia-php/database/zipball/71c0b9c44f7b4d47b3d7517f592374743eb604d6",
"reference": "71c0b9c44f7b4d47b3d7517f592374743eb604d6",
"shasum": ""
},
"require": {
@@ -3981,7 +3919,7 @@
"utopia-php/cache": "0.13.*",
"utopia-php/framework": "0.33.*",
"utopia-php/mongo": "0.11.*",
"utopia-php/pools": "1.*"
"utopia-php/pools": "0.8.*"
},
"require-dev": {
"fakerphp/faker": "1.23.*",
@@ -3999,7 +3937,38 @@
"Utopia\\Database\\": "src/Database"
}
},
"notification-url": "https://packagist.org/downloads/",
"autoload-dev": {
"psr-4": {
"Tests\\E2E\\": "tests/e2e",
"Tests\\Unit\\": "tests/unit"
}
},
"scripts": {
"build": [
"Composer\\Config::disableProcessTimeout",
"docker compose build"
],
"start": [
"Composer\\Config::disableProcessTimeout",
"docker compose up -d"
],
"test": [
"Composer\\Config::disableProcessTimeout",
"docker compose exec tests vendor/bin/phpunit --configuration phpunit.xml"
],
"lint": [
"php -d memory_limit=2G ./vendor/bin/pint --test"
],
"format": [
"php -d memory_limit=2G ./vendor/bin/pint"
],
"check": [
"./vendor/bin/phpstan analyse --level 7 src tests --memory-limit 2G"
],
"coverage": [
"./vendor/bin/coverage-check ./tmp/clover.xml 90"
]
},
"license": [
"MIT"
],
@@ -4012,10 +3981,10 @@
"utopia"
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/4.6.1"
"source": "https://github.com/utopia-php/database/tree/ser-541-tag-4.5.2",
"issues": "https://github.com/utopia-php/database/issues"
},
"time": "2026-01-21T09:37:22+00:00"
"time": "2026-01-25T15:56:19+00:00"
},
{
"name": "utopia-php/detector",
@@ -4578,23 +4547,22 @@
},
{
"name": "utopia-php/migration",
"version": "1.4.6",
"version": "1.4.4",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/migration.git",
"reference": "f358db6fb6a01d855bbed39e283387069e4f277d"
"reference": "3fe751902012d09d323420cd3523be1ed855e868"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/f358db6fb6a01d855bbed39e283387069e4f277d",
"reference": "f358db6fb6a01d855bbed39e283387069e4f277d",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/3fe751902012d09d323420cd3523be1ed855e868",
"reference": "3fe751902012d09d323420cd3523be1ed855e868",
"shasum": ""
},
"require": {
"appwrite/appwrite": "19.*",
"ext-curl": "*",
"ext-openssl": "*",
"halaxa/json-machine": "^1.2",
"php": ">=8.1",
"utopia-php/console": "0.0.*",
"utopia-php/database": "4.*",
@@ -4628,9 +4596,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/migration/issues",
"source": "https://github.com/utopia-php/migration/tree/1.4.6"
"source": "https://github.com/utopia-php/migration/tree/1.4.4"
},
"time": "2026-01-20T11:07:17+00:00"
"time": "2026-01-16T10:00:07+00:00"
},
{
"name": "utopia-php/mongo",
@@ -4796,16 +4764,16 @@
},
{
"name": "utopia-php/pools",
"version": "1.0.2",
"version": "0.8.3",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/pools.git",
"reference": "b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1"
"reference": "ad7d6ba946376e81c603204285ce9a674b6502b8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/pools/zipball/b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1",
"reference": "b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1",
"url": "https://api.github.com/repos/utopia-php/pools/zipball/ad7d6ba946376e81c603204285ce9a674b6502b8",
"reference": "ad7d6ba946376e81c603204285ce9a674b6502b8",
"shasum": ""
},
"require": {
@@ -4815,8 +4783,7 @@
"require-dev": {
"laravel/pint": "1.*",
"phpstan/phpstan": "1.*",
"phpunit/phpunit": "11.*",
"swoole/ide-helper": "6.*"
"phpunit/phpunit": "11.*"
},
"type": "library",
"autoload": {
@@ -4843,9 +4810,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/pools/issues",
"source": "https://github.com/utopia-php/pools/tree/1.0.2"
"source": "https://github.com/utopia-php/pools/tree/0.8.3"
},
"time": "2026-01-28T13:12:36+00:00"
"time": "2025-12-17T09:35:18+00:00"
},
{
"name": "utopia-php/preloader",
@@ -4902,16 +4869,16 @@
},
{
"name": "utopia-php/queue",
"version": "0.15.1",
"version": "0.15.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/queue.git",
"reference": "e551606385990ec7901d222017c4cfc2749a518c"
"reference": "6abb268ba7ec00dea4e5201b007776ea1bce9242"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/queue/zipball/e551606385990ec7901d222017c4cfc2749a518c",
"reference": "e551606385990ec7901d222017c4cfc2749a518c",
"url": "https://api.github.com/repos/utopia-php/queue/zipball/6abb268ba7ec00dea4e5201b007776ea1bce9242",
"reference": "6abb268ba7ec00dea4e5201b007776ea1bce9242",
"shasum": ""
},
"require": {
@@ -4920,7 +4887,7 @@
"utopia-php/console": "0.0.*",
"utopia-php/fetch": "0.5.*",
"utopia-php/framework": "0.33.*",
"utopia-php/pools": "1.*",
"utopia-php/pools": "0.8.*",
"utopia-php/telemetry": "*"
},
"require-dev": {
@@ -4962,9 +4929,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/queue/issues",
"source": "https://github.com/utopia-php/queue/tree/0.15.1"
"source": "https://github.com/utopia-php/queue/tree/0.15.0"
},
"time": "2026-01-16T07:54:54+00:00"
"time": "2026-01-06T12:41:51+00:00"
},
{
"name": "utopia-php/registry",
@@ -5121,28 +5088,28 @@
},
{
"name": "utopia-php/swoole",
"version": "1.0.1",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/swoole.git",
"reference": "c5ce710dfffc4df09bf3e7aea2d1e55c53e77a95"
"reference": "95a937acb393dbf95cccba239d55886e2848ab0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/c5ce710dfffc4df09bf3e7aea2d1e55c53e77a95",
"reference": "c5ce710dfffc4df09bf3e7aea2d1e55c53e77a95",
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/95a937acb393dbf95cccba239d55886e2848ab0b",
"reference": "95a937acb393dbf95cccba239d55886e2848ab0b",
"shasum": ""
},
"require": {
"ext-swoole": "6.*",
"php": ">=8.1",
"ext-swoole": "*",
"php": ">=8.0",
"utopia-php/framework": "0.33.37"
},
"require-dev": {
"laravel/pint": "1.2.*",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.3",
"swoole/ide-helper": "6.0.2"
"swoole/ide-helper": "5.0.2"
},
"type": "library",
"autoload": {
@@ -5166,9 +5133,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/swoole/issues",
"source": "https://github.com/utopia-php/swoole/tree/1.0.1"
"source": "https://github.com/utopia-php/swoole/tree/1.0.0"
},
"time": "2026-01-28T12:43:38+00:00"
"time": "2026-01-14T14:00:11+00:00"
},
{
"name": "utopia-php/system",
@@ -5546,16 +5513,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "1.8.21",
"version": "1.8.17",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "1b47b2c794811c565f8b5e7eeaa19f749bcbeb6b"
"reference": "1bc5a39bf87d3c2064f2f8d45fa712340338bc41"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/1b47b2c794811c565f8b5e7eeaa19f749bcbeb6b",
"reference": "1b47b2c794811c565f8b5e7eeaa19f749bcbeb6b",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/1bc5a39bf87d3c2064f2f8d45fa712340338bc41",
"reference": "1bc5a39bf87d3c2064f2f8d45fa712340338bc41",
"shasum": ""
},
"require": {
@@ -5591,9 +5558,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": {
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/1.8.21"
"source": "https://github.com/appwrite/sdk-generator/tree/1.8.17"
},
"time": "2026-01-26T04:42:33+00:00"
"time": "2026-01-19T12:13:41+00:00"
},
{
"name": "doctrine/annotations",
@@ -6773,16 +6740,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.6.34",
"version": "9.6.31",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "b36f02317466907a230d3aa1d34467041271ef4a"
"reference": "945d0b7f346a084ce5549e95289962972c4272e5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a",
"reference": "b36f02317466907a230d3aa1d34467041271ef4a",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/945d0b7f346a084ce5549e95289962972c4272e5",
"reference": "945d0b7f346a084ce5549e95289962972c4272e5",
"shasum": ""
},
"require": {
@@ -6804,7 +6771,7 @@
"phpunit/php-timer": "^5.0.3",
"sebastian/cli-parser": "^1.0.2",
"sebastian/code-unit": "^1.0.8",
"sebastian/comparator": "^4.0.10",
"sebastian/comparator": "^4.0.9",
"sebastian/diff": "^4.0.6",
"sebastian/environment": "^5.1.5",
"sebastian/exporter": "^4.0.8",
@@ -6856,7 +6823,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.31"
},
"funding": [
{
@@ -6880,7 +6847,7 @@
"type": "tidelift"
}
],
"time": "2026-01-27T05:45:00+00:00"
"time": "2025-12-06T07:45:52+00:00"
},
{
"name": "psr/cache",
@@ -7100,16 +7067,16 @@
},
{
"name": "sebastian/comparator",
"version": "4.0.10",
"version": "4.0.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d"
"reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d",
"reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"shasum": ""
},
"require": {
@@ -7162,7 +7129,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10"
"source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9"
},
"funding": [
{
@@ -7182,7 +7149,7 @@
"type": "tidelift"
}
],
"time": "2026-01-24T09:22:56+00:00"
"time": "2025-08-10T06:51:50+00:00"
},
{
"name": "sebastian/complexity",
@@ -8008,16 +7975,16 @@
},
{
"name": "swoole/ide-helper",
"version": "6.0.2",
"version": "5.1.2",
"source": {
"type": "git",
"url": "https://github.com/swoole/ide-helper.git",
"reference": "6f12243dce071714c5febe059578d909698f9a52"
"reference": "33ec7af9111b76d06a70dd31191cc74793551112"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/6f12243dce071714c5febe059578d909698f9a52",
"reference": "6f12243dce071714c5febe059578d909698f9a52",
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/33ec7af9111b76d06a70dd31191cc74793551112",
"reference": "33ec7af9111b76d06a70dd31191cc74793551112",
"shasum": ""
},
"type": "library",
@@ -8034,22 +8001,22 @@
"description": "IDE help files for Swoole.",
"support": {
"issues": "https://github.com/swoole/ide-helper/issues",
"source": "https://github.com/swoole/ide-helper/tree/6.0.2"
"source": "https://github.com/swoole/ide-helper/tree/5.1.2"
},
"time": "2025-03-23T07:31:41+00:00"
"time": "2024-02-01T22:28:11+00:00"
},
{
"name": "symfony/console",
"version": "v8.0.4",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "ace03c4cf9805080ff40cbeec69fca180c339a3b"
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/ace03c4cf9805080ff40cbeec69fca180c339a3b",
"reference": "ace03c4cf9805080ff40cbeec69fca180c339a3b",
"url": "https://api.github.com/repos/symfony/console/zipball/6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
"shasum": ""
},
"require": {
@@ -8106,7 +8073,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v8.0.4"
"source": "https://github.com/symfony/console/tree/v8.0.3"
},
"funding": [
{
@@ -8126,7 +8093,7 @@
"type": "tidelift"
}
],
"time": "2026-01-13T13:06:50+00:00"
"time": "2025-12-23T14:52:06+00:00"
},
{
"name": "symfony/filesystem",
@@ -8200,16 +8167,16 @@
},
{
"name": "symfony/finder",
"version": "v8.0.5",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "8bd576e97c67d45941365bf824e18dc8538e6eb0"
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/8bd576e97c67d45941365bf824e18dc8538e6eb0",
"reference": "8bd576e97c67d45941365bf824e18dc8538e6eb0",
"url": "https://api.github.com/repos/symfony/finder/zipball/dd3a2953570a283a2ba4e17063bb98c734cf5b12",
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12",
"shasum": ""
},
"require": {
@@ -8244,7 +8211,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v8.0.5"
"source": "https://github.com/symfony/finder/tree/v8.0.3"
},
"funding": [
{
@@ -8264,7 +8231,7 @@
"type": "tidelift"
}
],
"time": "2026-01-26T15:08:38+00:00"
"time": "2025-12-23T14:52:06+00:00"
},
{
"name": "symfony/options-resolver",
@@ -8669,16 +8636,16 @@
},
{
"name": "symfony/process",
"version": "v8.0.5",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674"
"reference": "0cbbd88ec836f8757641c651bb995335846abb78"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674",
"reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674",
"url": "https://api.github.com/repos/symfony/process/zipball/0cbbd88ec836f8757641c651bb995335846abb78",
"reference": "0cbbd88ec836f8757641c651bb995335846abb78",
"shasum": ""
},
"require": {
@@ -8710,7 +8677,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v8.0.5"
"source": "https://github.com/symfony/process/tree/v8.0.3"
},
"funding": [
{
@@ -8730,20 +8697,20 @@
"type": "tidelift"
}
],
"time": "2026-01-26T15:08:38+00:00"
"time": "2025-12-19T10:01:18+00:00"
},
{
"name": "symfony/string",
"version": "v8.0.4",
"version": "v8.0.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "758b372d6882506821ed666032e43020c4f57194"
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/758b372d6882506821ed666032e43020c4f57194",
"reference": "758b372d6882506821ed666032e43020c4f57194",
"url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc",
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc",
"shasum": ""
},
"require": {
@@ -8800,7 +8767,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v8.0.4"
"source": "https://github.com/symfony/string/tree/v8.0.1"
},
"funding": [
{
@@ -8820,7 +8787,7 @@
"type": "tidelift"
}
],
"time": "2026-01-12T12:37:40+00:00"
"time": "2025-12-01T09:13:36+00:00"
},
{
"name": "textalk/websocket",
@@ -9050,9 +9017,18 @@
"time": "2024-03-07T20:33:40+00:00"
}
],
"aliases": [],
"aliases": [
{
"package": "utopia-php/database",
"version": "dev-ser-541-tag-4.5.2",
"alias": "4.0.99",
"alias_normalized": "4.0.99.0"
}
],
"minimum-stability": "stable",
"stability-flags": {},
"stability-flags": {
"utopia-php/database": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@@ -9064,7 +9040,7 @@
"ext-yaml": "*",
"ext-dom": "*",
"ext-redis": "*",
"ext-swoole": "6.*",
"ext-swoole": "*",
"ext-pdo": "*",
"ext-openssl": "*",
"ext-zlib": "*",
@@ -9076,5 +9052,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.9.0"
"plugin-api-version": "2.6.0"
}
-22
View File
@@ -98,7 +98,6 @@ services:
- ./public:/usr/src/code/public
- ./src:/usr/src/code/src
- ./dev:/usr/src/code/dev
# - ./vendor/utopia-php/framework:/usr/src/code/vendor/utopia-php/framework
depends_on:
- mariadb
- redis
@@ -112,7 +111,6 @@ services:
- _APP_ENV
- _APP_EDITION
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_LOCALE
- _APP_COMPRESSION_ENABLED
- _APP_COMPRESSION_MIN_SIZE_BYTES
@@ -302,7 +300,6 @@ services:
- _APP_LOGGING_CONFIG
- _APP_LOGGING_CONFIG_REALTIME
- _APP_DATABASE_SHARED_TABLES
- _APP_POOL_ADAPTER=swoole
appwrite-worker-audits:
entrypoint: worker-audits
@@ -320,7 +317,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -352,7 +348,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_EMAIL_SECURITY
- _APP_DB_HOST
@@ -390,7 +385,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -448,7 +442,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -483,7 +476,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
@@ -557,7 +549,6 @@ services:
# Basic
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_LOGGING_CONFIG
# Database
- _APP_OPENSSL_KEY_V1
@@ -615,7 +606,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
@@ -658,7 +648,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_OPTIONS_FORCE_HTTPS
@@ -702,7 +691,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
@@ -737,7 +725,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -795,7 +782,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
@@ -835,7 +821,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
- _APP_DOMAIN_TARGET_AAAA
@@ -880,7 +865,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_DOMAIN
- _APP_DOMAIN_TARGET_CNAME
- _APP_DOMAIN_TARGET_AAAA
@@ -919,7 +903,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@@ -951,7 +934,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@@ -983,7 +965,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
@@ -1015,7 +996,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -1044,7 +1024,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -1072,7 +1051,6 @@ services:
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_POOL_ADAPTER
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -1 +0,0 @@
appwrite health get-queue-audits
@@ -1 +0,0 @@
Create a longtext attribute.
@@ -1 +0,0 @@
Create a mediumtext attribute.
@@ -1 +0,0 @@
Create a text attribute.
@@ -1 +0,0 @@
Create a varchar attribute.
@@ -1 +0,0 @@
Update a longtext attribute. Changing the `default` value will not update already existing documents.
@@ -1 +0,0 @@
Update a mediumtext attribute. Changing the `default` value will not update already existing documents.
@@ -1 +0,0 @@
Update a text attribute. Changing the `default` value will not update already existing documents.
@@ -1 +0,0 @@
Update a varchar attribute. Changing the `default` value will not update already existing documents.
@@ -1 +0,0 @@
Create a longtext column.
@@ -1 +0,0 @@
Create a mediumtext column.
@@ -1 +0,0 @@
Create a text column.
@@ -1 +0,0 @@
Create a varchar column.
@@ -1 +0,0 @@
Update a longtext column. Changing the `default` value will not update already existing rows.
@@ -1 +0,0 @@
Update a mediumtext column. Changing the `default` value will not update already existing rows.
@@ -1 +0,0 @@
Update a text column. Changing the `default` value will not update already existing rows.
@@ -1 +0,0 @@
Update a varchar column. Changing the `default` value will not update already existing rows.
-24
View File
@@ -1,29 +1,5 @@
# Change Log
## 13.1.0
- Mark `appwrite generate` command as stable
- Improve permissions param to be a typesafe callback
- Fix relationship handling in generated code
- Fix `appwrite client` properly hanlding `--key` parameter
- Fix `init site` not working on Windows
## 13.1.0-rc.3
- Allow generation of server side CRUD operations on databases and tables
- Fix npm distribution failing due to missing template files in bundle
## 13.1.0-rc.2
- Update generated `databases` services to automatically initialize a client instance
- Update generator to use handlebars templates
## 13.1.0-rc.1
- Feat: `appwrite generate` command to create a fully typesafe SDK for your Appwrite project
- Chore: improve creation of columns during table creation by passing them directly instead of creating them one by one
- Improved config validation by adding extra rules in zod schema
## 13.0.1
- Fix `project init` command leading to Cannot convert to BigInt error
-5
View File
@@ -1,5 +0,0 @@
# Change Log
## 0.1.0
* Initial release
+3 -93
View File
@@ -15,8 +15,6 @@ class Key
{
public function __construct(
protected string $projectId,
protected string $teamId,
protected string $userId,
protected string $type,
protected string $role,
protected array $scopes,
@@ -36,16 +34,6 @@ class Key
return $this->projectId;
}
public function getUserId(): string
{
return $this->userId;
}
public function getTeamId(): string
{
return $this->teamId;
}
public function getType(): string
{
return $this->type;
@@ -107,12 +95,13 @@ class Key
* Decode the given secret key into a Key object, containing the project ID, type, role, scopes, and name.
* Can be a stored API key or a dynamic key (JWT).
*
* @param Document $project
* @param string $key
* @return Key
* @throws Exception
*/
public static function decode(
Document $project,
Document $team,
Document $user,
string $key
): Key {
if (\str_contains($key, '_')) {
@@ -129,8 +118,6 @@ class Key
$guestKey = new Key(
$project->getId(),
'',
'',
$type,
User::ROLE_GUESTS,
$roles[User::ROLE_GUESTS]['scopes'] ?? [],
@@ -146,7 +133,6 @@ class Key
leeway: 0
);
$payload = [];
try {
$payload = $jwtObj->decode($secret);
} catch (JWTException) {
@@ -169,8 +155,6 @@ class Key
return new Key(
$projectId,
'',
'',
$type,
$role,
$scopes,
@@ -204,86 +188,12 @@ class Key
return new Key(
$project->getId(),
'',
'',
$type,
$role,
$scopes,
$name,
$expired
);
case API_KEY_ACCOUNT:
$key = $user->find(
key: 'secret',
find: $key,
subject: 'keys'
);
// Invalid key
if (!$key) {
return $guestKey;
}
$expire = $key->getAttribute('expire');
$expired = false;
if (!empty($expire) && $expire < DateTime::formatTz(DateTime::now())) {
$expired = true;
}
$name = $key->getAttribute('name', 'UNKNOWN');
$role = User::ROLE_USERS;
$scopes = $key->getAttribute('scopes', []);
$key = new Key(
'',
'',
$user->getId(),
$type,
$role,
$scopes,
$name,
$expired
);
return $key;
case API_KEY_ORGANIZATION:
$key = $team->find(
key: 'secret',
find: $key,
subject: 'keys'
);
// Invalid key
if (!$key) {
return $guestKey;
}
$expire = $key->getAttribute('expire');
$expired = false;
if (!empty($expire) && $expire < DateTime::formatTz(DateTime::now())) {
$expired = true;
}
$name = $key->getAttribute('name', 'UNKNOWN');
$role = User::ROLE_APPS;
$scopes = $key->getAttribute('scopes', []);
$key = new Key(
'',
$team->getId(),
'',
$type,
$role,
$scopes,
$name,
$expired
);
return $key;
default:
return $guestKey;
}
+102
View File
@@ -0,0 +1,102 @@
<?php
namespace Appwrite\Auth\Validator;
use Utopia\Database\Validator\Roles;
use Utopia\Validator;
class Role extends Validator
{
/**
* @var array
*/
protected array $roles;
/**
* Constructor
*
* Sets the acceptable roles.
*
* @param array $list
* @param string $type of $list items
*/
public function __construct(array $roles)
{
$this->roles = $roles;
}
/**
* Get Description
*
* Returns validator description
*
* @return string
*/
public function getDescription(): string
{
return 'Value must be one of (' . \implode(', ', $this->roles) . ' (or) in the format "project-<projectId>-<role>")';
}
/**
* Is array
*
* Function will return true if object is array.
*
* @return bool
*/
public function isArray(): bool
{
return false;
}
/**
* Get Type
*
* Returns validator type.
*
* @return string
*/
public function getType(): string
{
return self::TYPE_STRING;
}
/**
* Is valid
*
* Validation will pass if $value is in the white list array.
*
* @param mixed $value
* @return bool
*/
public function isValid(mixed $value): bool
{
if (!\is_string($value)) {
return false;
}
$role = $value;
if (str_starts_with($value, "project-")) {
$prefix = "project-";
$rest = \substr($value, \strlen($prefix));
$lastDash = \strrpos($rest, '-');
if ($lastDash === false) {
return false;
}
$projectId = \substr($rest, 0, $lastDash);
$role = \substr($rest, $lastDash + 1);
if ($projectId === '' || $role === '') {
return false;
}
}
if (!\in_array($role, $this->roles)) {
return false;
}
return true;
}
}
-12
View File
@@ -364,18 +364,6 @@ class Mail extends Event
return $this;
}
/**
* Append variables to the email event.
*
* @param array $variables
* @return self
*/
public function appendVariables(array $variables): self
{
$this->variables = \array_merge($this->variables, $variables);
return $this;
}
/**
* Set attachment
* @param string $content
+1 -7
View File
@@ -107,9 +107,7 @@ class Exception extends \Exception
public const string USER_DELETION_PROHIBITED = 'user_deletion_prohibited';
public const string USER_TARGET_NOT_FOUND = 'user_target_not_found';
public const string USER_TARGET_ALREADY_EXISTS = 'user_target_already_exists';
public const string USER_API_KEY_AND_SESSION_SET = 'user_api_key_and_session_set';
public const string USER_JWT_AND_COOKIE_SET = 'user_jwt_and_cookie_set';
public const string USER_ID_MISSING = 'user_id_missing';
public const string USER_API_KEY_AND_SESSION_SET = 'user_key_and_session_set';
public const string API_KEY_EXPIRED = 'api_key_expired';
@@ -121,8 +119,6 @@ class Exception extends \Exception
public const string TEAM_INVITE_MISMATCH = 'team_invite_mismatch';
public const string TEAM_ALREADY_EXISTS = 'team_already_exists';
public const string ORGANIZATION_ID_MISSING = 'organization_id_missing';
/** Console */
public const string RESOURCE_ALREADY_EXISTS = 'resource_already_exists';
@@ -287,7 +283,6 @@ class Exception extends \Exception
/** Projects */
public const string PROJECT_NOT_FOUND = 'project_not_found';
public const string PROJECT_ID_MISSING = 'project_id_missing';
public const string PROJECT_PROVIDER_DISABLED = 'project_provider_disabled';
public const string PROJECT_PROVIDER_UNSUPPORTED = 'project_provider_unsupported';
public const string PROJECT_ALREADY_EXISTS = 'project_already_exists';
@@ -295,7 +290,6 @@ class Exception extends \Exception
public const string PROJECT_INVALID_FAILURE_URL = 'project_invalid_failure_url';
public const string PROJECT_RESERVED_PROJECT = 'project_reserved_project';
public const string PROJECT_KEY_EXPIRED = 'project_key_expired';
public const string ACCOUNT_KEY_EXPIRED = 'account_key_expired';
public const string PROJECT_SMTP_CONFIG_INVALID = 'project_smtp_config_invalid';
+27 -23
View File
@@ -39,34 +39,38 @@ class EventProcessor
return \json_decode($cachedFunctionEvents, true) ?? [];
}
$events = [];
$limit = 100;
$sum = 100;
$offset = 0;
try {
$events = [];
$limit = 100;
$sum = 100;
$offset = 0;
while ($sum >= $limit) {
$functions = $dbForProject->getAuthorization()->skip(fn () => $dbForProject->find('functions', [
Query::select(['$id', 'events']),
Query::limit($limit),
Query::offset($offset),
Query::orderAsc('$sequence'),
]));
while ($sum >= $limit) {
$functions = $dbForProject->find('functions', [
Query::select(['$id', 'events']),
Query::limit($limit),
Query::offset($offset),
Query::orderAsc('$sequence'),
]);
$sum = \count($functions);
$offset = $offset + $limit;
$sum = \count($functions);
$offset = $offset + $limit;
foreach ($functions as $function) {
$functionEvents = $function->getAttribute('events', []);
if (!empty($functionEvents)) {
\array_push($events, ...$functionEvents);
foreach ($functions as $function) {
$functionEvents = $function->getAttribute('events', []);
if (!empty($functionEvents)) {
$events = array_merge($events, $functionEvents);
}
}
}
$uniqueEvents = \array_flip(\array_unique($events));
$dbForProject->getCache()->save($cacheKey, \json_encode($uniqueEvents));
return $uniqueEvents;
} catch (\Throwable $e) {
return [];
}
$uniqueEvents = \array_flip(\array_unique($events));
$dbForProject->getCache()->save($cacheKey, \json_encode($uniqueEvents));
return $uniqueEvents;
}
/**
@@ -93,7 +97,7 @@ class EventProcessor
$webhookEvents = $webhook->getAttribute('events', []);
if (!empty($webhookEvents)) {
\array_push($events, ...$webhookEvents);
$events = array_merge($events, $webhookEvents);
}
}
+53 -53
View File
@@ -269,59 +269,59 @@ class Mapper
}
switch ((!empty($validator)) ? $validator::class : '') {
case \Appwrite\Auth\Validator\Password::class:
case \Appwrite\Event\Validator\Event::class:
case \Appwrite\Event\Validator\FunctionEvent::class:
case \Appwrite\Network\Validator\CNAME::class:
case \Appwrite\Network\Validator\Email::class:
case \Appwrite\Network\Validator\Redirect::class:
case \Appwrite\Network\Validator\DNS::class:
case \Appwrite\Network\Validator\Origin::class:
case \Appwrite\Task\Validator\Cron::class:
case \Appwrite\Utopia\Database\Validator\CustomId::class:
case \Utopia\Database\Validator\Key::class:
case \Utopia\Database\Validator\UID::class:
case \Utopia\Validator\Domain::class:
case \Utopia\Validator\HexColor::class:
case \Utopia\Validator\Host::class:
case \Utopia\Validator\IP::class:
case \Utopia\Validator\Origin::class:
case \Utopia\Validator\Text::class:
case \Utopia\Validator\URL::class:
case \Utopia\Validator\WhiteList::class:
case 'Appwrite\Auth\Validator\Password':
case 'Appwrite\Event\Validator\Event':
case 'Appwrite\Event\Validator\FunctionEvent':
case 'Appwrite\Network\Validator\CNAME':
case 'Appwrite\Network\Validator\Email':
case 'Appwrite\Network\Validator\Redirect':
case 'Appwrite\Network\Validator\DNS':
case 'Appwrite\Network\Validator\Origin':
case 'Appwrite\Task\Validator\Cron':
case 'Appwrite\Utopia\Database\Validator\CustomId':
case 'Utopia\Database\Validator\Key':
case 'Utopia\Database\Validator\UID':
case 'Utopia\Validator\Domain':
case 'Utopia\Validator\HexColor':
case 'Utopia\Validator\Host':
case 'Utopia\Validator\IP':
case 'Utopia\Validator\Origin':
case 'Utopia\Validator\Text':
case 'Utopia\Validator\URL':
case 'Utopia\Validator\WhiteList':
default:
$type = Type::string();
break;
case \Appwrite\Utopia\Database\Validator\Queries\Attributes::class:
case \Appwrite\Utopia\Database\Validator\Queries\Base::class:
case \Appwrite\Utopia\Database\Validator\Queries\Buckets::class:
case \Appwrite\Utopia\Database\Validator\Queries\Tables::class:
case \Appwrite\Utopia\Database\Validator\Queries\Collections::class:
case \Appwrite\Utopia\Database\Validator\Queries\Columns::class:
case \Appwrite\Utopia\Database\Validator\Queries\Databases::class:
case \Appwrite\Utopia\Database\Validator\Queries\Deployments::class:
case \Appwrite\Utopia\Database\Validator\Queries\Executions::class:
case \Appwrite\Utopia\Database\Validator\Queries\Files::class:
case \Appwrite\Utopia\Database\Validator\Queries\Functions::class:
case \Appwrite\Utopia\Database\Validator\Queries\Indexes::class:
case \Appwrite\Utopia\Database\Validator\Queries\Installations::class:
case \Appwrite\Utopia\Database\Validator\Queries\Memberships::class:
case \Appwrite\Utopia\Database\Validator\Queries\Projects::class:
case \Appwrite\Utopia\Database\Validator\Queries\Rules::class:
case \Appwrite\Utopia\Database\Validator\Queries\Teams::class:
case \Appwrite\Utopia\Database\Validator\Queries\Users::class:
case \Appwrite\Utopia\Database\Validator\Queries\Variables::class:
case \Utopia\Database\Validator\Authorization::class:
case \Utopia\Database\Validator\Permissions::class:
case \Utopia\Database\Validator\Queries::class:
case \Utopia\Database\Validator\Queries\Documents::class:
case \Utopia\Database\Validator\Roles::class:
case 'Appwrite\Utopia\Database\Validator\Queries\Attributes':
case 'Appwrite\Utopia\Database\Validator\Queries\Base':
case 'Appwrite\Utopia\Database\Validator\Queries\Buckets':
case 'Appwrite\Utopia\Database\Validator\Queries\Tables':
case 'Appwrite\Utopia\Database\Validator\Queries\Collections':
case 'Appwrite\Utopia\Database\Validator\Queries\Columns':
case 'Appwrite\Utopia\Database\Validator\Queries\Databases':
case 'Appwrite\Utopia\Database\Validator\Queries\Deployments':
case 'Appwrite\Utopia\Database\Validator\Queries\Executions':
case 'Appwrite\Utopia\Database\Validator\Queries\Files':
case 'Appwrite\Utopia\Database\Validator\Queries\Functions':
case 'Appwrite\Utopia\Database\Validator\Queries\Indexes':
case 'Appwrite\Utopia\Database\Validator\Queries\Installations':
case 'Appwrite\Utopia\Database\Validator\Queries\Memberships':
case 'Appwrite\Utopia\Database\Validator\Queries\Projects':
case 'Appwrite\Utopia\Database\Validator\Queries\Rules':
case 'Appwrite\Utopia\Database\Validator\Queries\Teams':
case 'Appwrite\Utopia\Database\Validator\Queries\Users':
case 'Appwrite\Utopia\Database\Validator\Queries\Variables':
case 'Utopia\Database\Validator\Authorization':
case 'Utopia\Database\Validator\Permissions':
case 'Utopia\Database\Validator\Queries':
case 'Utopia\Database\Validator\Queries\Documents':
case 'Utopia\Database\Validator\Roles':
$type = Type::listOf(Type::string());
break;
case \Utopia\Validator\Boolean::class:
case 'Utopia\Validator\Boolean':
$type = Type::boolean();
break;
case \Utopia\Validator\ArrayList::class:
case 'Utopia\Validator\ArrayList':
$type = Type::listOf(self::param(
$utopia,
$validator->getValidator(),
@@ -329,11 +329,11 @@ class Mapper
$injections
));
break;
case \Utopia\Validator\Integer::class:
case \Utopia\Validator\Numeric::class:
case 'Utopia\Validator\Integer':
case 'Utopia\Validator\Numeric':
$type = Type::int();
break;
case \Utopia\Validator\Range::class:
case 'Utopia\Validator\Range':
// Check if the Range validator is for float or integer
if ($validator instanceof \Utopia\Validator\Range && $validator->getType() === \Utopia\Validator\Range::TYPE_FLOAT) {
$type = Type::float();
@@ -341,16 +341,16 @@ class Mapper
$type = Type::int();
}
break;
case \Utopia\Validator\FloatValidator::class:
case 'Utopia\Validator\FloatValidator':
$type = Type::float();
break;
case \Utopia\Validator\Assoc::class:
case 'Utopia\Validator\Assoc':
$type = Types::assoc();
break;
case \Utopia\Validator\JSON::class:
case 'Utopia\Validator\JSON':
$type = Types::json();
break;
case \Utopia\Storage\Validator\File::class:
case 'Utopia\Storage\Validator\File':
$type = Types::inputFile();
break;
}
@@ -327,7 +327,7 @@ class Create extends Action
->setPreview($preview)
->setBody($body)
->setBodyTemplate($bodyTemplate)
->appendVariables($emailVariables)
->setVariables($emailVariables)
->setRecipient($user->getAttribute('email'));
// since this is console project, set email sender name!
@@ -144,7 +144,7 @@ class Base extends Action
return $deployment;
}
public function redeployVcsSite(Request $request, Document $site, Document $project, Document $installation, Database $dbForProject, Database $dbForPlatform, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, Authorization $authorization, string $referenceType = 'branch', string $reference = '', array $platform): Document
public function redeployVcsSite(Request $request, Document $site, Document $project, Document $installation, Database $dbForProject, Database $dbForPlatform, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, Authorization $authorization, string $referenceType = 'branch', string $reference = ''): Document
{
$deploymentId = ID::unique();
$providerInstallationId = $installation->getAttribute('providerInstallationId', '');
@@ -235,7 +235,7 @@ class Base extends Action
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration
@@ -265,22 +265,6 @@ 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
@@ -1,108 +0,0 @@
<?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());
}
}
@@ -1,101 +0,0 @@
<?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());
}
}
@@ -1,108 +0,0 @@
<?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());
}
}
@@ -1,101 +0,0 @@
<?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());
}
}
@@ -1,108 +0,0 @@
<?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());
}
}
@@ -1,101 +0,0 @@
<?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());
}
}
@@ -1,119 +0,0 @@
<?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());
}
}
@@ -1,106 +0,0 @@
<?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());
}
}
@@ -6,7 +6,6 @@ use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Functions\EventProcessor;
use Appwrite\Platform\Modules\Databases\Http\Databases\Action as DatabasesAction;
use Appwrite\Utopia\Database\Validator\CustomId;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
@@ -251,35 +250,6 @@ abstract class Action extends DatabasesAction
return $document;
}
/**
* Validate relationship values.
* Handles Document objects, ID strings, and associative arrays.
*/
protected function validateRelationship(mixed $relation): void
{
$relationId = null;
if ($relation instanceof Document) {
$relationId = $relation->getId();
} elseif (\is_string($relation)) {
$relationId = $relation;
} elseif (\is_array($relation) && !\array_is_list($relation)) {
$relationId = $relation['$id'] ?? null;
} else {
throw new Exception(Exception::RELATIONSHIP_VALUE_INVALID, 'Relationship value must be an object, document ID string, or associative array');
}
if ($relationId !== null) {
if (!\is_string($relationId)) {
throw new Exception(Exception::RELATIONSHIP_VALUE_INVALID, 'Relationship $id must be a string');
}
$validator = new CustomId();
if (!$validator->isValid($relationId)) {
throw new Exception(Exception::RELATIONSHIP_VALUE_INVALID, $validator->getDescription());
}
}
}
/**
* Resolves relationships in a document and attaches metadata.
*/
@@ -319,9 +319,6 @@ class Create extends Action
$relation['$id'] = ID::unique();
$relation = new Document($relation);
}
$this->validateRelationship($relation);
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
@@ -210,9 +210,6 @@ class Update extends Action
$relation['$id'] = ID::unique();
$relation = new Document($relation);
}
$this->validateRelationship($relation);
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
@@ -220,9 +220,6 @@ class Upsert extends Action
$relation['$id'] = ID::unique();
$relation = new Document($relation);
}
$this->validateRelationship($relation);
if ($relation instanceof Document) {
$relation = $this->removeReadonlyAttributes($relation, $isAPIKey || $isPrivilegedUser);
@@ -1,67 +0,0 @@
<?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(...));
}
}
@@ -1,68 +0,0 @@
<?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(...));
}
}
@@ -1,67 +0,0 @@
<?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(...));
}
}
@@ -1,68 +0,0 @@
<?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(...));
}
}
@@ -4,7 +4,6 @@ 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;
@@ -52,11 +51,7 @@ 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).')
@@ -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\Deprecated;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response as UtopiaResponse;
@@ -53,10 +53,7 @@ class Update extends StringUpdate
model: $this->getResponseModel(),
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'tablesDB.updateTextColumn',
)
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).')
@@ -1,67 +0,0 @@
<?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(...));
}
}
@@ -1,68 +0,0 @@
<?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(...));
}
}
@@ -1,70 +0,0 @@
<?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(...));
}
}
@@ -1,71 +0,0 @@
<?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(...));
}
}
@@ -20,10 +20,6 @@ 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;
@@ -32,12 +28,8 @@ 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;
@@ -198,22 +190,6 @@ 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
@@ -23,10 +23,6 @@ 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;
@@ -35,12 +31,8 @@ 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;
@@ -178,22 +170,6 @@ 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
@@ -87,7 +87,7 @@ class Create extends Base
->param('logging', true, new Boolean(), 'When disabled, executions will exclude logs and errors, and will be slightly faster.', true)
->param('entrypoint', '', new Text(1028, 0), 'Entrypoint File. This path is relative to the "providerRootDirectory".', true)
->param('commands', '', new Text(8192, 0), 'Build Commands.', true)
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('projectScopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for API key auto-generated for every execution. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.', true)
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for API key auto-generated for every execution. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.', true)
->param('installationId', '', new Text(128, 0), 'Appwrite Installation ID for VCS (Version Control System) deployment.', true)
->param('providerRepositoryId', '', new Text(128, 0), 'Repository ID of the repo linked to the function.', true)
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function.', true)
@@ -83,7 +83,7 @@ class Update extends Base
->param('logging', true, new Boolean(), 'When disabled, executions will exclude logs and errors, and will be slightly faster.', true)
->param('entrypoint', '', new Text(1028, 0), 'Entrypoint File. This path is relative to the "providerRootDirectory".', true)
->param('commands', '', new Text(8192, 0), 'Build Commands.', true)
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('projectScopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for API Key auto-generated for every execution. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.', true)
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for API Key auto-generated for every execution. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.', true)
->param('installationId', '', new Text(128, 0), 'Appwrite Installation ID for VCS (Version Controle System) deployment.', true)
->param('providerRepositoryId', null, new Nullable(new Text(128, 0)), 'Repository ID of the repo linked to the function', true)
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function', true)
@@ -7,7 +7,6 @@ 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;
@@ -51,7 +50,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(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('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('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)
@@ -1037,7 +1037,7 @@ class Builds extends Action
// VCS branch
$branchName = $deployment->getAttribute('providerBranch');
if (!empty($branchName)) {
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$branchPrefix = substr($branchName, 0, 16);
if (strlen($branchName) > 16) {
$remainingChars = substr($branchName, 16);
@@ -88,7 +88,6 @@ class Create extends Action
->inject('queueForBuilds')
->inject('plan')
->inject('authorization')
->inject('platform')
->callback($this->action(...));
}
@@ -109,8 +108,7 @@ class Create extends Action
Device $deviceForLocal,
Build $queueForBuilds,
array $plan,
Authorization $authorization,
array $platform,
Authorization $authorization
) {
$activate = \strval($activate) === 'true' || \strval($activate) === '1';
@@ -274,7 +272,7 @@ class Create extends Action
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration
@@ -344,7 +342,7 @@ class Create extends Action
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
$ruleId = md5($domain);
$authorization->skip(
@@ -66,7 +66,6 @@ class Create extends Action
->inject('queueForBuilds')
->inject('deviceForSites')
->inject('authorization')
->inject('platform')
->callback($this->action(...));
}
@@ -81,8 +80,7 @@ class Create extends Action
Event $queueForEvents,
Build $queueForBuilds,
Device $deviceForSites,
Authorization $authorization,
array $platform
Authorization $authorization
) {
$site = $dbForProject->getDocument('sites', $siteId);
@@ -145,7 +143,7 @@ class Create extends Action
$dbForProject->updateDocument('sites', $site->getId(), $site);
// Preview deployments for sites
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration
@@ -80,7 +80,6 @@ class Create extends Base
->inject('queueForBuilds')
->inject('gitHub')
->inject('authorization')
->inject('platform')
->callback($this->action(...));
}
@@ -100,8 +99,7 @@ class Create extends Base
Event $queueForEvents,
Build $queueForBuilds,
GitHub $github,
Authorization $authorization,
array $platform
Authorization $authorization
) {
$site = $dbForProject->getDocument('sites', $siteId);
@@ -135,7 +133,6 @@ class Create extends Base
github: $github,
activate: $activate,
authorization: $authorization,
platform: $platform
);
$queueForEvents
@@ -189,7 +186,7 @@ class Create extends Base
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
$sitesDomain = $platform['sitePreviewDomain'];
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
// TODO: (@Meldiron) Remove after 1.7.x migration
@@ -74,7 +74,6 @@ class Create extends Base
->inject('queueForBuilds')
->inject('gitHub')
->inject('authorization')
->inject('platform')
->callback($this->action(...));
}
@@ -91,8 +90,7 @@ class Create extends Base
Event $queueForEvents,
Build $queueForBuilds,
GitHub $github,
Authorization $authorization,
array $platform
Authorization $authorization
) {
$site = $dbForProject->getDocument('sites', $siteId);
@@ -117,8 +115,7 @@ class Create extends Base
activate: $activate,
authorization: $authorization,
reference: $reference,
referenceType: $type,
platform: $platform
referenceType: $type
);
$queueForEvents
@@ -7,7 +7,6 @@ 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;
@@ -50,7 +49,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(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('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('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')
-29
View File
@@ -12,7 +12,6 @@ use Appwrite\SDK\Language\Flutter;
use Appwrite\SDK\Language\Go;
use Appwrite\SDK\Language\GraphQL;
use Appwrite\SDK\Language\Kotlin;
use Appwrite\SDK\Language\Markdown;
use Appwrite\SDK\Language\Node;
use Appwrite\SDK\Language\PHP;
use Appwrite\SDK\Language\Python;
@@ -32,27 +31,6 @@ use Utopia\Validator\WhiteList;
class SDKs extends Action
{
protected array $supportedSDKS = [
'web',
'cli',
'php',
'nodejs',
'deno',
'python',
'ruby',
'flutter',
'react-native',
'dart',
'go',
'swift',
'apple',
'dotnet',
'android',
'graphql',
'rest',
'markdown',
];
public static function getName(): string
{
return 'sdks';
@@ -83,9 +61,6 @@ class SDKs extends Action
if (!$sdks) {
$selectedPlatform ??= Console::confirm('Choose Platform ("' . implode('", "', static::getPlatforms()) . '" or "*" for all):');
$selectedSDK ??= \strtolower(Console::confirm('Choose SDK ("*" for all):'));
if ($selectedSDK !== '*' && !\in_array($selectedSDK, $this->supportedSDKS)) {
throw new \Exception('Unknown SDK "' . $selectedSDK . '" given. Options are: ' . implode(', ', $this->supportedSDKS));
}
} else {
$sdks = explode(',', $sdks);
}
@@ -277,10 +252,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
case 'rest':
$config = new REST();
break;
case 'markdown':
$config = new Markdown();
$config->setNPMPackage('@appwrite.io/docs');
break;
default:
throw new \Exception('Language "' . $language['key'] . '" not supported');
}
+2 -2
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.', true)
->param('variables', '', new Text(16384), 'JSON of env variables to use when setting up the site.')
->callback($this->action(...));
}
@@ -190,7 +190,7 @@ class Screenshot extends Action
'cookie' => $cookieConsole
], [
'name' => 'Screenshot API key',
'scopes' => \array_keys(Config::getParam('projectScopes', []))
'scopes' => \array_keys(Config::getParam('scopes', []))
]);
if ($response['headers']['status-code'] !== 201) {
@@ -276,7 +276,7 @@ class Certificates extends Action
]));
// Rule not found (or) not in the expected state
if ($rule->isEmpty() || !\in_array($rule->getAttribute('status'), [RULE_STATUS_CERTIFICATE_GENERATING, RULE_STATUS_VERIFIED])) {
if ($rule->isEmpty() || $rule->getAttribute('status') !== RULE_STATUS_CERTIFICATE_GENERATING) {
Console::warning('Certificate generation for ' . $domain->get() . ' is skipped as the associated rule is either empty or not in the expected state.');
return;
}
+1 -31
View File
@@ -125,9 +125,6 @@ class Deletes extends Action
case DELETE_TYPE_USERS:
$this->deleteUser($getProjectDB, $document, $project);
break;
case DELETE_TYPE_TEAMS:
$this->deleteTeam($getProjectDB, $document, $project);
break;
case DELETE_TYPE_BUCKETS:
$this->deleteBucket($getProjectDB, $deviceForFiles, $document, $project);
break;
@@ -533,7 +530,7 @@ class Deletes extends Action
}
/**
* @var Database $dbForProject
* @var $dbForProject Database
*/
$dbForProject = $getProjectDB($document);
@@ -664,24 +661,6 @@ class Deletes extends Action
}
}
private function deleteTeam(callable $getProjectDB, Document $document, Document $project): void
{
$teamId = $document->getId();
$teamInternalId = $document->getSequence();
$dbForProject = $getProjectDB($project);
if ($project->getId() === 'console') {
// Delete Keys
$this->deleteByGroup('keys', [
Query::equal('resourceInternalId', [$teamInternalId]),
Query::equal('resourceType', ['teams']),
Query::orderAsc()
], $dbForProject);
}
$dbForProject->purgeCachedDocument('teams', $teamId);
}
/**
* @param callable $getProjectDB
* @param Document $document user document
@@ -701,15 +680,6 @@ class Deletes extends Action
Query::orderAsc()
], $dbForProject);
if ($project->getId() === 'console') {
// Delete Keys
$this->deleteByGroup('keys', [
Query::equal('resourceInternalId', [$userInternalId]),
Query::equal('resourceType', ['users']),
Query::orderAsc()
], $dbForProject);
}
$dbForProject->purgeCachedDocument('users', $userId);
// Delete Memberships and decrement team membership counts

Some files were not shown because too many files have changed in this diff Show More